Compare commits

...

124 Commits

Author SHA1 Message Date
dan 14faa061fd Fix an almost entirely harmless buffer overread in the sessions module.
FossilOrigin-Name: 89b0ee3351381f7bc666cb206f77a56f2e0d4a0e
2016-04-29 10:13:22 +00:00
dan 8443533178 Merge latest changes from trunk with this branch.
FossilOrigin-Name: 45467ee49872f495d5276cf830f10c3cf4ac8e3c
2016-04-28 14:59:05 +00:00
dan 14cee38be8 Avoid running sessionfault.test and sessionfault2.test as part of the "inmemory_journal" permutation.
FossilOrigin-Name: 5973d3bf2e5aa979ccc9a4a3a0eb08b67098b499
2016-04-28 14:54:54 +00:00
drh 75ab50ce8f Use comments to mark several branches as optimizations. No changes to code.
FossilOrigin-Name: 33e627472780b872716c504f2d585cc057c390a5
2016-04-28 14:15:12 +00:00
dan 3104c4d6f4 Ensure that quota.test deletes the directory named "test.db" that it creates.
FossilOrigin-Name: 045edd4b17c6b76079ac90773c035d8c1f8d525d
2016-04-28 09:53:14 +00:00
drh 10c0a2a7c9 Remove an unnecessary conditional from the sqlite3DecOrHexToI64() routine.
FossilOrigin-Name: fcf85bfe50b254e825ee63a4cd0aa0b333b06eed
2016-04-28 03:52:18 +00:00
drh 609d5846ba Change the sqlite3Atoi64() routine so that it returns failure if not all of
the input characters are consumed, even if it consumed all characters up to
the first 0x00.  This has no impact on external APIs as far as I can tell.

FossilOrigin-Name: 46d4ffff3bd33d7e901e76cfac1cbde38d4f61d0
2016-04-28 00:32:16 +00:00
dan 05accd2216 Modify the permutations.test script so as to set any permutation specific configuration values before running each individual test script.
FossilOrigin-Name: 2662d8fef791f7b8b3b14f9c27dfedec84620dee
2016-04-27 18:54:49 +00:00
drh ad975d539e More simplification of the sqlite3AtoF() routine. Add special comments
to indicate branches that are for optimization purposes only and that give
the correct answer even if always or never taken.

FossilOrigin-Name: 0065fe97cb8e5076acae1bf1560fd2f69dab9014
2016-04-27 15:24:13 +00:00
drh c6daa01c05 Remove still more unnecessary branches from sqlite3AtoF().
FossilOrigin-Name: 3adfe9f3e6ce7cc09fcb570d9b65e830a96cac15
2016-04-27 02:35:03 +00:00
drh 15af62acff Further simplifications to sqlite3AtoF() to remove unneeded branches.
FossilOrigin-Name: dd69e53cb077873171af5312c633ca185595bf31
2016-04-26 23:14:45 +00:00
drh e5f06fdc87 Remove an unnecessary line from the sqlite3AtoF() routine.
FossilOrigin-Name: a9d007494cfe30a26dca5352655dc7702351476e
2016-04-26 21:02:53 +00:00
drh 97a7e5e68c The pcache and the built-in VFSes should not use mutexes when
SQLITE_CONFIG_SINGLETHREAD is set.

FossilOrigin-Name: 12418b100196abbfbfb85e0ab4bb6b1cbf335df7
2016-04-26 18:58:54 +00:00
drh b283a0cde9 Fix the "checksymbols" target in Makefile.in to be able to deal with the
sqlite3changegroup family of interfaces.

FossilOrigin-Name: d819bfbd46dc7f065d2a3ab0ef9f8322d8394e11
2016-04-26 13:13:53 +00:00
dan ae20690e2c Update the RBU vacuum code so that databases that use custom collation sequences can be vacuumed.
FossilOrigin-Name: 7dd48c10790a7b9c4165214399c261a0aa701297
2016-04-25 19:25:12 +00:00
drh b1ec87afdb When checking for the WHERE-clause push-down optimization, verify that
all terms of the compound inner SELECT are non-aggregate, not just the
last term.  Fix for ticket [f7f8c97e97597].

FossilOrigin-Name: ec215f94ac9748c0acd82af0cc9e7a92249462f9
2016-04-25 02:20:10 +00:00
mistachkin 1de86ca17f Fix a typo in the Makefile.
FossilOrigin-Name: d0a579b35105810821bbfec6b50ecfebac7a17ee
2016-04-25 01:43:24 +00:00
drh 23ee893752 Fix the fix to the temporary directory search algorithm so that it continues
to return "." as a fallback if that directory has the correct permissions.

FossilOrigin-Name: b38fe522cfc971b37ca04e7b63a92bbb6e0b01e1
2016-04-23 20:59:23 +00:00
drh 7694e06461 Change the temporary directory search algorithm on unix so that directories
with only -wx permission are allowed.  And do not allow "." to be returned if
it lacks -wx permission.

FossilOrigin-Name: 67985761aa93fb613b87d340e75371fa55b0f778
2016-04-21 23:37:24 +00:00
dan 83b74f29c5 Add the sqlite3rbu_vacuum() API, to create an RBU handle that can be used to rebuild a database in the same way as the VACUUM command.
FossilOrigin-Name: bd4a6f8313eb71399a7141ebf7f2617d7b1464c3
2016-04-21 18:13:37 +00:00
dan b7a208686a If a call to sqlite3rbu_close() on an rbu handle opened by sqlite3rbu_vacuum() returns other than SQLITE_OK, delete the contents of the rbu_state table. This ensures that if an RBU vacuum operation either completes successfully or encounters an error, the next call to sqlite3rbu_vacuum() with the same parameters starts a new RBU vacuum operation.
FossilOrigin-Name: 6e4ac704f51bdd1e0b16814f6a45ab29f26400ee
2016-04-21 16:44:38 +00:00
dan 2e8bfb67d4 Fix a problem in rbu vacuum on tables with a large sqlite_master table.
FossilOrigin-Name: 23eac52e987996afe8db847921aef434cebd25b5
2016-04-21 15:26:26 +00:00
drh 26f7977c53 Add the SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION method for enabling
sqlite3_load_extension() while leaving the load_extension() SQL function
disabled.

FossilOrigin-Name: c4f165c460c4244ed434107feac005efa3c386cf
2016-04-21 02:27:56 +00:00
drh f602a16123 Test cases for SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION.
FossilOrigin-Name: debafa5efd37ac60e030d0963ce8e7c4f51a0f10
2016-04-21 01:58:21 +00:00
drh 191dd06195 Revert sqlite3_enable_load_extension() to its original long-standing behavior.
Add SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION which will enable only the C-API and
leave the SQL function disabled.

FossilOrigin-Name: b2ae5bfa32e608625bd177907596df3dbc2212e1
2016-04-21 01:30:09 +00:00
dan 94d49697b5 Add a documentation comment for sqlite3rbu_vacuum() to sqlite3rbu.h.
FossilOrigin-Name: da5c753ddac3cbfdf03710a82f5fd9fa2e29e819
2016-04-20 20:08:58 +00:00
drh cdce61e133 When an error occurs while transitioning out of WAL mode, make sure the
locking state is not left at EXCLUSIVE.

FossilOrigin-Name: 3340f086510b08ce5b42a8781f1df51bf7c27701
2016-04-20 19:30:47 +00:00
drh 333f80562b Fix a locking race condition in Windows 10 that can occur when two or more
processes attempt to recover the same hot journal at the same time.

FossilOrigin-Name: 38a4e9d92887898b779493c71e4500f777a4e2e7
2016-04-20 18:31:27 +00:00
dan 132dde5cdf Add fault injection tests for rbu vacuum. Fix some problems revealed by the same.
FossilOrigin-Name: f042fdd1ea7febec7228e51efc2b0281805e196a
2016-04-20 17:47:52 +00:00
drh 1a55dedf7b <b>API Change:</b> Modify sqlite3_enable_load_extension() so that it only
enables/disables the load_extension() SQL function, and leaves the C-APIs
enabled at all times.  In this way, applications can enable extension loading
for the C interface without having to expose that capability to the SQL.

FossilOrigin-Name: edb454e45ae008e051e2f48d704a855b0c3e4be9
2016-04-20 00:30:05 +00:00
dan 1aea63032a Updates to ensure the values of PRAGMA settings like "page_size", "auto_vacuum", "user_version" and "application_id" are not lost when a database is RBU vacuumed.
FossilOrigin-Name: 74ffea76b8c9ddd7699ce6ca77dce005bd7922ac
2016-04-19 19:27:09 +00:00
dan 46f0035b48 When an RBU vacuum is started on a db identified using a URI filename, pass the same URI parameters when creating the new version of the db. This ensures that RBU vacuum works with password protected databases.
FossilOrigin-Name: ca021ba88106500f347ed65199a4832bc9eb5ef8
2016-04-19 17:11:05 +00:00
dan bff4b6367c Detect attempts to use rbu vacuum on a wal mode database (not allowed). And attempts to write to a database in the middle of an rbu vacuum (which prevents the vacuum from resuming).
FossilOrigin-Name: 00b2f4b09ffca5156e43c4db2bfe0b2c979c49b0
2016-04-19 16:20:24 +00:00
dan 58e3812988 Another fix to rbu vacuum for a zipvfs case.
FossilOrigin-Name: 29407d70e44ad9ea5ddaf1011d0e212b602a3ddf
2016-04-18 21:00:01 +00:00
dan beccf1d16f Fix some zipvfs related problems in RBU vacuum.
FossilOrigin-Name: d76f4aaa4caab713460421bd27365a82ac986c20
2016-04-18 18:18:18 +00:00
drh a6dddd9bde Remove quotes from identifiers used as datatype names in a CREATE TABLE
statement.  Fix for ticket [7d7525cb01b68]

FossilOrigin-Name: eba27d4d17a76884292667d570d542e580ee3e77
2016-04-18 15:46:14 +00:00
drh f9986d90d1 The last parameter to pread64() and pwrite64() should be off64_t, not off_t.
FossilOrigin-Name: 3a7d72986fabe9434ff5bd02c93169314f072b23
2016-04-18 13:09:55 +00:00
dan 303a094466 Add the -vacuum switch to the "rbu" demonstration program.
FossilOrigin-Name: 9a0078a538c7e73a009960347b8953c5af99fefd
2016-04-18 09:17:05 +00:00
dan 2bb5f4478e Changes so that rbu vacuum works with zipvfs databases.
FossilOrigin-Name: bae7f875f476f6e01112751cb404fef42ba0a01c
2016-04-16 19:02:53 +00:00
dan 977cbe78b3 Avoid creating any extra files ("<target>-vacuum") when running an RBU vacuum. Ensure that the OAL file created is "<target>-oal", not "<target>-vacuum-oal".
FossilOrigin-Name: dc19aacc7e99213edca9bb57b5c11a8a1ac99113
2016-04-16 17:53:14 +00:00
dan ee65eea4af Fix a couple of assert() statements that were failing with OOM error tests.
FossilOrigin-Name: 8eb3d7d8360530f364bbbebac53e1f0e6753d924
2016-04-16 15:03:20 +00:00
dan f89157653a Add the experimental sqlite3rbu_vacuum() API function. For opening an RBU handle that rebuilds a database from scratch.
FossilOrigin-Name: 0216b48f28042ad86711e00802c2da8ce9be3044
2016-04-15 20:46:41 +00:00
drh eacd29d484 CLI enhancement: Add the ".eqp full" option, that shows both the EXPLAIN
QUERY PLAN and the EXPLAIN output for each command run.  Also disable
any ".wheretrace" and ".selecttrace" when showing EQP output.

FossilOrigin-Name: 3e217d6265ecd16db783bed7ce1d9d0f9c4828bb
2016-04-15 15:03:27 +00:00
dan 5313f2e12e In the ICU extension toupper() and tolower() SQL functions, avoid calling u_strToUpper() or u_strToLower() a second time if the buffer passed to the first invocation turns out to be large enough.
FossilOrigin-Name: d23e581351fb8eea28e7b13b3dcadfc817c3a05f
2016-04-14 17:29:13 +00:00
drh 497116007e Add the SF_HasAgg constant (currently unused). Also enhance the comments on
many other constant definitions to detail constraints on their values.

FossilOrigin-Name: 7b7a69d098f7581a43b818c251717c2450b797de
2016-04-14 16:40:13 +00:00
dan fc26f7cfed Correctly interpret negative "PRAGMA cache_size" values when determining the cache-size used for sorting large amounts of data (i.e. the functionality in vdbesort.c).
FossilOrigin-Name: 79147dca87cfd7eb62d57baa3b70fa2a8542232a
2016-04-14 15:44:37 +00:00
drh 7111c93c40 Add some missing testcase() macros to the pushDownWhereTerms() routine.
FossilOrigin-Name: 67d7f79c5e5be41a18817c802b5c4d349e3a83a4
2016-04-14 15:38:33 +00:00
drh f1b5ff73cb Rename WhereInfo.pResultSet to pDistinctSet to more accurately reflect what
it represents.

FossilOrigin-Name: 5317961411695e107e8cefdeaba62280429979ca
2016-04-14 13:35:26 +00:00
drh 8f2ce91462 Since the return value of sqlite3OsClose() is always ignored, we might as
well make it "void" instead of "int", and thereby save 50 bytes in the
compiled binary.

FossilOrigin-Name: 7ee570e7a9a2159a8c0d41805c00f91ca0de00e3
2016-04-14 13:16:58 +00:00
drh 7512cb47e8 Additional ".selecttrace" debugging output when the query is transformed from a
DISTINCT into a GROUP BY.

FossilOrigin-Name: 5a46914510af4d5557b299db65c68d5df1070766
2016-04-14 13:06:49 +00:00
drh 07d683fdbc Fix compiler warnings by removing surplus local variables in the schema
pretty-printer logic of the command-line shell.

FossilOrigin-Name: 55a62483b9121a8b373d038a26fdebc4308661f6
2016-04-13 21:00:36 +00:00
drh 0cb64edc95 Fixes for harmless compiler warnings.
FossilOrigin-Name: 68142dc541b7a0a36fcb075a26f10f03c1e7c422
2016-04-13 15:52:16 +00:00
drh 4926fec967 Add the --indent option to the .schema and .fullschema commands in the shell,
to enable simple but effective pretty-printing.

FossilOrigin-Name: 83cfe82cd6d31ec0a6193525fd92e63a2a43b142
2016-04-13 15:33:42 +00:00
mistachkin 02d436b1f6 A couple more compiler warning fixes.
FossilOrigin-Name: 929fa4c31e7c5b8c6cbb1412478ea91b15ad5529
2016-04-12 20:26:51 +00:00
mistachkin c5896b5cbb Even more compiler warning fixes.
FossilOrigin-Name: 7faec9ea335c53953338886398b85aef87348a1c
2016-04-12 20:15:12 +00:00
mistachkin 77fac879d2 More harmless compiler warning fixes.
FossilOrigin-Name: ab69527c1608da0b668f3b49e967661dd99cc3d4
2016-04-12 20:05:06 +00:00
mistachkin 02267cc213 Compilation fix for a C99-ism in the 'fts3view' tool.
FossilOrigin-Name: bedb88a4b9c808ea781ae69058399a1a3a3d15fa
2016-04-12 19:30:31 +00:00
mistachkin 74f598b677 Fix harmless compiler warnings in the 'session' module.
FossilOrigin-Name: a18a6ce2271865d04cd75a8a5baa63798b7393db
2016-04-12 19:20:22 +00:00
drh 741c2772db Fix speedtest1 so that it automatically unlinks its test database prior
to startup.

FossilOrigin-Name: b65b69f6b686c6555876b6fc701da95cc49120b5
2016-04-12 17:13:33 +00:00
drh 2160ca5f8d Add the --temp option to the speedtest1.c performance test program.
FossilOrigin-Name: 8053a6e2bf616fc9326f0323962176e318d7d2a5
2016-04-12 16:59:39 +00:00
drh e11003d5ba Improved localtime() support for WindowsCE
FossilOrigin-Name: 662c32af0276a9ef4eea2d29e2523ccc44b6d128
2016-04-12 16:23:30 +00:00
mistachkin 8366ddf242 Add and adjust comments.
FossilOrigin-Name: 541c6da23850673f5d2a2e31c3967b796ee2effc
2016-04-12 16:11:52 +00:00
drh 752b102e9b Add the sqlite3_snapshot_cmp() interface (available only with
SQLITE_ENABLE_SNAPSHOT).

FossilOrigin-Name: 7e7289655185e7643ead6d685922528bc4d9e0ae
2016-04-12 16:04:07 +00:00
dan 745be369c7 Update the documentation for sqlite3_snapshot_cmp() to make the circumstances under which the comparison is valid clearer. Add tests for the same.
FossilOrigin-Name: 8fc834741bf6c8a832a180795c3d6f5c3dcfcd62
2016-04-12 15:14:25 +00:00
drh 70b8d6bbcc Update the header comment on the memjournal.c file. No code changes.
FossilOrigin-Name: 07f10deabb0f4207408142541e3913d638dfcdeb
2016-04-12 11:58:18 +00:00
drh 6f07734349 Performance optimization the Vdbe allocator.
FossilOrigin-Name: e2c4995bf1099cc02bcb1dc4a4631f06a870d171
2016-04-12 00:26:59 +00:00
drh f3c57ff54c Avoid unnecessary calls to object destructors for a small performance gain.
FossilOrigin-Name: aec94b6ee68fe50e2cc14388281e2ef531e21d68
2016-04-12 00:16:54 +00:00
drh 926957f0a6 Performance improvements in sqlite3WhereExprUsage().
FossilOrigin-Name: fdf752394b48fb7b9afe7b8a7d83f859985cc2d2
2016-04-12 00:00:33 +00:00
mistachkin 0cedb963a3 Further refinements.
FossilOrigin-Name: b35bb928b25492f6dd71ccf9c250cb9f0cce09ff
2016-04-11 22:45:45 +00:00
mistachkin 9cdd401d37 Merge updates from trunk.
FossilOrigin-Name: b8094166b3c6a8ec7913b403e08b5e6790fb03c1
2016-04-11 22:24:03 +00:00
mistachkin 4f2c822cc5 Fix typo in the MSVC makefile.
FossilOrigin-Name: 3189a7f1851f823218d85a2455bf218d00d81543
2016-04-11 22:23:04 +00:00
mistachkin 0e188e1d1e Fix some compilation issues.
FossilOrigin-Name: 016481b39f8b23b4f0f851053068d8eaee6122e1
2016-04-11 22:10:26 +00:00
dan ad2d5baf1f Add the sqlite3_snapshot_cmp() API.
FossilOrigin-Name: c698a21af740ca1019c3a771fb83e569cd6bf23e
2016-04-11 19:59:52 +00:00
drh 244b9d6ec6 Performance optimization to sqlite3Dequote() and its callers.
FossilOrigin-Name: 9efe2265b1e70172778d333c5b9d9a76095427ab
2016-04-11 19:01:08 +00:00
drh affa855c94 Performance optimization for the sqlite3ExprListDelete() routine.
FossilOrigin-Name: 2764aeaa11f38cf2ff4d6191e6d5466ddb203022
2016-04-11 18:25:05 +00:00
drh bea119cdeb Performance optimizations in the column cache of the code generator, and
especially the sqlite3ExprCacheRemove() routine.

FossilOrigin-Name: e35b345cf858018ae0c07f79725f8d58062168db
2016-04-11 18:15:37 +00:00
drh 3c19469ca2 Simplification and performance improvements in sqlite3ExprDup() and its
subroutines.  More work is possible in this area.

FossilOrigin-Name: 476cc2838824e0667e80ce527b9caa551dee4a77
2016-04-11 16:43:43 +00:00
drh c310db39ff Rename the OP_MX_JUMP macro to SQLITE_MX_JUMP_OPCODE to avoid confusing the
opcode name generator.

FossilOrigin-Name: e554a4c38bda9c73bf129bb7c665c53ccc4d96a8
2016-04-11 16:35:05 +00:00
drh 4f0010b1bc Performance improvement in sqlite3ExprDelete().
FossilOrigin-Name: 60ad80e3af4bae9f5c74fedf09eec9689e2e3dbf
2016-04-11 14:49:39 +00:00
drh 7cc84c2cdd Remove the VdbeOp.opflags field and its associated initialization overhead.
Update mkopcodeh.tcl to reorder opcode numbers to help the resolveP2Values()
routine run faster.

FossilOrigin-Name: 099478fa7521ba52262ef2bf24dd8f0114ce92e1
2016-04-11 13:36:42 +00:00
drh 8679fbabaa Back off of the parser optimization in the previous check-in, slightly, to
preserve some backwards compatibility regarding some undocumented behavior
in the '#AAA' style query parameter.

FossilOrigin-Name: ef1966c2469a0f5dbdb31a0287bd37badb2b8f28
2016-04-11 01:43:33 +00:00
drh 8f3b137fa6 Small size reduction and performance improvement in the parser.
FossilOrigin-Name: 16df71284bf081c8b3d3aa57c129a07067ddbed3
2016-04-11 01:26:31 +00:00
drh 08de4f7933 Factor out the common operation of setting the Expr.x.pSelect field of an
Expr object into a subroutine.

FossilOrigin-Name: 6a5cceee486c5e3625556e4c7076ff90e9d8fa43
2016-04-11 01:06:47 +00:00
drh ba26faa33f Fix a problem in the code generator for joins on virtual tables where the
outer loop of the join uses the IN operator.

FossilOrigin-Name: 6c56b3a04778bc62ca50307ad838dd301cd91ac2
2016-04-09 18:04:28 +00:00
drh bfc7a8bb01 Fix the sqlite3BtreeDelete() routine so that it preserves the correct
key even when the row being deleted is not on a leaf page.
Fix for ticket [a306e56ff68b8fa56]

FossilOrigin-Name: ca2ef8a86cf806cbbcc64db03251b1df5b2c5501
2016-04-09 17:04:05 +00:00
drh 53801efcdf Limit the number of digits shown in the "prereq" mask for ".wheretrace"
debugging output.

FossilOrigin-Name: 3686ed7413ae6cdbc8020c0023205e0455e87467
2016-04-09 14:36:07 +00:00
drh 11b264019c Update documentation for sqlite3_snapshot_open(). No code changes.
FossilOrigin-Name: 1dfa5234d3ee38c6af2d18a6294afa93232821e7
2016-04-08 19:44:31 +00:00
drh dca595c4a3 Add test cases for ticket [7f7f8026eda387d544].
FossilOrigin-Name: 87aa9357fbe6749bae60e30af54ca16e48678802
2016-04-07 21:14:35 +00:00
drh 38b3dde00e Prevent the in-memory journal read cursor from entering an inconsistent state
when it reads the last few bytes out of the journal file.  Fix for
ticket [7f7f8026eda38].

FossilOrigin-Name: c4b9c611bdcd85f31d68aaf114ee34a9f27eba6d
2016-04-07 18:42:23 +00:00
drh 45c3c66385 Avoid decrementing a pointer off the front end of the buffer in OP_MakeRecord.
FossilOrigin-Name: 153135bfb3b8f7c407ccf36571e2d4d5afe28ea3
2016-04-07 14:16:16 +00:00
drh be5000d6bf Instead of just commenting out the unneeded code in the previous check-in,
remove it completely.

FossilOrigin-Name: 8415d4848ab36ca33b23d1fad6b063544de04a3b
2016-04-07 14:05:20 +00:00
drh 3b42be9178 Remove an unnecessary test for a NULL pointer in freeP4().
FossilOrigin-Name: e84e88e31b67afe42e2494d984ab1cafd107465a
2016-04-07 14:01:10 +00:00
drh f878e6e1a7 Update comments on the unix file locking protocol. No changes to code.
FossilOrigin-Name: 716b20de4306de1653ba5bcdbfb8d210d2d46e1a
2016-04-07 13:45:20 +00:00
drh 40dc357a01 Remove an unnecessary branch in the sqlite3LogEstToInt() routine.
FossilOrigin-Name: da81d7afeb0566a09a505ba5fce901e991e4a029
2016-04-05 23:39:53 +00:00
drh ed06a131da Carry table column types through into VIEW definitions, where possible.
FossilOrigin-Name: fb555c3c2af7f5e62ff839658f4fba7b645d3a68
2016-04-05 20:59:12 +00:00
mistachkin 18a1549322 Remove superfluous directories from the Makefile clean targets.
FossilOrigin-Name: 0bf9926c7a7865694edd48535777248e73d86bbf
2016-04-05 19:46:10 +00:00
mistachkin c0d10c8d4f Merge updates from trunk.
FossilOrigin-Name: 00990020d07d7c87b922cdbfa5373298a86bb4b3
2016-04-05 17:59:56 +00:00
drh 60de73e83d Incorrect version of build.c checked in at [87e5f5a6c60e3] (because I
neglected to press the "Save" button on the text editor).  There is no change
to the logic, just improved presentation.

FossilOrigin-Name: cf569f9f2fab1828e4bfced111fd9a6ee23ea8c0
2016-04-05 15:59:23 +00:00
drh aed11f2072 Make sure "0" intended as a NULL pointer is cast to a pointer when used
in a varargs functions parameter.

FossilOrigin-Name: ed128e8b826cd9620b7146d01d461ed28b9a672d
2016-04-05 14:02:16 +00:00
drh 868f0398e4 Remove an unnecessary conditional from the index builder.
FossilOrigin-Name: 87e5f5a6c60e37e943b3ce80617e81b09852515e
2016-04-05 14:01:34 +00:00
drh 1c715f67b9 Use SQLITE_WITHIN() for pointer range comparisons in some testing code.
FossilOrigin-Name: 7cacf4e954c8de5af5efb56d8271a5ac1edc1c04
2016-04-05 13:35:43 +00:00
drh cca6698408 Do not allow pointer arithmetic to move a pointer across a memory allocation
boundary.

FossilOrigin-Name: 85b979319bcb8ec301ae39b36ad60348e4515be7
2016-04-05 13:19:19 +00:00
drh 73a6bb5851 Fix documentation typos. Comment changes only. No changes to code.
FossilOrigin-Name: d5fc2f7f90f8cbd53810c7a445b0e9c9a0e39182
2016-04-04 18:04:56 +00:00
mistachkin 48dcf2b60b Improve error messages from the 'shell1-5.0' test.
FossilOrigin-Name: cefd36ff7b7f142bcebdb16b4d24ae274cdf2709
2016-04-04 17:59:37 +00:00
drh bdeb125741 Improved handling of UTF8 by the command-line shell.
FossilOrigin-Name: 4534ebf15fbcd6fe2028957b7aa591b6cd5da95f
2016-04-04 17:34:54 +00:00
drh de613c6d4a Add the ".auth ON|OFF" command to the command-line shell.
FossilOrigin-Name: 65c7bcc42786a254966c531ba9062abb8fc8c5bf
2016-04-04 17:23:10 +00:00
dan 455684a036 Test that the view name is passed to the authorization callback when a SELECT statement is run on a view.
FossilOrigin-Name: 8627a4cd6d64bd076b56c1e8ccc3b1dfc1b4c07d
2016-04-04 16:40:44 +00:00
mistachkin 49e1125b69 Add and enhance the new tests.
FossilOrigin-Name: f4cbd18db47af4af990d7891dcc831e92b3f17e0
2016-04-04 15:47:46 +00:00
drh ae0c84bd9e Enhance sqlite3session_apply() and sqlite3session_apply_strm() so that
conflicts are retried before the xConflict() callback is invoked, as long
as the "apply" operation is making forward progress.

FossilOrigin-Name: 42a219668413e18dae917b03b04a21d108cc44be
2016-04-04 14:57:25 +00:00
drh 5fd0c12049 Minor performance optimization in the comparison opcodes of the VDBE.
FossilOrigin-Name: e375fe52cea7903c11ecef71c3452c67a96b663e
2016-04-04 13:46:24 +00:00
drh 51b55a3ee6 Fix harmless compiler warnings.
FossilOrigin-Name: 0213d6af84965676626c2fb4d78b4c74675207cc
2016-04-04 12:38:05 +00:00
mistachkin 1810f22809 Refinements to the previous check-in.
FossilOrigin-Name: b36dfdff787dc4a107b2c3fcbb98bfc4922872d8
2016-04-04 02:33:34 +00:00
mistachkin 1fe36bb8a8 Experimental changes to the command line shell to make it work better with Unicode on Windows.
FossilOrigin-Name: 74183a5f803999e1d4e288851c72519c3c53f6b5
2016-04-04 02:16:44 +00:00
mistachkin 1293120345 More refactoring and cleanup work on the Win32 string conversion and utility routines.
FossilOrigin-Name: 02ccb444a3d0b9a52ffd04cae9d9b6f654128c35
2016-04-04 02:05:46 +00:00
mistachkin 5daed673b8 Revise and enhance the Win32 string conversion routines.
FossilOrigin-Name: 345860c92195544aad44ea9b0d14c9ebbd50adf2
2016-04-03 22:44:16 +00:00
mistachkin 899c5c9d34 Replace the new fprintf() calls.
FossilOrigin-Name: f76c3a0ca40989fe9401c3b6f662f8e6ef2a730c
2016-04-03 20:50:02 +00:00
mistachkin 0784f8a460 Merge updates from trunk.
FossilOrigin-Name: 566b551e5a81440a5c8ff865ceb4422c76d67cf7
2016-04-03 20:45:04 +00:00
drh 076b6468f5 Preupdate hook documentation fixes. No changes to code.
FossilOrigin-Name: 59814f35d13db1f6379b9ae218b5432bc03c6197
2016-04-01 17:54:07 +00:00
drh f6661a8896 When reading an sqlite_stat1 table with missing entries for some indexes,
set the default for the missing indexes after all other indexes are set
so that the default values are more in line with indexes that are actually
in the stat1 table.

FossilOrigin-Name: a62340dc0507e36f6dec05b1fda68d8399ec62ec
2016-04-01 12:35:22 +00:00
mistachkin 2779989110 Update the clean target in the MSVC makefile.
FossilOrigin-Name: 69f4d83210f6425b2c0d699b397ef4fa4422d438
2016-03-31 22:53:37 +00:00
drh 5996a77987 Enhance the query planner so that IS and IS NULL operators are able to drive
an index on a LEFT OUTER JOIN.

FossilOrigin-Name: c648539b52ca28c0b2cb61208e2c32b1d29626a1
2016-03-31 20:40:28 +00:00
mistachkin 6cc16fc070 Cleanup localtime() support for Windows CE.
FossilOrigin-Name: 39759a553208d8ef72964bdd539a0883e1d99cf6
2016-01-23 01:54:15 +00:00
mistachkin e787cbbe2a Merge updates from trunk.
FossilOrigin-Name: 5cbab63756f6f276996f39d16d70b178581f63cd
2016-01-06 20:50:02 +00:00
mistachkin 710b33b999 Alternative to [76f5efa6], move definition of utf8_printf up.
FossilOrigin-Name: 54c5522dda239cb9775709495ed7eb56a5dd8e11
2016-01-03 18:59:28 +00:00
103 changed files with 3606 additions and 1356 deletions
+3 -3
View File
@@ -1032,7 +1032,7 @@ FTS5_SRC = \
fts5parse.c: $(TOP)/ext/fts5/fts5parse.y lemon
cp $(TOP)/ext/fts5/fts5parse.y .
rm -f fts5parse.h
./lemon $(OPTS) fts5parse.y
./lemon$(BEXE) $(OPTS) fts5parse.y
fts5parse.h: fts5parse.c
@@ -1164,8 +1164,9 @@ loadfts$(EXE): $(TOP)/tool/loadfts.c libsqlite3.la
# symbols that do not begin with "sqlite3_". It is run as part of the
# releasetest.tcl script.
#
VALIDIDS=' sqlite3(changeset|changegroup|session)?_'
checksymbols: sqlite3.lo
nm -g --defined-only sqlite3.o | egrep -v ' sqlite3(changeset|session)?_' ; test $$? -ne 0
nm -g --defined-only sqlite3.o | egrep -v $(VALIDIDS); test $$? -ne 0
echo '0 errors out of 1 tests'
# Build the amalgamation-autoconf package. The amalamgation-tarball target builds
@@ -1228,7 +1229,6 @@ clean:
rm -f lemon$(BEXE) lempar.c parse.* sqlite*.tar.gz
rm -f mkkeywordhash$(BEXE) keywordhash.h
rm -f *.da *.bb *.bbg gmon.out
rm -rf quota2a quota2b quota2c
rm -rf tsrc .target_source
rm -f tclsqlite3$(TEXE)
rm -f testfixture$(TEXE) test.db
+2 -5
View File
@@ -1882,7 +1882,7 @@ fts3_write.lo: $(TOP)\ext\fts3\fts3_write.c $(HDR) $(EXTHDR)
rtree.lo: $(TOP)\ext\rtree\rtree.c $(HDR) $(EXTHDR)
$(LTCOMPILE) $(CORE_COMPILE_OPTS) $(NO_WARN) -DSQLITE_CORE -c $(TOP)\ext\rtree\rtree.c
sqlite3session.lo: $(TOP)\ext\session\sqlite3sesion.c $(HDR) $(EXTHDR)
sqlite3session.lo: $(TOP)\ext\session\sqlite3session.c $(HDR) $(EXTHDR)
$(LTCOMPILE) $(CORE_COMPILE_OPTS) $(NO_WARN) -DSQLITE_CORE -c $(TOP)\ext\session\sqlite3session.c
# FTS5 things
@@ -2075,9 +2075,6 @@ clean:
del /Q notasharedlib.* 2>NUL
-rmdir /Q/S .deps 2>NUL
-rmdir /Q/S .libs 2>NUL
-rmdir /Q/S quota2a 2>NUL
-rmdir /Q/S quota2b 2>NUL
-rmdir /Q/S quota2c 2>NUL
-rmdir /Q/S tsrc 2>NUL
del /Q .target_source 2>NUL
del /Q tclsqlite3.exe 2>NUL
@@ -2089,7 +2086,7 @@ clean:
del /Q mptester.exe wordcount.exe rbu.exe srcck1.exe 2>NUL
del /Q sqlite3.c sqlite3-*.c 2>NUL
del /Q sqlite3rc.h 2>NUL
del /Q shell.c sqlite3ext.h 2>NUL
del /Q shell.c sqlite3ext.h sqlite3session.h 2>NUL
del /Q sqlite3_analyzer.exe sqlite3_analyzer.c 2>NUL
del /Q sqlite-*-output.vsix 2>NUL
del /Q fuzzershell.exe fuzzcheck.exe sqldiff.exe 2>NUL
+1 -1
View File
@@ -458,7 +458,7 @@ static int testTokenizerNext(
if( pCsr->iLangid & 0x00000001 ){
for(i=0; i<nToken; i++) pCsr->aBuffer[i] = pToken[i];
}else{
for(i=0; i<nToken; i++) pCsr->aBuffer[i] = testTolower(pToken[i]);
for(i=0; i<nToken; i++) pCsr->aBuffer[i] = (char)testTolower(pToken[i]);
}
pCsr->iToken++;
pCsr->iInput = (int)(p - pCsr->aInput);
+1 -1
View File
@@ -398,8 +398,8 @@ static void showSegmentStats(sqlite3 *db, const char *zTab){
if( sqlite3_step(pStmt)==SQLITE_ROW
&& (nLeaf = sqlite3_column_int(pStmt, 0))>0
){
nIdx = sqlite3_column_int(pStmt, 5);
sqlite3_int64 sz;
nIdx = sqlite3_column_int(pStmt, 5);
printf("For level %d:\n", i);
printf(" Number of indexes...................... %9d\n", nIdx);
printf(" Number of leaf segments................ %9d\n", nLeaf);
+2 -2
View File
@@ -345,11 +345,11 @@ int sqlite3Fts5HashWrite(
if( pHash->eDetail==FTS5_DETAIL_FULL ){
pPtr[p->nData++] = 0x01;
p->nData += sqlite3Fts5PutVarint(&pPtr[p->nData], iCol);
p->iCol = iCol;
p->iCol = (i16)iCol;
p->iPos = 0;
}else{
bNew = 1;
p->iCol = iPos = iCol;
p->iCol = (i16)(iPos = iCol);
}
}
+1 -1
View File
@@ -3244,7 +3244,7 @@ static void fts5IterSetOutputs_Col100(Fts5Iter *pIter, Fts5SegIter *pSeg){
if( aiCol==aiColEnd ) goto setoutputs_col_out;
}
if( *aiCol==iPrev ){
*aOut++ = (iPrev - iPrevOut) + 2;
*aOut++ = (u8)((iPrev - iPrevOut) + 2);
iPrevOut = iPrev;
}
}
+17 -11
View File
@@ -354,15 +354,17 @@ static void icuRegexpFunc(sqlite3_context *p, int nArg, sqlite3_value **apArg){
** http://www.icu-project.org/userguide/posix.html#case_mappings
*/
static void icuCaseFunc16(sqlite3_context *p, int nArg, sqlite3_value **apArg){
const UChar *zInput;
UChar *zOutput = 0;
int nInput;
int nOut;
const UChar *zInput; /* Pointer to input string */
UChar *zOutput = 0; /* Pointer to output buffer */
int nInput; /* Size of utf-16 input string in bytes */
int nOut; /* Size of output buffer in bytes */
int cnt;
int bToUpper; /* True for toupper(), false for tolower() */
UErrorCode status;
const char *zLocale = 0;
assert(nArg==1 || nArg==2);
bToUpper = (sqlite3_user_data(p)!=0);
if( nArg==2 ){
zLocale = (const char *)sqlite3_value_text(apArg[1]);
}
@@ -386,19 +388,23 @@ static void icuCaseFunc16(sqlite3_context *p, int nArg, sqlite3_value **apArg){
}
zOutput = zNew;
status = U_ZERO_ERROR;
if( sqlite3_user_data(p) ){
if( bToUpper ){
nOut = 2*u_strToUpper(zOutput,nOut/2,zInput,nInput/2,zLocale,&status);
}else{
nOut = 2*u_strToLower(zOutput,nOut/2,zInput,nInput/2,zLocale,&status);
}
if( !U_SUCCESS(status) ){
if( status==U_BUFFER_OVERFLOW_ERROR ) continue;
icuFunctionError(p,
sqlite3_user_data(p) ? "u_strToUpper" : "u_strToLower", status);
return;
if( U_SUCCESS(status) ){
sqlite3_result_text16(p, zOutput, nOut, xFree);
}else if( status==U_BUFFER_OVERFLOW_ERROR ){
assert( cnt==0 );
continue;
}else{
icuFunctionError(p, bToUpper ? "u_strToUpper" : "u_strToLower", status);
}
return;
}
sqlite3_result_text16(p, zOutput, nOut, xFree);
assert( 0 ); /* Unreachable */
}
/*
+4 -4
View File
@@ -625,10 +625,10 @@ static int amatchLoadOneRule(
}else{
memset(pRule, 0, sizeof(*pRule));
pRule->zFrom = &pRule->zTo[nTo+1];
pRule->nFrom = nFrom;
pRule->nFrom = (amatch_len)nFrom;
memcpy(pRule->zFrom, zFrom, nFrom+1);
memcpy(pRule->zTo, zTo, nTo+1);
pRule->nTo = nTo;
pRule->nTo = (amatch_len)nTo;
pRule->rCost = rCost;
pRule->iLang = (int)iLang;
}
@@ -1081,7 +1081,7 @@ static void amatchAddWord(
pWord->rCost = rCost;
pWord->iSeq = pCur->nWord++;
amatchWriteCost(pWord);
pWord->nMatch = nMatch;
pWord->nMatch = (short)nMatch;
pWord->pNext = pCur->pAllWords;
pCur->pAllWords = pWord;
pWord->sCost.zKey = pWord->zCost;
@@ -1162,7 +1162,7 @@ static int amatchNext(sqlite3_vtab_cursor *cur){
#endif
nWord = (int)strlen(pWord->zWord+2);
if( nWord+20>nBuf ){
nBuf = nWord+100;
nBuf = (char)(nWord+100);
zBuf = sqlite3_realloc(zBuf, nBuf);
if( zBuf==0 ) return SQLITE_NOMEM;
}
+2 -2
View File
@@ -344,10 +344,10 @@ static int fuzzerLoadOneRule(
memset(pRule, 0, sizeof(*pRule));
pRule->zFrom = pRule->zTo;
pRule->zFrom += nTo + 1;
pRule->nFrom = nFrom;
pRule->nFrom = (fuzzer_len)nFrom;
memcpy(pRule->zFrom, zFrom, nFrom+1);
memcpy(pRule->zTo, zTo, nTo+1);
pRule->nTo = nTo;
pRule->nTo = (fuzzer_len)nTo;
pRule->rCost = nCost;
pRule->iRuleset = (int)iRuleset;
}
+5 -5
View File
@@ -136,7 +136,7 @@ struct ReCompiled {
static void re_add_state(ReStateSet *pSet, int newState){
unsigned i;
for(i=0; i<pSet->nState; i++) if( pSet->aState[i]==newState ) return;
pSet->aState[pSet->nState++] = newState;
pSet->aState[pSet->nState++] = (ReStateNumber)newState;
}
/* Extract the next unicode character from *pzIn and return it. Advance
@@ -358,7 +358,7 @@ static int re_insert(ReCompiled *p, int iBefore, int op, int arg){
p->aArg[i] = p->aArg[i-1];
}
p->nState++;
p->aOp[iBefore] = op;
p->aOp[iBefore] = (char)op;
p->aArg[iBefore] = arg;
return iBefore;
}
@@ -677,12 +677,12 @@ const char *re_compile(ReCompiled **ppRe, const char *zIn, int noCase){
for(j=0, i=1; j<sizeof(pRe->zInit)-2 && pRe->aOp[i]==RE_OP_MATCH; i++){
unsigned x = pRe->aArg[i];
if( x<=127 ){
pRe->zInit[j++] = x;
pRe->zInit[j++] = (unsigned char)x;
}else if( x<=0xfff ){
pRe->zInit[j++] = 0xc0 | (x>>6);
pRe->zInit[j++] = (unsigned char)(0xc0 | (x>>6));
pRe->zInit[j++] = 0x80 | (x&0x3f);
}else if( x<=0xffff ){
pRe->zInit[j++] = 0xd0 | (x>>12);
pRe->zInit[j++] = (unsigned char)(0xd0 | (x>>12));
pRe->zInit[j++] = 0x80 | ((x>>6)&0x3f);
pRe->zInit[j++] = 0x80 | (x&0x3f);
}else{
+10 -10
View File
@@ -390,7 +390,7 @@ static int editdist1(const char *zA, const char *zB, int *pnMatch){
/* Special processing if either string is empty */
if( nA==0 ){
cBprev = dc;
cBprev = (char)dc;
for(xB=res=0; (cB = zB[xB])!=0; xB++){
res += insertOrDeleteCost(cBprev, cB, zB[xB+1])/FINAL_INS_COST_DIV;
cBprev = cB;
@@ -398,7 +398,7 @@ static int editdist1(const char *zA, const char *zB, int *pnMatch){
return res;
}
if( nB==0 ){
cAprev = dc;
cAprev = (char)dc;
for(xA=res=0; (cA = zA[xA])!=0; xA++){
res += insertOrDeleteCost(cAprev, cA, zA[xA+1]);
cAprev = cA;
@@ -420,8 +420,8 @@ static int editdist1(const char *zA, const char *zB, int *pnMatch){
/* Compute the Wagner edit distance */
m[0] = 0;
cx[0] = dc;
cBprev = dc;
cx[0] = (char)dc;
cBprev = (char)dc;
for(xB=1; xB<=nB; xB++){
cBnext = zB[xB];
cB = zB[xB-1];
@@ -429,7 +429,7 @@ static int editdist1(const char *zA, const char *zB, int *pnMatch){
m[xB] = m[xB-1] + insertOrDeleteCost(cBprev, cB, cBnext);
cBprev = cB;
}
cAprev = dc;
cAprev = (char)dc;
for(xA=1; xA<=nA; xA++){
int lastA = (xA==nA);
cA = zA[xA-1];
@@ -476,7 +476,7 @@ static int editdist1(const char *zA, const char *zB, int *pnMatch){
d = m[xB];
dc = cx[xB];
m[xB] = totalCost;
cx[xB] = ncx;
cx[xB] = (char)ncx;
cBprev = cB;
}
cAprev = cA;
@@ -711,9 +711,9 @@ static int editDist3ConfigLoad(
if( nExtra<0 ) nExtra = 0;
pCost = sqlite3_malloc64( sizeof(*pCost) + nExtra );
if( pCost==0 ){ rc = SQLITE_NOMEM; break; }
pCost->nFrom = nFrom;
pCost->nTo = nTo;
pCost->iCost = iCost;
pCost->nFrom = (u8)nFrom;
pCost->nTo = (u8)nTo;
pCost->iCost = (u16)iCost;
memcpy(pCost->a, zFrom, nFrom);
memcpy(pCost->a + nFrom, zTo, nTo);
pCost->pNext = pLang->pCost;
@@ -1616,7 +1616,7 @@ static unsigned char *transliterate(const unsigned char *zIn, int nIn){
zIn += sz;
nIn -= sz;
if( c<=127 ){
zOut[nOut++] = c;
zOut[nOut++] = (unsigned char)c;
}else{
int xTop, xBtm, x;
xTop = sizeof(translit)/sizeof(translit[0]) - 1;
+40 -16
View File
@@ -24,12 +24,22 @@
*/
void usage(const char *zArgv0){
fprintf(stderr,
"Usage: %s [-step NSTEP] TARGET-DB RBU-DB\n"
"Usage: %s ?OPTIONS? TARGET-DB RBU-DB\n"
"\n"
" Argument RBU-DB must be an RBU database containing an update suitable for\n"
" target database TARGET-DB. If NSTEP is set to less than or equal to zero\n"
" (the default value), this program attempts to apply the entire update to\n"
" the target database.\n"
"Where options are:\n"
"\n"
" -step NSTEP\n"
" -vacuum\n"
"\n"
" If the -vacuum switch is not present, argument RBU-DB must be an RBU\n"
" database containing an update suitable for target database TARGET-DB.\n"
" Or, if -vacuum is specified, then TARGET-DB is a database to vacuum using\n"
" RBU, and RBU-DB is used as the state database for the vacuum (refer to\n"
" API documentation for details).\n"
"\n"
" If NSTEP is set to less than or equal to zero (the default value), this \n"
" program attempts to perform the entire update or vacuum operation before\n"
" exiting\n"
"\n"
" If NSTEP is greater than zero, then a maximum of NSTEP calls are made\n"
" to sqlite3rbu_step(). If the RBU update has not been completely applied\n"
@@ -69,29 +79,43 @@ int main(int argc, char **argv){
char *zErrmsg; /* Error message, if any */
sqlite3rbu *pRbu; /* RBU handle */
int nStep = 0; /* Maximum number of step() calls */
int bVacuum = 0;
int rc;
sqlite3_int64 nProgress = 0;
int nArg = argc-2;
/* Process command line arguments. Following this block local variables
** zTarget, zRbu and nStep are all set. */
if( argc==5 ){
size_t nArg1 = strlen(argv[1]);
if( nArg1>5 || nArg1<2 || memcmp("-step", argv[1], nArg1) ) usage(argv[0]);
nStep = atoi(argv[2]);
}else if( argc!=3 ){
usage(argv[0]);
if( argc<3 ) usage(argv[0]);
for(i=1; i<nArg; i++){
const char *zArg = argv[i];
int nArg = strlen(zArg);
if( nArg>1 && nArg<=8 && 0==memcmp(zArg, "-vacuum", nArg) ){
bVacuum = 1;
}else if( nArg>1 && nArg<=5 && 0==memcmp(zArg, "-step", nArg) && i<nArg-1 ){
i++;
nStep = atoi(argv[i]);
}else{
usage(argv[0]);
}
}
zTarget = argv[argc-2];
zRbu = argv[argc-1];
report_default_vfs();
/* Open an RBU handle. If nStep is less than or equal to zero, call
/* Open an RBU handle. A vacuum handle if -vacuum was specified, or a
** regular RBU update handle otherwise. */
if( bVacuum ){
pRbu = sqlite3rbu_vacuum(zTarget, zRbu);
}else{
pRbu = sqlite3rbu_open(zTarget, zRbu, 0);
}
report_rbu_vfs(pRbu);
/* If nStep is less than or equal to zero, call
** sqlite3rbu_step() until either the RBU has been completely applied
** or an error occurs. Or, if nStep is greater than zero, call
** sqlite3rbu_step() a maximum of nStep times. */
pRbu = sqlite3rbu_open(zTarget, zRbu, 0);
report_rbu_vfs(pRbu);
for(i=0; (nStep<=0 || i<nStep) && sqlite3rbu_step(pRbu)==SQLITE_OK; i++);
nProgress = sqlite3rbu_progress(pRbu);
rc = sqlite3rbu_close(pRbu, &zErrmsg);
+98
View File
@@ -0,0 +1,98 @@
# 2016 April 20
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
# May you find forgiveness for yourself and forgive others.
# May you share freely, never taking more than you give.
#
#***********************************************************************
#
# This file contains fault injection tests for RBU vacuum operations.
#
source [file join [file dirname [info script]] rbu_common.tcl]
source $testdir/malloc_common.tcl
set ::testprefix rbufault3
foreach {fault errlist} {
oom-* {
{1 SQLITE_NOMEM}
{1 SQLITE_IOERR_NOMEM}
{1 {SQLITE_NOMEM - out of memory}}
}
ioerr-* {
{1 {SQLITE_IOERR - disk I/O error}}
{1 SQLITE_IOERR}
{1 SQLITE_IOERR_WRITE}
{1 SQLITE_IOERR_FSYNC}
{1 SQLITE_IOERR_READ}
{1 {SQLITE_IOERR - unable to open database: test.db2}}
{1 {SQLITE_ERROR - unable to open database: test.db2}}
{1 {SQLITE_ERROR - SQL logic error or missing database}}
}
cantopen* {
{1 {SQLITE_CANTOPEN - unable to open database: test.db2}}
{1 {SQLITE_CANTOPEN - unable to open database: test.db2}}
{1 {SQLITE_CANTOPEN - unable to open database file}}
{1 SQLITE_CANTOPEN}
}
} {
reset_db
do_execsql_test 0 {
CREATE TABLE target(x UNIQUE, y, z, PRIMARY KEY(y));
INSERT INTO target VALUES(1, 2, 3);
INSERT INTO target VALUES(4, 5, 6);
INSERT INTO target VALUES(7, 8, 9);
CREATE INDEX i1 ON target(z);
}
faultsim_save_and_close
do_faultsim_test 1 -faults $fault -prep {
faultsim_restore_and_reopen
forcedelete test.db2
} -body {
sqlite3rbu_vacuum rbu test.db test.db2
while {[rbu step]=="SQLITE_OK"} {}
rbu close
} -test {
eval [list faultsim_test_result {0 SQLITE_DONE} {*}$::errlist]
}
do_faultsim_test 2 -faults $fault -prep {
faultsim_restore_and_reopen
forcedelete test.db2
} -body {
sqlite3rbu_vacuum rbu test.db test.db2
rbu step
rbu close
} -test {
eval [list faultsim_test_result {0 SQLITE_OK} {*}$::errlist]
}
forcedelete test.db2
sqlite3rbu_vacuum rbu test.db test.db2
rbu step
rbu close
faultsim_save_and_close
do_faultsim_test 3 -faults $fault -prep {
faultsim_restore_and_reopen
forcedelete test.db2
} -body {
sqlite3rbu_vacuum rbu test.db test.db2
rbu step
rbu close
} -test {
eval [list faultsim_test_result {0 SQLITE_OK} {*}$::errlist]
}
}
finish_test
+410
View File
@@ -0,0 +1,410 @@
# 2016 April 15
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
# May you find forgiveness for yourself and forgive others.
# May you share freely, never taking more than you give.
#
#***********************************************************************
#
# This file contains tests for the RBU module. More specifically, it
# contains tests to ensure that the sqlite3rbu_vacuum() API works as
# expected.
#
source [file join [file dirname [info script]] rbu_common.tcl]
set ::testprefix rbuvacuum
proc do_rbu_vacuum_test {tn step} {
uplevel [list do_test $tn.1 {
if {$step==0} { sqlite3rbu_vacuum rbu test.db state.db }
while 1 {
if {$step==1} { sqlite3rbu_vacuum rbu test.db state.db }
set rc [rbu step]
if {$rc!="SQLITE_OK"} break
if {$step==1} { rbu close }
}
rbu close
} {SQLITE_DONE}]
uplevel [list do_execsql_test $tn.2 {
PRAGMA integrity_check
} ok]
}
foreach step {0 1} {
set ::testprefix rbuvacuum-step=$step
reset_db
# Simplest possible vacuum.
do_execsql_test 1.0 {
PRAGMA page_size = 1024;
CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c);
INSERT INTO t1 VALUES(1, 2, 3);
INSERT INTO t1 VALUES(4, 5, 6);
INSERT INTO t1 VALUES(7, 8, 9);
PRAGMA integrity_check;
} {ok}
do_rbu_vacuum_test 1.1 $step
# A vacuum that actually reclaims space.
do_execsql_test 1.2.1 {
INSERT INTO t1 VALUES(8, randomblob(900), randomblob(900));
INSERT INTO t1 VALUES(9, randomblob(900), randomblob(900));
INSERT INTO t1 VALUES(10, randomblob(900), randomblob(900));
INSERT INTO t1 VALUES(11, randomblob(900), randomblob(900));
INSERT INTO t1 VALUES(12, randomblob(900), randomblob(900));
PRAGMA page_count;
} {12}
do_execsql_test 1.2.2 {
DELETE FROM t1 WHERE rowid BETWEEN 8 AND 11;
PRAGMA page_count;
} {12}
do_rbu_vacuum_test 1.2.3 $step
do_execsql_test 1.2.4 {
PRAGMA page_count;
} {3}
# Add an index to the table.
do_execsql_test 1.3.1 {
CREATE INDEX t1b ON t1(b);
INSERT INTO t1 VALUES(13, randomblob(900), randomblob(900));
INSERT INTO t1 VALUES(14, randomblob(900), randomblob(900));
INSERT INTO t1 VALUES(15, randomblob(900), randomblob(900));
INSERT INTO t1 VALUES(16, randomblob(900), randomblob(900));
PRAGMA page_count;
} {18}
do_execsql_test 1.3.2 {
DELETE FROM t1 WHERE rowid BETWEEN 12 AND 15;
PRAGMA page_count;
} {18}
do_rbu_vacuum_test 1.3.3 $step
do_execsql_test 1.3.4 {
PRAGMA page_count;
} {5}
# WITHOUT ROWID table.
do_execsql_test 1.4.1 {
CREATE TABLE t2(a, b, c, PRIMARY KEY(a, b)) WITHOUT ROWID;
INSERT INTO t2 VALUES(randomblob(900), 1, randomblob(900));
INSERT INTO t2 VALUES(randomblob(900), 2, randomblob(900));
INSERT INTO t2 VALUES(randomblob(900), 3, randomblob(900));
INSERT INTO t2 VALUES(randomblob(900), 4, randomblob(900));
INSERT INTO t2 VALUES(randomblob(900), 6, randomblob(900));
INSERT INTO t2 VALUES(randomblob(900), 7, randomblob(900));
INSERT INTO t2 VALUES(randomblob(900), 8, randomblob(900));
DELETE FROM t2 WHERE b BETWEEN 2 AND 7;
PRAGMA page_count;
} {20}
do_rbu_vacuum_test 1.4.2 $step
do_execsql_test 1.4.3 {
PRAGMA page_count;
} {10}
# WITHOUT ROWID table with an index.
do_execsql_test 1.4.1 {
CREATE INDEX t2c ON t2(c);
INSERT INTO t2 VALUES(randomblob(900), 9, randomblob(900));
INSERT INTO t2 VALUES(randomblob(900), 10, randomblob(900));
INSERT INTO t2 VALUES(randomblob(900), 11, randomblob(900));
INSERT INTO t2 VALUES(randomblob(900), 12, randomblob(900));
INSERT INTO t2 VALUES(randomblob(900), 13, randomblob(900));
DELETE FROM t2 WHERE b BETWEEN 8 AND 12;
PRAGMA page_count;
} {35}
do_rbu_vacuum_test 1.4.2 $step
do_execsql_test 1.4.3 {
PRAGMA page_count;
} {15}
do_execsql_test 1.4.4 {
VACUUM;
PRAGMA page_count;
} {15}
do_execsql_test 1.5.1 {
CREATE TABLE t3(a, b, c);
INSERT INTO t3 VALUES('a', 'b', 'c');
INSERT INTO t3 VALUES('d', 'e', 'f');
INSERT INTO t3 VALUES('g', 'h', 'i');
}
do_rbu_vacuum_test 1.5.2 $step
do_execsql_test 1.5.3 {
SELECT * FROM t3
} {a b c d e f g h i}
do_execsql_test 1.5.4 {
CREATE INDEX t3a ON t3(a);
CREATE INDEX t3b ON t3(b);
CREATE INDEX t3c ON t3(c);
INSERT INTO t3 VALUES('j', 'k', 'l');
DELETE FROM t3 WHERE a = 'g';
}
do_rbu_vacuum_test 1.5.5 $step
do_execsql_test 1.5.6 {
SELECT rowid, * FROM t3 ORDER BY b
} {1 a b c 2 d e f 4 j k l}
do_execsql_test 1.6.1 {
CREATE TABLE t4(a PRIMARY KEY, b, c);
INSERT INTO t4 VALUES('a', 'b', 'c');
INSERT INTO t4 VALUES('d', 'e', 'f');
INSERT INTO t4 VALUES('g', 'h', 'i');
}
do_rbu_vacuum_test 1.6.2 $step
do_execsql_test 1.6.3 {
SELECT * FROM t4
} {a b c d e f g h i}
do_execsql_test 1.6.4 {
CREATE INDEX t4a ON t4(a);
CREATE INDEX t4b ON t4(b);
CREATE INDEX t4c ON t4(c);
INSERT INTO t4 VALUES('j', 'k', 'l');
DELETE FROM t4 WHERE a='g';
}
do_rbu_vacuum_test 1.6.5 $step
do_execsql_test 1.6.6 {
SELECT * FROM t4 ORDER BY b
} {a b c d e f j k l}
reset_db
do_execsql_test 1.7.0 {
CREATE TABLE t1(a INTEGER PRIMARY KEY AUTOINCREMENT, b);
INSERT INTO t1 VALUES(NULL, 'one');
INSERT INTO t1 VALUES(NULL, 'two');
DELETE FROM t1 WHERE a=2;
INSERT INTO t1 VALUES(NULL, 'three');
INSERT INTO t1 VALUES(NULL, 'four');
DELETE FROM t1 WHERE a=4;
INSERT INTO t1 VALUES(NULL, 'five');
INSERT INTO t1 VALUES(NULL, 'six');
DELETE FROM t1 WHERE a=6;
SELECT * FROM t1;
} {1 one 3 three 5 five}
do_rbu_vacuum_test 1.7.1 $step
do_execsql_test 1.7.2 {
INSERT INTO t1 VALUES(NULL, 'seven');
SELECT * FROM t1;
} {1 one 3 three 5 five 7 seven}
reset_db
do_execsql_test 1.8.0 {
CREATE TABLE t1(a INTEGER PRIMARY KEY AUTOINCREMENT, b);
CREATE INDEX i1 ON t1(b);
INSERT INTO t1 VALUES(NULL, 'one');
INSERT INTO t1 VALUES(NULL, 'two');
INSERT INTO t1 VALUES(NULL, 'three');
INSERT INTO t1 VALUES(NULL, 'four');
INSERT INTO t1 VALUES(NULL, 'five');
INSERT INTO t1 VALUES(NULL, 'six');
ANALYZE;
SELECT * FROM sqlite_stat1;
} {t1 i1 {6 1}}
do_rbu_vacuum_test 1.8.1 $step
do_execsql_test 1.7.2 {
SELECT * FROM sqlite_stat1;
} {t1 i1 {6 1}}
reset_db
do_execsql_test 1.9.0 {
PRAGMA page_size = 8192;
PRAGMA auto_vacuum = 2;
PRAGMA user_version = 412;
PRAGMA application_id = 413;
CREATE TABLE t1(a INTEGER PRIMARY KEY AUTOINCREMENT, b);
CREATE INDEX i1 ON t1(b);
INSERT INTO t1 VALUES(NULL, 'one');
INSERT INTO t1 VALUES(NULL, 'two');
INSERT INTO t1 VALUES(NULL, 'three');
INSERT INTO t1 VALUES(NULL, 'four');
INSERT INTO t1 VALUES(NULL, 'five');
INSERT INTO t1 VALUES(NULL, 'six');
PRAGMA main.page_size;
PRAGMA main.auto_vacuum;
PRAGMA main.user_version;
PRAGMA main.application_id;
} {8192 2 412 413}
do_rbu_vacuum_test 1.9.1 $step
do_execsql_test 1.9.2 {
PRAGMA main.page_size;
PRAGMA main.auto_vacuum;
PRAGMA main.user_version;
PRAGMA main.application_id;
} {8192 2 412 413}
# Vacuum a database with a large sqlite_master table.
#
reset_db
do_test 1.10.1 {
for {set i 1} {$i < 50} {incr i} {
execsql "PRAGMA page_size = 1024"
execsql "CREATE TABLE t$i (a, b, c, PRIMARY KEY(a, b));"
execsql "
INSERT INTO t$i VALUES(1, 2, 3);
INSERT INTO t$i VALUES(4, 5, 6);
"
}
} {}
do_rbu_vacuum_test 1.10.2 $step
# Database with empty tables.
#
reset_db
do_execsql_test 1.11.1 {
CREATE TABLE t1(a INTEGER PRIMARY KEY, b);
CREATE TABLE t2(a INTEGER PRIMARY KEY, b);
CREATE TABLE t3(a INTEGER PRIMARY KEY, b);
CREATE TABLE t4(a INTEGER PRIMARY KEY, b);
INSERT INTO t4 VALUES(1, 2);
}
do_rbu_vacuum_test 1.11.2 $step
do_execsql_test 1.11.3 {
SELECT * FROM t1;
SELECT * FROM t2;
SELECT * FROM t3;
SELECT * FROM t4;
} {1 2}
reset_db
do_execsql_test 1.12.1 {
CREATE TABLE t1(a INTEGER PRIMARY KEY, b);
CREATE TABLE t2(a INTEGER PRIMARY KEY, b);
CREATE TABLE t3(a INTEGER PRIMARY KEY, b);
CREATE TABLE t4(a INTEGER PRIMARY KEY, b);
INSERT INTO t1 VALUES(1, 2);
}
do_rbu_vacuum_test 1.12.2 $step
do_execsql_test 1.12.3 {
SELECT * FROM t1;
SELECT * FROM t2;
SELECT * FROM t3;
SELECT * FROM t4;
} {1 2}
}
set ::testprefix rbuvacuum
#-------------------------------------------------------------------------
# Test some error cases:
#
# 2.1.* the db being vacuumed being in wal mode already.
# 2.2.* database modified mid vacuum.
#
reset_db
do_execsql_test 2.1.0 {
CREATE TABLE t1(a, b);
INSERT INTO t1 VALUES(1, 2);
INSERT INTO t1 VALUES(3, 4);
INSERT INTO t1 VALUES(5, 6);
INSERT INTO t1 VALUES(7, 8);
PRAGMA journal_mode = wal;
INSERT INTO t1 VALUES(9, 10);
} wal
do_test 2.1.1 {
sqlite3rbu_vacuum rbu test.db state.db
rbu step
} {SQLITE_ERROR}
do_test 2.1.2 {
list [catch { rbu close } msg] $msg
} {1 {SQLITE_ERROR - cannot vacuum wal mode database}}
reset_db
do_execsql_test 2.2.0 {
CREATE TABLE tx(a PRIMARY KEY, b BLOB);
INSERT INTO tx VALUES(1, randomblob(900));
INSERT INTO tx SELECT a+1, randomblob(900) FROM tx;
INSERT INTO tx SELECT a+2, randomblob(900) FROM tx;
INSERT INTO tx SELECT a+4, randomblob(900) FROM tx;
INSERT INTO tx SELECT a+8, randomblob(900) FROM tx;
}
db_save_and_close
for {set i 1} 1 {incr i} {
db_restore_and_reopen
sqlite3rbu_vacuum rbu test.db state.db
for {set step 0} {$step<$i} {incr step} { rbu step }
rbu close
if {[file exists test.db-wal]} break
execsql { INSERT INTO tx VALUES(20, 20) }
do_test 2.2.$i.1 {
sqlite3rbu_vacuum rbu test.db state.db
rbu step
} {SQLITE_BUSY}
do_test 2.2.$i.2 {
list [catch { rbu close } msg] $msg
} {1 {SQLITE_BUSY - database modified during rbu vacuum}}
}
#-------------------------------------------------------------------------
# Test that a database that uses custom collation sequences can be RBU
# vacuumed.
#
reset_db
forcedelete state.db
proc noop {args} {}
proc length_cmp {x y} {
set n1 [string length $x]
set n2 [string length $y]
return [expr $n1 - $n2]
}
sqlite3_create_collation_v2 db length length_cmp noop
do_execsql_test 3.0 {
CREATE TABLE t1(a INTEGER PRIMARY KEY, b);
INSERT INTO t1 VALUES(1, 'i');
INSERT INTO t1 VALUES(2, 'iiii');
INSERT INTO t1 VALUES(3, 'ii');
INSERT INTO t1 VALUES(4, 'iii');
SELECT a FROM t1 ORDER BY b COLLATE length;
} {1 3 4 2}
do_execsql_test 3.1 {
CREATE INDEX i1 ON t1(b COLLATE length);
}
do_test 3.2 {
sqlite3rbu_vacuum rbu test.db state.db
while {[rbu step]=="SQLITE_OK"} {}
list [catch { rbu close } msg] $msg
} {1 {SQLITE_ERROR - no such collation sequence: length}}
do_test 3.3 {
sqlite3rbu_vacuum rbu test.db state.db
set db1 [rbu db 0]
sqlite3_create_collation_v2 $db1 length length_cmp noop
while {[rbu step]=="SQLITE_OK"} {}
list [catch { rbu close } msg] $msg
} {1 {SQLITE_ERROR - no such collation sequence: length}}
do_test 3.4 {
sqlite3rbu_vacuum rbu test.db state.db
set db1 [rbu db 1]
sqlite3_create_collation_v2 $db1 length length_cmp noop
while {[rbu step]=="SQLITE_OK"} {}
list [catch { rbu close } msg] $msg
} {1 {SQLITE_ERROR - no such collation sequence: length}}
do_test 3.5 {
sqlite3rbu_vacuum rbu test.db state.db
set db1 [rbu db 0]
set db2 [rbu db 1]
sqlite3_create_collation_v2 $db1 length length_cmp noop
sqlite3_create_collation_v2 $db2 length length_cmp noop
while {[rbu step]=="SQLITE_OK"} {}
list [catch { rbu close } msg] $msg
} {0 SQLITE_DONE}
catch { db close }
finish_test
+579 -179
View File
File diff suppressed because it is too large Load Diff
+32
View File
@@ -314,6 +314,38 @@ sqlite3rbu *sqlite3rbu_open(
const char *zState
);
/*
** Open an RBU handle to perform an RBU vacuum on database file zTarget.
** An RBU vacuum is similar to SQLite's built-in VACUUM command, except
** that it can be suspended and resumed like an RBU update.
**
** The second argument to this function, which may not be NULL, identifies
** a database in which to store the state of the RBU vacuum operation if
** it is suspended. The first time sqlite3rbu_vacuum() is called, to start
** an RBU vacuum operation, the state database should either not exist or
** be empty (contain no tables). If an RBU vacuum is suspended by calling
** sqlite3rbu_close() on the RBU handle before sqlite3rbu_step() has
** returned SQLITE_DONE, the vacuum state is stored in the state database.
** The vacuum can be resumed by calling this function to open a new RBU
** handle specifying the same target and state databases.
**
** This function does not delete the state database after an RBU vacuum
** is completed, even if it created it. However, if the call to
** sqlite3rbu_close() returns any value other than SQLITE_OK, the contents
** of the state tables within the state database are zeroed. This way,
** the next call to sqlite3rbu_vacuum() opens a handle that starts a
** new RBU vacuum operation.
**
** As with sqlite3rbu_open(), Zipvfs users should rever to the comment
** describing the sqlite3rbu_create_vfs() API function below for
** a description of the complications associated with using RBU with
** zipvfs databases.
*/
sqlite3rbu *sqlite3rbu_vacuum(
const char *zTarget,
const char *zState
);
/*
** Internally, each RBU connection uses a separate SQLite database
** connection to access the target and rbu update databases. This
+49 -2
View File
@@ -20,8 +20,9 @@
#include <tcl.h>
#include <assert.h>
/* From main.c (apparently...) */
/* From main.c */
extern const char *sqlite3ErrName(int);
extern int sqlite3TestMakePointerStr(Tcl_Interp*, char*, void*);
void test_rbu_delta(sqlite3_context *pCtx, int nArg, sqlite3_value **apVal){
Tcl_Interp *interp = (Tcl_Interp*)sqlite3_user_data(pCtx);
@@ -66,7 +67,8 @@ static int test_sqlite3rbu_cmd(
{"create_rbu_delta", 2, ""}, /* 2 */
{"savestate", 2, ""}, /* 3 */
{"dbMain_eval", 3, "SQL"}, /* 4 */
{"bp_progress", 2, ""}, /* 5 */
{"bp_progress", 2, ""}, /* 5 */
{"db", 3, "RBU"}, /* 6 */
{0,0,0}
};
int iCmd;
@@ -149,6 +151,22 @@ static int test_sqlite3rbu_cmd(
break;
}
case 6: /* db */ {
int bArg;
if( Tcl_GetBooleanFromObj(interp, objv[2], &bArg) ){
ret = TCL_ERROR;
}else{
char zBuf[50];
sqlite3 *db = sqlite3rbu_db(pRbu, bArg);
if( sqlite3TestMakePointerStr(interp, zBuf, (void*)db) ){
ret = TCL_ERROR;
}else{
Tcl_SetResult(interp, zBuf, TCL_VOLATILE);
}
}
break;
}
default: /* seems unlikely */
assert( !"cannot happen" );
break;
@@ -187,6 +205,34 @@ static int test_sqlite3rbu(
return TCL_OK;
}
/*
** Tclcmd: sqlite3rbu_vacuum CMD <target-db> <state-db>
*/
static int test_sqlite3rbu_vacuum(
ClientData clientData,
Tcl_Interp *interp,
int objc,
Tcl_Obj *CONST objv[]
){
sqlite3rbu *pRbu = 0;
const char *zCmd;
const char *zTarget;
const char *zStateDb = 0;
if( objc!=4 ){
Tcl_WrongNumArgs(interp, 1, objv, "NAME TARGET-DB STATE-DB");
return TCL_ERROR;
}
zCmd = Tcl_GetString(objv[1]);
zTarget = Tcl_GetString(objv[2]);
zStateDb = Tcl_GetString(objv[3]);
pRbu = sqlite3rbu_vacuum(zTarget, zStateDb);
Tcl_CreateObjCommand(interp, zCmd, test_sqlite3rbu_cmd, (ClientData)pRbu, 0);
Tcl_SetObjResult(interp, objv[1]);
return TCL_OK;
}
/*
** Tclcmd: sqlite3rbu_create_vfs ?-default? NAME PARENT
*/
@@ -274,6 +320,7 @@ int SqliteRbu_Init(Tcl_Interp *interp){
Tcl_ObjCmdProc *xProc;
} aObjCmd[] = {
{ "sqlite3rbu", test_sqlite3rbu },
{ "sqlite3rbu_vacuum", test_sqlite3rbu_vacuum },
{ "sqlite3rbu_create_vfs", test_sqlite3rbu_create_vfs },
{ "sqlite3rbu_destroy_vfs", test_sqlite3rbu_destroy_vfs },
{ "sqlite3rbu_internal_test", test_sqlite3rbu_internal_test },
+1
View File
@@ -17,6 +17,7 @@ if {![info exists testdir]} {
}
source [file join [file dirname [info script]] session_common.tcl]
source $testdir/tester.tcl
ifcapable !session {finish_test; return}
set testprefix sessionfault
+1
View File
@@ -17,6 +17,7 @@ if {![info exists testdir]} {
}
source [file join [file dirname [info script]] session_common.tcl]
source $testdir/tester.tcl
ifcapable !session {finish_test; return}
set testprefix sessionfault2
do_execsql_test 1.0.0 {
+17 -13
View File
@@ -592,14 +592,19 @@ static int sessionChangeEqual(
int iCol; /* Used to iterate through table columns */
for(iCol=0; iCol<pTab->nCol; iCol++){
int n1 = sessionSerialLen(a1);
int n2 = sessionSerialLen(a2);
if( pTab->abPK[iCol] ){
int n1 = sessionSerialLen(a1);
int n2 = sessionSerialLen(a2);
if( pTab->abPK[iCol] && (n1!=n2 || memcmp(a1, a2, n1)) ){
return 0;
if( pTab->abPK[iCol] && (n1!=n2 || memcmp(a1, a2, n1)) ){
return 0;
}
a1 += n1;
a2 += n2;
}else{
if( bLeftPkOnly==0 ) a1 += sessionSerialLen(a1);
if( bRightPkOnly==0 ) a2 += sessionSerialLen(a2);
}
if( pTab->abPK[iCol] || bLeftPkOnly==0 ) a1 += n1;
if( pTab->abPK[iCol] || bRightPkOnly==0 ) a2 += n2;
}
return 1;
@@ -935,9 +940,9 @@ static int sessionTableInfo(
int nDbCol = 0;
int nThis;
int i;
u8 *pAlloc;
u8 *pAlloc = 0;
char **azCol = 0;
u8 *abPK;
u8 *abPK = 0;
assert( pazCol && pabPK );
@@ -1593,9 +1598,9 @@ static void sessionDeleteTable(SessionTable *pList){
pNext = pTab->pNext;
for(i=0; i<pTab->nChange; i++){
SessionChange *p;
SessionChange *pNext;
for(p=pTab->apChange[i]; p; p=pNext){
pNext = p->pNext;
SessionChange *pNextChange;
for(p=pTab->apChange[i]; p; p=pNextChange){
pNextChange = p->pNext;
sqlite3_free(p);
}
}
@@ -2882,7 +2887,6 @@ static int sessionChangesetNext(
** modified fields are present in the new.* record. The old.* record
** is currently completely empty. This block shifts the PK fields from
** new.* to old.*, to accommodate the code that reads these arrays. */
int i;
for(i=0; i<p->nCol; i++){
assert( p->apValue[i]==0 );
assert( p->abPK[i]==0 || p->apValue[i+p->nCol] );
@@ -3655,7 +3659,7 @@ static int sessionConflictHandler(
void *pCtx, /* First argument for conflict handler */
int *pbReplace /* OUT: Set to true if PK row is found */
){
int res; /* Value returned by conflict handler */
int res = 0; /* Value returned by conflict handler */
int rc;
int nCol;
int op;
+2 -3
View File
@@ -314,7 +314,8 @@ static void test_append_value(Tcl_Obj *pList, sqlite3_value *pVal){
pObj = Tcl_NewStringObj(z, n);
break;
}
case SQLITE_BLOB:
default:
assert( sqlite3_value_type(pVal)==SQLITE_BLOB );
Tcl_ListObjAppendElement(0, pList, Tcl_NewStringObj("b", 1));
pObj = Tcl_NewByteArrayObj(
sqlite3_value_blob(pVal),
@@ -871,7 +872,6 @@ static int test_sqlite3session_foreach(
pOld = Tcl_NewObj();
if( op!=SQLITE_INSERT ){
int i;
for(i=0; i<nCol; i++){
sqlite3_value *pVal;
sqlite3changeset_old(pIter, i, &pVal);
@@ -880,7 +880,6 @@ static int test_sqlite3session_foreach(
}
pNew = Tcl_NewObj();
if( op!=SQLITE_DELETE ){
int i;
for(i=0; i<nCol; i++){
sqlite3_value *pVal;
sqlite3changeset_new(pIter, i, &pVal);
-1
View File
@@ -905,7 +905,6 @@ clean:
rm -f mkkeywordhash mkkeywordhash.exe keywordhash.h
rm -f $(PUBLISH)
rm -f *.da *.bb *.bbg gmon.out
rm -rf quota2a quota2b quota2c
rm -rf tsrc target_source
rm -f testloadext.dll libtestloadext.so
rm -f amalgamation-testfixture amalgamation-testfixture.exe
+106 -104
View File
@@ -1,8 +1,8 @@
C Add\sanother\sOOM\stest\sto\sthis\sbranch.
D 2016-03-31T15:08:10.284
F Makefile.in e812bb732d7af01baa09f1278bd4f4a2e3a09449
C Fix\san\salmost\sentirely\sharmless\sbuffer\soverread\sin\sthe\ssessions\smodule.
D 2016-04-29T10:13:22.999
F Makefile.in 9e816d0323e418fbc0f8b2c05fc14e0b3763d9e8
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
F Makefile.msc cde766eb7c27a7ca42000e66c5f0c37a17a05998
F Makefile.msc 71b8b16cf9393f68e2e2035486ca104872558836
F README.md 8ecc12493ff9f820cdea6520a9016001cb2e59b7
F VERSION 5d234da9b5dae329fab75ff75884cfe0a9cb3fda
F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50
@@ -81,7 +81,7 @@ F ext/fts3/fts3_icu.c deb46f7020d87ea7a14a433fb7a7f4bef42a9652
F ext/fts3/fts3_porter.c 3565faf04b626cddf85f03825e86056a4562c009
F ext/fts3/fts3_snippet.c 68ae118b0f834ea53d2b89e4087fc0f0b8c4ee4e
F ext/fts3/fts3_term.c 88c55a6fa1a51ab494e33dced0401a6c28791fd7
F ext/fts3/fts3_test.c 11e36437b0f3f2266acea5b4787f615e4337a237
F ext/fts3/fts3_test.c a940cf104d545ad1abf926956ce65db2aa5af0cf
F ext/fts3/fts3_tokenize_vtab.c a27593ab19657166f6fa5ec073b678cc29a75860
F ext/fts3/fts3_tokenizer.c 3cf21cd2212db17a88d4ef7da0fd8a80275979a1
F ext/fts3/fts3_tokenizer.h 64c6ef6c5272c51ebe60fc607a896e84288fcbc3
@@ -91,7 +91,7 @@ F ext/fts3/fts3_unicode2.c c3d01968d497bd7001e7dc774ba75b372738c057
F ext/fts3/fts3_write.c c3863f23b6b4623c8b9d5cf31c12ce4469f78ca9
F ext/fts3/fts3speed.tcl b54caf6a18d38174f1a6e84219950d85e98bb1e9
F ext/fts3/mkfts3amal.tcl 252ecb7fe6467854f2aa237bf2c390b74e71f100
F ext/fts3/tool/fts3view.c 5d78b668f4e9598af9147f8999632599fb0d9dd5
F ext/fts3/tool/fts3view.c 202801a2056995b763864d60c2dee744d46f1677
F ext/fts3/unicode/CaseFolding.txt 8c678ca52ecc95e16bc7afc2dbf6fc9ffa05db8c
F ext/fts3/unicode/UnicodeData.txt cd07314edb62d49fde34debdaf92fa2aa69011e7
F ext/fts3/unicode/mkunicode.tcl 2debed3f582d77b3fdd0b8830880250021571fd8
@@ -103,8 +103,8 @@ F ext/fts5/fts5_aux.c daa57fb45216491814520bbb587e97bf81ced458
F ext/fts5/fts5_buffer.c 4c1502d4c956cd092c89ce4480867f9d8bf325cd
F ext/fts5/fts5_config.c 5af9c360e99669d29f06492c370892394aba0857
F ext/fts5/fts5_expr.c 5ca4bafe29aa3d27683c90e836192e4aefd20a3f
F ext/fts5/fts5_hash.c f3a7217c86eb8f272871be5f6aa1b6798960a337
F ext/fts5/fts5_index.c fdd82bb421a5d1e64d004acb43f4dd9970c8d2b3
F ext/fts5/fts5_hash.c 880998e596b60f078348d48732ca4ad9a90caad2
F ext/fts5/fts5_index.c b429e23fabb57506f71e406997cc46b89190dc97
F ext/fts5/fts5_main.c b4a0fc5bf17f2f1f056ee76cdd7d2af08b360f55
F ext/fts5/fts5_storage.c 3309c6a8e34b974513016fd1ef47c83f5898f94c
F ext/fts5/fts5_tcl.c f8731e0508299bd43f1a2eff7dbeaac870768966
@@ -201,28 +201,28 @@ F ext/fts5/tool/loadfts5.tcl 95b03429ee6b138645703c6ca192c3ac96eaf093
F ext/fts5/tool/mkfts5c.tcl d1c2a9ab8e0ec690a52316f33dd9b1d379942f45
F ext/fts5/tool/showfts5.tcl d54da0e067306663e2d5d523965ca487698e722c
F ext/icu/README.txt d9fbbad0c2f647c3fdf715fc9fd64af53aedfc43
F ext/icu/icu.c 4bdf4c5daedabcd8e6eb6e6a377657f7b978f9f7
F ext/icu/icu.c 43df9d8ef2fae7a325100ebd713ab089dc829dd7
F ext/icu/sqliteicu.h 728867a802baa5a96de7495e9689a8e01715ef37
F ext/misc/amatch.c a1a8f66c29d40bd71b075546ddeddb477b17a2bb
F ext/misc/amatch.c 211108e201105e4bb0c076527b8cfd34330fc234
F ext/misc/closure.c 0d2a038df8fbae7f19de42e7c7d71f2e4dc88704
F ext/misc/compress.c 122faa92d25033d6c3f07c39231de074ab3d2e83
F ext/misc/eval.c f971962e92ebb8b0a4e6b62949463ee454d88fa2
F ext/misc/fileio.c d4171c815d6543a9edef8308aab2951413cd8d0f
F ext/misc/fuzzer.c 4c84635c71c26cfa7c2e5848cf49fe2d2cfcd767
F ext/misc/fuzzer.c 7c64b8197bb77b7d64eff7cac7848870235d4c25
F ext/misc/ieee754.c f190d0cc5182529acb15babd177781be1ac1718c
F ext/misc/json1.c b9c88d5c3b6ecd8c731ffdd7f5b3d902857f8c96
F ext/misc/nextchar.c 35c8b8baacb96d92abbb34a83a997b797075b342
F ext/misc/percentile.c bcbee3c061b884eccb80e21651daaae8e1e43c63
F ext/misc/regexp.c af92cdaa5058fcec1451e49becc7ba44dba023dc
F ext/misc/regexp.c a68d25c659bd2d893cd1215667bbf75ecb9dc7d4
F ext/misc/rot13.c 1ac6f95f99b575907b9b09c81a349114cf9be45a
F ext/misc/series.c e11e534ada797d5b816d7e7a93c022306563ca35
F ext/misc/showauth.c 732578f0fe4ce42d577e1c86dc89dd14a006ab52
F ext/misc/spellfix.c 598bbc45516227701558becdd38f4e6fe8e97cc2
F ext/misc/spellfix.c bf1b922c2750698e9a3d4c50cce6974adb7e93be
F ext/misc/totype.c 4a167594e791abeed95e0a8db028822b5e8fe512
F ext/misc/vfslog.c fe40fab5c077a40477f7e5eba994309ecac6cc95
F ext/misc/vtshim.c babb0dc2bf116029e3e7c9a618b8a1377045303e
F ext/misc/wholenumber.c 784b12543d60702ebdd47da936e278aa03076212
F ext/rbu/rbu.c ba3983dceffa0938532e79142f391737513de023
F ext/rbu/rbu.c b2c0b5e6ae1a89affc0edfc127ebfa5f637a0ce4
F ext/rbu/rbu1.test 42bd835e019eff789ec241017965277baeb658b1
F ext/rbu/rbu10.test 046b0980041d30700464a800bbf6733ed2df515d
F ext/rbu/rbu11.test 9bc68c2d3dbeb1720153626e3bd0466dcc017702
@@ -243,12 +243,14 @@ F ext/rbu/rbucrash.test 8d2ed5d4b05fef6c00c2a6b5f7ead71fa172a695
F ext/rbu/rbudiff.test 2df0a8a7d998ecf81764c21eeda3cde5611c5091
F ext/rbu/rbufault.test cc0be8d5d392d98b0c2d6a51be377ea989250a89
F ext/rbu/rbufault2.test 9a7f19edd6ea35c4c9f807d8a3db0a03a5670c06
F ext/rbu/rbufault3.test 54a399888ac4af44c68f9f58afbed23149428bca
F ext/rbu/rbufts.test 828cd689da825f0a7b7c53ffc1f6f7fdb6fa5bda
F ext/rbu/rbuprogress.test 2023a7df2c523e3df1cb532eff811cda385a789a
F ext/rbu/rbusave.test 0f43b6686084f426ddd040b878426452fd2c2f48
F ext/rbu/sqlite3rbu.c 007fc4db8c0b95c7ef10162b5864921ef5cc8106
F ext/rbu/sqlite3rbu.h d7cc99350c10134f358fe1a8997d9225b3f712b2
F ext/rbu/test_rbu.c 3505641a78b723589b8780d5f9b2faeeb73e037d
F ext/rbu/rbuvacuum.test 66e02cf299836770e718e95c36686be0b26dbda3
F ext/rbu/sqlite3rbu.c bf36625990c6865ecf08bd844d8097ed2d0a6958
F ext/rbu/sqlite3rbu.h 2acd0a6344a6079de15c8dc9d84d3df83a665930
F ext/rbu/test_rbu.c 9bbdf6bd8efd58fbc4f192698df50569598fbb9e
F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761
F ext/rtree/rtree.c 0b870ccb7b58b734a2a8e1e2755a7c0ded070920
F ext/rtree/rtree.h 834dbcb82dc85b2481cde6a07cdadfddc99e9b9e
@@ -289,18 +291,18 @@ F ext/session/sessionE.test e60a238c47f0feb3bb707e7f35e22be09c7e8f26
F ext/session/sessionF.test c2f178d4dfd723a5fd94a730ea2ccb44c669e3ce
F ext/session/sessionG.test 01ef705096a9d3984eebdcca79807a211dee1b60
F ext/session/session_common.tcl a1293167d14774b5e728836720497f40fe4ea596
F ext/session/sessionfault.test d52cbb7bee48cc8ee80335e07eb72fcb6b15eb40
F ext/session/sessionfault2.test ac1dfd77a0fb0ea310aee40a16645ef1b66d3f88
F ext/session/sqlite3session.c 2fc72bd989c424a15802da766c7ebd8eed47bcf6
F ext/session/sessionfault.test da273f2712b6411e85e71465a1733b8501dbf6f7
F ext/session/sessionfault2.test 04aa0bc9aa70ea43d8de82c4f648db4de1e990b0
F ext/session/sqlite3session.c beb43b6b888801bb006320bc236baa95f4cc32ae
F ext/session/sqlite3session.h 64e9e7f185725ef43b97f4a9a0c0df0669844f1d
F ext/session/test_session.c 187bd344c5ae9d5be85e22ef7c3010f0c17307ce
F ext/session/test_session.c 464f2c8bf502795d95969387eb8e93f68c513c15
F ext/userauth/sqlite3userauth.h 19cb6f0e31316d0ee4afdfb7a85ef9da3333a220
F ext/userauth/user-auth.txt e6641021a9210364665fe625d067617d03f27b04
F ext/userauth/userauth.c 5fa3bdb492f481bbc1709fc83c91ebd13460c69e
F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x
F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8
F magic.txt 8273bf49ba3b0c8559cb2774495390c31fd61c60
F main.mk 942e1fd30eb352492cf599aa7fcb5334783e4cbf
F main.mk a283660f75c3c4b75d8c9d12a40fa38a066eee9d
F mkso.sh fd21c06b063bb16a5d25deea1752c2da6ac3ed83
F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271
F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504
@@ -313,41 +315,41 @@ F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b
F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786
F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a
F src/alter.c 1bb0709b3048e24217b80ec6bd78a3e99a47c01b
F src/analyze.c ab57b6763dd4c6170a20673d14882c033affd188
F src/analyze.c 37fedc80ac966ce1745811746e68e4d8fa64c7fe
F src/attach.c 771153bd1f4ab0b97a44a13dde2c7e5e1efeba22
F src/auth.c b56c78ebe40a2110fd361379f7e8162d23f92240
F src/backup.c f60f0aa55d25d853ffde53d0b0370a7bb7ee41ce
F src/bitvec.c 3ee4c8b2c94ed3a7377256e18199e6ff5cf33f63
F src/btmutex.c bc87dd3b062cc26edfe79918de2200ccb8d41e73
F src/btree.c 577fb5674e2f0aa0a38246afc19e1885a0b8c9b0
F src/btree.c 3ae6aea66cc4e13d30162ff0d0d43c7088e34abf
F src/btree.h a5008b9afe56e8e54ade6c436a910f112defcca9
F src/btreeInt.h c18b7d2a3494695133e4e60ee36061d37f45d9a5
F src/build.c 39faaaeecb77eb3936d4bd5024e865e3836ca323
F src/build.c 42e8ee74dfa3a4b99bfb2c201f8a66ab50688d95
F src/callback.c 2e76147783386374bf01b227f752c81ec872d730
F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e
F src/ctime.c 60e135af364d777a9ab41c97e5e89cd224da6198
F src/date.c 0b73e681c11fca867fec554750c07fe0d4e417c1
F src/date.c 1cc9fb516ec9932c6fd4d2a0d2f8bc4480145c39
F src/dbstat.c c845548d4346e606e2f2b7d2e714ace2b8a7dd1b
F src/delete.c eeac28b3d3d88e3541bdf93e91ea7492a7b67842
F src/expr.c 289ffac5240b60fee0a824d3d5ab2d7bd2630c94
F src/delete.c 78eb999114ec04fcf1b7d123ccedb4b5b734930e
F src/expr.c 8796c0739b2ad091e6779253f62aad6e767e2be1
F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
F src/fkey.c 4c0bd09e602b8ae8d36d81e31e4872d0b53c87bb
F src/func.c 552d300265aed09eea21f68ac742a440550c0062
F src/global.c 884d4c7eba9f5fc25c96a23b21520da19b7713e2
F src/hash.c 4263fbc955f26c2e8cdc0cf214bc42435aa4e4f5
F src/func.c ef4c18c8a66143413ce41a58d582d2c14ddf78e1
F src/global.c c45ea22aff29334f6a9ec549235ac3357c970015
F src/hash.c 55b5fb474100cee0b901edaf203e26c970940f36
F src/hash.h c8f3c31722cf3277d03713909761e152a5b81094
F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08
F src/insert.c 8f4e9fcbd8e95e85f15647ba8b413b18d556ec2b
F src/legacy.c 75d3023be8f0d2b99d60f905090341a03358c58e
F src/loadext.c e70f8f9e97624a232870ea5486e682c813ac3002
F src/main.c 5ac9dccc03faadd6f867f67b9018ff41eeeadb46
F src/loadext.c 8b3a73f0624c5f7cadbd5cb89940783bee1d39a6
F src/main.c 405d13e3a4f7c5add9fb27702ae70ed0a6e32cca
F src/malloc.c 1443d1ad95d67c21d77af7ae3f44678252f0efec
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
F src/mem1.c 6919bcf12f221868ea066eec27e579fed95ce98b
F src/mem2.c f1940d9e91948dd6a908fbb9ce3835c36b5d83c3
F src/mem3.c 8768ac94694f31ffaf8b4d0ea5dc08af7010a35a
F src/mem5.c 9bf955937b07f8c32541c8a9991f33ce3173d944
F src/memjournal.c 5253fd4335a8d9c64e5df25cb9da6329af5242c7
F src/memjournal.c 95752936c11dc6995672d1dd783cd633eea0cc95
F src/msvc.h d9ba56c6851227ab44b3f228a35f3f5772296495
F src/mutex.c 8e45800ee78e0cd1f1f3fe8e398853307f4a085c
F src/mutex.h 779d588e3b7756ec3ecf7d78cde1d84aba414f85
@@ -355,19 +357,19 @@ F src/mutex_noop.c 9d4309c075ba9cc7249e19412d3d62f7f94839c4
F src/mutex_unix.c 27bb6cc49485ee46711a6580ab7b3f1402211d23
F src/mutex_w32.c 5e6fe1c298fb5a8a15aaed4161d5759311431c17
F src/notify.c 9711a7575036f0d3040ba61bc6e217f13a9888e7
F src/os.c ca10edb445ad2c5fdc7285b49d72bcdf261fa23e
F src/os.h 91ff889115ecd01f436d3611f7f5ea4dc12d92f1
F src/os.c 4d83917f072ad958fba9235136fa2ed43df47905
F src/os.h 8e976e59eb4ca1c0fca6d35ee803e38951cb0343
F src/os_common.h b2f4707a603e36811d9b1a13278bffd757857b85
F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa
F src/os_unix.c b1ccb273771f41dbdbe0ba7c1ad63c38ad5972ec
F src/os_win.c ff870d89f4cb088a04cbf5ea0cbd9ff1b089ff4a
F src/os_unix.c 8422fba2eb592fbbb2d4006b6f2a67cad8951495
F src/os_win.c 852fc2ff6084296348ed3739c548b2cf32df394e
F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca
F src/pager.c 38718a019ca762ba4f6795425d5a54db70d1790d
F src/pager.h e1d38a2f14849e219df0f91f8323504d134c8a56
F src/parse.y 5ea8c81c5c41b27887f41b4a7e1c58470d7d3821
F src/pager.c d20fa46d5beda38095be6070dd4c59e502817c72
F src/pager.h 329bdf078a4e0a3b35084534d58625d21fd03681
F src/parse.y 10eb2f3fb62341291528c7984498054731f9d31e
F src/pcache.c 647bb53a86b7bbcf55ad88089b3ea5a9170b90df
F src/pcache.h 4d0ccaad264d360981ec5e6a2b596d6e85242545
F src/pcache1.c c40cdb93586e21b5dd826b5e671240bd91c26b05
F src/pcache1.c 7f51d2b541aab57596adf62db2c4bb025d34f04d
F src/pragma.c faf42922bb7ab2f6672cb550356c1967abae3c84
F src/pragma.h 64c78a648751b9f4f297276c4eb7507b14b4628c
F src/prepare.c 22df6171aec1d86904ed2ad30c2348a5748aa04e
@@ -375,22 +377,22 @@ F src/printf.c 63e6fb12bbe702dd664dc3703776c090383a5a26
F src/random.c ba2679f80ec82c4190062d756f22d0c358180696
F src/resolve.c b8f7174e5f8c33c44ded3a25a973d0bb89228c20
F src/rowset.c 9fe4b3ad7cc00944386bb600233d8f523de07a6e
F src/select.c 7849cee0a01952a9c93cd28989daedfa57731143
F src/shell.c cd3f82fdc5c895b817a375b7ab8319cb41f447ce
F src/sqlite.h.in 843a0dfcf8c5e961cfafa62009fed0867b88241e
F src/select.c fd4a7ce2937497181063cfedb92058ac89491a5d
F src/shell.c 14ff7f660530a52b117d110ba3390b7b2eb719b6
F src/sqlite.h.in 9984129d86243424b765fcb3f147c697bd20bb54
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
F src/sqlite3ext.h 98f72cbfe00169c39089115427d06ea05fe4b4a2
F src/sqliteInt.h 594bf31a7a0cc788688ca947e562576e23bd7904
F src/sqliteInt.h ec538389481a3d093f07fb344c5a9dc988042304
F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247
F src/status.c 70912d7be68e9e2dbc4010c93d344af61d4c59ba
F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9
F src/tclsqlite.c 56569acc73d36e836b64aefecbbb709a92ba0077
F src/test1.c 7187b7e924bfc97780e6fd2a40dad94a32bddca0
F src/tclsqlite.c 9c4c4589d078de37813ded708d8838b338ffb060
F src/test1.c ee8fd5c32acb93fb6fe885ca4801cfab85f5563f
F src/test2.c 5586f43fcd9a1be0830793cf9d354082c261b25b
F src/test3.c a8887dabbbee3059af338f20d290084a63ed1b0f
F src/test4.c d168f83cc78d02e8d35567bb5630e40dcd85ac1e
F src/test5.c 5a34feec76d9b3a86aab30fd4f6cc9c48cbab4c1
F src/test6.c 41cacf3b0dd180823919bf9e1fbab287c9266723
F src/test6.c 2c014d4977efd6107ec9eef3dfdec56ac516f824
F src/test7.c 9c89a4f1ed6bb13af0ed805b8d782bd83fcd57e3
F src/test8.c fa262391d3edea6490a71bfaa8fed477ccbbac75
F src/test9.c bea1e8cf52aa93695487badedd6e1886c321ea60
@@ -402,21 +404,21 @@ F src/test_blob.c b2551a9b5573232db5f66f292307c37067937239
F src/test_btree.c 2e9978eca99a9a4bfa8cae949efb00886860a64f
F src/test_config.c 7003f6f35134de6f19c6588f44783e43390ea277
F src/test_demovfs.c 0de72c2c89551629f58486fde5734b7d90758852
F src/test_devsym.c e7498904e72ba7491d142d5c83b476c4e76993bc
F src/test_devsym.c 4e58dec2602d8e139ca08659f62a62450587cb58
F src/test_fs.c f10f840ca4f8c72e4837908bd8347ac4bcab074b
F src/test_func.c 37453d346cfcf118774efd5bf6187f7e6a7e3254
F src/test_hexio.c abfdecb6fa58c354623978efceb088ca18e379cd
F src/test_init.c 66b33120ffe9cd853b5a905ec850d51151337b32
F src/test_intarray.c 870124b95ec4c645d4eb84f15efb7133528fb1a5
F src/test_intarray.h 9dc57417fb65bc7835cc18548852cc08cc062202
F src/test_journal.c 5360fbe1d1e4416ca36290562fd5a2e3f70f32aa
F src/test_journal.c d3b83f2bcb7792c709e57abddc456a2b1818643a
F src/test_loadext.c 337056bae59f80b9eb00ba82088b39d0f4fe6dfd
F src/test_malloc.c 96df9381a1ff1f6d3805ff7231b9baf1386aaabf
F src/test_multiplex.c 6a9de820fcaaf506c59aa14bc8693822333cea48
F src/test_malloc.c 94c18e88d6df6d471a0d04ddb809f833d1739950
F src/test_multiplex.c eafc567ebe162e36f17b5062285dfe90461cf8e9
F src/test_multiplex.h c08e4e8f8651f0c5e0509b138ff4d5b43ed1f5d3
F src/test_mutex.c dbdfaff8580071f2212a0deae3325a93a737819c
F src/test_onefile.c 38f7cbe79d5bafe95bde683cc3a53b8ca16daf10
F src/test_osinst.c 5423dc1d355f594371f27dd292ca54bd320b8196
F src/test_onefile.c 416f87a28d6d673352d33fc4b1c7d39db878e50f
F src/test_osinst.c ad0233b1dabb0390e25edded4ebd79a2a61538c6
F src/test_pcache.c a5cd24730cb43c5b18629043314548c9169abb00
F src/test_quota.c 180813f43683be5725458fc1ff13ac455d8e722d
F src/test_quota.h 2a8ad1952d1d2ca9af0ce0465e56e6c023b5e15d
@@ -425,40 +427,40 @@ F src/test_schema.c 2bdba21b82f601da69793e1f1d11bf481a79b091
F src/test_server.c a2615049954cbb9cfb4a62e18e2f0616e4dc38fe
F src/test_sqllog.c 0d138a8180a312bf996b37fa66da5c5799d4d57b
F src/test_superlock.c 06797157176eb7085027d9dd278c0d7a105e3ec9
F src/test_syscall.c 2e21ca7f7dc54a028f1967b63f1e76155c356f9b
F src/test_syscall.c 268c072541162564a882c57f54a6fee12ef4a4d2
F src/test_tclvar.c d86412527da65468ee6fa1b8607c65d0af736bc4
F src/test_thread.c af391ec03d23486dffbcc250b7e58e073f172af9
F src/test_vfs.c 3b65d42e18b262805716bd96178c81da8f2d9283
F src/test_vfs.c 4d02f38bfb8f7f273da7ba84bfe000f5babf206c
F src/test_vfstrace.c bab9594adc976cbe696ff3970728830b4c5ed698
F src/test_windirent.c 8f5fada630348558d5745b334702f301da1ffc61
F src/test_windirent.h b12055cab6227f7be10f5c19296f67c60cc5e2a5
F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9
F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c
F src/tokenize.c 3d338cdd00d916ce8a05c397001d64ed58e6fe1c
F src/tokenize.c 3b29883b0ce4a6c6f643965b66b5ca6613178e59
F src/treeview.c e4b41a37530a191579d3c53142cc44ee2eb99373
F src/trigger.c e14840ee0c3e549e758ec9bf3e4146e166002280
F src/update.c 3e67ab3c0814635f355fb1f8ab010a2b9e016e7d
F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c
F src/util.c 8873d696c9ccc4206058c402e09e101f1b81561a
F src/util.c 810ec3f22e2d1b62e66c30fe3621ebdedd23584d
F src/vacuum.c feb1eabb20987983d9350cad98299b21fa811f52
F src/vdbe.c 0f0e4a6255f9a5272857a818314d081db26bcd90
F src/vdbe.h c16ba943d407baa1c7085eefea73a063fc631863
F src/vdbe.c d3843a66d74a7696477ee5141e5eb9a7e5e2401c
F src/vdbe.h 5591b5add447096e31288b5a0a78ec5d7b5c5170
F src/vdbeInt.h ddb157974436d87652de7dc641f7191496d9a8cd
F src/vdbeapi.c ba85b78fe08dc4a9ce747e62c89a2b4a4547e74c
F src/vdbeaux.c fa06ba5441714160ab5f64422660ee286968672f
F src/vdbeaux.c ace1875da40b7185e604586768d5ac90de7e4f7f
F src/vdbeblob.c c9f2f494b911c6fa34efd9803f0a10807da80f77
F src/vdbemem.c 5cfef60e60e19cab6275d1b975bf4c791d575beb
F src/vdbesort.c 307460bfa4de4d1c3901fcd42089159131e34062
F src/vdbesort.c 0a8f98366ae794442e6d1ef71d9553226d885d19
F src/vdbetrace.c f75c5455d8cf389ef86a8bfdfd3177e0e3692484
F src/vtab.c 23b6cdfa996152d43b390504ed4a942c8caf3a00
F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9
F src/wal.c 10deb6b43887662691e5f53d10b3c171c401169b
F src/wal.c 4db22ed7e77bcf672b1a685d6ddeffba8d5be302
F src/wal.h 2f7c831cf3b071fa548bf2d5cac640846a7ff19c
F src/walker.c 0f142b5bd3ed2041fc52d773880748b212e63354
F src/where.c fe7925faafbe9a458972035c0bb4753d672f04ed
F src/whereInt.h 93297d56edd137b7ea004490690fb6e2ce028a34
F src/wherecode.c 863aedf086131743763c1960637fde904eadc442
F src/whereexpr.c fb87944b1254234e5bba671aaf6dee476241506a
F src/where.c bae50f2f18f9e8584549a77363858623b07e4915
F src/whereInt.h 7de94b751f088fe3fdc8cc04a491376f0900a059
F src/wherecode.c 8fdad9fbba723df1c1e8d07e7ea8507572040340
F src/whereexpr.c eacc0e60d029a082b4fc0cc42ea98544add1319e
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
@@ -497,7 +499,7 @@ F test/attach2.test 0ec5defa340363de6cd50fd595046465e9aaba2d
F test/attach3.test 359eb65d00102cdfcef6fa4e81dc1648f8f80b27
F test/attach4.test 53bf502f17647c6d6c5add46dda6bac8b6f4665c
F test/attachmalloc.test 3a4bfca9545bfe906a8d2e622de10fbac5b711b0
F test/auth.test 855233ef26eb3601b6886567ea4e326c72959360
F test/auth.test 872a122b3977c1d1bb9fd637dc20016e5c01880f
F test/auth2.test 264c6af53cad9aba5218c68bbe18036e39007bfa
F test/auth3.test 5cfa94ed90c6617c42b7ba4b133fd79678b251c7
F test/autoinc.test c58912526998a39e11f66b533e23cfabea7f25b7
@@ -519,7 +521,7 @@ F test/backup_malloc.test 7162d604ec2b4683c4b3799a48657fb8b5e2d450
F test/badutf.test d5360fc31f643d37a973ab0d8b4fb85799c3169f
F test/badutf2.test f5bc7f2d280670ecd79b9cf4f0f1760c607fe51f
F test/bc_common.tcl b5e42d80305be95697e6370e015af571e5333a1c
F test/bestindex1.test d5ba89a7941a941476d8d69be39b146aaed3614c
F test/bestindex1.test 0cf1bd2d7b97d3a3a8c10736125274f64765c4ee
F test/bestindex2.test 4a06b8922ab2fd09434870da8d1cdf525aaf7060
F test/between.test 34d375fb5ce1ae283ffe82b6b233e9f38e84fc6c
F test/bigfile.test aa74f4e5db51c8e54a1d9de9fa65d01d1eb20b59
@@ -610,12 +612,12 @@ F test/ctime.test 7bd009071e242aac4f18521581536b652b789a47
F test/cursorhint.test 7bc346788390475e77a345da2b92270d04d35856
F test/date.test 984ac1e3e5e031386866f034006148d3972b4a65
F test/dbstatus.test 8de104bb5606f19537d23cd553b41349b5ab1204
F test/dbstatus2.test 10418e62b3db5dca070f0c3eef3ea13946f339c2
F test/dbstatus2.test e93ab03bfae6d62d4d935f20de928c19ca0ed0ab
F test/default.test 0cb49b1c315a0d81c81d775e407f66906a2a604d
F test/delete.test e1bcdf8926234e27aac24b346ad83d3329ec8b6f
F test/delete2.test 3a03f2cca1f9a67ec469915cb8babd6485db43fa
F test/delete3.test 555e84a00a99230b7d049d477a324a631126a6ab
F test/delete4.test 3ac0b8d23689ba764c2e8b78c1b56b8f1b942fa2
F test/delete4.test 738044ee892ee0c84e0848e36ba92c55f907d52b
F test/descidx1.test 6d03b44c8538fe0eb4924e19fba10cdd8f3c9240
F test/descidx2.test 9f1a0c83fd57f8667c82310ca21b30a350888b5d
F test/descidx3.test 09ddbe3f5295f482d2f8b687cf6db8bad7acd9a2
@@ -642,7 +644,7 @@ F test/e_select2.test aceb80ab927d46fba5ce7586ebabf23e2bb0604f
F test/e_totalchanges.test b12ee5809d3e63aeb83238dd501a7bca7fd72c10
F test/e_update.test f46c2554d915c9197548681e8d8c33a267e84528
F test/e_uri.test 25385396082b67fd02ae0038b95a3b3575fe0519
F test/e_vacuum.test 4d5b391384bb7d56bb9337d956f08035332421fc
F test/e_vacuum.test 120f29ea56bdce4d43279527ece894ab5d1729d3
F test/e_wal.test ae9a593207a77d711443ee69ffe081fda9243625
F test/e_walauto.test 248af31e73c98df23476a22bdb815524c9dc3ba8
F test/e_walckpt.test 28c371a6bb5e5fe7f31679c1df1763a19d19e8a0
@@ -657,7 +659,7 @@ F test/eval.test a64c9105d6ff163df7cf09d6ac29cdad5922078c
F test/exclusive.test 9a57bd66e39144b888ca75c309914fcdefb4e3f9
F test/exclusive2.test 32798111aae78a5deec980eee383213f189df308
F test/exec.test e949714dc127eaa5ecc7d723efec1ec27118fdd7
F test/exists.test 8f7b27b61c2fbe5822f0a1f899c715d14e416e30
F test/exists.test 79a75323c78f02bbe9c251ea502a092f9ef63dac
F test/expr.test 79c3e7502d9e571553b85f0ecc8ff2ac7d0e4931
F test/extension01.test 00d13cec817f331a687a243e0e5a2d87b0e358c9
F test/extraquick.test cb254400bd42bfb777ff675356aabf3287978f79
@@ -806,7 +808,7 @@ F test/fuzzerfault.test 8792cd77fd5bce765b05d0c8e01b9edcf8af8536
F test/genesis.tcl 1e2e2e8e5cc4058549a154ff1892fe5c9de19f98
F test/hexlit.test d7b0a5f41123df1e43985b91b8b2e70f95282d21
F test/hidden.test 23c1393a79e846d68fd902d72c85d5e5dcf98711
F test/hook.test 40523db3aa76d62bda71c26f824fa0eabc420f0e
F test/hook.test 3b7b99d0eece6d279812c2aef6fa08bdfabc633e
F test/icu.test 73956798bace8982909c00476b216714a6d0559a
F test/ieee754.test 806fc0ce7f305f57e3331eaceeddcfec9339e607
F test/imposter1.test c3f1db2d3db2c24611a6596a3fc0ffc14f1466c8
@@ -823,7 +825,7 @@ F test/incrblob_err.test 69f9247fed50278d48ea710d1a8f9cdb09e4c0b8
F test/incrblobfault.test 280474078f6da9e732cd2a215d3d854969014b6e
F test/incrcorrupt.test 6c567fbf870aa9e91866fe52ce6f200cd548939a
F test/incrvacuum.test d2a6ddf5e429720b5fe502766af747915ccf6c32
F test/incrvacuum2.test 676c41428765d58f1da7dbe659ef27726d3d30ac
F test/incrvacuum2.test 7d26cfda66c7e55898d196de54ac4ec7d86a4e3d
F test/incrvacuum3.test 75256fb1377e7c39ef2de62bfc42bbff67be295a
F test/incrvacuum_ioerr.test 6ae2f783424e47a0033304808fe27789cf93e635
F test/index.test fe3c7a1aad82af92623747e9c3f3aa94ccd51238
@@ -845,7 +847,7 @@ F test/insert5.test 394f96728d1258f406fe5f5aeb0aaf29487c39a6
F test/instr.test 737bbf80685232033f3abedc6ae92f75860b5dd2
F test/intarray.test 066b7d7ac38d25bf96f87f1b017bfc687551cdd4
F test/interrupt.test dfe9a67a94b0b2d8f70545ba1a6cca10780d71cc
F test/intpkey.test 70aab09756b9bd3bcb6b0358f971d7bbace46522
F test/intpkey.test 153b70e32d008f4f4b2dff8daf448a6110b62a9c
F test/io.test f95bca1783b01ea7761671560d023360d2dfa4cc
F test/ioerr.test 2a24bd6ed5a8b062e64bfe1f6cf94fb25e92210d
F test/ioerr2.test 2593563599e2cc6b6b4fcf5878b177bdd5d8df26
@@ -860,7 +862,7 @@ F test/join4.test 1a352e4e267114444c29266ce79e941af5885916
F test/join5.test 8a5c0be6f0c260a5c7177c3b8f07c7856141038a
F test/join6.test cfe6503791ceb0cbb509966740286ec423cbf10b
F test/journal1.test 69abc726c51b4a0409189f9a85191205297c0577
F test/journal2.test ae06f566c28552c313ded3fee79a6c69e6d049b1
F test/journal2.test 9dac6b4ba0ca79c3b21446bbae993a462c2397c4
F test/journal3.test ff8af941f9e06161d3db1b46bb9f965ff0e7f307
F test/jrnlmode.test 7864d59cf7f6e552b9b99ba0f38acd167edc10fa
F test/jrnlmode2.test 81610545a4e6ed239ea8fa661891893385e23a1d
@@ -875,7 +877,7 @@ F test/like.test 81632c437a947bf1f7130b19537da6a1a844806a
F test/like2.test 3b2ee13149ba4a8a60b59756f4e5d345573852da
F test/like3.test 3608a2042b6f922f900fbfd5d3ce4e7eca57f7c4
F test/limit.test 0c99a27a87b14c646a9d583c7c89fd06c352663e
F test/loadext.test 648cb95f324d1775c54a55c12271b2d1156b633b
F test/loadext.test 42a3b8166dfcadcb0e0c8710dc520d97c31a8b98
F test/loadext2.test 0408380b57adca04004247179837a18e866a74f7
F test/lock.test b984ab9034e7389be0d863fe4e64cbbc4d2028f5
F test/lock2.test 5242d8ac4e2d59c403aebff606af449b455aceff
@@ -975,10 +977,10 @@ F test/parser1.test 222b5cbf3e2e659fec1bf7d723488c8b9c94f1d0
F test/pcache.test c8acbedd3b6fd0f9a7ca887a83b11d24a007972b
F test/pcache2.test af7f3deb1a819f77a6d0d81534e97d1cf62cd442
F test/percentile.test 4243af26b8f3f4555abe166f723715a1f74c77ff
F test/permutations.test cd1fa041074ed08eeaa563e4d1bacb0c69337ec1
F test/pragma.test afbf028be1c35b68f57db8eb015c4a3c59d8f28e
F test/permutations.test b6b3e165fdc1b8c82a820033646dbfc6a7a01746
F test/pragma.test dd5313eee9c6d9d4726593a68ede8768d3b50ccc
F test/pragma2.test e5d5c176360c321344249354c0c16aec46214c9f
F test/pragma3.test 3f1984a04657331f838df5c519b443c2088df922
F test/pragma3.test 14c12bc5352b1e100e0b6b44f371053a81ccf8ed
F test/printf.test b3ff34e73d59124140eaf89f7672e21bc2ca5fcc
F test/printf2.test 0b61566dd1c0f0b802f59dffa228c5dc5aa6b054
F test/progress.test ebab27f670bd0d4eb9d20d49cef96e68141d92fb
@@ -986,7 +988,7 @@ F test/ptrchng.test ef1aa72d6cf35a2bbd0869a649b744e9d84977fc
F test/queryonly.test 5f653159e0f552f0552d43259890c1089391dcca
F test/quick.test 1681febc928d686362d50057c642f77a02c62e57
F test/quota-glob.test 32901e9eed6705d68ca3faee2a06b73b57cb3c26
F test/quota.test 36cd78b178c4eb0401d4f25754ef410fbd9df2a7
F test/quota.test bfb269ce81ea52f593f9648316cd5013d766dd2a
F test/quota2.test 7dc12e08b11cbc4c16c9ba2aa2e040ea8d8ab4b8
F test/quote.test 215897dbe8de1a6f701265836d6601cc6ed103e6
F test/randexpr1.tcl 40dec52119ed3a2b8b2a773bce24b63a3a746459
@@ -1011,7 +1013,7 @@ F test/savepoint2.test 9b8543940572a2f01a18298c3135ad0c9f4f67d7
F test/savepoint4.test c8f8159ade6d2acd9128be61e1230f1c1edc6cc0
F test/savepoint5.test 0735db177e0ebbaedc39812c8d065075d563c4fd
F test/savepoint6.test f41279c5e137139fa5c21485773332c7adb98cd7
F test/savepoint7.test db3db281486c925095f305aad09fe806e5188ff3
F test/savepoint7.test cde525ea3075283eb950cdcdefe23ead4f700daa
F test/savepointfault.test f044eac64b59f09746c7020ee261734de82bf9b2
F test/scanstatus.test 5253c219e331318a437f436268e0e82345700285
F test/schema.test 8f7999be894260f151adf15c2c7540f1c6d6a481
@@ -1024,7 +1026,7 @@ F test/securedel2.test 2d54c28e46eb1fd6902089958b20b1b056c6f1c5
F test/select1.test be62204d2bd9a5a8a149e9974cfddce893d8f686
F test/select2.test 352480e0e9c66eda9c3044e412abdf5be0215b56
F test/select3.test 2ce595f8fb8e2ac10071d3b4e424cadd4634a054
F test/select4.test d926792a5e4d88fef0ddcddeb45d27ce75f7296c
F test/select4.test 5389d9895968d1196c457d59b3ee6515d771d328
F test/select5.test e758b8ef94f69b111df4cb819008856655dcd535
F test/select6.test 39eac4a5c03650b2b473c532882273283ee8b7a0
F test/select7.test 95e370c42d47c3c52377d05e9ffc01ccff7c1f61
@@ -1051,7 +1053,7 @@ F test/sharedA.test 0cdf1a76dfa00e6beee66af5b534b1e8df2720f5
F test/sharedB.test 16cc7178e20965d75278f410943109b77b2e645e
F test/shared_err.test 2f2aee20db294b9924e81f6ccbe60f19e21e8506
F test/sharedlock.test 5ede3c37439067c43b0198f580fd374ebf15d304
F test/shell1.test dff5b20ad989770aface6d714491121172dfe8b0
F test/shell1.test 023657b3f8ba108dbd5ff2ebc8fceb3cf6d4ff9f
F test/shell2.test e242a9912f44f4c23c3d1d802a83e934e84c853b
F test/shell3.test da513d522ef6f01cee8475dcf8332bff8982b3dd
F test/shell4.test 69995ee1cc278eb149aa8746ce1f935f4eaf98b9
@@ -1065,7 +1067,7 @@ F test/skipscan2.test d1d1450952b7275f0b0a3a981f0230532743951a
F test/skipscan3.test ec5bab3f81c7038b43450e7b3062e04a198bdbb5
F test/skipscan5.test 67817a4b6857c47e0e33ba3e506da6f23ef68de2
F test/skipscan6.test 5866039d03a56f5bd0b3d172a012074a1d90a15b
F test/snapshot.test 9ed24c792fb05382814258daf68b2256f23de57f
F test/snapshot.test 3adc4ef09d407b501f899a6c329bdf45dc725c1b
F test/snapshot_fault.test 062ff0438a074978d45e9f9a92e7ad459b74ee73
F test/soak.test 0b5b6375c9f4110c828070b826b3b4b0bb65cd5f
F test/softheap1.test 843cd84db9891b2d01b9ab64cef3e9020f98d087
@@ -1073,7 +1075,7 @@ F test/sort.test c2adc635c2564241fefec0b3a68391ef6868fd3b
F test/sort2.test cc23b7c19d684657559e8a55b02f7fcee03851d0
F test/sort3.test 1480ed7c4c157682542224e05e3b75faf4a149e5
F test/sort4.test 5c34d9623a4ae5921d956dfa2b70e77ed0fc6e5c
F test/sort5.test d3041ce3c475aa04142a959ae56ef6593f98a99f
F test/sort5.test e47ec7a490b9b36787755874175d8f413a3883d9
F test/sortfault.test d4ccf606a0c77498e2beb542764fd9394acb4d66
F test/speed1.test f2974a91d79f58507ada01864c0e323093065452
F test/speed1p.explain d841e650a04728b39e6740296b852dccdca9b2cb
@@ -1083,14 +1085,14 @@ F test/speed3.test d32043614c08c53eafdc80f33191d5bd9b920523
F test/speed4.test abc0ad3399dcf9703abed2fff8705e4f8e416715
F test/speed4p.explain 6b5f104ebeb34a038b2f714150f51d01143e59aa
F test/speed4p.test 0e51908951677de5a969b723e03a27a1c45db38b
F test/speedtest1.c 21af8db2492a903835b654517ac8d90aed0af91f
F test/speedtest1.c 4476f7030775507f060d27b789e1f4123c5a5866
F test/spellfix.test f9c1f431e2c096c8775fec032952320c0e4700db
F test/spellfix2.test dfc8f519a3fc204cb2dfa8b4f29821ae90f6f8c3
F test/spellfix3.test 0f9efaaa502a0e0a09848028518a6fb096c8ad33
F test/sqldiff1.test 28cd737cf1b0078b1ec1bbf425e674c47785835e
F test/sqllimits1.test a74ee2a3740b9f9c2437c246d8fb77354862a142
F test/sqllog.test 6af6cb0b09f4e44e1917e06ce85be7670302517a
F test/stat.test b65bad7120c52583b8f0054d99eff80718119a77
F test/stat.test 66e95f97b9f724f9ab921d054ee0db3c2689f1ee
F test/statfault.test f525a7bf633e50afd027700e9a486090684b1ac1
F test/stmt.test 64844332db69cf1a735fcb3e11548557fc95392f
F test/subquery.test d7268d193dd33d5505df965399d3a594e76ae13f
@@ -1100,7 +1102,7 @@ F test/substr.test 18f57c4ca8a598805c4d64e304c418734d843c1a
F test/subtype1.test 7fe09496352f97053af1437150751be2d0a0cae8
F test/superlock.test ec94f0556b6488d97f71c79f9061ae08d9ab8f12
F test/symlink.test c9ebe7330d228249e447038276bfc8a7b22f4849
F test/sync.test 2f607e1821aa3af3c5c53b58835c05e511c95899
F test/sync.test 2f84bdbc2b2df1fcb0220575b4b9f8cea94b7529
F test/syscall.test f59ba4e25f7ba4a4c031026cc2ef8b6e4b4c639c
F test/sysfault.test c9f2b0d8d677558f74de750c75e12a5454719d04
F test/tabfunc01.test f977868fa8bb7beb4b2072883190411653473906
@@ -1111,7 +1113,7 @@ F test/tclsqlite.test e1306001a0ca92250b691ea6d3cecaca5b6342aa
F test/tempdb.test bd92eba8f20e16a9136e434e20b280794de3cdb6
F test/temptable.test d2c9b87a54147161bcd1822e30c1d1cd891e5b30
F test/temptrigger.test 8ec228b0db5d7ebc4ee9b458fc28cb9e7873f5e1
F test/tester.tcl 7b740ee852c55e1e72b6ebe5044acee7aa4e5553
F test/tester.tcl 30c7a9be8601d1c1c9c93d013545ebcb28d64254
F test/thread001.test 9f22fd3525a307ff42a326b6bc7b0465be1745a5
F test/thread002.test e630504f8a06c00bf8bbe68528774dd96aeb2e58
F test/thread003.test ee4c9efc3b86a6a2767516a37bd64251272560a7
@@ -1127,10 +1129,10 @@ F test/threadtest4.c c1e67136ceb6c7ec8184e56ac61db28f96bd2925
F test/tkt-02a8e81d44.test 6c80d9c7514e2a42d4918bf87bf6bc54f379110c
F test/tkt-26ff0c2d1e.test 888324e751512972c6e0d1a09df740d8f5aaf660
F test/tkt-2a5629202f.test 0521bd25658428baa26665aa53ffed9367d33af2
F test/tkt-2d1a5c67d.test d371279946622698ab393ff88cad9f5f6d82960b
F test/tkt-2d1a5c67d.test be1326f3061caec85085f4c9ee4490561ca037c0
F test/tkt-2ea2425d34.test 1cf13e6f75d149b3209a0cb32927a82d3d79fb28
F test/tkt-31338dca7e.test 6fb8807851964da0d24e942f2e19c7c705b9fb58
F test/tkt-313723c356.test c47f8a9330523e6f35698bf4489bcb29609b53ac
F test/tkt-313723c356.test 4b306ad45c736cedf2f5221f6155b92143244b6d
F test/tkt-385a5b56b9.test c0a06ada41d7f06b1686da0e718553f853771d1e
F test/tkt-38cb5df375.test f3cc8671f1eb604d4ae9cf886ed4366bec656678
F test/tkt-3998683a16.test 6d1d04d551ed1704eb3396ca87bb9ccc8c5c1eb7
@@ -1141,7 +1143,7 @@ F test/tkt-4c86b126f2.test cbcc611becd0396890169ab23102dd70048bbc9a
F test/tkt-4dd95f6943.test 3d0ce415d2ee15d3d564121960016b9c7be79407
F test/tkt-4ef7e3cfca.test 3965ae11cc9cf6e334f9d7d3c1e20bf8d56254b1
F test/tkt-54844eea3f.test a12b851128f46a695e4e378cca67409b9b8f5894
F test/tkt-5d863f876e.test c9f36ca503fa154a3655f92a69d2c30da1747bfa
F test/tkt-5d863f876e.test 726e76d725f6fe0eb2fc8a522b721b79807380ee
F test/tkt-5e10420e8d.test 904d1687b3c06d43e5b3555bbcf6802e7c0ffd84
F test/tkt-5ee23731f.test 9db6e1d7209dc0794948b260d6f82b2b1de83a9f
F test/tkt-6bfb98dfc0.test 24780633627b5cfc0635a5500c2389ebfb563336
@@ -1157,7 +1159,7 @@ F test/tkt-8c63ff0ec.test 258b7fc8d7e4e1cb5362c7d65c143528b9c4cbed
F test/tkt-91e2e8ba6f.test 08c4f94ae07696b05c9b822da0b4e5337a2f54c5
F test/tkt-94c04eaadb.test f738c57c7f68ab8be1c054415af7774617cb6223
F test/tkt-9a8b09f8e6.test b2ef151d0984b2ebf237760dbeaa50724e5a0667
F test/tkt-9d68c883.test 458f7d82a523d7644b54b497c986378a7d8c8b67
F test/tkt-9d68c883.test 16f7cb96781ba579bc2e19bb14b4ad609d9774b6
F test/tkt-9f2eb3abac.test cb6123ac695a08b4454c3792fbe85108f67fabf8
F test/tkt-a7b7803e.test 159ef554234fa1f9fb318c751b284bd1cf858da4
F test/tkt-a8a0d2996a.test eb597379dbcefa24765763d7f682c00cb5924fa9
@@ -1308,7 +1310,7 @@ F test/vacuum3.test 77ecdd54592b45a0bcb133339f99f1ae0ae94d0d
F test/vacuum4.test d3f8ecff345f166911568f397d2432c16d2867d9
F test/varint.test ab7b110089a08b9926ed7390e7e97bdefeb74102
F test/veryquick.test 57ab846bacf7b90cf4e9a672721ea5c5b669b661
F test/view.test f6c3a39e0c819891265e1d0754e99960d81ef6c9
F test/view.test 765802c7a66d37fabd5ac8e2f2dbe572b43eb9ab
F test/vtab1.test 7c4b81abd88361ada9cbe414c459efca26be6bda
F test/vtab2.test f8cd1bb9aba7143eba97812d9617880a36d247ad
F test/vtab3.test b45f47d20f225ccc9c28dc915d92740c2dee311e
@@ -1396,7 +1398,7 @@ F test/without_rowid5.test 89b1c587bd92a0590e440da33e7666bf4891572a
F test/without_rowid6.test 1f99644e6508447fb050f73697350c7ceca3392e
F test/wordcount.c 2a0a6c0d0e8e8bbbac1f06d72a6791828c37c0cf
F test/zeroblob.test 3857870fe681b8185654414a9bccfde80b62a0fa
F test/zerodamage.test 2d725c214b883e25ae6bb85ef228ecdfa03c6a7b
F test/zerodamage.test e59a56443d6298ecf7435f618f0b27654f0c849e
F tool/GetFile.cs a15e08acb5dd7539b75ba23501581d7c2b462cb5
F tool/GetTclKit.bat 629d87562e0487c386db630033931d12d62e6372
F tool/Replace.cs 02c67258801c2fb5f63231e0ac0f220b4b36ba91
@@ -1415,12 +1417,12 @@ F tool/getlock.c f4c39b651370156cae979501a7b156bdba50e7ce
F tool/lemon.c cfbfe061a4b2766512f6b484882eee2c86a14506
F tool/lempar.c 404ea3dc27dbeed343f0e61b1d36e97b9f5f0fb6
F tool/loadfts.c c3c64e4d5e90e8ba41159232c2189dba4be7b862
F tool/logest.c eef612f8adf4d0993dafed0416064cf50d5d33c6
F tool/logest.c 11346aa019e2e77a00902aa7d0cabd27bd2e8cca
F tool/mkautoconfamal.sh e855df211ecbcc7131dee817110ff386cfb112f7
F tool/mkkeywordhash.c f7f3b342211ac6a14258b9726d5b97cf4f548f22
F tool/mkmsvcmin.tcl 2f12f7fa8858bbe61cf81820a2da96c79ed1ca8d
F tool/mkopcodec.tcl d1b6362bd3aa80d5520d4d6f3765badf01f6c43c
F tool/mkopcodeh.tcl 385c62d78c38b2d92146dcb5abd319dbbc33506d
F tool/mkopcodeh.tcl a01d2c1d8a6205b03fc635adf3735b4c523befd3
F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e
F tool/mkpragmatab.tcl f0d5bb266d1d388cf86fce5ba01a891e95d72d41
F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97
@@ -1436,7 +1438,7 @@ F tool/replace.tcl 7727c60a04299b65a92f5e1590896fea0f25b9e0
F tool/restore_jrnl.tcl 6957a34f8f1f0f8285e07536225ec3b292a9024a
F tool/rollback-test.c 9fc98427d1e23e84429d7e6d07d9094fbdec65a5
F tool/run-speed-test.sh f95d19fd669b68c4c38b6b475242841d47c66076
F tool/showdb.c 82dca79a999b2701c62417636345e9974151fdad
F tool/showdb.c c695a5d5c8110640e0d9fadf5e254da90c79c36e
F tool/showjournal.c 5bad7ae8784a43d2b270d953060423b8bd480818
F tool/showlocks.c 9920bcc64f58378ff1118caead34147201f48c68
F tool/showstat4.c bda40d6e395df7edb6e9ea630784d3d762c35b4b
@@ -1482,7 +1484,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
P 195f3340ee4d870420e4f58d44300bab5436b920
R 553c882c4eb73691c7e02bdd576b9d70
P 45467ee49872f495d5276cf830f10c3cf4ac8e3c
R 50a6a2b7911c16c6704703bf8b17ce71
U dan
Z 5ef40d72349254975dc55c844d6daff8
Z da972510c8d8b75cf481b4f80618fa01
+1 -1
View File
@@ -1 +1 @@
49763fc3ae2fb6117b0443ea28661568467f9bf2
89b0ee3351381f7bc666cb206f77a56f2e0d4a0e
+17 -14
View File
@@ -1826,7 +1826,7 @@ int sqlite3AnalysisLoad(sqlite3 *db, int iDb){
analysisInfo sInfo;
HashElem *i;
char *zSql;
int rc;
int rc = SQLITE_OK;
assert( iDb>=0 && iDb<db->nDb );
assert( db->aDb[iDb].pBt!=0 );
@@ -1835,31 +1835,34 @@ int sqlite3AnalysisLoad(sqlite3 *db, int iDb){
assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
for(i=sqliteHashFirst(&db->aDb[iDb].pSchema->idxHash);i;i=sqliteHashNext(i)){
Index *pIdx = sqliteHashData(i);
sqlite3DefaultRowEst(pIdx);
pIdx->aiRowLogEst[0] = 0;
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
sqlite3DeleteIndexSamples(db, pIdx);
pIdx->aSample = 0;
#endif
}
/* Check to make sure the sqlite_stat1 table exists */
/* Load new statistics out of the sqlite_stat1 table */
sInfo.db = db;
sInfo.zDatabase = db->aDb[iDb].zName;
if( sqlite3FindTable(db, "sqlite_stat1", sInfo.zDatabase)==0 ){
return SQLITE_ERROR;
if( sqlite3FindTable(db, "sqlite_stat1", sInfo.zDatabase)!=0 ){
zSql = sqlite3MPrintf(db,
"SELECT tbl,idx,stat FROM %Q.sqlite_stat1", sInfo.zDatabase);
if( zSql==0 ){
rc = SQLITE_NOMEM_BKPT;
}else{
rc = sqlite3_exec(db, zSql, analysisLoader, &sInfo, 0);
sqlite3DbFree(db, zSql);
}
}
/* Load new statistics out of the sqlite_stat1 table */
zSql = sqlite3MPrintf(db,
"SELECT tbl,idx,stat FROM %Q.sqlite_stat1", sInfo.zDatabase);
if( zSql==0 ){
rc = SQLITE_NOMEM_BKPT;
}else{
rc = sqlite3_exec(db, zSql, analysisLoader, &sInfo, 0);
sqlite3DbFree(db, zSql);
/* Set appropriate defaults on all indexes not in the sqlite_stat1 table */
assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
for(i=sqliteHashFirst(&db->aDb[iDb].pSchema->idxHash);i;i=sqliteHashNext(i)){
Index *pIdx = sqliteHashData(i);
if( pIdx->aiRowLogEst[0]==0 ) sqlite3DefaultRowEst(pIdx);
}
/* Load the statistics from the sqlite_stat4 table. */
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
if( rc==SQLITE_OK && OptimizationEnabled(db, SQLITE_Stat34) ){
+24 -24
View File
@@ -6545,8 +6545,8 @@ static int pageInsertArray(
u8 *pSlot;
sz = cachedCellSize(pCArray, i);
if( (aData[1]==0 && aData[2]==0) || (pSlot = pageFindSlot(pPg,sz,&rc))==0 ){
if( (pData - pBegin)<sz ) return 1;
pData -= sz;
if( pData<pBegin ) return 1;
pSlot = pData;
}
/* pSlot and pCArray->apCell[i] will never overlap on a well-formed
@@ -6708,7 +6708,7 @@ static int editPage(
for(i=0; i<nNew && !CORRUPT_DB; i++){
u8 *pCell = pCArray->apCell[i+iNew];
int iOff = get2byteAligned(&pPg->aCellIdx[i*2]);
if( pCell>=aData && pCell<&aData[pPg->pBt->usableSize] ){
if( SQLITE_WITHIN(pCell, aData, &aData[pPg->pBt->usableSize]) ){
pCell = &pTmp[pCell - aData];
}
assert( 0==memcmp(pCell, &aData[iOff],
@@ -8140,6 +8140,28 @@ int sqlite3BtreeDelete(BtCursor *pCur, u8 flags){
pPage = pCur->apPage[iCellDepth];
pCell = findCell(pPage, iCellIdx);
/* If the bPreserve flag is set to true, then the cursor position must
** be preserved following this delete operation. If the current delete
** will cause a b-tree rebalance, then this is done by saving the cursor
** key and leaving the cursor in CURSOR_REQUIRESEEK state before
** returning.
**
** Or, if the current delete will not cause a rebalance, then the cursor
** will be left in CURSOR_SKIPNEXT state pointing to the entry immediately
** before or after the deleted entry. In this case set bSkipnext to true. */
if( bPreserve ){
if( !pPage->leaf
|| (pPage->nFree+cellSizePtr(pPage,pCell)+2)>(int)(pBt->usableSize*2/3)
){
/* A b-tree rebalance will be required after deleting this entry.
** Save the cursor key. */
rc = saveCursorKey(pCur);
if( rc ) return rc;
}else{
bSkipnext = 1;
}
}
/* If the page containing the entry to delete is not a leaf page, move
** the cursor to the largest entry in the tree that is smaller than
** the entry being deleted. This cell will replace the cell being deleted
@@ -8166,28 +8188,6 @@ int sqlite3BtreeDelete(BtCursor *pCur, u8 flags){
invalidateIncrblobCursors(p, pCur->info.nKey, 0);
}
/* If the bPreserve flag is set to true, then the cursor position must
** be preserved following this delete operation. If the current delete
** will cause a b-tree rebalance, then this is done by saving the cursor
** key and leaving the cursor in CURSOR_REQUIRESEEK state before
** returning.
**
** Or, if the current delete will not cause a rebalance, then the cursor
** will be left in CURSOR_SKIPNEXT state pointing to the entry immediately
** before or after the deleted entry. In this case set bSkipnext to true. */
if( bPreserve ){
if( !pPage->leaf
|| (pPage->nFree+cellSizePtr(pPage,pCell)+2)>(int)(pBt->usableSize*2/3)
){
/* A b-tree rebalance will be required after deleting this entry.
** Save the cursor key. */
rc = saveCursorKey(pCur);
if( rc ) return rc;
}else{
bSkipnext = 1;
}
}
/* Make the page containing the entry to be deleted writable. Then free any
** overflow pages associated with the entry and finally remove the cell
** itself from within the page. */
+45 -33
View File
@@ -1086,6 +1086,7 @@ void sqlite3AddColumn(Parse *pParse, Token *pName, Token *pType){
zType = z + sqlite3Strlen30(z) + 1;
memcpy(zType, pType->z, pType->n);
zType[pType->n] = 0;
sqlite3Dequote(zType);
pCol->affinity = sqlite3AffinityType(zType, &pCol->szEst);
pCol->colFlags |= COLFLAG_HASTYPE;
}
@@ -2176,44 +2177,55 @@ int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){
** statement that defines the view.
*/
assert( pTable->pSelect );
if( pTable->pCheck ){
pSel = sqlite3SelectDup(db, pTable->pSelect, 0);
if( pSel ){
n = pParse->nTab;
sqlite3SrcListAssignCursors(pParse, pSel->pSrc);
pTable->nCol = -1;
db->lookaside.bDisable++;
sqlite3ColumnsFromExprList(pParse, pTable->pCheck,
&pTable->nCol, &pTable->aCol);
db->lookaside.bDisable--;
}else{
pSel = sqlite3SelectDup(db, pTable->pSelect, 0);
if( pSel ){
n = pParse->nTab;
sqlite3SrcListAssignCursors(pParse, pSel->pSrc);
pTable->nCol = -1;
db->lookaside.bDisable++;
#ifndef SQLITE_OMIT_AUTHORIZATION
xAuth = db->xAuth;
db->xAuth = 0;
pSelTab = sqlite3ResultSetOfSelect(pParse, pSel);
db->xAuth = xAuth;
xAuth = db->xAuth;
db->xAuth = 0;
pSelTab = sqlite3ResultSetOfSelect(pParse, pSel);
db->xAuth = xAuth;
#else
pSelTab = sqlite3ResultSetOfSelect(pParse, pSel);
pSelTab = sqlite3ResultSetOfSelect(pParse, pSel);
#endif
db->lookaside.bDisable--;
pParse->nTab = n;
if( pSelTab ){
assert( pTable->aCol==0 );
pTable->nCol = pSelTab->nCol;
pTable->aCol = pSelTab->aCol;
pSelTab->nCol = 0;
pSelTab->aCol = 0;
sqlite3DeleteTable(db, pSelTab);
assert( sqlite3SchemaMutexHeld(db, 0, pTable->pSchema) );
}else{
pTable->nCol = 0;
nErr++;
pParse->nTab = n;
if( pTable->pCheck ){
/* CREATE VIEW name(arglist) AS ...
** The names of the columns in the table are taken from
** arglist which is stored in pTable->pCheck. The pCheck field
** normally holds CHECK constraints on an ordinary table, but for
** a VIEW it holds the list of column names.
*/
sqlite3ColumnsFromExprList(pParse, pTable->pCheck,
&pTable->nCol, &pTable->aCol);
if( db->mallocFailed==0
&& pParse->nErr==0
&& pTable->nCol==pSel->pEList->nExpr
){
sqlite3SelectAddColumnTypeAndCollation(pParse, pTable, pSel);
}
sqlite3SelectDelete(db, pSel);
} else {
}else if( pSelTab ){
/* CREATE VIEW name AS... without an argument list. Construct
** the column names from the SELECT statement that defines the view.
*/
assert( pTable->aCol==0 );
pTable->nCol = pSelTab->nCol;
pTable->aCol = pSelTab->aCol;
pSelTab->nCol = 0;
pSelTab->aCol = 0;
assert( sqlite3SchemaMutexHeld(db, 0, pTable->pSchema) );
}else{
pTable->nCol = 0;
nErr++;
}
if( pSelTab ) sqlite3DeleteTable(db, pSelTab);
sqlite3SelectDelete(db, pSel);
db->lookaside.bDisable--;
} else {
nErr++;
}
pTable->pSchema->schemaFlags |= DB_UnresetViews;
#endif /* SQLITE_OMIT_VIEW */
@@ -2762,6 +2774,7 @@ static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){
tnum = pIndex->tnum;
}
pKey = sqlite3KeyInfoOfIndex(pParse, pIndex);
assert( pKey!=0 || db->mallocFailed || pParse->nErr );
/* Open the sorter cursor if we are to use one. */
iSorter = pParse->nTab++;
@@ -2785,8 +2798,7 @@ static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){
sqlite3VdbeChangeP5(v, OPFLAG_BULKCSR|((memRootPage>=0)?OPFLAG_P2ISREG:0));
addr1 = sqlite3VdbeAddOp2(v, OP_SorterSort, iSorter, 0); VdbeCoverage(v);
assert( pKey!=0 || db->mallocFailed || pParse->nErr );
if( IsUniqueIndex(pIndex) && pKey!=0 ){
if( IsUniqueIndex(pIndex) ){
int j2 = sqlite3VdbeCurrentAddr(v) + 3;
sqlite3VdbeGoto(v, j2);
addr2 = sqlite3VdbeCurrentAddr(v);
+10 -1
View File
@@ -50,6 +50,15 @@
#ifndef SQLITE_OMIT_DATETIME_FUNCS
/*
** The MSVC CRT on Windows CE may not have a localtime() function.
** So declare a substitute. The substitute function itself is
** defined in "os_win.c".
*/
#if !defined(SQLITE_OMIT_LOCALTIME) && defined(_WIN32_WCE) && \
(!defined(SQLITE_MSVC_LOCALTIME_API) || !SQLITE_MSVC_LOCALTIME_API)
struct tm *__cdecl localtime(const time_t *);
#endif
/*
** A structure for holding a single date and time.
@@ -418,6 +427,7 @@ static void clearYMD_HMS_TZ(DateTime *p){
p->validTZ = 0;
}
#ifndef SQLITE_OMIT_LOCALTIME
/*
** On recent Windows platforms, the localtime_s() function is available
** as part of the "Secure CRT". It is essentially equivalent to
@@ -436,7 +446,6 @@ static void clearYMD_HMS_TZ(DateTime *p){
#define HAVE_LOCALTIME_S 1
#endif
#ifndef SQLITE_OMIT_LOCALTIME
/*
** The following routine implements the rough equivalent of localtime_r()
** using whatever operating-system specific localtime facility that
+7 -17
View File
@@ -143,7 +143,7 @@ Expr *sqlite3LimitWhere(
*/
if( pOrderBy && (pLimit == 0) ) {
sqlite3ErrorMsg(pParse, "ORDER BY without LIMIT on %s", zStmtType);
goto limit_where_cleanup_2;
goto limit_where_cleanup;
}
/* We only need to generate a select expression if there
@@ -165,16 +165,16 @@ Expr *sqlite3LimitWhere(
*/
pSelectRowid = sqlite3PExpr(pParse, TK_ROW, 0, 0, 0);
if( pSelectRowid == 0 ) goto limit_where_cleanup_2;
if( pSelectRowid == 0 ) goto limit_where_cleanup;
pEList = sqlite3ExprListAppend(pParse, 0, pSelectRowid);
if( pEList == 0 ) goto limit_where_cleanup_2;
if( pEList == 0 ) goto limit_where_cleanup;
/* duplicate the FROM clause as it is needed by both the DELETE/UPDATE tree
** and the SELECT subtree. */
pSelectSrc = sqlite3SrcListDup(pParse->db, pSrc, 0);
if( pSelectSrc == 0 ) {
sqlite3ExprListDelete(pParse->db, pEList);
goto limit_where_cleanup_2;
goto limit_where_cleanup;
}
/* generate the SELECT expression tree. */
@@ -184,21 +184,11 @@ Expr *sqlite3LimitWhere(
/* now generate the new WHERE rowid IN clause for the DELETE/UDPATE */
pWhereRowid = sqlite3PExpr(pParse, TK_ROW, 0, 0, 0);
if( pWhereRowid == 0 ) goto limit_where_cleanup_1;
pInClause = sqlite3PExpr(pParse, TK_IN, pWhereRowid, 0, 0);
if( pInClause == 0 ) goto limit_where_cleanup_1;
pInClause->x.pSelect = pSelect;
pInClause->flags |= EP_xIsSelect;
sqlite3ExprSetHeightAndFlags(pParse, pInClause);
pInClause = pWhereRowid ? sqlite3PExpr(pParse, TK_IN, pWhereRowid, 0, 0) : 0;
sqlite3PExprAddSelect(pParse, pInClause, pSelect);
return pInClause;
/* something went wrong. clean up anything allocated. */
limit_where_cleanup_1:
sqlite3SelectDelete(pParse->db, pSelect);
return 0;
limit_where_cleanup_2:
limit_where_cleanup:
sqlite3ExprDelete(pParse->db, pWhere);
sqlite3ExprListDelete(pParse->db, pOrderBy);
sqlite3ExprDelete(pParse->db, pLimit);
+127 -92
View File
@@ -471,15 +471,13 @@ Expr *sqlite3ExprAlloc(
pNew->flags |= EP_IntValue;
pNew->u.iValue = iValue;
}else{
int c;
pNew->u.zToken = (char*)&pNew[1];
assert( pToken->z!=0 || pToken->n==0 );
if( pToken->n ) memcpy(pNew->u.zToken, pToken->z, pToken->n);
pNew->u.zToken[pToken->n] = 0;
if( dequote && nExtra>=3
&& ((c = pToken->z[0])=='\'' || c=='"' || c=='[' || c=='`') ){
if( dequote && sqlite3Isquote(pNew->u.zToken[0]) ){
if( pNew->u.zToken[0]=='"' ) pNew->flags |= EP_DblQuoted;
sqlite3Dequote(pNew->u.zToken);
if( c=='"' ) pNew->flags |= EP_DblQuoted;
}
}
}
@@ -562,6 +560,22 @@ Expr *sqlite3PExpr(
return p;
}
/*
** Add pSelect to the Expr.x.pSelect field. Or, if pExpr is NULL (due
** do a memory allocation failure) then delete the pSelect object.
*/
void sqlite3PExprAddSelect(Parse *pParse, Expr *pExpr, Select *pSelect){
if( pExpr ){
pExpr->x.pSelect = pSelect;
ExprSetProperty(pExpr, EP_xIsSelect|EP_Subquery);
sqlite3ExprSetHeightAndFlags(pParse, pExpr);
}else{
assert( pParse->db->mallocFailed );
sqlite3SelectDelete(pParse->db, pSelect);
}
}
/*
** If the expression is always either TRUE or FALSE (respectively),
** then return 1. If one cannot determine the truth value of the
@@ -722,8 +736,8 @@ void sqlite3ExprAssignVarNumber(Parse *pParse, Expr *pExpr){
/*
** Recursively delete an expression tree.
*/
void sqlite3ExprDelete(sqlite3 *db, Expr *p){
if( p==0 ) return;
static SQLITE_NOINLINE void sqlite3ExprDeleteNN(sqlite3 *db, Expr *p){
assert( p!=0 );
/* Sanity check: Assert that the IntValue is non-negative if it exists */
assert( !ExprHasProperty(p, EP_IntValue) || p->u.iValue>=0 );
if( !ExprHasProperty(p, EP_TokenOnly) ){
@@ -742,6 +756,9 @@ void sqlite3ExprDelete(sqlite3 *db, Expr *p){
sqlite3DbFree(db, p);
}
}
void sqlite3ExprDelete(sqlite3 *db, Expr *p){
if( p ) sqlite3ExprDeleteNN(db, p);
}
/*
** Return the number of bytes allocated for the expression structure
@@ -793,7 +810,7 @@ static int dupedExprStructSize(Expr *p, int flags){
assert( flags==EXPRDUP_REDUCE || flags==0 ); /* Only one flag value allowed */
assert( EXPR_FULLSIZE<=0xfff );
assert( (0xfff & (EP_Reduced|EP_TokenOnly))==0 );
if( 0==(flags&EXPRDUP_REDUCE) ){
if( 0==flags ){
nSize = EXPR_FULLSIZE;
}else{
assert( !ExprHasProperty(p, EP_TokenOnly|EP_Reduced) );
@@ -855,88 +872,88 @@ static int dupedExprSize(Expr *p, int flags){
** if any. Before returning, *pzBuffer is set to the first byte past the
** portion of the buffer copied into by this function.
*/
static Expr *exprDup(sqlite3 *db, Expr *p, int flags, u8 **pzBuffer){
Expr *pNew = 0; /* Value to return */
assert( flags==0 || flags==EXPRDUP_REDUCE );
static Expr *exprDup(sqlite3 *db, Expr *p, int dupFlags, u8 **pzBuffer){
Expr *pNew; /* Value to return */
u8 *zAlloc; /* Memory space from which to build Expr object */
u32 staticFlag; /* EP_Static if space not obtained from malloc */
assert( db!=0 );
if( p ){
const int isReduced = (flags&EXPRDUP_REDUCE);
u8 *zAlloc;
u32 staticFlag = 0;
assert( p );
assert( dupFlags==0 || dupFlags==EXPRDUP_REDUCE );
assert( pzBuffer==0 || dupFlags==EXPRDUP_REDUCE );
assert( pzBuffer==0 || isReduced );
/* Figure out where to write the new Expr structure. */
if( pzBuffer ){
zAlloc = *pzBuffer;
staticFlag = EP_Static;
}else{
zAlloc = sqlite3DbMallocRawNN(db, dupedExprSize(p, dupFlags));
staticFlag = 0;
}
pNew = (Expr *)zAlloc;
/* Figure out where to write the new Expr structure. */
if( pzBuffer ){
zAlloc = *pzBuffer;
staticFlag = EP_Static;
if( pNew ){
/* Set nNewSize to the size allocated for the structure pointed to
** by pNew. This is either EXPR_FULLSIZE, EXPR_REDUCEDSIZE or
** EXPR_TOKENONLYSIZE. nToken is set to the number of bytes consumed
** by the copy of the p->u.zToken string (if any).
*/
const unsigned nStructSize = dupedExprStructSize(p, dupFlags);
const int nNewSize = nStructSize & 0xfff;
int nToken;
if( !ExprHasProperty(p, EP_IntValue) && p->u.zToken ){
nToken = sqlite3Strlen30(p->u.zToken) + 1;
}else{
zAlloc = sqlite3DbMallocRawNN(db, dupedExprSize(p, flags));
nToken = 0;
}
if( dupFlags ){
assert( ExprHasProperty(p, EP_Reduced)==0 );
memcpy(zAlloc, p, nNewSize);
}else{
u32 nSize = (u32)exprStructSize(p);
memcpy(zAlloc, p, nSize);
if( nSize<EXPR_FULLSIZE ){
memset(&zAlloc[nSize], 0, EXPR_FULLSIZE-nSize);
}
}
pNew = (Expr *)zAlloc;
if( pNew ){
/* Set nNewSize to the size allocated for the structure pointed to
** by pNew. This is either EXPR_FULLSIZE, EXPR_REDUCEDSIZE or
** EXPR_TOKENONLYSIZE. nToken is set to the number of bytes consumed
** by the copy of the p->u.zToken string (if any).
*/
const unsigned nStructSize = dupedExprStructSize(p, flags);
const int nNewSize = nStructSize & 0xfff;
int nToken;
if( !ExprHasProperty(p, EP_IntValue) && p->u.zToken ){
nToken = sqlite3Strlen30(p->u.zToken) + 1;
/* Set the EP_Reduced, EP_TokenOnly, and EP_Static flags appropriately. */
pNew->flags &= ~(EP_Reduced|EP_TokenOnly|EP_Static|EP_MemToken);
pNew->flags |= nStructSize & (EP_Reduced|EP_TokenOnly);
pNew->flags |= staticFlag;
/* Copy the p->u.zToken string, if any. */
if( nToken ){
char *zToken = pNew->u.zToken = (char*)&zAlloc[nNewSize];
memcpy(zToken, p->u.zToken, nToken);
}
if( 0==((p->flags|pNew->flags) & EP_TokenOnly) ){
/* Fill in the pNew->x.pSelect or pNew->x.pList member. */
if( ExprHasProperty(p, EP_xIsSelect) ){
pNew->x.pSelect = sqlite3SelectDup(db, p->x.pSelect, dupFlags);
}else{
nToken = 0;
pNew->x.pList = sqlite3ExprListDup(db, p->x.pList, dupFlags);
}
if( isReduced ){
assert( ExprHasProperty(p, EP_Reduced)==0 );
memcpy(zAlloc, p, nNewSize);
}else{
u32 nSize = (u32)exprStructSize(p);
memcpy(zAlloc, p, nSize);
if( nSize<EXPR_FULLSIZE ){
memset(&zAlloc[nSize], 0, EXPR_FULLSIZE-nSize);
}
}
/* Fill in pNew->pLeft and pNew->pRight. */
if( ExprHasProperty(pNew, EP_Reduced|EP_TokenOnly) ){
zAlloc += dupedExprNodeSize(p, dupFlags);
if( ExprHasProperty(pNew, EP_Reduced) ){
pNew->pLeft = p->pLeft ?
exprDup(db, p->pLeft, EXPRDUP_REDUCE, &zAlloc) : 0;
pNew->pRight = p->pRight ?
exprDup(db, p->pRight, EXPRDUP_REDUCE, &zAlloc) : 0;
}
/* Set the EP_Reduced, EP_TokenOnly, and EP_Static flags appropriately. */
pNew->flags &= ~(EP_Reduced|EP_TokenOnly|EP_Static|EP_MemToken);
pNew->flags |= nStructSize & (EP_Reduced|EP_TokenOnly);
pNew->flags |= staticFlag;
/* Copy the p->u.zToken string, if any. */
if( nToken ){
char *zToken = pNew->u.zToken = (char*)&zAlloc[nNewSize];
memcpy(zToken, p->u.zToken, nToken);
if( pzBuffer ){
*pzBuffer = zAlloc;
}
if( 0==((p->flags|pNew->flags) & EP_TokenOnly) ){
/* Fill in the pNew->x.pSelect or pNew->x.pList member. */
if( ExprHasProperty(p, EP_xIsSelect) ){
pNew->x.pSelect = sqlite3SelectDup(db, p->x.pSelect, isReduced);
}else{
pNew->x.pList = sqlite3ExprListDup(db, p->x.pList, isReduced);
}
}else{
if( !ExprHasProperty(p, EP_TokenOnly) ){
pNew->pLeft = sqlite3ExprDup(db, p->pLeft, 0);
pNew->pRight = sqlite3ExprDup(db, p->pRight, 0);
}
/* Fill in pNew->pLeft and pNew->pRight. */
if( ExprHasProperty(pNew, EP_Reduced|EP_TokenOnly) ){
zAlloc += dupedExprNodeSize(p, flags);
if( ExprHasProperty(pNew, EP_Reduced) ){
pNew->pLeft = exprDup(db, p->pLeft, EXPRDUP_REDUCE, &zAlloc);
pNew->pRight = exprDup(db, p->pRight, EXPRDUP_REDUCE, &zAlloc);
}
if( pzBuffer ){
*pzBuffer = zAlloc;
}
}else{
if( !ExprHasProperty(p, EP_TokenOnly) ){
pNew->pLeft = sqlite3ExprDup(db, p->pLeft, 0);
pNew->pRight = sqlite3ExprDup(db, p->pRight, 0);
}
}
}
}
return pNew;
@@ -988,7 +1005,7 @@ static With *withDup(sqlite3 *db, With *p){
*/
Expr *sqlite3ExprDup(sqlite3 *db, Expr *p, int flags){
assert( flags==0 || flags==EXPRDUP_REDUCE );
return exprDup(db, p, flags, 0);
return p ? exprDup(db, p, flags, 0) : 0;
}
ExprList *sqlite3ExprListDup(sqlite3 *db, ExprList *p, int flags){
ExprList *pNew;
@@ -1210,7 +1227,7 @@ void sqlite3ExprListSetName(
pItem = &pList->a[pList->nExpr-1];
assert( pItem->zName==0 );
pItem->zName = sqlite3DbStrNDup(pParse->db, pName->z, pName->n);
if( dequote && pItem->zName ) sqlite3Dequote(pItem->zName);
if( dequote ) sqlite3Dequote(pItem->zName);
}
}
@@ -1259,10 +1276,9 @@ void sqlite3ExprListCheckLength(
/*
** Delete an entire expression list.
*/
void sqlite3ExprListDelete(sqlite3 *db, ExprList *pList){
static SQLITE_NOINLINE void exprListDeleteNN(sqlite3 *db, ExprList *pList){
int i;
struct ExprList_item *pItem;
if( pList==0 ) return;
assert( pList->a!=0 || pList->nExpr==0 );
for(pItem=pList->a, i=0; i<pList->nExpr; i++, pItem++){
sqlite3ExprDelete(db, pItem->pExpr);
@@ -1272,6 +1288,9 @@ void sqlite3ExprListDelete(sqlite3 *db, ExprList *pList){
sqlite3DbFree(db, pList->a);
sqlite3DbFree(db, pList);
}
void sqlite3ExprListDelete(sqlite3 *db, ExprList *pList){
if( pList ) exprListDeleteNN(db, pList);
}
/*
** Return the bitwise-OR of all Expr.flags fields in the given
@@ -2316,6 +2335,19 @@ static void codeInteger(Parse *pParse, Expr *pExpr, int negFlag, int iMem){
}
}
#if defined(SQLITE_DEBUG)
/*
** Verify the consistency of the column cache
*/
static int cacheIsValid(Parse *pParse){
int i, n;
for(i=n=0; i<SQLITE_N_COLCACHE; i++){
if( pParse->aColCache[i].iReg>0 ) n++;
}
return n==pParse->nColCache;
}
#endif
/*
** Clear a cache entry.
*/
@@ -2326,6 +2358,9 @@ static void cacheEntryClear(Parse *pParse, struct yColCache *p){
}
p->tempReg = 0;
}
p->iReg = 0;
pParse->nColCache--;
assert( pParse->db->mallocFailed || cacheIsValid(pParse) );
}
@@ -2369,6 +2404,8 @@ void sqlite3ExprCacheStore(Parse *pParse, int iTab, int iCol, int iReg){
p->iReg = iReg;
p->tempReg = 0;
p->lru = pParse->iCacheCnt++;
pParse->nColCache++;
assert( pParse->db->mallocFailed || cacheIsValid(pParse) );
return;
}
}
@@ -2390,6 +2427,7 @@ void sqlite3ExprCacheStore(Parse *pParse, int iTab, int iCol, int iReg){
p->iReg = iReg;
p->tempReg = 0;
p->lru = pParse->iCacheCnt++;
assert( cacheIsValid(pParse) );
return;
}
}
@@ -2399,15 +2437,13 @@ void sqlite3ExprCacheStore(Parse *pParse, int iTab, int iCol, int iReg){
** Purge the range of registers from the column cache.
*/
void sqlite3ExprCacheRemove(Parse *pParse, int iReg, int nReg){
int i;
int iLast = iReg + nReg - 1;
struct yColCache *p;
for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){
int r = p->iReg;
if( r>=iReg && r<=iLast ){
cacheEntryClear(pParse, p);
p->iReg = 0;
}
if( iReg<=0 || pParse->nColCache==0 ) return;
p = &pParse->aColCache[SQLITE_N_COLCACHE-1];
while(1){
if( p->iReg >= iReg && p->iReg < iReg+nReg ) cacheEntryClear(pParse, p);
if( p==pParse->aColCache ) break;
p--;
}
}
@@ -2443,7 +2479,6 @@ void sqlite3ExprCachePop(Parse *pParse){
for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){
if( p->iReg && p->iLevel>pParse->iCacheLevel ){
cacheEntryClear(pParse, p);
p->iReg = 0;
}
}
}
@@ -2578,7 +2613,6 @@ void sqlite3ExprCacheClear(Parse *pParse){
for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){
if( p->iReg ){
cacheEntryClear(pParse, p);
p->iReg = 0;
}
}
}
@@ -2620,6 +2654,7 @@ static int usedAsColumnCache(Parse *pParse, int iFrom, int iTo){
}
#endif /* SQLITE_DEBUG || SQLITE_COVERAGE_TEST */
/*
** Convert an expression node to a TK_REGISTER
*/
+8
View File
@@ -1386,6 +1386,14 @@ static void loadExt(sqlite3_context *context, int argc, sqlite3_value **argv){
sqlite3 *db = sqlite3_context_db_handle(context);
char *zErrMsg = 0;
/* Disallow the load_extension() SQL function unless the SQLITE_LoadExtFunc
** flag is set. See the sqlite3_enable_load_extension() API.
*/
if( (db->flags & SQLITE_LoadExtFunc)==0 ){
sqlite3_result_error(context, "not authorized", -1);
return;
}
if( argc==2 ){
zProc = (const char *)sqlite3_value_text(argv[1]);
}else{
+4 -3
View File
@@ -70,6 +70,7 @@ const unsigned char sqlite3UpperToLower[] = {
** isxdigit() 0x08
** toupper() 0x20
** SQLite identifier character 0x40
** Quote character 0x80
**
** Bit 0x20 is set if the mapped character requires translation to upper
** case. i.e. if the character is a lower-case ASCII character.
@@ -95,7 +96,7 @@ const unsigned char sqlite3CtypeMap[256] = {
0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, /* 08..0f ........ */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 10..17 ........ */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 18..1f ........ */
0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, /* 20..27 !"#$%&' */
0x01, 0x00, 0x80, 0x00, 0x40, 0x00, 0x00, 0x80, /* 20..27 !"#$%&' */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 28..2f ()*+,-./ */
0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, /* 30..37 01234567 */
0x0c, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 38..3f 89:;<=>? */
@@ -103,8 +104,8 @@ const unsigned char sqlite3CtypeMap[256] = {
0x00, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x02, /* 40..47 @ABCDEFG */
0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, /* 48..4f HIJKLMNO */
0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, /* 50..57 PQRSTUVW */
0x02, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x40, /* 58..5f XYZ[\]^_ */
0x00, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x22, /* 60..67 `abcdefg */
0x02, 0x02, 0x02, 0x80, 0x00, 0x00, 0x00, 0x40, /* 58..5f XYZ[\]^_ */
0x80, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x22, /* 60..67 `abcdefg */
0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, /* 68..6f hijklmno */
0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, /* 70..77 pqrstuvw */
0x22, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, /* 78..7f xyz{|}~. */
+2 -2
View File
@@ -55,7 +55,7 @@ void sqlite3HashClear(Hash *pH){
static unsigned int strHash(const char *z){
unsigned int h = 0;
unsigned char c;
while( (c = (unsigned char)*z++)!=0 ){
while( (c = (unsigned char)*z++)!=0 ){ /*OPTIMIZATION-IF-TRUE*/
h = (h<<3) ^ h ^ sqlite3UpperToLower[c];
}
return h;
@@ -148,7 +148,7 @@ static HashElem *findElementWithHash(
int count; /* Number of elements left to test */
unsigned int h; /* The computed hash */
if( pH->ht ){
if( pH->ht ){ /*OPTIMIZATION-IF-TRUE*/
struct _ht *pEntry;
h = strHash(pKey) % pH->htsize;
pEntry = &pH->ht[h];
+5 -4
View File
@@ -464,8 +464,9 @@ static int sqlite3LoadExtension(
/* Ticket #1863. To avoid a creating security problems for older
** applications that relink against newer versions of SQLite, the
** ability to run load_extension is turned off by default. One
** must call sqlite3_enable_load_extension() to turn on extension
** loading. Otherwise you get the following error.
** must call either sqlite3_enable_load_extension(db) or
** sqlite3_db_config(db, SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION, 1, 0)
** to turn on extension loading.
*/
if( (db->flags & SQLITE_LoadExtension)==0 ){
if( pzErrMsg ){
@@ -604,9 +605,9 @@ void sqlite3CloseExtensions(sqlite3 *db){
int sqlite3_enable_load_extension(sqlite3 *db, int onoff){
sqlite3_mutex_enter(db->mutex);
if( onoff ){
db->flags |= SQLITE_LoadExtension;
db->flags |= SQLITE_LoadExtension|SQLITE_LoadExtFunc;
}else{
db->flags &= ~SQLITE_LoadExtension;
db->flags &= ~(SQLITE_LoadExtension|SQLITE_LoadExtFunc);
}
sqlite3_mutex_leave(db->mutex);
return SQLITE_OK;
+1
View File
@@ -804,6 +804,7 @@ int sqlite3_db_config(sqlite3 *db, int op, ...){
{ SQLITE_DBCONFIG_ENABLE_FKEY, SQLITE_ForeignKeys },
{ SQLITE_DBCONFIG_ENABLE_TRIGGER, SQLITE_EnableTrigger },
{ SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER, SQLITE_Fts3Tokenizer },
{ SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION, SQLITE_LoadExtension },
};
unsigned int i;
rc = SQLITE_ERROR; /* IMP: R-42790-23372 */
+12 -1
View File
@@ -13,6 +13,15 @@
** This file contains code use to implement an in-memory rollback journal.
** The in-memory rollback journal is used to journal transactions for
** ":memory:" databases and when the journal_mode=MEMORY pragma is used.
**
** Update: The in-memory journal is also used to temporarily cache
** smaller journals that are not critical for power-loss recovery.
** For example, statement journals that are not too big will be held
** entirely in memory, thus reducing the number of file I/O calls, and
** more importantly, reducing temporary file creation events. If these
** journals become too large for memory, they are spilled to disk. But
** in the common case, they are usually small and no file I/O needs to
** occur.
*/
#include "sqliteInt.h"
@@ -94,6 +103,7 @@ static int memjrnlRead(
#endif
assert( (iAmt+iOfst)<=p->endpoint.iOffset );
assert( p->readpoint.iOffset==0 || p->readpoint.pChunk!=0 );
if( p->readpoint.iOffset!=iOfst || iOfst==0 ){
sqlite3_int64 iOff = 0;
for(pChunk=p->pFirst;
@@ -104,6 +114,7 @@ static int memjrnlRead(
}
}else{
pChunk = p->readpoint.pChunk;
assert( pChunk!=0 );
}
iChunkOffset = (int)(iOfst%p->nChunkSize);
@@ -115,7 +126,7 @@ static int memjrnlRead(
nRead -= iSpace;
iChunkOffset = 0;
} while( nRead>=0 && (pChunk=pChunk->pNext)!=0 && nRead>0 );
p->readpoint.iOffset = iOfst+iAmt;
p->readpoint.iOffset = pChunk ? iOfst+iAmt : 0;
p->readpoint.pChunk = pChunk;
return SQLITE_OK;
+4 -8
View File
@@ -81,13 +81,11 @@ int sqlite3_memdebug_vfs_oom_test = 1;
** of this would be completely automatic if SQLite were coded using
** C++ instead of plain old C.
*/
int sqlite3OsClose(sqlite3_file *pId){
int rc = SQLITE_OK;
void sqlite3OsClose(sqlite3_file *pId){
if( pId->pMethods ){
rc = pId->pMethods->xClose(pId);
pId->pMethods->xClose(pId);
pId->pMethods = 0;
}
return rc;
}
int sqlite3OsRead(sqlite3_file *id, void *pBuf, int amt, i64 offset){
DO_OS_MALLOC_TEST(id);
@@ -305,12 +303,10 @@ int sqlite3OsOpenMalloc(
}
return rc;
}
int sqlite3OsCloseFree(sqlite3_file *pFile){
int rc = SQLITE_OK;
void sqlite3OsCloseFree(sqlite3_file *pFile){
assert( pFile );
rc = sqlite3OsClose(pFile);
sqlite3OsClose(pFile);
sqlite3_free(pFile);
return rc;
}
/*
+2 -2
View File
@@ -160,7 +160,7 @@ int sqlite3OsInit(void);
/*
** Functions for accessing sqlite3_file methods
*/
int sqlite3OsClose(sqlite3_file*);
void sqlite3OsClose(sqlite3_file*);
int sqlite3OsRead(sqlite3_file*, void*, int amt, i64 offset);
int sqlite3OsWrite(sqlite3_file*, const void*, int amt, i64 offset);
int sqlite3OsTruncate(sqlite3_file*, i64 size);
@@ -205,6 +205,6 @@ int sqlite3OsCurrentTimeInt64(sqlite3_vfs *, sqlite3_int64*);
** sqlite3_malloc() to obtain space for the file-handle structure.
*/
int sqlite3OsOpenMalloc(sqlite3_vfs *, const char *, sqlite3_file **, int,int*);
int sqlite3OsCloseFree(sqlite3_file *);
void sqlite3OsCloseFree(sqlite3_file *);
#endif /* _SQLITE_OS_H_ */
+23 -18
View File
@@ -405,7 +405,7 @@ static struct unix_syscall {
#else
{ "pread64", (sqlite3_syscall_ptr)0, 0 },
#endif
#define osPread64 ((ssize_t(*)(int,void*,size_t,off_t))aSyscall[10].pCurrent)
#define osPread64 ((ssize_t(*)(int,void*,size_t,off64_t))aSyscall[10].pCurrent)
{ "write", (sqlite3_syscall_ptr)write, 0 },
#define osWrite ((ssize_t(*)(int,const void*,size_t))aSyscall[11].pCurrent)
@@ -423,7 +423,7 @@ static struct unix_syscall {
#else
{ "pwrite64", (sqlite3_syscall_ptr)0, 0 },
#endif
#define osPwrite64 ((ssize_t(*)(int,const void*,size_t,off_t))\
#define osPwrite64 ((ssize_t(*)(int,const void*,size_t,off64_t))\
aSyscall[13].pCurrent)
{ "fchmod", (sqlite3_syscall_ptr)fchmod, 0 },
@@ -1502,7 +1502,7 @@ static int unixLock(sqlite3_file *id, int eFileLock){
** lock transitions in terms of the POSIX advisory shared and exclusive
** lock primitives (called read-locks and write-locks below, to avoid
** confusion with SQLite lock names). The algorithms are complicated
** slightly in order to be compatible with windows systems simultaneously
** slightly in order to be compatible with Windows95 systems simultaneously
** accessing the same database file, in case that is ever required.
**
** Symbols defined in os.h indentify the 'pending byte' and the 'reserved
@@ -1510,8 +1510,14 @@ static int unixLock(sqlite3_file *id, int eFileLock){
** range', a range of 510 bytes at a well known offset.
**
** To obtain a SHARED lock, a read-lock is obtained on the 'pending
** byte'. If this is successful, a random byte from the 'shared byte
** range' is read-locked and the lock on the 'pending byte' released.
** byte'. If this is successful, 'shared byte range' is read-locked
** and the lock on the 'pending byte' released. (Legacy note: When
** SQLite was first developed, Windows95 systems were still very common,
** and Widnows95 lacks a shared-lock capability. So on Windows95, a
** single randomly selected by from the 'shared byte range' is locked.
** Windows95 is now pretty much extinct, but this work-around for the
** lack of shared-locks on Windows95 lives on, for backwards
** compatibility.)
**
** A process may only obtain a RESERVED lock after it has a SHARED lock.
** A RESERVED lock is implemented by grabbing a write-lock on the
@@ -1530,11 +1536,6 @@ static int unixLock(sqlite3_file *id, int eFileLock){
** range'. Since all other locks require a read-lock on one of the bytes
** within this range, this ensures that no other locks are held on the
** database.
**
** The reason a single byte cannot be used instead of the 'shared byte
** range' is that some versions of windows do not support read-locks. By
** locking a random byte from a range, concurrent SHARED locks may exist
** even if the locking primitive used is always a write-lock.
*/
int rc = SQLITE_OK;
unixFile *pFile = (unixFile*)id;
@@ -4287,10 +4288,12 @@ static int unixOpenSharedMemory(unixFile *pDbFd){
pShmNode->h = -1;
pDbFd->pInode->pShmNode = pShmNode;
pShmNode->pInode = pDbFd->pInode;
pShmNode->mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
if( pShmNode->mutex==0 ){
rc = SQLITE_NOMEM_BKPT;
goto shm_open_err;
if( sqlite3GlobalConfig.bCoreMutex ){
pShmNode->mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
if( pShmNode->mutex==0 ){
rc = SQLITE_NOMEM_BKPT;
goto shm_open_err;
}
}
if( pInode->bProcessLock==0 ){
@@ -5415,14 +5418,14 @@ static const char *unixTempFileDir(void){
if( !azDirs[0] ) azDirs[0] = getenv("SQLITE_TMPDIR");
if( !azDirs[1] ) azDirs[1] = getenv("TMPDIR");
for(i=0; i<sizeof(azDirs)/sizeof(azDirs[0]); zDir=azDirs[i++]){
for(i=0; i<=sizeof(azDirs)/sizeof(azDirs[0]); zDir=azDirs[i++]){
if( zDir==0 ) continue;
if( osStat(zDir, &buf) ) continue;
if( !S_ISDIR(buf.st_mode) ) continue;
if( osAccess(zDir, 07) ) continue;
break;
if( osAccess(zDir, 03) ) continue;
return zDir;
}
return zDir;
return 0;
}
/*
@@ -5438,9 +5441,11 @@ static int unixGetTempname(int nBuf, char *zBuf){
** using the io-error infrastructure to test that SQLite handles this
** function failing.
*/
zBuf[0] = 0;
SimulateIOError( return SQLITE_IOERR );
zDir = unixTempFileDir();
if( zDir==0 ) return SQLITE_IOERR_GETTEMPPATH;
do{
u64 r;
sqlite3_randomness(sizeof(r), &r);
+195 -86
View File
@@ -1260,8 +1260,8 @@ int sqlite3_win32_reset_heap(){
int rc;
MUTEX_LOGIC( sqlite3_mutex *pMaster; ) /* The main static mutex */
MUTEX_LOGIC( sqlite3_mutex *pMem; ) /* The memsys static mutex */
MUTEX_LOGIC( pMaster = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER); )
MUTEX_LOGIC( pMem = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MEM); )
MUTEX_LOGIC( pMaster = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); )
MUTEX_LOGIC( pMem = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MEM); )
sqlite3_mutex_enter(pMaster);
sqlite3_mutex_enter(pMem);
winMemAssertMagic();
@@ -1306,6 +1306,12 @@ void sqlite3_win32_write_debug(const char *zBuf, int nBuf){
int nMin = MIN(nBuf, (SQLITE_WIN32_DBG_BUF_SIZE - 1)); /* may be negative. */
if( nMin<-1 ) nMin = -1; /* all negative values become -1. */
assert( nMin==-1 || nMin==0 || nMin<SQLITE_WIN32_DBG_BUF_SIZE );
#ifdef SQLITE_ENABLE_API_ARMOR
if( !zBuf ){
(void)SQLITE_MISUSE_BKPT;
return;
}
#endif
#if defined(SQLITE_WIN32_HAS_ANSI)
if( nMin>0 ){
memset(zDbgBuf, 0, SQLITE_WIN32_DBG_BUF_SIZE);
@@ -1631,147 +1637,244 @@ void sqlite3MemSetDefault(void){
#endif /* SQLITE_WIN32_MALLOC */
/*
** Convert a UTF-8 string to Microsoft Unicode (UTF-16?).
** Convert a UTF-8 string to Microsoft Unicode.
**
** Space to hold the returned string is obtained from malloc.
** Space to hold the returned string is obtained from sqlite3_malloc().
*/
static LPWSTR winUtf8ToUnicode(const char *zFilename){
static LPWSTR winUtf8ToUnicode(const char *zText){
int nChar;
LPWSTR zWideFilename;
LPWSTR zWideText;
nChar = osMultiByteToWideChar(CP_UTF8, 0, zFilename, -1, NULL, 0);
nChar = osMultiByteToWideChar(CP_UTF8, 0, zText, -1, NULL, 0);
if( nChar==0 ){
return 0;
}
zWideFilename = sqlite3MallocZero( nChar*sizeof(zWideFilename[0]) );
if( zWideFilename==0 ){
zWideText = sqlite3MallocZero( nChar*sizeof(WCHAR) );
if( zWideText==0 ){
return 0;
}
nChar = osMultiByteToWideChar(CP_UTF8, 0, zFilename, -1, zWideFilename,
nChar = osMultiByteToWideChar(CP_UTF8, 0, zText, -1, zWideText,
nChar);
if( nChar==0 ){
sqlite3_free(zWideFilename);
zWideFilename = 0;
sqlite3_free(zWideText);
zWideText = 0;
}
return zWideFilename;
return zWideText;
}
/*
** Convert Microsoft Unicode to UTF-8. Space to hold the returned string is
** obtained from sqlite3_malloc().
** Convert a Microsoft Unicode string to UTF-8.
**
** Space to hold the returned string is obtained from sqlite3_malloc().
*/
static char *winUnicodeToUtf8(LPCWSTR zWideFilename){
static char *winUnicodeToUtf8(LPCWSTR zWideText){
int nByte;
char *zFilename;
char *zText;
nByte = osWideCharToMultiByte(CP_UTF8, 0, zWideFilename, -1, 0, 0, 0, 0);
nByte = osWideCharToMultiByte(CP_UTF8, 0, zWideText, -1, 0, 0, 0, 0);
if( nByte == 0 ){
return 0;
}
zFilename = sqlite3MallocZero( nByte );
if( zFilename==0 ){
zText = sqlite3MallocZero( nByte );
if( zText==0 ){
return 0;
}
nByte = osWideCharToMultiByte(CP_UTF8, 0, zWideFilename, -1, zFilename, nByte,
nByte = osWideCharToMultiByte(CP_UTF8, 0, zWideText, -1, zText, nByte,
0, 0);
if( nByte == 0 ){
sqlite3_free(zFilename);
zFilename = 0;
sqlite3_free(zText);
zText = 0;
}
return zFilename;
return zText;
}
/*
** Convert an ANSI string to Microsoft Unicode, based on the
** current codepage settings for file apis.
** Convert an ANSI string to Microsoft Unicode, using the ANSI or OEM
** code page.
**
** Space to hold the returned string is obtained
** from sqlite3_malloc.
** Space to hold the returned string is obtained from sqlite3_malloc().
*/
static LPWSTR winMbcsToUnicode(const char *zFilename){
static LPWSTR winMbcsToUnicode(const char *zText, int useAnsi){
int nByte;
LPWSTR zMbcsFilename;
int codepage = osAreFileApisANSI() ? CP_ACP : CP_OEMCP;
LPWSTR zMbcsText;
int codepage = useAnsi ? CP_ACP : CP_OEMCP;
nByte = osMultiByteToWideChar(codepage, 0, zFilename, -1, NULL,
nByte = osMultiByteToWideChar(codepage, 0, zText, -1, NULL,
0)*sizeof(WCHAR);
if( nByte==0 ){
return 0;
}
zMbcsFilename = sqlite3MallocZero( nByte*sizeof(zMbcsFilename[0]) );
if( zMbcsFilename==0 ){
zMbcsText = sqlite3MallocZero( nByte*sizeof(WCHAR) );
if( zMbcsText==0 ){
return 0;
}
nByte = osMultiByteToWideChar(codepage, 0, zFilename, -1, zMbcsFilename,
nByte = osMultiByteToWideChar(codepage, 0, zText, -1, zMbcsText,
nByte);
if( nByte==0 ){
sqlite3_free(zMbcsFilename);
zMbcsFilename = 0;
sqlite3_free(zMbcsText);
zMbcsText = 0;
}
return zMbcsFilename;
return zMbcsText;
}
/*
** Convert Microsoft Unicode to multi-byte character string, based on the
** user's ANSI codepage.
** Convert a Microsoft Unicode string to a multi-byte character string,
** using the ANSI or OEM code page.
**
** Space to hold the returned string is obtained from
** sqlite3_malloc().
** Space to hold the returned string is obtained from sqlite3_malloc().
*/
static char *winUnicodeToMbcs(LPCWSTR zWideFilename){
static char *winUnicodeToMbcs(LPCWSTR zWideText, int useAnsi){
int nByte;
char *zFilename;
int codepage = osAreFileApisANSI() ? CP_ACP : CP_OEMCP;
char *zText;
int codepage = useAnsi ? CP_ACP : CP_OEMCP;
nByte = osWideCharToMultiByte(codepage, 0, zWideFilename, -1, 0, 0, 0, 0);
nByte = osWideCharToMultiByte(codepage, 0, zWideText, -1, 0, 0, 0, 0);
if( nByte == 0 ){
return 0;
}
zFilename = sqlite3MallocZero( nByte );
if( zFilename==0 ){
zText = sqlite3MallocZero( nByte );
if( zText==0 ){
return 0;
}
nByte = osWideCharToMultiByte(codepage, 0, zWideFilename, -1, zFilename,
nByte = osWideCharToMultiByte(codepage, 0, zWideText, -1, zText,
nByte, 0, 0);
if( nByte == 0 ){
sqlite3_free(zFilename);
zFilename = 0;
sqlite3_free(zText);
zText = 0;
}
return zFilename;
return zText;
}
/*
** Convert multibyte character string to UTF-8. Space to hold the
** returned string is obtained from sqlite3_malloc().
** Convert a multi-byte character string to UTF-8.
**
** Space to hold the returned string is obtained from sqlite3_malloc().
*/
char *sqlite3_win32_mbcs_to_utf8(const char *zFilename){
char *zFilenameUtf8;
static char *winMbcsToUtf8(const char *zText, int useAnsi){
char *zTextUtf8;
LPWSTR zTmpWide;
zTmpWide = winMbcsToUnicode(zFilename);
zTmpWide = winMbcsToUnicode(zText, useAnsi);
if( zTmpWide==0 ){
return 0;
}
zFilenameUtf8 = winUnicodeToUtf8(zTmpWide);
zTextUtf8 = winUnicodeToUtf8(zTmpWide);
sqlite3_free(zTmpWide);
return zFilenameUtf8;
return zTextUtf8;
}
/*
** Convert UTF-8 to multibyte character string. Space to hold the
** returned string is obtained from sqlite3_malloc().
** Convert a UTF-8 string to a multi-byte character string.
**
** Space to hold the returned string is obtained from sqlite3_malloc().
*/
char *sqlite3_win32_utf8_to_mbcs(const char *zFilename){
char *zFilenameMbcs;
static char *winUtf8ToMbcs(const char *zText, int useAnsi){
char *zTextMbcs;
LPWSTR zTmpWide;
zTmpWide = winUtf8ToUnicode(zFilename);
zTmpWide = winUtf8ToUnicode(zText);
if( zTmpWide==0 ){
return 0;
}
zFilenameMbcs = winUnicodeToMbcs(zTmpWide);
zTextMbcs = winUnicodeToMbcs(zTmpWide, useAnsi);
sqlite3_free(zTmpWide);
return zFilenameMbcs;
return zTextMbcs;
}
/*
** This is a public wrapper for the winUtf8ToUnicode() function.
*/
LPWSTR sqlite3_win32_utf8_to_unicode(const char *zText){
#ifdef SQLITE_ENABLE_API_ARMOR
if( !zText ){
(void)SQLITE_MISUSE_BKPT;
return 0;
}
#endif
#ifndef SQLITE_OMIT_AUTOINIT
if( sqlite3_initialize() ) return 0;
#endif
return winUtf8ToUnicode(zText);
}
/*
** This is a public wrapper for the winUnicodeToUtf8() function.
*/
char *sqlite3_win32_unicode_to_utf8(LPCWSTR zWideText){
#ifdef SQLITE_ENABLE_API_ARMOR
if( !zWideText ){
(void)SQLITE_MISUSE_BKPT;
return 0;
}
#endif
#ifndef SQLITE_OMIT_AUTOINIT
if( sqlite3_initialize() ) return 0;
#endif
return winUnicodeToUtf8(zWideText);
}
/*
** This is a public wrapper for the winMbcsToUtf8() function.
*/
char *sqlite3_win32_mbcs_to_utf8(const char *zText){
#ifdef SQLITE_ENABLE_API_ARMOR
if( !zText ){
(void)SQLITE_MISUSE_BKPT;
return 0;
}
#endif
#ifndef SQLITE_OMIT_AUTOINIT
if( sqlite3_initialize() ) return 0;
#endif
return winMbcsToUtf8(zText, osAreFileApisANSI());
}
/*
** This is a public wrapper for the winMbcsToUtf8() function.
*/
char *sqlite3_win32_mbcs_to_utf8_v2(const char *zText, int useAnsi){
#ifdef SQLITE_ENABLE_API_ARMOR
if( !zText ){
(void)SQLITE_MISUSE_BKPT;
return 0;
}
#endif
#ifndef SQLITE_OMIT_AUTOINIT
if( sqlite3_initialize() ) return 0;
#endif
return winMbcsToUtf8(zText, useAnsi);
}
/*
** This is a public wrapper for the winUtf8ToMbcs() function.
*/
char *sqlite3_win32_utf8_to_mbcs(const char *zText){
#ifdef SQLITE_ENABLE_API_ARMOR
if( !zText ){
(void)SQLITE_MISUSE_BKPT;
return 0;
}
#endif
#ifndef SQLITE_OMIT_AUTOINIT
if( sqlite3_initialize() ) return 0;
#endif
return winUtf8ToMbcs(zText, osAreFileApisANSI());
}
/*
** This is a public wrapper for the winUtf8ToMbcs() function.
*/
char *sqlite3_win32_utf8_to_mbcs_v2(const char *zText, int useAnsi){
#ifdef SQLITE_ENABLE_API_ARMOR
if( !zText ){
(void)SQLITE_MISUSE_BKPT;
return 0;
}
#endif
#ifndef SQLITE_OMIT_AUTOINIT
if( sqlite3_initialize() ) return 0;
#endif
return winUtf8ToMbcs(zText, useAnsi);
}
/*
@@ -1873,7 +1976,7 @@ static int winGetLastErrorMsg(DWORD lastErrno, int nBuf, char *zBuf){
if( dwLen > 0 ){
/* allocate a buffer and convert to UTF8 */
sqlite3BeginBenignMalloc();
zOut = sqlite3_win32_mbcs_to_utf8(zTemp);
zOut = winMbcsToUtf8(zTemp, osAreFileApisANSI());
sqlite3EndBenignMalloc();
/* free the system buffer allocated by FormatMessage */
osLocalFree(zTemp);
@@ -2015,16 +2118,17 @@ static void winLogIoerr(int nRetry, int lineno){
}
}
#if SQLITE_OS_WINCE
/*************************************************************************
** This section contains code for WinCE only.
*/
#if !defined(SQLITE_MSVC_LOCALTIME_API) || !SQLITE_MSVC_LOCALTIME_API
/*
** The MSVC CRT on Windows CE may not have a localtime() function. So
** create a substitute.
** This #if does not rely on the SQLITE_OS_WINCE define because the
** corresponding section in "date.c" cannot use it.
*/
#include <time.h>
#if !defined(SQLITE_OMIT_LOCALTIME) && defined(_WIN32_WCE) && \
(!defined(SQLITE_MSVC_LOCALTIME_API) || !SQLITE_MSVC_LOCALTIME_API)
/*
** The MSVC CRT on Windows CE may not have a localtime() function.
** So define a substitute.
*/
# include <time.h>
struct tm *__cdecl localtime(const time_t *t)
{
static struct tm y;
@@ -2048,6 +2152,10 @@ struct tm *__cdecl localtime(const time_t *t)
}
#endif
#if SQLITE_OS_WINCE
/*************************************************************************
** This section contains code for WinCE only.
*/
#define HANDLE_TO_WINFILE(a) (winFile*)&((char*)a)[-(int)offsetof(winFile,h)]
/*
@@ -3061,9 +3169,8 @@ static int winLock(sqlite3_file *id, int locktype){
** the PENDING_LOCK byte is temporary.
*/
newLocktype = pFile->locktype;
if( (pFile->locktype==NO_LOCK)
|| ( (locktype==EXCLUSIVE_LOCK)
&& (pFile->locktype==RESERVED_LOCK))
if( pFile->locktype==NO_LOCK
|| (locktype==EXCLUSIVE_LOCK && pFile->locktype<=RESERVED_LOCK)
){
int cnt = 3;
while( cnt-->0 && (res = winLockFile(&pFile->h, SQLITE_LOCKFILE_FLAGS,
@@ -3657,10 +3764,12 @@ static int winOpenSharedMemory(winFile *pDbFd){
pShmNode->pNext = winShmNodeList;
winShmNodeList = pShmNode;
pShmNode->mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
if( pShmNode->mutex==0 ){
rc = SQLITE_IOERR_NOMEM_BKPT;
goto shm_open_err;
if( sqlite3GlobalConfig.bCoreMutex ){
pShmNode->mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
if( pShmNode->mutex==0 ){
rc = SQLITE_IOERR_NOMEM_BKPT;
goto shm_open_err;
}
}
rc = winOpen(pDbFd->pVfs,
@@ -4318,7 +4427,7 @@ static char *winConvertToUtf8Filename(const void *zFilename){
}
#ifdef SQLITE_WIN32_HAS_ANSI
else{
zConverted = sqlite3_win32_mbcs_to_utf8(zFilename);
zConverted = winMbcsToUtf8(zFilename, osAreFileApisANSI());
}
#endif
/* caller will handle out of memory */
@@ -4339,7 +4448,7 @@ static void *winConvertFromUtf8Filename(const char *zFilename){
}
#ifdef SQLITE_WIN32_HAS_ANSI
else{
zConverted = sqlite3_win32_utf8_to_mbcs(zFilename);
zConverted = winUtf8ToMbcs(zFilename, osAreFileApisANSI());
}
#endif
/* caller will handle out of memory */
@@ -4540,7 +4649,7 @@ static int winGetTempname(sqlite3_vfs *pVfs, char **pzBuf){
return winLogError(SQLITE_IOERR_GETTEMPPATH, osGetLastError(),
"winGetTempname3", 0);
}
zUtf8 = sqlite3_win32_mbcs_to_utf8(zMbcsPath);
zUtf8 = winMbcsToUtf8(zMbcsPath, osAreFileApisANSI());
if( zUtf8 ){
sqlite3_snprintf(nMax, zBuf, "%s", zUtf8);
sqlite3_free(zUtf8);
@@ -5318,7 +5427,7 @@ static int winFullPathname(
"winFullPathname4", zRelative);
}
sqlite3_free(zConverted);
zOut = sqlite3_win32_mbcs_to_utf8(zTemp);
zOut = winMbcsToUtf8(zTemp, osAreFileApisANSI());
sqlite3_free(zTemp);
}
#endif
+1
View File
@@ -7311,6 +7311,7 @@ int sqlite3PagerCloseWal(Pager *pPager){
pPager->pageSize, (u8*)pPager->pTmpSpace);
pPager->pWal = 0;
pagerFixMaplimit(pPager);
if( rc && !pPager->exclusiveMode ) pagerUnlockDb(pPager, SHARED_LOCK);
}
}
return rc;
+10 -1
View File
@@ -68,7 +68,11 @@ typedef struct PgHdr DbPage;
#define PAGER_LOCKINGMODE_EXCLUSIVE 1
/*
** Numeric constants that encode the journalmode.
** Numeric constants that encode the journalmode.
**
** The numeric values encoded here (other than PAGER_JOURNALMODE_QUERY)
** are exposed in the API via the "PRAGMA journal_mode" command and
** therefore cannot be changed without a compatibility break.
*/
#define PAGER_JOURNALMODE_QUERY (-1) /* Query the value of journalmode */
#define PAGER_JOURNALMODE_DELETE 0 /* Commit by deleting journal file */
@@ -86,6 +90,11 @@ typedef struct PgHdr DbPage;
/*
** Flags for sqlite3PagerSetFlags()
**
** Value constraints (enforced via assert()):
** PAGER_FULLFSYNC == SQLITE_FullFSync
** PAGER_CKPT_FULLFSYNC == SQLITE_CkptFullFSync
** PAGER_CACHE_SPILL == SQLITE_CacheSpill
*/
#define PAGER_SYNCHRONOUS_OFF 0x01 /* PRAGMA synchronous=OFF */
#define PAGER_SYNCHRONOUS_NORMAL 0x02 /* PRAGMA synchronous=NORMAL */
+34 -55
View File
@@ -194,28 +194,6 @@ columnlist ::= columnlist COMMA columnname carglist.
columnlist ::= columnname carglist.
columnname(A) ::= nm(A) typetoken(Y). {sqlite3AddColumn(pParse,&A,&Y);}
// An IDENTIFIER can be a generic identifier, or one of several
// keywords. Any non-standard keyword can also be an identifier.
//
%token_class id ID|INDEXED.
// The following directive causes tokens ABORT, AFTER, ASC, etc. to
// fallback to ID if they will not parse as their original value.
// This obviates the need for the "id" nonterminal.
//
%fallback ID
ABORT ACTION AFTER ANALYZE ASC ATTACH BEFORE BEGIN BY CASCADE CAST COLUMNKW
CONFLICT DATABASE DEFERRED DESC DETACH EACH END EXCLUSIVE EXPLAIN FAIL FOR
IGNORE IMMEDIATE INITIALLY INSTEAD LIKE_KW MATCH NO PLAN
QUERY KEY OF OFFSET PRAGMA RAISE RECURSIVE RELEASE REPLACE RESTRICT ROW
ROLLBACK SAVEPOINT TEMP TRIGGER VACUUM VIEW VIRTUAL WITH WITHOUT
%ifdef SQLITE_OMIT_COMPOUND_SELECT
EXCEPT INTERSECT UNION
%endif SQLITE_OMIT_COMPOUND_SELECT
REINDEX RENAME CTIME_KW IF
.
%wildcard ANY.
// Define operator precedence early so that this is the first occurrence
// of the operator tokens in the grammer. Keeping the operators together
// causes them to be assigned integer values that are close together,
@@ -240,6 +218,29 @@ columnname(A) ::= nm(A) typetoken(Y). {sqlite3AddColumn(pParse,&A,&Y);}
%left COLLATE.
%right BITNOT.
// An IDENTIFIER can be a generic identifier, or one of several
// keywords. Any non-standard keyword can also be an identifier.
//
%token_class id ID|INDEXED.
// The following directive causes tokens ABORT, AFTER, ASC, etc. to
// fallback to ID if they will not parse as their original value.
// This obviates the need for the "id" nonterminal.
//
%fallback ID
ABORT ACTION AFTER ANALYZE ASC ATTACH BEFORE BEGIN BY CASCADE CAST COLUMNKW
CONFLICT DATABASE DEFERRED DESC DETACH EACH END EXCLUSIVE EXPLAIN FAIL FOR
IGNORE IMMEDIATE INITIALLY INSTEAD LIKE_KW MATCH NO PLAN
QUERY KEY OF OFFSET PRAGMA RAISE RECURSIVE RELEASE REPLACE RESTRICT ROW
ROLLBACK SAVEPOINT TEMP TRIGGER VACUUM VIEW VIRTUAL WITH WITHOUT
%ifdef SQLITE_OMIT_COMPOUND_SELECT
EXCEPT INTERSECT UNION
%endif SQLITE_OMIT_COMPOUND_SELECT
REINDEX RENAME CTIME_KW IF
.
%wildcard ANY.
// And "ids" is an identifer-or-string.
//
%token_class ids ID|STRING.
@@ -871,11 +872,15 @@ expr(A) ::= nm(X) DOT nm(Y) DOT nm(Z). {
term(A) ::= INTEGER|FLOAT|BLOB(X). {spanExpr(&A,pParse,@X,X);/*A-overwrites-X*/}
term(A) ::= STRING(X). {spanExpr(&A,pParse,@X,X);/*A-overwrites-X*/}
expr(A) ::= VARIABLE(X). {
Token t = X; /*A-overwrites-X*/
if( t.n>=2 && t.z[0]=='#' && sqlite3Isdigit(t.z[1]) ){
if( !(X.z[0]=='#' && sqlite3Isdigit(X.z[1])) ){
spanExpr(&A, pParse, TK_VARIABLE, X);
sqlite3ExprAssignVarNumber(pParse, A.pExpr);
}else{
/* When doing a nested parse, one can include terms in an expression
** that look like this: #1 #2 ... These terms refer to registers
** in the virtual machine. #N is the N-th register. */
Token t = X; /*A-overwrites-X*/
assert( t.n>=2 );
spanSet(&A, &t, &t);
if( pParse->nested==0 ){
sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", &t);
@@ -884,9 +889,6 @@ expr(A) ::= VARIABLE(X). {
A.pExpr = sqlite3PExpr(pParse, TK_REGISTER, 0, 0, &t);
if( A.pExpr ) sqlite3GetInt32(&t.z[1], &A.pExpr->iTable);
}
}else{
spanExpr(&A, pParse, TK_VARIABLE, t);
sqlite3ExprAssignVarNumber(pParse, A.pExpr);
}
}
expr(A) ::= expr(A) COLLATE ids(C). {
@@ -1122,36 +1124,19 @@ expr(A) ::= expr(A) between_op(N) expr(X) AND expr(Y). [BETWEEN] {
expr(A) ::= LP(B) select(X) RP(E). {
spanSet(&A,&B,&E); /*A-overwrites-B*/
A.pExpr = sqlite3PExpr(pParse, TK_SELECT, 0, 0, 0);
if( A.pExpr ){
A.pExpr->x.pSelect = X;
ExprSetProperty(A.pExpr, EP_xIsSelect|EP_Subquery);
sqlite3ExprSetHeightAndFlags(pParse, A.pExpr);
}else{
sqlite3SelectDelete(pParse->db, X);
}
sqlite3PExprAddSelect(pParse, A.pExpr, X);
}
expr(A) ::= expr(A) in_op(N) LP select(Y) RP(E). [IN] {
A.pExpr = sqlite3PExpr(pParse, TK_IN, A.pExpr, 0, 0);
if( A.pExpr ){
A.pExpr->x.pSelect = Y;
ExprSetProperty(A.pExpr, EP_xIsSelect|EP_Subquery);
sqlite3ExprSetHeightAndFlags(pParse, A.pExpr);
}else{
sqlite3SelectDelete(pParse->db, Y);
}
sqlite3PExprAddSelect(pParse, A.pExpr, Y);
exprNot(pParse, N, &A);
A.zEnd = &E.z[E.n];
}
expr(A) ::= expr(A) in_op(N) nm(Y) dbnm(Z). [IN] {
SrcList *pSrc = sqlite3SrcListAppend(pParse->db, 0,&Y,&Z);
Select *pSelect = sqlite3SelectNew(pParse, 0,pSrc,0,0,0,0,0,0,0);
A.pExpr = sqlite3PExpr(pParse, TK_IN, A.pExpr, 0, 0);
if( A.pExpr ){
A.pExpr->x.pSelect = sqlite3SelectNew(pParse, 0,pSrc,0,0,0,0,0,0,0);
ExprSetProperty(A.pExpr, EP_xIsSelect|EP_Subquery);
sqlite3ExprSetHeightAndFlags(pParse, A.pExpr);
}else{
sqlite3SrcListDelete(pParse->db, pSrc);
}
sqlite3PExprAddSelect(pParse, A.pExpr, pSelect);
exprNot(pParse, N, &A);
A.zEnd = Z.z ? &Z.z[Z.n] : &Y.z[Y.n];
}
@@ -1159,13 +1144,7 @@ expr(A) ::= expr(A) between_op(N) expr(X) AND expr(Y). [BETWEEN] {
Expr *p;
spanSet(&A,&B,&E); /*A-overwrites-B*/
p = A.pExpr = sqlite3PExpr(pParse, TK_EXISTS, 0, 0, 0);
if( p ){
p->x.pSelect = Y;
ExprSetProperty(p, EP_xIsSelect|EP_Subquery);
sqlite3ExprSetHeightAndFlags(pParse, p);
}else{
sqlite3SelectDelete(pParse->db, Y);
}
sqlite3PExprAddSelect(pParse, p, Y);
}
%endif SQLITE_OMIT_SUBQUERY
+2 -2
View File
@@ -690,8 +690,8 @@ static int pcache1Init(void *NotUsed){
#if SQLITE_THREADSAFE
if( sqlite3GlobalConfig.bCoreMutex ){
pcache1.grp.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_LRU);
pcache1.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_PMEM);
pcache1.grp.mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_LRU);
pcache1.mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_PMEM);
}
#endif
if( pcache1.separateCache
+43 -20
View File
@@ -74,7 +74,7 @@ static void clearSelect(sqlite3 *db, Select *p, int bFree){
sqlite3ExprListDelete(db, p->pOrderBy);
sqlite3ExprDelete(db, p->pLimit);
sqlite3ExprDelete(db, p->pOffset);
sqlite3WithDelete(db, p->pWith);
if( p->pWith ) sqlite3WithDelete(db, p->pWith);
if( bFree ) sqlite3DbFree(db, p);
p = pPrior;
bFree = 1;
@@ -169,7 +169,7 @@ void sqlite3SelectSetName(Select *p, const char *zName){
** Delete the given Select structure and all of its substructures.
*/
void sqlite3SelectDelete(sqlite3 *db, Select *p){
clearSelect(db, p, 1);
if( p ) clearSelect(db, p, 1);
}
/*
@@ -1704,7 +1704,7 @@ int sqlite3ColumnsFromExprList(
** This routine requires that all identifiers in the SELECT
** statement be resolved.
*/
static void selectAddColumnTypeAndCollation(
void sqlite3SelectAddColumnTypeAndCollation(
Parse *pParse, /* Parsing contexts */
Table *pTab, /* Add column type information to this table */
Select *pSelect /* SELECT used to determine types and collations */
@@ -1726,10 +1726,20 @@ static void selectAddColumnTypeAndCollation(
sNC.pSrcList = pSelect->pSrc;
a = pSelect->pEList->a;
for(i=0, pCol=pTab->aCol; i<pTab->nCol; i++, pCol++){
const char *zType;
int n, m;
p = a[i].pExpr;
columnType(&sNC, p, 0, 0, 0, &pCol->szEst);
zType = columnType(&sNC, p, 0, 0, 0, &pCol->szEst);
szAll += pCol->szEst;
pCol->affinity = sqlite3ExprAffinity(p);
if( zType && (m = sqlite3Strlen30(zType))>0 ){
n = sqlite3Strlen30(pCol->zName);
pCol->zName = sqlite3DbReallocOrFree(db, pCol->zName, n+m+2);
if( pCol->zName ){
memcpy(&pCol->zName[n+1], zType, m+1);
pCol->colFlags |= COLFLAG_HASTYPE;
}
}
if( pCol->affinity==0 ) pCol->affinity = SQLITE_AFF_BLOB;
pColl = sqlite3ExprCollSeq(pParse, p);
if( pColl && pCol->zColl==0 ){
@@ -1766,7 +1776,7 @@ Table *sqlite3ResultSetOfSelect(Parse *pParse, Select *pSelect){
pTab->zName = 0;
pTab->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) );
sqlite3ColumnsFromExprList(pParse, pSelect->pEList, &pTab->nCol, &pTab->aCol);
selectAddColumnTypeAndCollation(pParse, pTab, pSelect);
sqlite3SelectAddColumnTypeAndCollation(pParse, pTab, pSelect);
pTab->iPKey = -1;
if( db->mallocFailed ){
sqlite3DeleteTable(db, pTab);
@@ -1779,20 +1789,20 @@ Table *sqlite3ResultSetOfSelect(Parse *pParse, Select *pSelect){
** Get a VDBE for the given parser context. Create a new one if necessary.
** If an error occurs, return NULL and leave a message in pParse.
*/
Vdbe *sqlite3GetVdbe(Parse *pParse){
Vdbe *v = pParse->pVdbe;
if( v==0 ){
v = pParse->pVdbe = sqlite3VdbeCreate(pParse);
if( v ) sqlite3VdbeAddOp0(v, OP_Init);
if( pParse->pToplevel==0
&& OptimizationEnabled(pParse->db,SQLITE_FactorOutConst)
){
pParse->okConstFactor = 1;
}
static SQLITE_NOINLINE Vdbe *allocVdbe(Parse *pParse){
Vdbe *v = pParse->pVdbe = sqlite3VdbeCreate(pParse);
if( v ) sqlite3VdbeAddOp0(v, OP_Init);
if( pParse->pToplevel==0
&& OptimizationEnabled(pParse->db,SQLITE_FactorOutConst)
){
pParse->okConstFactor = 1;
}
return v;
}
Vdbe *sqlite3GetVdbe(Parse *pParse){
Vdbe *v = pParse->pVdbe;
return v ? v : allocVdbe(pParse);
}
/*
@@ -3775,12 +3785,18 @@ static int pushDownWhereTerms(
){
Expr *pNew;
int nChng = 0;
Select *pX; /* For looping over compound SELECTs in pSubq */
if( pWhere==0 ) return 0;
if( (pSubq->selFlags & (SF_Aggregate|SF_Recursive))!=0 ){
return 0; /* restrictions (1) and (2) */
for(pX=pSubq; pX; pX=pX->pPrior){
if( (pX->selFlags & (SF_Aggregate|SF_Recursive))!=0 ){
testcase( pX->selFlags & SF_Aggregate );
testcase( pX->selFlags & SF_Recursive );
testcase( pX!=pSubq );
return 0; /* restrictions (1) and (2) */
}
}
if( pSubq->pLimit!=0 ){
return 0; /* restriction (3) */
return 0; /* restriction (3) */
}
while( pWhere->op==TK_AND ){
nChng += pushDownWhereTerms(db, pSubq, pWhere->pRight, iCursor);
@@ -4550,7 +4566,7 @@ static void selectAddSubqueryTypeInfo(Walker *pWalker, Select *p){
Select *pSel = pFrom->pSelect;
if( pSel ){
while( pSel->pPrior ) pSel = pSel->pPrior;
selectAddColumnTypeAndCollation(pParse, pTab, pSel);
sqlite3SelectAddColumnTypeAndCollation(pParse, pTab, pSel);
}
}
}
@@ -5082,6 +5098,13 @@ int sqlite3Select(
** the sDistinct.isTnct is still set. Hence, isTnct represents the
** original setting of the SF_Distinct flag, not the current setting */
assert( sDistinct.isTnct );
#if SELECTTRACE_ENABLED
if( sqlite3SelectTrace & 0x400 ){
SELECTTRACE(0x400,pParse,p,("Transform DISTINCT into GROUP BY:\n"));
sqlite3TreeViewSelect(0, p, 0);
}
#endif
}
/* If there is an ORDER BY clause, then create an ephemeral index to
+500 -248
View File
File diff suppressed because it is too large Load Diff
+93 -18
View File
@@ -1932,12 +1932,30 @@ struct sqlite3_mem_methods {
** following this call. The second parameter may be a NULL pointer, in
** which case the new setting is not reported back. </dd>
**
** <dt>SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION</dt>
** <dd> ^This option is used to enable or disable the [sqlite3_load_extension()]
** interface independently of the [load_extension()] SQL function.
** The [sqlite3_enable_load_extension()] API enables or disables both the
** C-API [sqlite3_load_extension()] and the SQL function [load_extension()].
** There should be two additional arguments.
** When the first argument to this interface is 1, then only the C-API is
** enabled and the SQL function remains disabled. If the first argment to
** this interface is 0, then both the C-API and the SQL function are disabled.
** If the first argument is -1, then no changes are made to state of either the
** C-API or the SQL function.
** The second parameter is a pointer to an integer into which
** is written 0 or 1 to indicate whether [sqlite3_load_extension()] interface
** is disabled or enabled following this call. The second parameter may
** be a NULL pointer, in which case the new setting is not reported back.
** </dd>
**
** </dl>
*/
#define SQLITE_DBCONFIG_LOOKASIDE 1001 /* void* int int */
#define SQLITE_DBCONFIG_ENABLE_FKEY 1002 /* int int* */
#define SQLITE_DBCONFIG_ENABLE_TRIGGER 1003 /* int int* */
#define SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER 1004 /* int int* */
#define SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION 1005 /* int int* */
/*
@@ -5187,7 +5205,7 @@ void *sqlite3_rollback_hook(sqlite3*, void(*)(void *), void*);
** ^The sqlite3_update_hook() interface registers a callback function
** with the [database connection] identified by the first argument
** to be invoked whenever a row is updated, inserted or deleted in
** a rowid table.
** a [rowid table].
** ^Any callback set by a previous call to this function
** for the same database connection is overridden.
**
@@ -5474,9 +5492,18 @@ int sqlite3_table_column_metadata(
** should free this memory by calling [sqlite3_free()].
**
** ^Extension loading must be enabled using
** [sqlite3_enable_load_extension()] prior to calling this API,
** [sqlite3_enable_load_extension()] or
** [sqlite3_db_config](db,[SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION],1,NULL)
** prior to calling this API,
** otherwise an error will be returned.
**
** <b>Security warning:</b> It is recommended that the
** [SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION] method be used to enable only this
** interface. The use of the [sqlite3_enable_load_extension()] interface
** should be avoided. This will keep the SQL function [load_extension()]
** disabled and prevent SQL injections from giving attackers
** access to extension loading capabilities.
**
** See also the [load_extension() SQL function].
*/
int sqlite3_load_extension(
@@ -5499,6 +5526,17 @@ int sqlite3_load_extension(
** ^Call the sqlite3_enable_load_extension() routine with onoff==1
** to turn extension loading on and call it with onoff==0 to turn
** it back off again.
**
** ^This interface enables or disables both the C-API
** [sqlite3_load_extension()] and the SQL function [load_extension()].
** Use [sqlite3_db_config](db,[SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION],..)
** to enable or disable only the C-API.
**
** <b>Security warning:</b> It is recommended that extension loading
** be disabled using the [SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION] method
** rather than this interface, so the [load_extension()] SQL function
** remains disabled. This will prevent SQL injections from giving attackers
** access to extension loading capabilities.
*/
int sqlite3_enable_load_extension(sqlite3 *db, int onoff);
@@ -6761,7 +6799,7 @@ int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int resetFlg);
** database file in rollback mode databases. Any pages written as part of
** transaction rollback or database recovery operations are not included.
** If an IO or other error occurs while writing a page to disk, the effect
** on subsequent SQLITE_DBSTATUS_CACHE_WRITE requests is undefined). ^The
** on subsequent SQLITE_DBSTATUS_CACHE_WRITE requests is undefined.)^ ^The
** highwater mark associated with SQLITE_DBSTATUS_CACHE_WRITE is always 0.
** </dd>
**
@@ -7137,7 +7175,7 @@ typedef struct sqlite3_backup sqlite3_backup;
** must be different or else sqlite3_backup_init(D,N,S,M) will fail with
** an error.
**
** ^A call to sqlite3_backup_init() will fail, returning SQLITE_ERROR, if
** ^A call to sqlite3_backup_init() will fail, returning NULL, if
** there is already a read or read-write transaction open on the
** destination database.
**
@@ -7917,13 +7955,13 @@ int sqlite3_db_cacheflush(sqlite3*);
/*
** CAPI3REF: The pre-update hook.
** EXPERIMENTAL
**
** ^These interfaces are only available if SQLite is compiled using the
** [SQLITE_ENABLE_UPDATE_HOOK] compile-time option.
** [SQLITE_ENABLE_PREUPDATE_HOOK] compile-time option.
**
** ^The [sqlite3_preupdate_hook()] interface registers a callback function
** that is invoked prior to each [INSERT], [UPDATE], and [DELETE] operation.
** that is invoked prior to each [INSERT], [UPDATE], and [DELETE] operation
** on a [rowid table].
** ^At most one preupdate hook may be registered at a time on a single
** [database connection]; each call to [sqlite3_preupdate_hook()] overrides
** the previous setting.
@@ -7932,8 +7970,9 @@ int sqlite3_db_cacheflush(sqlite3*);
** ^The third parameter to [sqlite3_preupdate_hook()] is passed through as
** the first parameter to callbacks.
**
** ^The preupdate hook only fires for changes to real tables; the preupdate
** hook is not invoked for changes to virtual tables.
** ^The preupdate hook only fires for changes to [rowid tables]; the preupdate
** hook is not invoked for changes to [virtual tables] or [WITHOUT ROWID]
** tables.
**
** ^The second parameter to the preupdate callback is a pointer to
** the [database connection] that registered the preupdate hook.
@@ -8080,20 +8119,29 @@ SQLITE_EXPERIMENTAL int sqlite3_snapshot_get(
** CAPI3REF: Start a read transaction on an historical snapshot
** EXPERIMENTAL
**
** ^The [sqlite3_snapshot_open(D,S,P)] interface attempts to move the
** read transaction that is currently open on schema S of
** [database connection] D so that it refers to historical [snapshot] P.
** ^The [sqlite3_snapshot_open(D,S,P)] interface starts a
** read transaction for schema S of
** [database connection] D such that the read transaction
** refers to historical [snapshot] P, rather than the most
** recent change to the database.
** ^The [sqlite3_snapshot_open()] interface returns SQLITE_OK on success
** or an appropriate [error code] if it fails.
**
** ^In order to succeed, a call to [sqlite3_snapshot_open(D,S,P)] must be
** the first operation, apart from other sqlite3_snapshot_open() calls,
** following the [BEGIN] that starts a new read transaction.
** ^A [snapshot] will fail to open if it has been overwritten by a
** the first operation following the [BEGIN] that takes the schema S
** out of [autocommit mode].
** ^In other words, schema S must not currently be in
** a transaction for [sqlite3_snapshot_open(D,S,P)] to work, but the
** database connection D must be out of [autocommit mode].
** ^A [snapshot] will fail to open if it has been overwritten by a
** [checkpoint].
** ^A [snapshot] will fail to open if the database connection D has not
** previously completed at least one read operation against the database
** file. (Hint: Run "[PRAGMA application_id]" against a newly opened
** ^(A call to [sqlite3_snapshot_open(D,S,P)] will fail if the
** database connection D does not know that the database file for
** schema S is in [WAL mode]. A database connection might not know
** that the database file is in [WAL mode] if there has been no prior
** I/O on that database connection, or if the database entered [WAL mode]
** after the most recent I/O on the database connection.)^
** (Hint: Run "[PRAGMA application_id]" against a newly opened
** database connection in order to make it ready to use snapshots.)
**
** The [sqlite3_snapshot_open()] interface is only available when the
@@ -8118,6 +8166,33 @@ SQLITE_EXPERIMENTAL int sqlite3_snapshot_open(
*/
SQLITE_EXPERIMENTAL void sqlite3_snapshot_free(sqlite3_snapshot*);
/*
** CAPI3REF: Compare the ages of two snapshot handles.
** EXPERIMENTAL
**
** The sqlite3_snapshot_cmp(P1, P2) interface is used to compare the ages
** of two valid snapshot handles.
**
** If the two snapshot handles are not associated with the same database
** file, the result of the comparison is undefined.
**
** Additionally, the result of the comparison is only valid if both of the
** snapshot handles were obtained by calling sqlite3_snapshot_get() since the
** last time the wal file was deleted. The wal file is deleted when the
** database is changed back to rollback mode or when the number of database
** clients drops to zero. If either snapshot handle was obtained before the
** wal file was last deleted, the value returned by this function
** is undefined.
**
** Otherwise, this API returns a negative value if P1 refers to an older
** snapshot than P2, zero if the two handles refer to the same database
** snapshot, and a positive value if P1 is a newer snapshot than P2.
*/
SQLITE_EXPERIMENTAL int sqlite3_snapshot_cmp(
sqlite3_snapshot *p1,
sqlite3_snapshot *p2
);
/*
** Undo the hack that converts floating point types to integer for
** builds on processors without floating point support.
+60 -23
View File
@@ -1350,6 +1350,11 @@ struct sqlite3 {
/*
** Possible values for the sqlite3.flags.
**
** Value constraints (enforced via assert()):
** SQLITE_FullFSync == PAGER_FULLFSYNC
** SQLITE_CkptFullFSync == PAGER_CKPT_FULLFSYNC
** SQLITE_CacheSpill == PAGER_CACHE_SPILL
*/
#define SQLITE_VdbeTrace 0x00000001 /* True to trace VDBE execution */
#define SQLITE_InternChanges 0x00000002 /* Uncommitted Hash table changes */
@@ -1377,13 +1382,14 @@ struct sqlite3 {
#define SQLITE_AutoIndex 0x00100000 /* Enable automatic indexes */
#define SQLITE_PreferBuiltin 0x00200000 /* Preference to built-in funcs */
#define SQLITE_LoadExtension 0x00400000 /* Enable load_extension */
#define SQLITE_EnableTrigger 0x00800000 /* True to enable triggers */
#define SQLITE_DeferFKs 0x01000000 /* Defer all FK constraints */
#define SQLITE_QueryOnly 0x02000000 /* Disable database changes */
#define SQLITE_VdbeEQP 0x04000000 /* Debug EXPLAIN QUERY PLAN */
#define SQLITE_Vacuum 0x08000000 /* Currently in a VACUUM */
#define SQLITE_CellSizeCk 0x10000000 /* Check btree cell sizes on load */
#define SQLITE_Fts3Tokenizer 0x20000000 /* Enable fts3_tokenizer(2) */
#define SQLITE_LoadExtFunc 0x00800000 /* Enable load_extension() SQL func */
#define SQLITE_EnableTrigger 0x01000000 /* True to enable triggers */
#define SQLITE_DeferFKs 0x02000000 /* Defer all FK constraints */
#define SQLITE_QueryOnly 0x04000000 /* Disable database changes */
#define SQLITE_VdbeEQP 0x08000000 /* Debug EXPLAIN QUERY PLAN */
#define SQLITE_Vacuum 0x10000000 /* Currently in a VACUUM */
#define SQLITE_CellSizeCk 0x20000000 /* Check btree cell sizes on load */
#define SQLITE_Fts3Tokenizer 0x40000000 /* Enable fts3_tokenizer(2) */
/*
@@ -1484,6 +1490,13 @@ struct FuncDestructor {
** values must correspond to OPFLAG_LENGTHARG and OPFLAG_TYPEOFARG. And
** SQLITE_FUNC_CONSTANT must be the same as SQLITE_DETERMINISTIC. There
** are assert() statements in the code to verify this.
**
** Value constraints (enforced via assert()):
** SQLITE_FUNC_MINMAX == NC_MinMaxAgg == SF_MinMaxAgg
** SQLITE_FUNC_LENGTH == OPFLAG_LENGTHARG
** SQLITE_FUNC_TYPEOF == OPFLAG_TYPEOFARG
** SQLITE_FUNC_CONSTANT == SQLITE_DETERMINISTIC from the API
** SQLITE_FUNC_ENCMASK depends on SQLITE_UTF* macros in the API
*/
#define SQLITE_FUNC_ENCMASK 0x0003 /* SQLITE_UTF8, SQLITE_UTF16BE or UTF16LE */
#define SQLITE_FUNC_LIKE 0x0004 /* Candidate for the LIKE optimization */
@@ -2483,6 +2496,9 @@ struct SrcList {
/*
** Flags appropriate for the wctrlFlags parameter of sqlite3WhereBegin()
** and the WhereInfo.wctrlFlags member.
**
** Value constraints (enforced via assert()):
** WHERE_USE_LIMIT == SF_FixedLimit
*/
#define WHERE_ORDERBY_NORMAL 0x0000 /* No-op */
#define WHERE_ORDERBY_MIN 0x0001 /* ORDER BY processing for min() func */
@@ -2543,15 +2559,16 @@ struct NameContext {
/*
** Allowed values for the NameContext, ncFlags field.
**
** Note: NC_MinMaxAgg must have the same value as SF_MinMaxAgg and
** SQLITE_FUNC_MINMAX.
** Value constraints (all checked via assert()):
** NC_HasAgg == SF_HasAgg
** NC_MinMaxAgg == SF_MinMaxAgg == SQLITE_FUNC_MINMAX
**
*/
#define NC_AllowAgg 0x0001 /* Aggregate functions are allowed here */
#define NC_HasAgg 0x0002 /* One or more aggregate functions seen */
#define NC_PartIdx 0x0002 /* True if resolving a partial index WHERE */
#define NC_IsCheck 0x0004 /* True if resolving names in a CHECK constraint */
#define NC_InAggFunc 0x0008 /* True if analyzing arguments to an agg func */
#define NC_PartIdx 0x0010 /* True if resolving a partial index WHERE */
#define NC_HasAgg 0x0010 /* One or more aggregate functions seen */
#define NC_IdxExpr 0x0020 /* True if resolving columns of CREATE INDEX */
#define NC_MinMaxAgg 0x1000 /* min/max aggregates seen. See note above */
@@ -2600,24 +2617,30 @@ struct Select {
/*
** Allowed values for Select.selFlags. The "SF" prefix stands for
** "Select Flag".
**
** Value constraints (all checked via assert())
** SF_HasAgg == NC_HasAgg
** SF_MinMaxAgg == NC_MinMaxAgg == SQLITE_FUNC_MINMAX
** SF_FixedLimit == WHERE_USE_LIMIT
*/
#define SF_Distinct 0x00001 /* Output should be DISTINCT */
#define SF_All 0x00002 /* Includes the ALL keyword */
#define SF_Resolved 0x00004 /* Identifiers have been resolved */
#define SF_Aggregate 0x00008 /* Contains aggregate functions */
#define SF_UsesEphemeral 0x00010 /* Uses the OpenEphemeral opcode */
#define SF_Expanded 0x00020 /* sqlite3SelectExpand() called on this */
#define SF_HasTypeInfo 0x00040 /* FROM subqueries have Table metadata */
#define SF_Compound 0x00080 /* Part of a compound query */
#define SF_Values 0x00100 /* Synthesized from VALUES clause */
#define SF_MultiValue 0x00200 /* Single VALUES term with multiple rows */
#define SF_NestedFrom 0x00400 /* Part of a parenthesized FROM clause */
#define SF_MaybeConvert 0x00800 /* Need convertCompoundSelectToSubquery() */
#define SF_Aggregate 0x00008 /* Contains agg functions or a GROUP BY */
#define SF_HasAgg 0x00010 /* Contains aggregate functions */
#define SF_UsesEphemeral 0x00020 /* Uses the OpenEphemeral opcode */
#define SF_Expanded 0x00040 /* sqlite3SelectExpand() called on this */
#define SF_HasTypeInfo 0x00080 /* FROM subqueries have Table metadata */
#define SF_Compound 0x00100 /* Part of a compound query */
#define SF_Values 0x00200 /* Synthesized from VALUES clause */
#define SF_MultiValue 0x00400 /* Single VALUES term with multiple rows */
#define SF_NestedFrom 0x00800 /* Part of a parenthesized FROM clause */
#define SF_MinMaxAgg 0x01000 /* Aggregate containing min() or max() */
#define SF_Recursive 0x02000 /* The recursive part of a recursive CTE */
#define SF_FixedLimit 0x04000 /* nSelectRow set by a constant LIMIT */
#define SF_Converted 0x08000 /* By convertCompoundSelectToSubquery() */
#define SF_IncludeHidden 0x10000 /* Include hidden columns in output */
#define SF_MaybeConvert 0x08000 /* Need convertCompoundSelectToSubquery() */
#define SF_Converted 0x10000 /* By convertCompoundSelectToSubquery() */
#define SF_IncludeHidden 0x20000 /* Include hidden columns in output */
/*
@@ -2814,6 +2837,7 @@ struct Parse {
u8 hasCompound; /* Need to invoke convertCompoundSelectToSubquery() */
u8 okConstFactor; /* OK to factor out constants */
u8 disableLookaside; /* Number of times lookaside has been disabled */
u8 nColCache; /* Number of entries in aColCache[] */
int aTempReg[8]; /* Holding area for temporary registers */
int nRangeReg; /* Size of the temporary register block */
int iRangeReg; /* First register in temporary register block */
@@ -2927,6 +2951,15 @@ struct AuthContext {
/*
** Bitfield flags for P5 value in various opcodes.
**
** Value constraints (enforced via assert()):
** OPFLAG_LENGTHARG == SQLITE_FUNC_LENGTH
** OPFLAG_TYPEOFARG == SQLITE_FUNC_TYPEOF
** OPFLAG_BULKCSR == BTREE_BULKLOAD
** OPFLAG_SEEKEQ == BTREE_SEEK_EQ
** OPFLAG_FORDELETE == BTREE_FORDELETE
** OPFLAG_SAVEPOSITION == BTREE_SAVEPOSITION
** OPFLAG_AUXDELETE == BTREE_AUXDELETE
*/
#define OPFLAG_NCHANGE 0x01 /* OP_Insert: Set to update db->nChange */
/* Also used in P2 (not P5) of OP_Delete */
@@ -3301,6 +3334,7 @@ int sqlite3CantopenError(int);
# define sqlite3Isdigit(x) (sqlite3CtypeMap[(unsigned char)(x)]&0x04)
# define sqlite3Isxdigit(x) (sqlite3CtypeMap[(unsigned char)(x)]&0x08)
# define sqlite3Tolower(x) (sqlite3UpperToLower[(unsigned char)(x)])
# define sqlite3Isquote(x) (sqlite3CtypeMap[(unsigned char)(x)]&0x80)
#else
# define sqlite3Toupper(x) toupper((unsigned char)(x))
# define sqlite3Isspace(x) isspace((unsigned char)(x))
@@ -3309,6 +3343,7 @@ int sqlite3CantopenError(int);
# define sqlite3Isdigit(x) isdigit((unsigned char)(x))
# define sqlite3Isxdigit(x) isxdigit((unsigned char)(x))
# define sqlite3Tolower(x) tolower((unsigned char)(x))
# define sqlite3Isquote(x) ((x)=='"'||(x)=='\''||(x)=='['||(x)=='`')
#endif
#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS
int sqlite3IsIdChar(u8);
@@ -3432,7 +3467,7 @@ char *sqlite3VMPrintf(sqlite3*,const char*, va_list);
void sqlite3SetString(char **, sqlite3*, const char*);
void sqlite3ErrorMsg(Parse*, const char*, ...);
int sqlite3Dequote(char*);
void sqlite3Dequote(char*);
void sqlite3TokenInit(Token*,char*);
int sqlite3KeywordCode(const unsigned char*, int);
int sqlite3RunParser(Parse*, const char*, char **);
@@ -3449,6 +3484,7 @@ Expr *sqlite3ExprAlloc(sqlite3*,int,const Token*,int);
Expr *sqlite3Expr(sqlite3*,int,const char*);
void sqlite3ExprAttachSubtrees(sqlite3*,Expr*,Expr*,Expr*);
Expr *sqlite3PExpr(Parse*, int, Expr*, Expr*, const Token*);
void sqlite3PExprAddSelect(Parse*, Expr*, Select*);
Expr *sqlite3ExprAnd(sqlite3*,Expr*, Expr*);
Expr *sqlite3ExprFunction(Parse*,ExprList*, Token*);
void sqlite3ExprAssignVarNumber(Parse*, Expr*);
@@ -3468,6 +3504,7 @@ void sqlite3CollapseDatabaseArray(sqlite3*);
void sqlite3CommitInternalChanges(sqlite3*);
void sqlite3DeleteColumnNames(sqlite3*,Table*);
int sqlite3ColumnsFromExprList(Parse*,ExprList*,i16*,Column**);
void sqlite3SelectAddColumnTypeAndCollation(Parse*,Table*,Select*);
Table *sqlite3ResultSetOfSelect(Parse*,Select*);
void sqlite3OpenMasterTable(Parse *, int);
Index *sqlite3PrimaryKeyIndex(Table*);
+1 -1
View File
@@ -3035,7 +3035,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
/* set ppHook to point at pUpdateHook or pRollbackHook, depending on
** whether [$db update_hook] or [$db rollback_hook] was invoked.
*/
Tcl_Obj **ppHook;
Tcl_Obj **ppHook = 0;
if( choice==DB_WAL_HOOK ) ppHook = &pDb->pWalHook;
if( choice==DB_UPDATE_HOOK ) ppHook = &pDb->pUpdateHook;
if( choice==DB_ROLLBACK_HOOK ) ppHook = &pDb->pRollbackHook;
+33 -4
View File
@@ -1271,7 +1271,7 @@ static int sqlite3_mprintf_int64(
return TCL_ERROR;
}
for(i=2; i<5; i++){
if( sqlite3Atoi64(argv[i], &a[i-2], 1000000, SQLITE_UTF8) ){
if( sqlite3Atoi64(argv[i], &a[i-2], sqlite3Strlen30(argv[i]), SQLITE_UTF8) ){
Tcl_AppendResult(interp, "argument is not a valid 64-bit integer", 0);
return TCL_ERROR;
}
@@ -2359,6 +2359,31 @@ static int test_snapshot_free(
}
#endif /* SQLITE_ENABLE_SNAPSHOT */
#ifdef SQLITE_ENABLE_SNAPSHOT
/*
** Usage: sqlite3_snapshot_cmp SNAPSHOT1 SNAPSHOT2
*/
static int test_snapshot_cmp(
void * clientData,
Tcl_Interp *interp,
int objc,
Tcl_Obj *CONST objv[]
){
int res;
sqlite3_snapshot *p1;
sqlite3_snapshot *p2;
if( objc!=3 ){
Tcl_WrongNumArgs(interp, 1, objv, "SNAPSHOT1 SNAPSHOT2");
return TCL_ERROR;
}
p1 = (sqlite3_snapshot*)sqlite3TestTextToPtr(Tcl_GetString(objv[1]));
p2 = (sqlite3_snapshot*)sqlite3TestTextToPtr(Tcl_GetString(objv[2]));
res = sqlite3_snapshot_cmp(p1, p2);
Tcl_SetObjResult(interp, Tcl_NewIntObj(res));
return TCL_OK;
}
#endif /* SQLITE_ENABLE_SNAPSHOT */
/*
** Usage: sqlite3_next_stmt DB STMT
**
@@ -5188,7 +5213,9 @@ static int vfs_unregister_all(
/*
** tclcmd: vfs_reregister_all
**
** Restore all VFSes that were removed using vfs_unregister_all
** Restore all VFSes that were removed using vfs_unregister_all. Taking
** care to put the linked list back together in the same order as it was
** in before vfs_unregister_all was invoked.
*/
static int vfs_reregister_all(
ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
@@ -5197,8 +5224,8 @@ static int vfs_reregister_all(
Tcl_Obj *CONST objv[] /* Command arguments */
){
int i;
for(i=0; i<nVfs; i++){
sqlite3_vfs_register(apVfs[i], i==0);
for(i=nVfs-1; i>=0; i--){
sqlite3_vfs_register(apVfs[i], 1);
}
return TCL_OK;
}
@@ -6963,6 +6990,7 @@ static int test_sqlite3_db_config(
{ "FKEY", SQLITE_DBCONFIG_ENABLE_FKEY },
{ "TRIGGER", SQLITE_DBCONFIG_ENABLE_TRIGGER },
{ "FTS3_TOKENIZER", SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER },
{ "LOAD_EXTENSION", SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION },
};
int i;
int v;
@@ -7249,6 +7277,7 @@ int Sqlitetest1_Init(Tcl_Interp *interp){
{ "sqlite3_snapshot_get", test_snapshot_get, 0 },
{ "sqlite3_snapshot_open", test_snapshot_open, 0 },
{ "sqlite3_snapshot_free", test_snapshot_free, 0 },
{ "sqlite3_snapshot_cmp", test_snapshot_cmp, 0 },
#endif
};
static int bitmask_size = sizeof(Bitmask)*8;
+27 -1
View File
@@ -701,6 +701,10 @@ static int cfCurrentTime(sqlite3_vfs *pCfVfs, double *pTimeOut){
sqlite3_vfs *pVfs = (sqlite3_vfs *)pCfVfs->pAppData;
return pVfs->xCurrentTime(pVfs, pTimeOut);
}
static int cfGetLastError(sqlite3_vfs *pCfVfs, int n, char *z){
sqlite3_vfs *pVfs = (sqlite3_vfs *)pCfVfs->pAppData;
return pVfs->xGetLastError(pVfs, n, z);
}
static int processDevSymArgs(
Tcl_Interp *interp,
@@ -827,7 +831,7 @@ static int crashEnableCmd(
cfRandomness, /* xRandomness */
cfSleep, /* xSleep */
cfCurrentTime, /* xCurrentTime */
0, /* xGetlastError */
cfGetLastError, /* xGetLastError */
0, /* xCurrentTimeInt64 */
};
@@ -940,6 +944,27 @@ static int devSymObjCmd(
devsym_register(iDc, iSectorSize);
return TCL_OK;
}
/*
** tclcmd: unregister_devsim
*/
static int dsUnregisterObjCmd(
void * clientData,
Tcl_Interp *interp,
int objc,
Tcl_Obj *CONST objv[]
){
void devsym_unregister(void);
if( objc!=1 ){
Tcl_WrongNumArgs(interp, 1, objv, "");
return TCL_ERROR;
}
devsym_unregister();
return TCL_OK;
}
/*
@@ -1010,6 +1035,7 @@ int Sqlitetest6_Init(Tcl_Interp *interp){
Tcl_CreateObjCommand(interp, "sqlite3_crash_enable", crashEnableCmd, 0, 0);
Tcl_CreateObjCommand(interp, "sqlite3_crashparams", crashParamsObjCmd, 0, 0);
Tcl_CreateObjCommand(interp, "sqlite3_simulate_device", devSymObjCmd, 0, 0);
Tcl_CreateObjCommand(interp, "unregister_devsim", dsUnregisterObjCmd, 0, 0);
Tcl_CreateObjCommand(interp, "register_jt_vfs", jtObjCmd, 0, 0);
Tcl_CreateObjCommand(interp, "unregister_jt_vfs", jtUnregisterObjCmd, 0, 0);
#endif
+9 -1
View File
@@ -133,7 +133,8 @@ struct DevsymGlobal g = {0, 0, 512};
*/
static int devsymClose(sqlite3_file *pFile){
devsym_file *p = (devsym_file *)pFile;
return sqlite3OsClose(p->pReal);
sqlite3OsClose(p->pReal);
return SQLITE_OK;
}
/*
@@ -395,4 +396,11 @@ void devsym_register(int iDeviceChar, int iSectorSize){
}
}
void devsym_unregister(){
sqlite3_vfs_unregister(&devsym_vfs);
g.pVfs = 0;
g.iDeviceChar = 0;
g.iSectorSize = 0;
}
#endif
+18 -12
View File
@@ -160,6 +160,7 @@ static int jtRandomness(sqlite3_vfs*, int nByte, char *zOut);
static int jtSleep(sqlite3_vfs*, int microseconds);
static int jtCurrentTime(sqlite3_vfs*, double*);
static int jtCurrentTimeInt64(sqlite3_vfs*, sqlite3_int64*);
static int jtGetLastError(sqlite3_vfs*, int, char*);
static sqlite3_vfs jt_vfs = {
2, /* iVersion */
@@ -179,7 +180,7 @@ static sqlite3_vfs jt_vfs = {
jtRandomness, /* xRandomness */
jtSleep, /* xSleep */
jtCurrentTime, /* xCurrentTime */
0, /* xGetLastError */
jtGetLastError, /* xGetLastError */
jtCurrentTimeInt64 /* xCurrentTimeInt64 */
};
@@ -256,7 +257,8 @@ static int jtClose(sqlite3_file *pFile){
*pp = p->pNext;
}
leaveJtMutex();
return sqlite3OsClose(p->pReal);
sqlite3OsClose(p->pReal);
return SQLITE_OK;
}
/*
@@ -284,9 +286,10 @@ static int jtRead(
** b) The file-name specified when the file was opened matches
** all but the final 8 characters of the journal file name.
**
** c) There is currently a reserved lock on the file.
** c) There is currently a reserved lock on the file. This
** condition is waived if the noLock argument is non-zero.
**/
static jt_file *locateDatabaseHandle(const char *zJournal){
static jt_file *locateDatabaseHandle(const char *zJournal, int noLock){
jt_file *pMain = 0;
enterJtMutex();
for(pMain=g.pList; pMain; pMain=pMain->pNext){
@@ -294,7 +297,7 @@ static jt_file *locateDatabaseHandle(const char *zJournal){
if( (pMain->flags&SQLITE_OPEN_MAIN_DB)
&& ((int)strlen(pMain->zName)==nName)
&& 0==memcmp(pMain->zName, zJournal, nName)
&& (pMain->eLock>=SQLITE_LOCK_RESERVED)
&& ((pMain->eLock>=SQLITE_LOCK_RESERVED) || noLock)
){
break;
}
@@ -516,7 +519,7 @@ static int jtWrite(
jt_file *p = (jt_file *)pFile;
if( p->flags&SQLITE_OPEN_MAIN_JOURNAL ){
if( iOfst==0 ){
jt_file *pMain = locateDatabaseHandle(p->zName);
jt_file *pMain = locateDatabaseHandle(p->zName, 0);
assert( pMain );
if( iAmt==28 ){
@@ -561,7 +564,7 @@ static int jtWrite(
rc = sqlite3OsWrite(p->pReal, zBuf, iAmt, iOfst);
if( (p->flags&SQLITE_OPEN_MAIN_JOURNAL) && iAmt==12 ){
jt_file *pMain = locateDatabaseHandle(p->zName);
jt_file *pMain = locateDatabaseHandle(p->zName, 0);
int rc2 = readJournalFile(p, pMain);
if( rc==SQLITE_OK ) rc = rc2;
}
@@ -575,7 +578,7 @@ static int jtTruncate(sqlite3_file *pFile, sqlite_int64 size){
jt_file *p = (jt_file *)pFile;
if( p->flags&SQLITE_OPEN_MAIN_JOURNAL && size==0 ){
/* Truncating a journal file. This is the end of a transaction. */
jt_file *pMain = locateDatabaseHandle(p->zName);
jt_file *pMain = locateDatabaseHandle(p->zName, 0);
closeTransaction(pMain);
}
if( p->flags&SQLITE_OPEN_MAIN_DB && p->pWritable ){
@@ -603,11 +606,10 @@ static int jtSync(sqlite3_file *pFile, int flags){
** jt_file.pWritable bitvec of the main database file associated with
** this journal file.
*/
pMain = locateDatabaseHandle(p->zName);
assert(pMain);
pMain = locateDatabaseHandle(p->zName, 0);
/* Set the bitvec values */
if( pMain->pWritable ){
if( pMain && pMain->pWritable ){
pMain->nSync++;
rc = readJournalFile(p, pMain);
if( rc!=SQLITE_OK ){
@@ -729,7 +731,7 @@ static int jtDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){
int nPath = (int)strlen(zPath);
if( nPath>8 && 0==strcmp("-journal", &zPath[nPath-8]) ){
/* Deleting a journal file. The end of a transaction. */
jt_file *pMain = locateDatabaseHandle(zPath);
jt_file *pMain = locateDatabaseHandle(zPath, 0);
if( pMain ){
closeTransaction(pMain);
}
@@ -824,6 +826,10 @@ static int jtCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *pTimeOut){
return g.pVfs->xCurrentTimeInt64(g.pVfs, pTimeOut);
}
static int jtGetLastError(sqlite3_vfs *pVfs, int n, char *z){
return g.pVfs->xGetLastError(g.pVfs, n, z);
}
/**************************************************************************
** Start of public API.
*/
+1 -1
View File
@@ -1093,7 +1093,7 @@ static int test_db_config_lookaside(
if( Tcl_GetIntFromObj(interp, objv[3], &sz) ) return TCL_ERROR;
if( Tcl_GetIntFromObj(interp, objv[4], &cnt) ) return TCL_ERROR;
if( bufid==0 ){
rc = sqlite3_db_config(db, SQLITE_DBCONFIG_LOOKASIDE, 0, sz, cnt);
rc = sqlite3_db_config(db, SQLITE_DBCONFIG_LOOKASIDE, (void*)0, sz, cnt);
}else if( bufid>=1 && bufid<=2 && sz*cnt<=sizeof(azBuf[0]) ){
rc = sqlite3_db_config(db, SQLITE_DBCONFIG_LOOKASIDE, azBuf[bufid], sz,cnt);
}else{
+2 -2
View File
@@ -539,7 +539,7 @@ static int multiplexOpen(
memset(pGroup, 0, sz);
pMultiplexOpen->pGroup = pGroup;
pGroup->bEnabled = (unsigned char)-1;
pGroup->bTruncate = sqlite3_uri_boolean(zUri, "truncate",
pGroup->bTruncate = (unsigned char)sqlite3_uri_boolean(zUri, "truncate",
(flags & SQLITE_OPEN_MAIN_DB)==0);
pGroup->szChunk = (int)sqlite3_uri_int64(zUri, "chunksize",
SQLITE_MULTIPLEX_CHUNK_SIZE);
@@ -978,7 +978,7 @@ static int multiplexFileControl(sqlite3_file *pConn, int op, void *pArg){
case MULTIPLEX_CTRL_ENABLE:
if( pArg ) {
int bEnabled = *(int *)pArg;
pGroup->bEnabled = bEnabled;
pGroup->bEnabled = (unsigned char)bEnabled;
rc = SQLITE_OK;
}
break;
+1 -1
View File
@@ -508,7 +508,7 @@ static int fsSync(sqlite3_file *pFile, int flags){
if( p->eType==DATABASE_FILE ){
unsigned char zSize[4];
zSize[0] = (pReal->nDatabase&0xFF000000)>>24;
zSize[1] = (pReal->nDatabase&0x00FF0000)>>16;
zSize[1] = (unsigned char)((pReal->nDatabase&0x00FF0000)>>16);
zSize[2] = (pReal->nDatabase&0x0000FF00)>>8;
zSize[3] = (pReal->nDatabase&0x000000FF);
rc = pRealFile->pMethods->xWrite(pRealFile, zSize, 4, 0);
+3 -3
View File
@@ -644,9 +644,9 @@ static void vfslog_flush(VfslogVfs *p){
static void put32bits(unsigned char *p, unsigned int v){
p[0] = v>>24;
p[1] = v>>16;
p[2] = v>>8;
p[3] = v;
p[1] = (unsigned char)(v>>16);
p[2] = (unsigned char)(v>>8);
p[3] = (unsigned char)v;
}
static void vfslog_call(
+18 -9
View File
@@ -108,10 +108,13 @@ static int ts_ftruncate(int fd, off_t n);
static int ts_fcntl(int fd, int cmd, ... );
static int ts_read(int fd, void *aBuf, size_t nBuf);
static int ts_pread(int fd, void *aBuf, size_t nBuf, off_t off);
static int ts_pread64(int fd, void *aBuf, size_t nBuf, off_t off);
/* Note: pread64() and pwrite64() actually use off64_t as the type on their
** last parameter. But that datatype is not defined on many systems
** (ex: Mac, OpenBSD). So substitute a likely equivalent: sqlite3_uint64 */
static int ts_pread64(int fd, void *aBuf, size_t nBuf, sqlite3_uint64 off);
static int ts_write(int fd, const void *aBuf, size_t nBuf);
static int ts_pwrite(int fd, const void *aBuf, size_t nBuf, off_t off);
static int ts_pwrite64(int fd, const void *aBuf, size_t nBuf, off_t off);
static int ts_pwrite64(int fd, const void *aBuf, size_t nBuf, sqlite3_uint64 off);
static int ts_fchmod(int fd, mode_t mode);
static int ts_fallocate(int fd, off_t off, off_t len);
static void *ts_mmap(void *, size_t, int, int, int, off_t);
@@ -155,11 +158,11 @@ struct TestSyscallArray {
#define orig_fcntl ((int(*)(int,int,...))aSyscall[7].xOrig)
#define orig_read ((ssize_t(*)(int,void*,size_t))aSyscall[8].xOrig)
#define orig_pread ((ssize_t(*)(int,void*,size_t,off_t))aSyscall[9].xOrig)
#define orig_pread64 ((ssize_t(*)(int,void*,size_t,off_t))aSyscall[10].xOrig)
#define orig_pread64 ((ssize_t(*)(int,void*,size_t,sqlite3_uint64))aSyscall[10].xOrig)
#define orig_write ((ssize_t(*)(int,const void*,size_t))aSyscall[11].xOrig)
#define orig_pwrite ((ssize_t(*)(int,const void*,size_t,off_t))\
aSyscall[12].xOrig)
#define orig_pwrite64 ((ssize_t(*)(int,const void*,size_t,off_t))\
#define orig_pwrite64 ((ssize_t(*)(int,const void*,size_t,sqlite3_uint64))\
aSyscall[13].xOrig)
#define orig_fchmod ((int(*)(int,mode_t))aSyscall[14].xOrig)
#define orig_fallocate ((int(*)(int,off_t,off_t))aSyscall[15].xOrig)
@@ -326,7 +329,7 @@ static int ts_pread(int fd, void *aBuf, size_t nBuf, off_t off){
/*
** A wrapper around pread64().
*/
static int ts_pread64(int fd, void *aBuf, size_t nBuf, off_t off){
static int ts_pread64(int fd, void *aBuf, size_t nBuf, sqlite3_uint64 off){
if( tsIsFailErrno("pread64") ){
return -1;
}
@@ -357,7 +360,7 @@ static int ts_pwrite(int fd, const void *aBuf, size_t nBuf, off_t off){
/*
** A wrapper around pwrite64().
*/
static int ts_pwrite64(int fd, const void *aBuf, size_t nBuf, off_t off){
static int ts_pwrite64(int fd, const void *aBuf, size_t nBuf, sqlite3_uint64 off){
if( tsIsFailErrno("pwrite64") ){
return -1;
}
@@ -719,14 +722,20 @@ static int test_syscall(
};
int iCmd;
int rc;
sqlite3_vfs *pVfs = sqlite3_vfs_find(0);
if( objc<2 ){
Tcl_WrongNumArgs(interp, 1, objv, "SUB-COMMAND ...");
return TCL_ERROR;
}
rc = Tcl_GetIndexFromObjStruct(interp,
objv[1], aCmd, sizeof(aCmd[0]), "sub-command", 0, &iCmd
);
if( pVfs->iVersion<3 || pVfs->xSetSystemCall==0 ){
Tcl_AppendResult(interp, "VFS does not support xSetSystemCall", 0);
rc = TCL_ERROR;
}else{
rc = Tcl_GetIndexFromObjStruct(interp,
objv[1], aCmd, sizeof(aCmd[0]), "sub-command", 0, &iCmd
);
}
if( rc!=TCL_OK ) return rc;
return aCmd[iCmd].xCmd(clientData, interp, objc, objv);
}
+2 -3
View File
@@ -306,7 +306,6 @@ static void tvfsExecTcl(
** Close an tvfs-file.
*/
static int tvfsClose(sqlite3_file *pFile){
int rc;
TestvfsFile *pTestfile = (TestvfsFile *)pFile;
TestvfsFd *pFd = pTestfile->pFd;
Testvfs *p = (Testvfs *)pFd->pVfs->pAppData;
@@ -324,10 +323,10 @@ static int tvfsClose(sqlite3_file *pFile){
if( pFile->pMethods ){
ckfree((char *)pFile->pMethods);
}
rc = sqlite3OsClose(pFd->pReal);
sqlite3OsClose(pFd->pReal);
ckfree((char *)pFd);
pTestfile->pFd = 0;
return rc;
return SQLITE_OK;
}
/*
+1 -1
View File
@@ -583,7 +583,7 @@ int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzErrMsg){
sqlite3DeleteTable(db, pParse->pNewTable);
}
sqlite3WithDelete(db, pParse->pWithToFree);
if( pParse->pWithToFree ) sqlite3WithDelete(db, pParse->pWithToFree);
sqlite3DeleteTrigger(db, pParse->pNewTrigger);
for(i=pParse->nzVar-1; i>=0; i--) sqlite3DbFree(db, pParse->azVar[i]);
sqlite3DbFree(db, pParse->azVar);
+65 -61
View File
@@ -242,18 +242,13 @@ void sqlite3ErrorMsg(Parse *pParse, const char *zFormat, ...){
** brackets from around identifiers. For example: "[a-b-c]" becomes
** "a-b-c".
*/
int sqlite3Dequote(char *z){
void sqlite3Dequote(char *z){
char quote;
int i, j;
if( z==0 ) return -1;
if( z==0 ) return;
quote = z[0];
switch( quote ){
case '\'': break;
case '"': break;
case '`': break; /* For MySQL compatibility */
case '[': quote = ']'; break; /* For MS SqlServer compatibility */
default: return -1;
}
if( !sqlite3Isquote(quote) ) return;
if( quote=='[' ) quote = ']';
for(i=1, j=0;; i++){
assert( z[i] );
if( z[i]==quote ){
@@ -268,7 +263,6 @@ int sqlite3Dequote(char *z){
}
}
z[j] = 0;
return j;
}
/*
@@ -361,7 +355,7 @@ int sqlite3AtoF(const char *z, double *pResult, int length, u8 enc){
int eValid = 1; /* True exponent is either not used or is well-formed */
double result;
int nDigits = 0;
int nonNum = 0;
int nonNum = 0; /* True if input contains UTF16 with high byte non-zero */
assert( enc==SQLITE_UTF8 || enc==SQLITE_UTF16LE || enc==SQLITE_UTF16BE );
*pResult = 0.0; /* Default return value, in case of an error */
@@ -374,7 +368,7 @@ int sqlite3AtoF(const char *z, double *pResult, int length, u8 enc){
assert( SQLITE_UTF16LE==2 && SQLITE_UTF16BE==3 );
for(i=3-enc; i<length && z[i]==0; i+=2){}
nonNum = i<length;
zEnd = z+i+enc-3;
zEnd = &z[i^1];
z += (enc&1);
}
@@ -390,9 +384,6 @@ int sqlite3AtoF(const char *z, double *pResult, int length, u8 enc){
z+=incr;
}
/* skip leading zeroes */
while( z<zEnd && z[0]=='0' ) z+=incr, nDigits++;
/* copy max significant digits to significand */
while( z<zEnd && sqlite3Isdigit(*z) && s<((LARGEST_INT64-9)/10) ){
s = s*10 + (*z - '0');
@@ -409,12 +400,13 @@ int sqlite3AtoF(const char *z, double *pResult, int length, u8 enc){
z+=incr;
/* copy digits from after decimal to significand
** (decrease exponent by d to shift decimal right) */
while( z<zEnd && sqlite3Isdigit(*z) && s<((LARGEST_INT64-9)/10) ){
s = s*10 + (*z - '0');
z+=incr, nDigits++, d--;
while( z<zEnd && sqlite3Isdigit(*z) ){
if( s<((LARGEST_INT64-9)/10) ){
s = s*10 + (*z - '0');
d--;
}
z+=incr, nDigits++;
}
/* skip non-significant digits */
while( z<zEnd && sqlite3Isdigit(*z) ) z+=incr, nDigits++;
}
if( z>=zEnd ) goto do_atof_calc;
@@ -422,7 +414,12 @@ int sqlite3AtoF(const char *z, double *pResult, int length, u8 enc){
if( *z=='e' || *z=='E' ){
z+=incr;
eValid = 0;
if( z>=zEnd ) goto do_atof_calc;
/* This branch is needed to avoid a (harmless) buffer overread. The
** special comment alerts the mutation tester that the correct answer
** is obtained even if the branch is omitted */
if( z>=zEnd ) goto do_atof_calc; /*PREVENTS-HARMLESS-OVERREAD*/
/* get sign of exponent */
if( *z=='-' ){
esign = -1;
@@ -439,9 +436,7 @@ int sqlite3AtoF(const char *z, double *pResult, int length, u8 enc){
}
/* skip trailing spaces */
if( nDigits && eValid ){
while( z<zEnd && sqlite3Isspace(*z) ) z+=incr;
}
while( z<zEnd && sqlite3Isspace(*z) ) z+=incr;
do_atof_calc:
/* adjust exponent by d, and update sign */
@@ -453,41 +448,51 @@ do_atof_calc:
esign = 1;
}
/* if 0 significand */
if( !s ) {
/* In the IEEE 754 standard, zero is signed.
** Add the sign if we've seen at least one digit */
result = (sign<0 && nDigits) ? -(double)0 : (double)0;
if( s==0 ) {
/* In the IEEE 754 standard, zero is signed. */
result = sign<0 ? -(double)0 : (double)0;
} else {
/* attempt to reduce exponent */
if( esign>0 ){
while( s<(LARGEST_INT64/10) && e>0 ) e--,s*=10;
}else{
while( !(s%10) && e>0 ) e--,s/=10;
/* Attempt to reduce exponent.
**
** Branches that are not required for the correct answer but which only
** help to obtain the correct answer faster are marked with special
** comments, as a hint to the mutation tester.
*/
while( e>0 ){ /*OPTIMIZATION-IF-TRUE*/
if( esign>0 ){
if( s>=(LARGEST_INT64/10) ) break; /*OPTIMIZATION-IF-FALSE*/
s *= 10;
}else{
if( s%10!=0 ) break; /*OPTIMIZATION-IF-FALSE*/
s /= 10;
}
e--;
}
/* adjust the sign of significand */
s = sign<0 ? -s : s;
/* if exponent, scale significand as appropriate
** and store in result. */
if( e ){
if( e==0 ){ /*OPTIMIZATION-IF-TRUE*/
result = (double)s;
}else{
LONGDOUBLE_TYPE scale = 1.0;
/* attempt to handle extremely small/large numbers better */
if( e>307 && e<342 ){
while( e%308 ) { scale *= 1.0e+1; e -= 1; }
if( esign<0 ){
result = s / scale;
result /= 1.0e+308;
}else{
result = s * scale;
result *= 1.0e+308;
}
}else if( e>=342 ){
if( esign<0 ){
result = 0.0*s;
}else{
result = 1e308*1e308*s; /* Infinity */
if( e>307 ){ /*OPTIMIZATION-IF-TRUE*/
if( e<342 ){ /*OPTIMIZATION-IF-TRUE*/
while( e%308 ) { scale *= 1.0e+1; e -= 1; }
if( esign<0 ){
result = s / scale;
result /= 1.0e+308;
}else{
result = s * scale;
result *= 1.0e+308;
}
}else{ assert( e>=342 );
if( esign<0 ){
result = 0.0*s;
}else{
result = 1e308*1e308*s; /* Infinity */
}
}
}else{
/* 1.0e+22 is the largest power of 10 than can be
@@ -500,8 +505,6 @@ do_atof_calc:
result = s * scale;
}
}
} else {
result = (double)s;
}
}
@@ -509,7 +512,7 @@ do_atof_calc:
*pResult = result;
/* return true if number and no extra non-whitespace chracters after */
return z>=zEnd && nDigits>0 && eValid && nonNum==0;
return z==zEnd && nDigits>0 && eValid && nonNum==0;
#else
return !sqlite3Atoi64(z, pResult, length, enc);
#endif /* SQLITE_OMIT_FLOATING_POINT */
@@ -571,7 +574,7 @@ int sqlite3Atoi64(const char *zNum, i64 *pNum, int length, u8 enc){
int neg = 0; /* assume positive */
int i;
int c = 0;
int nonNum = 0;
int nonNum = 0; /* True if input contains UTF16 with high byte non-zero */
const char *zStart;
const char *zEnd = zNum + length;
assert( enc==SQLITE_UTF8 || enc==SQLITE_UTF16LE || enc==SQLITE_UTF16BE );
@@ -582,7 +585,7 @@ int sqlite3Atoi64(const char *zNum, i64 *pNum, int length, u8 enc){
assert( SQLITE_UTF16LE==2 && SQLITE_UTF16BE==3 );
for(i=3-enc; i<length && zNum[i]==0; i+=2){}
nonNum = i<length;
zEnd = zNum+i+enc-3;
zEnd = &zNum[i^1];
zNum += (enc&1);
}
while( zNum<zEnd && sqlite3Isspace(*zNum) ) zNum+=incr;
@@ -609,8 +612,11 @@ int sqlite3Atoi64(const char *zNum, i64 *pNum, int length, u8 enc){
testcase( i==18 );
testcase( i==19 );
testcase( i==20 );
if( (c!=0 && &zNum[i]<zEnd) || (i==0 && zStart==zNum)
|| i>19*incr || nonNum ){
if( &zNum[i]<zEnd /* Extra bytes at the end */
|| (i==0 && zStart==zNum) /* No digits */
|| i>19*incr /* Too many digits */
|| nonNum /* UTF16 with high-order bytes non-zero */
){
/* zNum is empty or contains non-numeric text or is longer
** than 19 digits (thus guaranteeing that it is too large) */
return 1;
@@ -652,7 +658,6 @@ int sqlite3DecOrHexToI64(const char *z, i64 *pOut){
#ifndef SQLITE_OMIT_HEX_INTEGER
if( z[0]=='0'
&& (z[1]=='x' || z[1]=='X')
&& sqlite3Isxdigit(z[2])
){
u64 u = 0;
int i, k;
@@ -1414,7 +1419,7 @@ LogEst sqlite3LogEst(u64 x){
if( x<2 ) return 0;
while( x<8 ){ y -= 10; x <<= 1; }
}else{
while( x>255 ){ y += 40; x >>= 4; }
while( x>255 ){ y += 40; x >>= 4; } /*OPTIMIZATION-IF-TRUE*/
while( x>15 ){ y += 10; x >>= 1; }
}
return a[x&7] + y - 10;
@@ -1448,7 +1453,6 @@ LogEst sqlite3LogEstFromDouble(double x){
*/
u64 sqlite3LogEstToInt(LogEst x){
u64 n;
if( x<10 ) return 1;
n = x%10;
x /= 10;
if( n>=5 ) n -= 2;
+46 -39
View File
@@ -674,37 +674,39 @@ int sqlite3VdbeExec(
/* Sanity checking on other operands */
#ifdef SQLITE_DEBUG
assert( pOp->opflags==sqlite3OpcodeProperty[pOp->opcode] );
if( (pOp->opflags & OPFLG_IN1)!=0 ){
assert( pOp->p1>0 );
assert( pOp->p1<=(p->nMem+1 - p->nCursor) );
assert( memIsValid(&aMem[pOp->p1]) );
assert( sqlite3VdbeCheckMemInvariants(&aMem[pOp->p1]) );
REGISTER_TRACE(pOp->p1, &aMem[pOp->p1]);
}
if( (pOp->opflags & OPFLG_IN2)!=0 ){
assert( pOp->p2>0 );
assert( pOp->p2<=(p->nMem+1 - p->nCursor) );
assert( memIsValid(&aMem[pOp->p2]) );
assert( sqlite3VdbeCheckMemInvariants(&aMem[pOp->p2]) );
REGISTER_TRACE(pOp->p2, &aMem[pOp->p2]);
}
if( (pOp->opflags & OPFLG_IN3)!=0 ){
assert( pOp->p3>0 );
assert( pOp->p3<=(p->nMem+1 - p->nCursor) );
assert( memIsValid(&aMem[pOp->p3]) );
assert( sqlite3VdbeCheckMemInvariants(&aMem[pOp->p3]) );
REGISTER_TRACE(pOp->p3, &aMem[pOp->p3]);
}
if( (pOp->opflags & OPFLG_OUT2)!=0 ){
assert( pOp->p2>0 );
assert( pOp->p2<=(p->nMem+1 - p->nCursor) );
memAboutToChange(p, &aMem[pOp->p2]);
}
if( (pOp->opflags & OPFLG_OUT3)!=0 ){
assert( pOp->p3>0 );
assert( pOp->p3<=(p->nMem+1 - p->nCursor) );
memAboutToChange(p, &aMem[pOp->p3]);
{
u8 opProperty = sqlite3OpcodeProperty[pOp->opcode];
if( (opProperty & OPFLG_IN1)!=0 ){
assert( pOp->p1>0 );
assert( pOp->p1<=(p->nMem+1 - p->nCursor) );
assert( memIsValid(&aMem[pOp->p1]) );
assert( sqlite3VdbeCheckMemInvariants(&aMem[pOp->p1]) );
REGISTER_TRACE(pOp->p1, &aMem[pOp->p1]);
}
if( (opProperty & OPFLG_IN2)!=0 ){
assert( pOp->p2>0 );
assert( pOp->p2<=(p->nMem+1 - p->nCursor) );
assert( memIsValid(&aMem[pOp->p2]) );
assert( sqlite3VdbeCheckMemInvariants(&aMem[pOp->p2]) );
REGISTER_TRACE(pOp->p2, &aMem[pOp->p2]);
}
if( (opProperty & OPFLG_IN3)!=0 ){
assert( pOp->p3>0 );
assert( pOp->p3<=(p->nMem+1 - p->nCursor) );
assert( memIsValid(&aMem[pOp->p3]) );
assert( sqlite3VdbeCheckMemInvariants(&aMem[pOp->p3]) );
REGISTER_TRACE(pOp->p3, &aMem[pOp->p3]);
}
if( (opProperty & OPFLG_OUT2)!=0 ){
assert( pOp->p2>0 );
assert( pOp->p2<=(p->nMem+1 - p->nCursor) );
memAboutToChange(p, &aMem[pOp->p2]);
}
if( (opProperty & OPFLG_OUT3)!=0 ){
assert( pOp->p3>0 );
assert( pOp->p3<=(p->nMem+1 - p->nCursor) );
memAboutToChange(p, &aMem[pOp->p3]);
}
}
#endif
#if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE)
@@ -2016,11 +2018,13 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
/* Neither operand is NULL. Do a comparison. */
affinity = pOp->p5 & SQLITE_AFF_MASK;
if( affinity>=SQLITE_AFF_NUMERIC ){
if( (flags1 & (MEM_Int|MEM_Real|MEM_Str))==MEM_Str ){
applyNumericAffinity(pIn1,0);
}
if( (flags3 & (MEM_Int|MEM_Real|MEM_Str))==MEM_Str ){
applyNumericAffinity(pIn3,0);
if( (flags1 | flags3)&MEM_Str ){
if( (flags1 & (MEM_Int|MEM_Real|MEM_Str))==MEM_Str ){
applyNumericAffinity(pIn1,0);
}
if( (flags3 & (MEM_Int|MEM_Real|MEM_Str))==MEM_Str ){
applyNumericAffinity(pIn3,0);
}
}
}else if( affinity==SQLITE_AFF_TEXT ){
if( (flags1 & MEM_Str)==0 && (flags1 & (MEM_Int|MEM_Real))!=0 ){
@@ -2753,7 +2757,9 @@ case OP_MakeRecord: {
testcase( serial_type==127 );
testcase( serial_type==128 );
nHdr += serial_type<=127 ? 1 : sqlite3VarintLen(serial_type);
}while( (--pRec)>=pData0 );
if( pRec==pData0 ) break;
pRec--;
}while(1);
/* EVIDENCE-OF: R-22564-11647 The header begins with a single varint
** which determines the total number of bytes in the header. The varint
@@ -6873,11 +6879,12 @@ default: { /* This is really OP_Noop and OP_Explain */
#ifdef SQLITE_DEBUG
if( db->flags & SQLITE_VdbeTrace ){
u8 opProperty = sqlite3OpcodeProperty[pOrigOp->opcode];
if( rc!=0 ) printf("rc=%d\n",rc);
if( pOrigOp->opflags & (OPFLG_OUT2) ){
if( opProperty & (OPFLG_OUT2) ){
registerTrace(pOrigOp->p2, &aMem[pOrigOp->p2]);
}
if( pOrigOp->opflags & OPFLG_OUT3 ){
if( opProperty & OPFLG_OUT3 ){
registerTrace(pOrigOp->p3, &aMem[pOrigOp->p3]);
}
}
+1 -1
View File
@@ -41,7 +41,7 @@ typedef struct SubProgram SubProgram;
struct VdbeOp {
u8 opcode; /* What operation to perform */
signed char p4type; /* One of the P4_xxx constants for p4 */
u8 opflags; /* Mask of the OPFLG_* flags in opcodes.h */
u8 notUsed1;
u8 p5; /* Fifth parameter is an unsigned character */
int p1; /* First operand */
int p2; /* Second parameter (often the jump destination) */
+103 -94
View File
@@ -545,73 +545,84 @@ int sqlite3VdbeAssertMayAbort(Vdbe *v, int mayAbort){
** (4) Initialize the p4.xAdvance pointer on opcodes that use it.
**
** (5) Reclaim the memory allocated for storing labels.
**
** This routine will only function correctly if the mkopcodeh.tcl generator
** script numbers the opcodes correctly. Changes to this routine must be
** coordinated with changes to mkopcodeh.tcl.
*/
static void resolveP2Values(Vdbe *p, int *pMaxFuncArgs){
int i;
int nMaxArgs = *pMaxFuncArgs;
Op *pOp;
Parse *pParse = p->pParse;
int *aLabel = pParse->aLabel;
p->readOnly = 1;
p->bIsReader = 0;
for(pOp=p->aOp, i=p->nOp-1; i>=0; i--, pOp++){
u8 opcode = pOp->opcode;
pOp = &p->aOp[p->nOp-1];
while(1){
/* NOTE: Be sure to update mkopcodeh.tcl when adding or removing
** cases from this switch! */
switch( opcode ){
case OP_Transaction: {
if( pOp->p2!=0 ) p->readOnly = 0;
/* fall thru */
}
case OP_AutoCommit:
case OP_Savepoint: {
p->bIsReader = 1;
break;
}
/* Only JUMP opcodes and the short list of special opcodes in the switch
** below need to be considered. The mkopcodeh.tcl generator script groups
** all these opcodes together near the front of the opcode list. Skip
** any opcode that does not need processing by virtual of the fact that
** it is larger than SQLITE_MX_JUMP_OPCODE, as a performance optimization.
*/
if( pOp->opcode<=SQLITE_MX_JUMP_OPCODE ){
/* NOTE: Be sure to update mkopcodeh.tcl when adding or removing
** cases from this switch! */
switch( pOp->opcode ){
case OP_Transaction: {
if( pOp->p2!=0 ) p->readOnly = 0;
/* fall thru */
}
case OP_AutoCommit:
case OP_Savepoint: {
p->bIsReader = 1;
break;
}
#ifndef SQLITE_OMIT_WAL
case OP_Checkpoint:
case OP_Checkpoint:
#endif
case OP_Vacuum:
case OP_JournalMode: {
p->readOnly = 0;
p->bIsReader = 1;
break;
}
case OP_Vacuum:
case OP_JournalMode: {
p->readOnly = 0;
p->bIsReader = 1;
break;
}
#ifndef SQLITE_OMIT_VIRTUALTABLE
case OP_VUpdate: {
if( pOp->p2>nMaxArgs ) nMaxArgs = pOp->p2;
break;
}
case OP_VFilter: {
int n;
assert( p->nOp - i >= 3 );
assert( pOp[-1].opcode==OP_Integer );
n = pOp[-1].p1;
if( n>nMaxArgs ) nMaxArgs = n;
break;
}
case OP_VUpdate: {
if( pOp->p2>nMaxArgs ) nMaxArgs = pOp->p2;
break;
}
case OP_VFilter: {
int n;
assert( (pOp - p->aOp) >= 3 );
assert( pOp[-1].opcode==OP_Integer );
n = pOp[-1].p1;
if( n>nMaxArgs ) nMaxArgs = n;
break;
}
#endif
case OP_Next:
case OP_NextIfOpen:
case OP_SorterNext: {
pOp->p4.xAdvance = sqlite3BtreeNext;
pOp->p4type = P4_ADVANCE;
break;
case OP_Next:
case OP_NextIfOpen:
case OP_SorterNext: {
pOp->p4.xAdvance = sqlite3BtreeNext;
pOp->p4type = P4_ADVANCE;
break;
}
case OP_Prev:
case OP_PrevIfOpen: {
pOp->p4.xAdvance = sqlite3BtreePrevious;
pOp->p4type = P4_ADVANCE;
break;
}
}
case OP_Prev:
case OP_PrevIfOpen: {
pOp->p4.xAdvance = sqlite3BtreePrevious;
pOp->p4type = P4_ADVANCE;
break;
if( (sqlite3OpcodeProperty[pOp->opcode] & OPFLG_JUMP)!=0 && pOp->p2<0 ){
assert( ADDR(pOp->p2)<pParse->nLabel );
pOp->p2 = aLabel[ADDR(pOp->p2)];
}
}
pOp->opflags = sqlite3OpcodeProperty[opcode];
if( (pOp->opflags & OPFLG_JUMP)!=0 && pOp->p2<0 ){
assert( ADDR(pOp->p2)<pParse->nLabel );
pOp->p2 = aLabel[ADDR(pOp->p2)];
}
if( pOp==p->aOp ) break;
pOp--;
}
sqlite3DbFree(p->db, pParse->aLabel);
pParse->aLabel = 0;
@@ -791,52 +802,50 @@ static void vdbeFreeOpArray(sqlite3 *, Op *, int);
** Delete a P4 value if necessary.
*/
static void freeP4(sqlite3 *db, int p4type, void *p4){
if( p4 ){
assert( db );
switch( p4type ){
case P4_FUNCCTX: {
freeEphemeralFunction(db, ((sqlite3_context*)p4)->pFunc);
/* Fall through into the next case */
}
case P4_REAL:
case P4_INT64:
case P4_DYNAMIC:
case P4_INTARRAY: {
sqlite3DbFree(db, p4);
break;
}
case P4_KEYINFO: {
if( db->pnBytesFreed==0 ) sqlite3KeyInfoUnref((KeyInfo*)p4);
break;
}
assert( db );
switch( p4type ){
case P4_FUNCCTX: {
freeEphemeralFunction(db, ((sqlite3_context*)p4)->pFunc);
/* Fall through into the next case */
}
case P4_REAL:
case P4_INT64:
case P4_DYNAMIC:
case P4_INTARRAY: {
sqlite3DbFree(db, p4);
break;
}
case P4_KEYINFO: {
if( db->pnBytesFreed==0 ) sqlite3KeyInfoUnref((KeyInfo*)p4);
break;
}
#ifdef SQLITE_ENABLE_CURSOR_HINTS
case P4_EXPR: {
sqlite3ExprDelete(db, (Expr*)p4);
break;
}
case P4_EXPR: {
sqlite3ExprDelete(db, (Expr*)p4);
break;
}
#endif
case P4_MPRINTF: {
if( db->pnBytesFreed==0 ) sqlite3_free(p4);
break;
}
case P4_FUNCDEF: {
freeEphemeralFunction(db, (FuncDef*)p4);
break;
}
case P4_MEM: {
if( db->pnBytesFreed==0 ){
sqlite3ValueFree((sqlite3_value*)p4);
}else{
Mem *p = (Mem*)p4;
if( p->szMalloc ) sqlite3DbFree(db, p->zMalloc);
sqlite3DbFree(db, p);
}
break;
}
case P4_VTAB : {
if( db->pnBytesFreed==0 ) sqlite3VtabUnlock((VTable *)p4);
break;
case P4_MPRINTF: {
if( db->pnBytesFreed==0 ) sqlite3_free(p4);
break;
}
case P4_FUNCDEF: {
freeEphemeralFunction(db, (FuncDef*)p4);
break;
}
case P4_MEM: {
if( db->pnBytesFreed==0 ){
sqlite3ValueFree((sqlite3_value*)p4);
}else{
Mem *p = (Mem*)p4;
if( p->szMalloc ) sqlite3DbFree(db, p->zMalloc);
sqlite3DbFree(db, p);
}
break;
}
case P4_VTAB : {
if( db->pnBytesFreed==0 ) sqlite3VtabUnlock((VTable *)p4);
break;
}
}
}
+11 -3
View File
@@ -931,7 +931,6 @@ int sqlite3VdbeSorterInit(
){
int pgsz; /* Page size of main database */
int i; /* Used to iterate through aTask[] */
int mxCache; /* Cache size */
VdbeSorter *pSorter; /* The new sorter */
KeyInfo *pKeyInfo; /* Copy of pCsr->pKeyInfo with db==0 */
int szKeyInfo; /* Size of pCsr->pKeyInfo in bytes */
@@ -988,11 +987,20 @@ int sqlite3VdbeSorterInit(
}
if( !sqlite3TempInMemory(db) ){
i64 mxCache; /* Cache size in bytes*/
u32 szPma = sqlite3GlobalConfig.szPma;
pSorter->mnPmaSize = szPma * pgsz;
mxCache = db->aDb[0].pSchema->cache_size;
if( mxCache<(int)szPma ) mxCache = (int)szPma;
pSorter->mxPmaSize = MIN((i64)mxCache*pgsz, SQLITE_MAX_PMASZ);
if( mxCache<0 ){
/* A negative cache-size value C indicates that the cache is abs(C)
** KiB in size. */
mxCache = mxCache * -1024;
}else{
mxCache = mxCache * pgsz;
}
mxCache = MIN(mxCache, SQLITE_MAX_PMASZ);
pSorter->mxPmaSize = MAX(pSorter->mnPmaSize, (int)mxCache);
/* EVIDENCE-OF: R-26747-61719 When the application provides any amount of
** scratch memory using SQLITE_CONFIG_SCRATCH, SQLite avoids unnecessary
+17
View File
@@ -3399,6 +3399,23 @@ int sqlite3WalSnapshotGet(Wal *pWal, sqlite3_snapshot **ppSnapshot){
void sqlite3WalSnapshotOpen(Wal *pWal, sqlite3_snapshot *pSnapshot){
pWal->pSnapshot = (WalIndexHdr*)pSnapshot;
}
/*
** Return a +ve value if snapshot p1 is newer than p2. A -ve value if
** p1 is older than p2 and zero if p1 and p2 are the same snapshot.
*/
int sqlite3_snapshot_cmp(sqlite3_snapshot *p1, sqlite3_snapshot *p2){
WalIndexHdr *pHdr1 = (WalIndexHdr*)p1;
WalIndexHdr *pHdr2 = (WalIndexHdr*)p2;
/* aSalt[0] is a copy of the value stored in the wal file header. It
** is incremented each time the wal file is restarted. */
if( pHdr1->aSalt[0]<pHdr2->aSalt[0] ) return -1;
if( pHdr1->aSalt[0]>pHdr2->aSalt[0] ) return +1;
if( pHdr1->mxFrame<pHdr2->mxFrame ) return -1;
if( pHdr1->mxFrame>pHdr2->mxFrame ) return +1;
return 0;
}
#endif /* SQLITE_ENABLE_SNAPSHOT */
#ifdef SQLITE_ENABLE_ZIPVFS
+30 -19
View File
@@ -1651,11 +1651,12 @@ static void whereTermPrint(WhereTerm *pTerm, int iTerm){
*/
static void whereLoopPrint(WhereLoop *p, WhereClause *pWC){
WhereInfo *pWInfo = pWC->pWInfo;
int nb = 1+(pWInfo->pTabList->nSrc+7)/8;
int nb = 1+(pWInfo->pTabList->nSrc+3)/4;
struct SrcList_item *pItem = pWInfo->pTabList->a + p->iTab;
Table *pTab = pItem->pTab;
Bitmask mAll = (((Bitmask)1)<<(nb*4)) - 1;
sqlite3DebugPrintf("%c%2d.%0*llx.%0*llx", p->cId,
p->iTab, nb, p->maskSelf, nb, p->prereq);
p->iTab, nb, p->maskSelf, nb, p->prereq & mAll);
sqlite3DebugPrintf(" %12s",
pItem->zAlias ? pItem->zAlias : pTab->zName);
if( (p->wsFlags & WHERE_VIRTUALTABLE)==0 ){
@@ -2201,8 +2202,6 @@ static int whereLoopAddBtreeIndex(
assert( (pNew->wsFlags & WHERE_TOP_LIMIT)==0 );
if( pNew->wsFlags & WHERE_BTM_LIMIT ){
opMask = WO_LT|WO_LE;
}else if( /*pProbe->tnum<=0 ||*/ (pSrc->fg.jointype & JT_LEFT)!=0 ){
opMask = WO_EQ|WO_IN|WO_GT|WO_GE|WO_LT|WO_LE;
}else{
opMask = WO_EQ|WO_IN|WO_GT|WO_GE|WO_LT|WO_LE|WO_ISNULL|WO_IS;
}
@@ -2240,6 +2239,18 @@ static int whereLoopAddBtreeIndex(
** to mix with a lower range bound from some other source */
if( pTerm->wtFlags & TERM_LIKEOPT && pTerm->eOperator==WO_LT ) continue;
/* Do not allow IS constraints from the WHERE clause to be used by the
** right table of a LEFT JOIN. Only constraints in the ON clause are
** allowed */
if( (pSrc->fg.jointype & JT_LEFT)!=0
&& !ExprHasProperty(pTerm->pExpr, EP_FromJoin)
&& (eOp & (WO_IS|WO_ISNULL))!=0
){
testcase( eOp & WO_IS );
testcase( eOp & WO_ISNULL );
continue;
}
pNew->wsFlags = saved_wsFlags;
pNew->u.btree.nEq = saved_nEq;
pNew->nLTerm = saved_nLTerm;
@@ -3870,9 +3881,9 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){
&& nRowEst
){
Bitmask notUsed;
int rc = wherePathSatisfiesOrderBy(pWInfo, pWInfo->pResultSet, pFrom,
int rc = wherePathSatisfiesOrderBy(pWInfo, pWInfo->pDistinctSet, pFrom,
WHERE_DISTINCTBY, nLoop-1, pFrom->aLoop[nLoop-1], &notUsed);
if( rc==pWInfo->pResultSet->nExpr ){
if( rc==pWInfo->pDistinctSet->nExpr ){
pWInfo->eDistinct = WHERE_DISTINCT_ORDERED;
}
}
@@ -4087,14 +4098,14 @@ static int whereShortCut(WhereLoopBuilder *pBuilder){
** used.
*/
WhereInfo *sqlite3WhereBegin(
Parse *pParse, /* The parser context */
SrcList *pTabList, /* FROM clause: A list of all tables to be scanned */
Expr *pWhere, /* The WHERE clause */
ExprList *pOrderBy, /* An ORDER BY (or GROUP BY) clause, or NULL */
ExprList *pResultSet, /* Result set of the query */
u16 wctrlFlags, /* One of the WHERE_* flags defined in sqliteInt.h */
int iAuxArg /* If WHERE_ONETABLE_ONLY is set, index cursor number,
** If WHERE_USE_LIMIT, then the limit amount */
Parse *pParse, /* The parser context */
SrcList *pTabList, /* FROM clause: A list of all tables to be scanned */
Expr *pWhere, /* The WHERE clause */
ExprList *pOrderBy, /* An ORDER BY (or GROUP BY) clause, or NULL */
ExprList *pDistinctSet, /* Try not to output two rows that duplicate these */
u16 wctrlFlags, /* The WHERE_* flags defined in sqliteInt.h */
int iAuxArg /* If WHERE_ONETABLE_ONLY is set, index cursor number
** If WHERE_USE_LIMIT, then the limit amount */
){
int nByteWInfo; /* Num. bytes allocated for WhereInfo struct */
int nTabList; /* Number of elements in pTabList */
@@ -4169,7 +4180,7 @@ WhereInfo *sqlite3WhereBegin(
pWInfo->pParse = pParse;
pWInfo->pTabList = pTabList;
pWInfo->pOrderBy = pOrderBy;
pWInfo->pResultSet = pResultSet;
pWInfo->pDistinctSet = pDistinctSet;
pWInfo->iBreak = pWInfo->iContinue = sqlite3VdbeMakeLabel(v);
pWInfo->wctrlFlags = wctrlFlags;
pWInfo->iLimit = iAuxArg;
@@ -4242,13 +4253,13 @@ WhereInfo *sqlite3WhereBegin(
if( db->mallocFailed ) goto whereBeginError;
if( wctrlFlags & WHERE_WANT_DISTINCT ){
if( isDistinctRedundant(pParse, pTabList, &pWInfo->sWC, pResultSet) ){
if( isDistinctRedundant(pParse, pTabList, &pWInfo->sWC, pDistinctSet) ){
/* The DISTINCT marking is pointless. Ignore it. */
pWInfo->eDistinct = WHERE_DISTINCT_UNIQUE;
}else if( pOrderBy==0 ){
/* Try to ORDER BY the result set to make distinct processing easier */
pWInfo->wctrlFlags |= WHERE_DISTINCTBY;
pWInfo->pOrderBy = pResultSet;
pWInfo->pOrderBy = pDistinctSet;
}
}
@@ -4327,10 +4338,10 @@ WhereInfo *sqlite3WhereBegin(
#endif
/* Attempt to omit tables from the join that do not effect the result */
if( pWInfo->nLevel>=2
&& pResultSet!=0
&& pDistinctSet!=0
&& OptimizationEnabled(db, SQLITE_OmitNoopJoin)
){
Bitmask tabUsed = sqlite3WhereExprListUsage(pMaskSet, pResultSet);
Bitmask tabUsed = sqlite3WhereExprListUsage(pMaskSet, pDistinctSet);
if( sWLB.pOrderBy ){
tabUsed |= sqlite3WhereExprListUsage(pMaskSet, sWLB.pOrderBy);
}
+9 -1
View File
@@ -408,7 +408,7 @@ struct WhereInfo {
Parse *pParse; /* Parsing and code generating context */
SrcList *pTabList; /* List of tables in the join */
ExprList *pOrderBy; /* The ORDER BY clause or NULL */
ExprList *pResultSet; /* Result set. DISTINCT operates on these */
ExprList *pDistinctSet; /* DISTINCT over all these values */
WhereLoop *pLoops; /* List of all WhereLoop objects */
Bitmask revMask; /* Mask of ORDER BY terms that need reversing */
LogEst nRowOut; /* Estimated number of output rows */
@@ -492,6 +492,14 @@ void sqlite3WhereTabFuncArgs(Parse*, struct SrcList_item*, WhereClause*);
** operators that are of interest to the query planner. An
** OR-ed combination of these values can be used when searching for
** particular WhereTerms within a WhereClause.
**
** Value constraints:
** WO_EQ == SQLITE_INDEX_CONSTRAINT_EQ
** WO_LT == SQLITE_INDEX_CONSTRAINT_LT
** WO_LE == SQLITE_INDEX_CONSTRAINT_LE
** WO_GT == SQLITE_INDEX_CONSTRAINT_GT
** WO_GE == SQLITE_INDEX_CONSTRAINT_GE
** WO_MATCH == SQLITE_INDEX_CONSTRAINT_MATCH
*/
#define WO_IN 0x0001
#define WO_EQ 0x0002
+7 -1
View File
@@ -941,7 +941,13 @@ Bitmask sqlite3WhereCodeOneLoopStart(
}
}
}
sqlite3ReleaseTempRange(pParse, iReg, nConstraint+2);
/* These registers need to be preserved in case there is an IN operator
** loop. So we could deallocate the registers here (and potentially
** reuse them later) if (pLoop->wsFlags & WHERE_IN_ABLE)==0. But it seems
** simpler and safer to simply not reuse the registers.
**
** sqlite3ReleaseTempRange(pParse, iReg, nConstraint+2);
*/
sqlite3ExprCachePop(pParse);
}else
#endif /* SQLITE_OMIT_VIRTUALTABLE */
+2 -2
View File
@@ -1282,10 +1282,10 @@ Bitmask sqlite3WhereExprUsage(WhereMaskSet *pMaskSet, Expr *p){
return mask;
}
mask = sqlite3WhereExprUsage(pMaskSet, p->pRight);
mask |= sqlite3WhereExprUsage(pMaskSet, p->pLeft);
if( p->pLeft ) mask |= sqlite3WhereExprUsage(pMaskSet, p->pLeft);
if( ExprHasProperty(p, EP_xIsSelect) ){
mask |= exprSelectUsage(pMaskSet, p->x.pSelect);
}else{
}else if( p->x.pList ){
mask |= sqlite3WhereExprListUsage(pMaskSet, p->x.pList);
}
return mask;
+47 -2
View File
@@ -2432,8 +2432,53 @@ do_test auth-6.3 {
execsql {SELECT rowid, * FROM t6}
} {101 1 2 3 4 5 6 7 8}
#-------------------------------------------------------------------------
# Test that view names are included as zArg4.
#
do_execsql_test auth-7.1 {
CREATE TABLE t7(a, b, c);
CREATE VIEW v7 AS SELECT * FROM t7;
} {}
set ::authargs [list]
proc auth {args} {
eval lappend ::authargs [lrange $args 0 4]
return SQLITE_OK
}
do_test auth-7.2 {
execsql {SELECT a, c FROM v7}
set ::authargs
} [list \
SQLITE_SELECT {} {} {} {} \
SQLITE_READ t7 a main v7 \
SQLITE_READ t7 b main v7 \
SQLITE_READ t7 c main v7 \
SQLITE_READ v7 a main {} \
SQLITE_READ v7 c main {} \
SQLITE_SELECT {} {} {} v7 \
]
set ::authargs [list]
do_test auth-7.3 {
execsql {SELECT a, c FROM t7}
set ::authargs
} [list \
SQLITE_SELECT {} {} {} {} \
SQLITE_READ t7 a main {} \
SQLITE_READ t7 c main {} \
]
set ::authargs [list]
do_test auth-7.4 {
execsql {SELECT a, c FROM t7 AS v7}
set ::authargs
} [list \
SQLITE_SELECT {} {} {} {} \
SQLITE_READ t7 a main {} \
SQLITE_READ t7 c main {} \
]
rename proc {}
rename proc_real proc
finish_test
+107
View File
@@ -165,4 +165,111 @@ foreach {tn mode} {
} $plan($mode)
}
# 2016-04-09.
# Demonstrate a register overwrite problem when using two virtual
# tables where the outer loop uses the IN operator.
#
set G(collist) [list PrimaryKey flagA columnA]
set G(cols) [join $G(collist) ,]
set G(nulls) "NULL"
proc vtab_command {method args} {
global G
switch -- $method {
xConnect {
return "CREATE TABLE t1($G(cols))"
}
xBestIndex {
set clist [lindex $args 0]
#puts $clist
set W [list]
set U [list]
set i 0
for {set idx 0} {$idx < [llength $clist]} {incr idx} {
array set c [lindex $clist $idx]
if {$c(op)=="eq" && $c(usable)} {
lappend W "[lindex $G(collist) $c(column)] = %$i%"
lappend U use $idx
incr i
}
}
if {$W==""} {
set sql "SELECT rowid, * FROM t1"
} else {
set sql "SELECT rowid, * FROM t1 WHERE [join $W { AND }]"
}
return [concat [list idxstr $sql] $U]
}
xFilter {
foreach {idxnum idxstr vals} $args {}
set map [list]
for {set i 0} {$i < [llength $vals]} {incr i} {
lappend map "%$i%"
set v [lindex $vals $i]
if {[string is integer $v]} {
lappend map $v
} else {
lappend map "'$v'"
}
}
set sql [string map $map $idxstr]
#puts "SQL: $sql"
return [list sql $sql]
}
}
return {}
}
db close
forcedelete test.db
sqlite3 db test.db
register_tcl_module db
do_execsql_test 3.1 "
CREATE TABLE t1($G(cols));
INSERT INTO t1 VALUES(1, 0, 'ValueA');
INSERT INTO t1 VALUES(2, 0, 'ValueA');
INSERT INTO t1 VALUES(3, 0, 'ValueB');
INSERT INTO t1 VALUES(4, 0, 'ValueB');
"
do_execsql_test 3.2 {
CREATE VIRTUAL TABLE VirtualTableA USING tcl(vtab_command);
CREATE VIRTUAL TABLE VirtualTableB USING tcl(vtab_command);
}
do_execsql_test 3.3 { SELECT primarykey FROM VirtualTableA } {1 2 3 4}
do_execsql_test 3.4 {
SELECT * FROM
VirtualTableA a CROSS JOIN VirtualTableB b ON b.PrimaryKey=a.PrimaryKey
WHERE a.ColumnA IN ('ValueA', 'ValueB') AND a.FlagA=0
} {
1 0 ValueA 1 0 ValueA
2 0 ValueA 2 0 ValueA
3 0 ValueB 3 0 ValueB
4 0 ValueB 4 0 ValueB
}
do_execsql_test 3.5 {
SELECT * FROM
VirtualTableA a CROSS JOIN VirtualTableB b ON b.PrimaryKey=a.PrimaryKey
WHERE a.FlagA=0 AND a.ColumnA IN ('ValueA', 'ValueB')
} {
1 0 ValueA 1 0 ValueA
2 0 ValueA 2 0 ValueA
3 0 ValueB 3 0 ValueB
4 0 ValueB 4 0 ValueB
}
finish_test
+1 -1
View File
@@ -86,7 +86,7 @@ do_test 2.3 { db_write db 1 } {0 4 0}
do_test 2.4 { db_write db 0 } {0 0 0}
do_test 2.5 { db_write db 1 } {0 0 0}
ifcapable wal {
if {[wal_is_capable]} {
do_test 2.6 {
execsql { PRAGMA journal_mode = WAL }
db_write db 1
+21 -2
View File
@@ -139,7 +139,26 @@ do_execsql_test 4.12 {
PRAGMA integrity_check;
} {ok}
# 2016-04-09
# Ticket https://sqlite.org/src/info/a306e56ff68b8fa5
# Failure to completely delete when reverse_unordered_selects is
# engaged.
#
db close
forcedelete test.db
sqlite3 db test.db
do_execsql_test 5.0 {
PRAGMA page_size=1024;
CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c);
CREATE INDEX x1 ON t1(b, c);
INSERT INTO t1(a,b,c) VALUES(1, 1, zeroblob(80));
INSERT INTO t1(a,b,c) SELECT a+1, 1, c FROM t1;
INSERT INTO t1(a,b,c) SELECT a+2, 1, c FROM t1;
INSERT INTO t1(a,b,c) SELECT a+10, 2, c FROM t1 WHERE b=1;
INSERT INTO t1(a,b,c) SELECT a+20, 3, c FROM t1 WHERE b=1;
PRAGMA reverse_unordered_selects = ON;
DELETE FROM t1 WHERE b=2;
SELECT a FROM t1 WHERE b=2;
} {}
finish_test
+1 -1
View File
@@ -176,7 +176,7 @@ if {![nonzero_reserved_bytes]} {
# EVIDENCE-OF: R-48521-51450 When in write-ahead log mode, only the
# auto_vacuum support property can be changed using VACUUM.
#
ifcapable wal {
if {[wal_is_capable]} {
do_test e_vacuum-1.3.3.1 {
execsql { PRAGMA journal_mode = wal }
execsql { PRAGMA page_size ; PRAGMA auto_vacuum }
+1
View File
@@ -19,6 +19,7 @@ source $testdir/lock_common.tcl
foreach jm {rollback wal} {
if {![wal_is_capable] && $jm=="wal"} continue
set testprefix exists-$jm
+1 -1
View File
@@ -704,7 +704,7 @@ do_execsql_test 7.5.2.0 {
ALTER TABLE t8 ADD COLUMN c DEFAULT 'xxx';
}
ifcapable !session {
if 0 {
# At time of writing, these two are broken. They demonstrate that the
# sqlite3_preupdate_old() method does not handle the case where ALTER TABLE
# has been used to add a column with a default value other than NULL.
+1 -1
View File
@@ -134,7 +134,7 @@ do_test incrvacuum2-3.2 {
integrity_check incrvacuum2-3.3
ifcapable wal {
if {[wal_is_capable]} {
# At one point, when a specific page was being extracted from the b-tree
# free-list (e.g. during an incremental-vacuum), all trunk pages that
# occurred before the specific page in the free-list trunk were being
+11
View File
@@ -604,5 +604,16 @@ do_test intpkey-15.7 {
}
} {}
# 2016-04-18 ticket https://www.sqlite.org/src/tktview/7d7525cb01b68712495d3a
# Be sure to escape quoted typenames.
#
do_execsql_test intpkey-16.0 {
CREATE TABLE t16a(id "INTEGER" PRIMARY KEY AUTOINCREMENT, b [TEXT], c `INT`);
} {}
do_execsql_test intpkey-16.1 {
PRAGMA table_info=t16a;
} {0 id INTEGER 0 {} 1 1 b TEXT 0 {} 0 2 c INT 0 {} 0}
finish_test
+1 -1
View File
@@ -204,7 +204,7 @@ db close
# delete the journal file when committing the transaction that switches
# the system to WAL mode.
#
ifcapable wal {
if {[wal_is_capable]} {
do_test journal2-2.1 {
faultsim_delete_and_reopen
set ::oplog [list]
+11 -1
View File
@@ -111,7 +111,7 @@ do_test loadext-1.2 {
#
do_test loadext-1.3 {
sqlite3 db2 test.db
sqlite3_enable_load_extension db2 1
sqlite3_db_config db2 SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION 1
catchsql {
SELECT half(1.0);
} db2
@@ -256,6 +256,7 @@ do_test loadext-4.2 {
}
} {0 {{}}}
# disable all extension loading
do_test loadext-4.3 {
sqlite3_enable_load_extension db 0
catchsql {
@@ -263,6 +264,15 @@ do_test loadext-4.3 {
}
} {1 {not authorized}}
# enable C-api extension loading only. Show that the SQL function
# still does not work.
do_test loadext-4.4 {
sqlite3_db_config db SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION 1
catchsql {
SELECT load_extension($::testextension,'testloadext_init')
}
} {1 {not authorized}}
source $testdir/malloc_common.tcl
+6 -6
View File
@@ -728,7 +728,7 @@ test_suite "inmemory_journal" -description {
ioerr.test ioerr2.test ioerr3.test ioerr4.test ioerr5.test
vacuum3.test incrblob_err.test diskfull.test backup_ioerr.test
e_fts3.test fts3cov.test fts3malloc.test fts3rnd.test
fts3snippet.test mmapfault.test
fts3snippet.test mmapfault.test sessionfault.test sessionfault2.test
# Exclude test scripts that use tcl IO to access journal files or count
# the number of fsync() calls.
@@ -942,7 +942,9 @@ test_suite "journaltest" -description {
unregister_jt_vfs
} -files [test_set $::allquicktests -exclude {
wal* incrvacuum.test ioerr.test corrupt4.test io.test crash8.test
async4.test bigfile.test backcompat.test
async4.test bigfile.test backcompat.test e_wal* fstat.test mmap2.test
pager1.test syscall.test tkt3457.test *malloc* mmap* multiplex* nolock*
pager2.test *fault* rowal* snapshot* superlock* symlink.test
}]
if {[info commands register_demovfs] != ""} {
@@ -1050,15 +1052,13 @@ proc run_tests {name args} {
set ::G(isquick) 1
set ::G(perm:dbconfig) $options(-dbconfig)
uplevel $options(-initialize)
foreach file [lsort $options(-files)] {
uplevel $options(-initialize)
if {[file tail $file] == $file} { set file [file join $::testdir $file] }
slave_test_file $file
uplevel $options(-shutdown)
}
uplevel $options(-shutdown)
unset ::G(perm:name)
unset ::G(perm:prefix)
unset ::G(perm:presql)
+2 -2
View File
@@ -628,10 +628,10 @@ ifcapable tempdb&&attach {
}
do_test pragma-6.2 {
execsql {
CREATE TABLE t2(a,b,c);
CREATE TABLE t2(a TYPE_X, b [TYPE_Y], c "TYPE_Z");
pragma table_info(t2)
}
} {0 a {} 0 {} 0 1 b {} 0 {} 0 2 c {} 0 {} 0}
} {0 a TYPE_X 0 {} 0 1 b TYPE_Y 0 {} 0 2 c TYPE_Z 0 {} 0}
do_test pragma-6.2.1 {
execsql {
pragma table_info;
+1 -1
View File
@@ -221,7 +221,7 @@ ifcapable shared_cache {
# This will not work with the in-memory journal permutation, as opening
# [db2] switches the journal mode back to "memory"
#
ifcapable wal {
if {[wal_is_capable]} {
if {[permutation]!="inmemory_journal"} {
sqlite3 db test.db
+2
View File
@@ -527,4 +527,6 @@ do_faultsim_test quota-5.6 -prep {
}
catch { sqlite3_quota_shutdown }
catch { db close }
forcedelete test.db
finish_test
+34
View File
@@ -95,4 +95,38 @@ do_test savepoint7-2.2 {
list $rc $msg [db eval {SELECT * FROM t2}]
} {1 {abort due to ROLLBACK} {}}
# Ticket: https://www.sqlite.org/src/tktview/7f7f8026eda387d544b
# Segfault in the in-memory journal logic triggered by a tricky
# combination of SAVEPOINT operations.
#
unset -nocomplain i
for {set i 248} {$i<=253} {incr i} {
do_test savepoint7-3.$i {
db close
forcedelete test.db
sqlite3 db test.db
db eval {
PRAGMA page_size=1024;
PRAGMA temp_store=MEMORY;
BEGIN;
CREATE TABLE t1(x INTEGER PRIMARY KEY, y TEXT);
WITH RECURSIVE c(x) AS (VALUES(1) UNION SELECT x+1 FROM c WHERE x<$::i)
INSERT INTO t1(x,y) SELECT x*10, printf('%04d%.800c',x,'*') FROM c;
SAVEPOINT one;
SELECT count(*) FROM t1;
WITH RECURSIVE c(x) AS (VALUES(1) UNION SELECT x+1 FROM c WHERE x<$::i)
INSERT INTO t1(x,y) SELECT x*10+1, printf('%04d%.800c',x,'*') FROM c;
ROLLBACK TO one;
SELECT count(*) FROM t1;
SAVEPOINT twoB;
WITH RECURSIVE c(x) AS (VALUES(1) UNION SELECT x+1 FROM c WHERE x<10)
INSERT INTO t1(x,y) SELECT x*10+2, printf('%04d%.800c',x,'*') FROM c;
ROLLBACK TO twoB;
RELEASE one;
COMMIT;
}
} [list $i $i]
}
finish_test
+36
View File
@@ -968,6 +968,42 @@ do_execsql_test select4-16.3 {
ORDER BY t3.a;
} {95 96 97 98 99}
# Ticket https://www.sqlite.org/src/tktview/f7f8c97e975978d45 on 2016-04-25
#
# The where push-down optimization from 2015-06-02 is suppose to disable
# on aggregate subqueries. But if the subquery is a compound where the
# last SELECT is non-aggregate but some other SELECT is an aggregate, the
# test is incomplete and the optimization is not properly disabled.
#
# The following test cases verify that the fix works.
#
do_execsql_test select4-17.1 {
DROP TABLE IF EXISTS t1;
CREATE TABLE t1(a int, b int);
INSERT INTO t1 VALUES(1,2),(1,18),(2,19);
SELECT x, y FROM (
SELECT 98 AS x, 99 AS y
UNION
SELECT a AS x, sum(b) AS y FROM t1 GROUP BY a
) AS w WHERE y>=20
ORDER BY +x;
} {1 20 98 99}
do_execsql_test select4-17.2 {
SELECT x, y FROM (
SELECT a AS x, sum(b) AS y FROM t1 GROUP BY a
UNION
SELECT 98 AS x, 99 AS y
) AS w WHERE y>=20
ORDER BY +x;
} {1 20 98 99}
do_catchsql_test select4-17.3 {
SELECT x, y FROM (
SELECT a AS x, sum(b) AS y FROM t1 GROUP BY a LIMIT 3
UNION
SELECT 98 AS x, 99 AS y
) AS w WHERE y>=20
ORDER BY +x;
} {1 {LIMIT clause should come after UNION not before}}
+58 -16
View File
@@ -76,20 +76,20 @@ do_test shell1-1.3.3 {
# -echo print commands before execution
do_test shell1-1.4.1 {
catchcmd "-echo test.db" ""
catchcmd "-echo test.db" ""
} {0 {}}
# -[no]header turn headers on or off
do_test shell1-1.5.1 {
catchcmd "-header test.db" ""
catchcmd "-header test.db" ""
} {0 {}}
do_test shell1-1.5.2 {
catchcmd "-noheader test.db" ""
catchcmd "-noheader test.db" ""
} {0 {}}
# -bail stop after hitting an error
do_test shell1-1.6.1 {
catchcmd "-bail test.db" ""
catchcmd "-bail test.db" ""
} {0 {}}
# -interactive force interactive I/O
@@ -103,40 +103,40 @@ do_test shell1-1.7.1 {
# -batch force batch I/O
do_test shell1-1.8.1 {
catchcmd "-batch test.db" ""
catchcmd "-batch test.db" ""
} {0 {}}
# -column set output mode to 'column'
do_test shell1-1.9.1 {
catchcmd "-column test.db" ""
catchcmd "-column test.db" ""
} {0 {}}
# -csv set output mode to 'csv'
do_test shell1-1.10.1 {
catchcmd "-csv test.db" ""
catchcmd "-csv test.db" ""
} {0 {}}
# -html set output mode to HTML
do_test shell1-1.11.1 {
catchcmd "-html test.db" ""
catchcmd "-html test.db" ""
} {0 {}}
# -line set output mode to 'line'
do_test shell1-1.12.1 {
catchcmd "-line test.db" ""
catchcmd "-line test.db" ""
} {0 {}}
# -list set output mode to 'list'
do_test shell1-1.13.1 {
catchcmd "-list test.db" ""
catchcmd "-list test.db" ""
} {0 {}}
# -separator 'x' set output field separator (|)
do_test shell1-1.14.1 {
catchcmd "-separator 'x' test.db" ""
catchcmd "-separator 'x' test.db" ""
} {0 {}}
do_test shell1-1.14.2 {
catchcmd "-separator x test.db" ""
catchcmd "-separator x test.db" ""
} {0 {}}
do_test shell1-1.14.3 {
set res [catchcmd "-separator" ""]
@@ -147,7 +147,7 @@ do_test shell1-1.14.3 {
# -stats print memory stats before each finalize
do_test shell1-1.14b.1 {
catchcmd "-stats test.db" ""
catchcmd "-stats test.db" ""
} {0 {}}
# -nullvalue 'text' set text string for NULL values
@@ -175,7 +175,7 @@ do_test shell1-1.16.1 {
# check first token handling
do_test shell1-2.1.1 {
catchcmd "test.db" ".foo"
catchcmd "test.db" ".foo"
} {1 {Error: unknown command or invalid arguments: "foo". Enter ".help" for help}}
do_test shell1-2.1.2 {
catchcmd "test.db" ".\"foo OFF\""
@@ -568,7 +568,7 @@ do_test shell1-3.21.2 {
do_test shell1-3.21.3 {
# too many arguments
catchcmd "test.db" ".schema FOO BAD"
} {1 {Usage: .schema ?LIKE-PATTERN?}}
} {1 {Usage: .schema ?--indent? ?LIKE-PATTERN?}}
do_test shell1-3.21.4 {
catchcmd "test.db" {
@@ -905,9 +905,51 @@ do_test shell1-5.0 {
error "failed with error: $res"
}
if {$res ne "$oldChar\n"} {
error "failed with byte $hex mismatch"
if {[llength $res] > 0} {
set got [format %02X [scan $res %c]]
} else {
set got <empty>
}
error "failed with byte $hex mismatch, got $got"
}
}
} {}
# The string used here is the word "test" in Chinese.
# In UTF-8, it is encoded as: \xE6\xB5\x8B\xE8\xAF\x95
set test \u6D4B\u8BD5
do_test shell1-6.0 {
set fileName $test; append fileName .db
catch {forcedelete $fileName}
set x [catchcmdex $fileName "CREATE TABLE t1(x);\n.schema\n"]
set code [lindex $x 0]
set res [string trim [lindex $x 1]]
if {$code ne "0"} {
error "failed with error: $res"
}
if {$res ne "CREATE TABLE t1(x);"} {
error "failed with mismatch: $res"
}
if {![file exists $fileName]} {
error "file \"$fileName\" (Unicode) does not exist"
}
forcedelete $fileName
} {}
do_test shell1-6.1 {
catch {forcedelete test3.db}
set x [catchcmdex test3.db \
"CREATE TABLE [encoding convertto utf-8 $test](x);\n.schema\n"]
set code [lindex $x 0]
set res [string trim [lindex $x 1]]
if {$code ne "0"} {
error "failed with error: $res"
}
if {$res ne "CREATE TABLE ${test}(x);"} {
error "failed with mismatch: $res"
}
forcedelete test3.db
} {}
finish_test
+74
View File
@@ -365,4 +365,78 @@ do_test 6.5 {
sqlite3_snapshot_free $snapshot
#-------------------------------------------------------------------------
# The following tests investigate the sqlite3_snapshot_cmp() API.
#
# Compare snapshots $p1 and $p2, checking that the result is $r.
#
proc do_snapshot_cmp_test {tn p1 p2 r} {
uplevel [list do_test $tn.1 [list sqlite3_snapshot_cmp $p1 $p2] $r]
uplevel [list do_test $tn.2 [list sqlite3_snapshot_cmp $p2 $p1] [expr $r*-1]]
uplevel [list do_test $tn.3 [list sqlite3_snapshot_cmp $p1 $p1] 0]
uplevel [list do_test $tn.4 [list sqlite3_snapshot_cmp $p2 $p2] 0]
}
catch { db2 close }
reset_db
do_execsql_test 7.1 {
PRAGMA journal_mode = wal;
CREATE TABLE t1(x);
} wal
do_test 7.1.2 {
execsql { BEGIN ; PRAGMA application_id }
set p1 [sqlite3_snapshot_get db main]
execsql {
INSERT INTO t1 VALUES(10);
COMMIT;
}
execsql { BEGIN ; PRAGMA application_id }
set p2 [sqlite3_snapshot_get db main]
execsql COMMIT
} {}
do_snapshot_cmp_test 7.1.3 $p1 $p2 -1
sqlite3_snapshot_free $p1
sqlite3_snapshot_free $p2
do_execsql_test 7.2.1 {
INSERT INTO t1 VALUES(11);
INSERT INTO t1 VALUES(12);
INSERT INTO t1 VALUES(13);
BEGIN;
PRAGMA application_id;
} {0}
do_test 7.2.2 {
set p1 [sqlite3_snapshot_get db main]
execsql {
COMMIT;
INSERT INTO t1 VALUES(14);
PRAGMA wal_checkpoint;
BEGIN;
PRAGMA application_id;
}
set p2 [sqlite3_snapshot_get db main]
execsql COMMIT
} {}
do_snapshot_cmp_test 7.2.3 $p1 $p2 -1
sqlite3_snapshot_free $p2
do_test 7.3.1 {
execsql {
INSERT INTO t1 VALUES(14);
BEGIN;
PRAGMA application_id;
}
set p2 [sqlite3_snapshot_get db main]
execsql COMMIT
} {}
do_snapshot_cmp_test 7.3.2 $p1 $p2 -1
sqlite3_snapshot_free $p1
sqlite3_snapshot_free $p2
finish_test
+72
View File
@@ -41,4 +41,76 @@ do_execsql_test 1.2 {
db close
tvfs delete
#-------------------------------------------------------------------------
# Test that the PMA size is determined correctly. The PMA size should be
# roughly the same amount of memory allocated to the main pager cache, or
# 250 pages if this is larger.
#
testvfs tvfs
tvfs script tv_callback
tvfs filter {xOpen xWrite}
proc tv_callback {method args} {
global iTemp
global F
switch $method {
xOpen {
if {[lindex $args 0]==""} { return "temp[incr iTemp]" }
return "SQLITE_OK"
}
xWrite {
foreach {filename id off amt} $args {}
if {[info exists F($id)]==0 || $F($id)<($off + $amt)} {
set F($id) [expr $off+$amt]
}
}
}
}
catch { db close }
forcedelete test.db
sqlite3 db test.db -vfs tvfs
execsql { CREATE TABLE t1(x) }
# Each iteration of the following loop attempts to sort 10001 records
# each a bit over 100 bytes in size. In total a little more than 1MiB
# of data.
#
breakpoint
foreach {tn pgsz cachesz bTemp} {
2 1024 1000 1
1 4096 1000 0
2 1024 1000 1
3 4096 -1000 1
4 1024 -1000 1
5 4096 -9000 0
6 1024 -9000 0
} {
do_execsql_test 2.$tn.0 "
PRAGMA page_size = $pgsz;
VACUUM;
PRAGMA cache_size = $cachesz;
"
do_test 2.$tn.1 {
set ::iTemp 0
catch { array unset F }
execsql {
WITH x(i, j) AS (
SELECT 1, randomblob(100)
UNION ALL
SELECT i+1, randomblob(100) FROM x WHERE i<10000
)
SELECT * FROM x ORDER BY j;
}
expr {[array names F]!=""}
} $bTemp
}
finish_test
+27 -14
View File
@@ -30,6 +30,7 @@ static const char zHelp[] =
" --shrink-memory Invoke sqlite3_db_release_memory() frequently.\n"
" --size N Relative test size. Default=100\n"
" --stats Show statistics at the end\n"
" --temp N N from 0 to 9. 0: no temp table. 9: all temp tables\n"
" --testset T Run test-set T\n"
" --trace Turn on SQL tracing\n"
" --threads N Use up to N threads for sorting\n"
@@ -69,6 +70,7 @@ static struct Global {
int bExplain; /* Print SQL with EXPLAIN prefix */
int bVerify; /* Try to verify that results are correct */
int bMemShrink; /* Call sqlite3_db_release_memory() often */
int eTemp; /* 0: no TEMP. 9: always TEMP. */
int szTest; /* Scale factor for test iterations */
const char *zWR; /* Might be WITHOUT ROWID */
const char *zNN; /* Might be NOT NULL */
@@ -78,6 +80,12 @@ static struct Global {
char zResult[3000]; /* Text of the current result */
} g;
/* Return " TEMP" or "", as appropriate for creating a table.
*/
static const char *isTemp(int N){
return g.eTemp>=N ? " TEMP" : "";
}
/* Print an error message and exit */
static void fatal_error(const char *zMsg, ...){
@@ -459,8 +467,8 @@ void testset_main(void){
maxb = roundup_allones(sz);
speedtest1_begin_test(100, "%d INSERTs into table with no index", n);
speedtest1_exec("BEGIN");
speedtest1_exec("CREATE TABLE t1(a INTEGER %s, b INTEGER %s, c TEXT %s);",
g.zNN, g.zNN, g.zNN);
speedtest1_exec("CREATE%s TABLE t1(a INTEGER %s, b INTEGER %s, c TEXT %s);",
isTemp(9), g.zNN, g.zNN, g.zNN);
speedtest1_prepare("INSERT INTO t1 VALUES(?1,?2,?3); -- %d times", n);
for(i=1; i<=n; i++){
x1 = swizzle(i,maxb);
@@ -477,8 +485,9 @@ void testset_main(void){
n = sz;
speedtest1_begin_test(110, "%d ordered INSERTS with one index/PK", n);
speedtest1_exec("BEGIN");
speedtest1_exec("CREATE TABLE t2(a INTEGER %s %s, b INTEGER %s, c TEXT %s) %s",
g.zNN, g.zPK, g.zNN, g.zNN, g.zWR);
speedtest1_exec(
"CREATE%s TABLE t2(a INTEGER %s %s, b INTEGER %s, c TEXT %s) %s",
isTemp(5), g.zNN, g.zPK, g.zNN, g.zNN, g.zWR);
speedtest1_prepare("INSERT INTO t2 VALUES(?1,?2,?3); -- %d times", n);
for(i=1; i<=n; i++){
x1 = swizzle(i,maxb);
@@ -495,8 +504,9 @@ void testset_main(void){
n = sz;
speedtest1_begin_test(120, "%d unordered INSERTS with one index/PK", n);
speedtest1_exec("BEGIN");
speedtest1_exec("CREATE TABLE t3(a INTEGER %s %s, b INTEGER %s, c TEXT %s) %s",
g.zNN, g.zPK, g.zNN, g.zNN, g.zWR);
speedtest1_exec(
"CREATE%s TABLE t3(a INTEGER %s %s, b INTEGER %s, c TEXT %s) %s",
isTemp(3), g.zNN, g.zPK, g.zNN, g.zNN, g.zWR);
speedtest1_prepare("INSERT INTO t3 VALUES(?1,?2,?3); -- %d times", n);
for(i=1; i<=n; i++){
x1 = swizzle(i,maxb);
@@ -654,12 +664,12 @@ void testset_main(void){
speedtest1_begin_test(180, "%d INSERTS with three indexes", n);
speedtest1_exec("BEGIN");
speedtest1_exec(
"CREATE TABLE t4(\n"
"CREATE%s TABLE t4(\n"
" a INTEGER %s %s,\n"
" b INTEGER %s,\n"
" c TEXT %s\n"
") %s",
g.zNN, g.zPK, g.zNN, g.zNN, g.zWR);
isTemp(1), g.zNN, g.zPK, g.zNN, g.zNN, g.zWR);
speedtest1_exec("CREATE INDEX t4b ON t4(b)");
speedtest1_exec("CREATE INDEX t4c ON t4(c)");
speedtest1_exec("INSERT INTO t4 SELECT * FROM t1");
@@ -1047,7 +1057,7 @@ void testset_rtree(int p1, int p2){
speedtest1_end_test();
speedtest1_begin_test(101, "Copy from rtree to a regular table");
speedtest1_exec("CREATE TABLE t1(id INTEGER PRIMARY KEY,x0,x1,y0,y1,z0,z1)");
speedtest1_exec(" TABLE t1(id INTEGER PRIMARY KEY,x0,x1,y0,y1,z0,z1)");
speedtest1_exec("INSERT INTO t1 SELECT * FROM rt1");
speedtest1_end_test();
@@ -1321,6 +1331,13 @@ int main(int argc, char **argv){
g.szTest = integerValue(argv[++i]);
}else if( strcmp(z,"stats")==0 ){
showStats = 1;
}else if( strcmp(z,"temp")==0 ){
if( i>=argc-1 ) fatal_error("missing argument on %s\n", argv[i]);
i++;
if( argv[i][0]<'0' || argv[i][0]>'9' || argv[i][1]!=0 ){
fatal_error("argument to --temp should be integer between 0 and 9");
}
g.eTemp = argv[i][0] - '0';
}else if( strcmp(z,"testset")==0 ){
if( i>=argc-1 ) fatal_error("missing argument on %s\n", argv[i]);
zTSet = argv[++i];
@@ -1352,11 +1369,7 @@ int main(int argc, char **argv){
argv[i], argv[0]);
}
}
#if 0
if( zDbName==0 ){
fatal_error(zHelp, argv[0]);
}
#endif
if( zDbName!=0 ) unlink(zDbName);
#if SQLITE_VERSION_NUMBER>=3006001
if( nHeap>0 ){
pHeap = malloc( nHeap );
+1 -1
View File
@@ -37,7 +37,7 @@ do_execsql_test stat-0.0 {
SELECT * FROM stat;
} {}
ifcapable wal {
if {[wal_is_capable]} {
do_execsql_test stat-0.1 {
PRAGMA journal_mode = WAL;
PRAGMA journal_mode = delete;
+2
View File
@@ -81,6 +81,7 @@ do_test sync-1.3 {
set sqlite_sync_count
} 11
ifcapable pager_pragmas {
if {[permutation]!="journaltest"} {
do_test sync-1.4 {
set sqlite_sync_count 0
execsql {
@@ -94,6 +95,7 @@ ifcapable pager_pragmas {
set sqlite_sync_count
} 0
}
}
finish_test
+6
View File
@@ -1944,6 +1944,12 @@ proc wal_check_journal_mode {testname {db db}} {
}
}
proc wal_is_capable {} {
ifcapable !wal { return 0 }
if {[permutation]=="journaltest"} { return 0 }
return 1
}
proc permutation {} {
set perm ""
catch {set perm $::G(perm:name)}
+2 -1
View File
@@ -19,7 +19,8 @@ set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix tkt-2d1a5c67d
ifcapable {!wal || !vtab} {finish_test; return}
ifcapable {!vtab} {finish_test; return}
if {[wal_is_capable]==0} {finish_test; return}
for {set ii 1} {$ii<=10} {incr ii} {
do_test tkt-2d1a5c67d.1.$ii {
+1 -1
View File
@@ -18,7 +18,7 @@ set testdir [file dirname $argv0]
source $testdir/tester.tcl
source $testdir/malloc_common.tcl
ifcapable !wal { finish_test ; return }
if {![wal_is_capable]} { finish_test ; return }
do_execsql_test tkt-313723c356.1 {
PRAGMA page_size = 1024;
+1 -1
View File
@@ -18,7 +18,7 @@ set testdir [file dirname $argv0]
source $testdir/tester.tcl
source $testdir/lock_common.tcl
set ::testprefix tkt-5d863f876e
ifcapable !wal {finish_test ; return }
if {![wal_is_capable]} {finish_test ; return }
do_multiclient_test tn {
do_test $tn.1 {
+2
View File
@@ -50,4 +50,6 @@ for {set i 0} {$i < 100} {incr i} {
} {ok}
}
catch { db close }
unregister_devsim
finish_test
+20
View File
@@ -92,6 +92,26 @@ do_test view-1.8 {
}
} {2 3 5 6 8 9}
do_execsql_test view-1.10 {
CREATE TABLE t9(x INTEGER);
CREATE VIEW v9a AS SELECT x FROM t9;
CREATE VIEW v9b AS SELECT * FROM t9;
CREATE VIEW v9c(x) AS SELECT x FROM t9;
CREATE VIEW v9d(x) AS SELECT * FROM t9;
} {}
do_execsql_test view-1.11 {
PRAGMA table_info(v9a);
} {0 x INTEGER 0 {} 0}
do_execsql_test view-1.12 {
PRAGMA table_info(v9b);
} {0 x INTEGER 0 {} 0}
do_execsql_test view-1.13 {
PRAGMA table_info(v9c);
} {0 x INTEGER 0 {} 0}
do_execsql_test view-1.14 {
PRAGMA table_info(v9d);
} {0 x INTEGER 0 {} 0}
do_test view-2.1 {
execsql {
CREATE VIEW v2 AS SELECT * FROM t1 WHERE a>5
+1 -1
View File
@@ -89,7 +89,7 @@ do_test zerodamage-2.1 {
concat [file_control_powersafe_overwrite db -1] [set ::max_journal_size]
} {0 0 24704}
ifcapable wal {
if {[wal_is_capable]} {
# Run a WAL-mode transaction with POWERSAFE_OVERWRITE on to verify that the
# WAL file does not get too big.
#

Some files were not shown because too many files have changed in this diff Show More