Compare commits

..

273 Commits

Author SHA1 Message Date
dan 93c803e960 Fix handling of "UPDATE OR REPLACE" statements run on zipfile virtual tables.
FossilOrigin-Name: 9a5ef341de2bd2fc4657a510f48159f7876f58d340b457b4272a71d389f88da3
2018-03-20 13:26:01 +00:00
dan d30830e42d Add a test case for the fix on this branch.
FossilOrigin-Name: 7834cf6c28c63f6ca0e29a508c0f6e3ec9c5c48715344c2db99a9866e92ef205
2018-03-20 12:12:06 +00:00
mistachkin 2cc8f4831e For 'zipfile', detect attempts to cause a duplicate entry via UPDATE.
FossilOrigin-Name: cf78a882799424610209e9ac5e76771db3f5e6704ffa181f9598eb0986d93eb8
2018-03-17 02:13:13 +00:00
mistachkin d42d8ae337 Another Win32 portability fix for the 'zipfile' tests.
FossilOrigin-Name: 9f604418ca21472d84d754f4c3b7f170e5c2bff05e8cee86640e45b43bc53a49
2018-03-17 00:44:29 +00:00
mistachkin 42a0dbfe92 Win32 portability fixes to the 'fileio' extension.
FossilOrigin-Name: 9d2b0f8b84aac862b0572b183e3ba53ea8c0d8742aaa3c3fbe59f6036054fd1a
2018-03-16 23:54:36 +00:00
mistachkin b5a4a7053b Enable more 'zipfile' tests on Win32.
FossilOrigin-Name: 49d2566c8e7d0df37494ee001fc6eae5f47f95e16f6a575f2d8d6777b62e6068
2018-03-16 23:54:26 +00:00
mistachkin 3c6de3266e Make a couple tests less sensitive to timing.
FossilOrigin-Name: bc2af8e0aa28d8d10612ab9464c008a970348b4720bb34d0c546d341e2bc09e0
2018-03-16 23:54:12 +00:00
mistachkin 2d44d556b5 Fix a duplicate test number and cleanup a bit of Makefile whitespace.
FossilOrigin-Name: 56d11c250961790579a7aeee65e83fdb29462ae37f9de93da13fbd890fc0a01d
2018-03-16 23:53:47 +00:00
drh 86c369428f Detect databases whose schema is corrupted using a CREATE TABLE AS statement
and issue an appropriate error message.

FossilOrigin-Name: d75e67654aa9620b9617786553a002f54e8c6dcbbcc58948a06bd98a0916d75a
2018-03-16 20:23:01 +00:00
drh 1e9c47be1e Better error message text when the schema is corrupted by a CREATE TABLE AS
entry.

FossilOrigin-Name: e13993cf833423eec5f94082cee7213b2d97bcf40dddb2683cf5a8ebf50a33e3
2018-03-16 20:15:58 +00:00
mistachkin 8bbddd8049 Fix a parsing issue associated with a corrupt sqlite_master table.
FossilOrigin-Name: 5f779ff6b48ec97efacd49b1715b7e5272694fa839be349c90667812bbffe22b
2018-03-16 19:10:05 +00:00
dan 9f2b04533e Fix a problem in test script thread001.test causing a spurious "-1 files were
left open" error when run separately.

FossilOrigin-Name: 1774f1c3baf0bc3d83a53c52702696ff21814fa1de07cc38fd098832e6757b09
2018-03-16 07:48:43 +00:00
drh b39161647e Fix a typo in a comment used to generate documentation. No code changes.
FossilOrigin-Name: f1784aff4e6ff1c84d3fa0069034290154220fd2fa85c7df342c717ad54f4b91
2018-03-15 17:46:42 +00:00
drh 3571e7bf4c Fix an issue with the fsdir() table-valued function not resetting correctly
after each pass of a join.

FossilOrigin-Name: 7ce4e71c1b7251be9e922b21dfeba1f9aef6a47ce6495ecb7f94fd785ab564f2
2018-03-15 15:09:45 +00:00
mistachkin 093d63bf34 Draft fix for an fsdir() issue reported via the mailing list.
FossilOrigin-Name: 48641010c24bf37f13d68c4d19c5c3e9b41404af12a4947705cc53a31db04178
2018-03-15 05:25:57 +00:00
drh 20a1f35928 Add the SQLITE_DBSTATUS_CACHE_SPILL option to sqlite3_db_status().
FossilOrigin-Name: 48a06eb02b42a021b835ff9766535805723259b9701b87fb17fa488b133cb53a
2018-03-14 15:25:43 +00:00
drh 15ca9e3e8c Disable one of the test cases from check-in [21ecbce1378f3cc4] when
API_ARMOR is not enabled.

FossilOrigin-Name: 8fb23d4281915b4507e4d42a300f4b5f958ad88ad408218659c7459775d7b114
2018-03-14 15:06:42 +00:00
drh ffc78a41ea Add the SQLITE_DBSTATUS_CACHE_SPILL option to sqlite3_db_status()
FossilOrigin-Name: 3faeb851374471a6f94a6fab3a62c73d03330eae6fc72cd1a277b03ad12dcdd0
2018-03-14 14:53:50 +00:00
dan 68cf69ed8d Improve detection of out-of-range parameters in sqlite3_stmt_status() for
SQLITE_ENABLE_API_ARMOR builds.

FossilOrigin-Name: 21ecbce1378f3cc4b1051628b8c1580bb807c8745a1f525bc089036af93a54af
2018-03-14 08:27:39 +00:00
dan 58db4c760f Fix a typo causing SQLITE_LOG_CACHE_SPILL builds to fail.
FossilOrigin-Name: 0171d4a71ca7911a9fd409a42eeed0eda4521b6e48df5cd058364c0a736313b7
2018-03-12 21:09:16 +00:00
mistachkin 840c300f4a Add more tests for the profile output of the Tcl trace_v2 method.
FossilOrigin-Name: 61eeb48f03f8a9a32330a5cae4387bb4e5618078cf669a5831910f99126900ec
2018-03-10 20:45:44 +00:00
drh ffdab721a3 Fix the second callback argument to the "profile" response of the
"trace_v2" method in the TCL interface so that it shows the actual
number of nanoseconds for the command, not the address of the variable
containing the number of nanoseconds.

FossilOrigin-Name: 8f9a12518642e5be9760956ff345fe54ed5bd3cab55328e88312278d3d78bc76
2018-03-10 20:25:08 +00:00
drh 42f3c5ff25 Add support for INSERT OR REPLACE and INSERT OR IGNORE on the zipfile
extension.

FossilOrigin-Name: 8ad35d483e4293d5571eeacc20fd26cdc4064fbee7b63d974879d507a0ee5792
2018-03-10 14:17:01 +00:00
drh 41a6f2cb6d Improved error messages from the zipfile extension.
FossilOrigin-Name: f634a7e386918b829389f20c330d312315fdd61125cd2c5f66cf17a5d74bce49
2018-03-10 13:21:41 +00:00
drh 70acb0aa6b Avoid harmless left-shifts of negative numbers in the zipfile extension
when building ZIP archives of files with pre-DOS dates.

FossilOrigin-Name: 16bba8650cc24a0fd606944422bb31f2b8bdbe0a5a483678989e400b751eab4d
2018-03-10 12:53:20 +00:00
drh ef29f73479 Fix the zipfile extension so that it is able to create symbolic link entries
in the ZIP file even on systems like Win32 that do not support symbolic links
on the native filesystem.

FossilOrigin-Name: 2a4493f4ad2d09c1097e98e7086623669f3f252571884d515e51a98b1c6855e1
2018-03-10 12:34:08 +00:00
drh 69d2d35523 Fix the .archive command in the CLI so that it actually compresses content.
FossilOrigin-Name: 3c2e3c2d3dd5d951099ad8d9f74d3c20dae11dd5615d86a6e2283b28ff5b19aa
2018-03-09 22:18:53 +00:00
drh 1bf208c701 Enhance the ".ar" command in the CLI so that it is able to update and
create ZIP Archives.

FossilOrigin-Name: 9404765ef7487013f01ecf24c0a1f70040cd11e7dbb6378646d15de4e5660a40
2018-03-09 21:54:01 +00:00
drh 393344f928 Setting ".stats 2" in the CLI causes column metadata for each
prepared statement to be displayed.

FossilOrigin-Name: 7fea00fd96a8ab7e65734540edb907b6224659ae95d7e0504755f2610c545587
2018-03-09 16:37:05 +00:00
drh a10b999d14 Simplification to the shell_exec() mechanism in the CLI.
FossilOrigin-Name: 72e8f529ac8a268611f16456b13d55cc6c62df7f1a0aaa78a169338a0d95b960
2018-03-09 15:24:33 +00:00
dan 2d066bbfd8 Fix a problem in test file nockpt.test causing errors with
SQLITE_DEFAULT_AUTOVACUUM builds.

FossilOrigin-Name: e547c83f3eb71175574d4b49a0981b048bf525f57d36a2410d955cf1832bec22
2018-03-09 14:11:36 +00:00
drh 6131adc074 Fix a test case in zipfilefault.test so that it only runs if JSON1 is
available.

FossilOrigin-Name: 072b244790893a699dc49d7a2cead85bed016f8e28d18ae7662fbeb3298cb235
2018-03-09 14:06:11 +00:00
drh 980e2cd39a Attempt to fix a harmless compiler warning from Clang.
FossilOrigin-Name: bba1bfbde62733e14f458bf3b71cb00d4899a4ebae2553d6ed24d48495cdced1
2018-03-09 12:46:34 +00:00
mistachkin 6630f9407c Enable API armor handling for the new deserialize APIs.
FossilOrigin-Name: 0798c91aa9d5d347680a9d80d420224297360e03341365d48aca829cd7c423db
2018-03-08 19:56:52 +00:00
drh 3baed31edc Add the --append and --zip options of the CLI to the --help message.
FossilOrigin-Name: f010c86ecef4a1aaad986fa8ceb8230814d6c909cc28ce19e55d63f592fee9d0
2018-03-08 18:14:41 +00:00
mistachkin 8368692815 Include the 'sessionfuzz' tool in the clean target for MSVC.
FossilOrigin-Name: 0f5a8666b8b479bb6e470590659c1775fb9b0d6a9eee931cb48f98651cd7ffcb
2018-03-08 18:09:22 +00:00
drh 7bdbe301f6 Updates to documentation on sqlite3_serialize() and sqlite3_deserialize().
No changes to code.

FossilOrigin-Name: e71ceb6089695c651aaf1fa8662c5caf771ac9efc2f2e8efa0eddae6a6a389ea
2018-03-08 16:36:23 +00:00
mistachkin f7c8a35b8d Fix harmless compiler warnings in the 'dbdump' tool.
FossilOrigin-Name: 2b9bb2664c56dd3280b4aad05b7f64dd23e5b992b5621a48dbfdb7c358d0f3ae
2018-03-07 21:39:25 +00:00
mistachkin 069720ea8b Fix harmless compiler warning.
FossilOrigin-Name: 706800ba377e4a1f615ee6ab44530742f23e1d1be5b658608ca2fd352b363cb2
2018-03-07 21:29:15 +00:00
mistachkin 98cb7a4894 Enable compilation of 'sessionfuzz' tool using MSVC.
FossilOrigin-Name: c58de43b8f2723d659fc9820caf667e215fdfa9aa2d7337fc82ba5b6f8db2e4c
2018-03-07 21:13:49 +00:00
drh f94c1902b9 Add the sessionfuzz test program and data obtained from a week of running
AFL.  Automatically run this test program on any "make test" on unix.

FossilOrigin-Name: ecaedfe596d4c05546bfd798fdca94aff6a81f55be7b17ddb65fc5547c4b5aa6
2018-03-07 20:48:21 +00:00
mistachkin 391ac1b959 Update the autoconf Makefile for MSVC.
FossilOrigin-Name: 36fec7a4a75006d860aaf3ea6707cea25c5e16f2ac05c21c27fde80f3bfeec63
2018-03-07 15:54:39 +00:00
mistachkin 45fb850b35 Fix various compilation issues seen with MSVC.
FossilOrigin-Name: d6fa938919dbb3fe73ccdd3cbf0e9264d524ed79125f93f977a7d91c425db821
2018-03-07 15:19:22 +00:00
mistachkin b649be3c3b Another tweak to the MSVC clean target.
FossilOrigin-Name: 493abf10bf7b2ea5a4bc430bec786598776f76985ab2d99c7d5117a9a9ff632c
2018-03-07 14:53:36 +00:00
mistachkin 23355215fb Fix harmless compiler warning in FTS5.
FossilOrigin-Name: 2d544711c7e9f4c2c3ca7ee7d588948d048da82e63c82f41c999fce947d6661d
2018-03-07 14:49:32 +00:00
mistachkin ac8ba26ecb Fix utility compilation issues with MSVC.
FossilOrigin-Name: 5bd5a79898790bef150b2bc7f275333444b1a723385e595931377ff4d32190bf
2018-03-07 14:42:17 +00:00
drh b0f0dc3073 Add the sqlite3_serialize() and sqlite3_deserialize() interfaces, enabled
when the -DSQLITE_ENABLE_DESERIALIZE compile-time option is used.

FossilOrigin-Name: fc42d31d6fca21abc5377a463ed800e3066b2f3fbd2d85cb486f402d2ae7cb15
2018-03-07 13:01:54 +00:00
drh 4811a710af Mark an unreachable branch using NEVER().
FossilOrigin-Name: fadbc5e23f93bedd705bdc83cd3781b3821a231034bae5b942c94da77227721c
2018-03-07 01:37:05 +00:00
drh 9c6396ecc7 Improved documentation for sqlite3_serialize() and sqlite3_deserialize().
Change the name of the compile-time option to enable these interfaces
from SQLITE_ENABLE_MEMDB to SQLITE_ENABLE_DESERIALIZE.

FossilOrigin-Name: f07e97aed435b02e1473053c0257ec5c89bf0b3e46076b7a9382de432bbc2497
2018-03-06 21:43:19 +00:00
drh 8784efaea9 Handle some boundary cases in memdb associated with OOM faults.
FossilOrigin-Name: b58ca4cb0c921e81efad527c80b220be120263cfdb04528ae26ecf8b8f66f44a
2018-03-06 20:54:27 +00:00
drh 14714167f7 Simplifications to the memdb VFS.
FossilOrigin-Name: 6c3f723a6856fa38ea3f11a36b56f46c5c1fcf17f4daf712e5e0b42562d5f4c6
2018-03-06 19:14:32 +00:00
dan a48b020ddd Avoid running a couple of tests in crash8.test that depend on the presence of
the journal file if running on an F2FS file-system that does not require a
journal file.

FossilOrigin-Name: 797e02e0ee703ab0fd53e26ba5c96ac7429b8022522bec201423718d508acf24
2018-03-06 11:46:34 +00:00
drh 5f9d192de9 Improvements to the memdb VFS.
FossilOrigin-Name: a14fed69d0d4932fc6c71cf8acc5199cca4efbd10bca563a8e86038d6afd5c64
2018-03-06 04:01:08 +00:00
drh bcdb28dff3 Merge the walIteratorInit() fix from trunk.
FossilOrigin-Name: 6399e101d5f6b8582640e0d90783e56042eaa1600db3bd02f8df5e7b01ac1cab
2018-03-06 02:00:20 +00:00
drh 49cc2f3b9c Fix walIteratorInit() so that it always leaves the iterator as a NULL pointer
if an OOM occurs.  This fixes an assertion fault introduced by 
check-in [044b0b65e716bff].

FossilOrigin-Name: e5ce256aa1f7a8ae995b79c9da895827bee5d8d0724fc15413ff203dc9e2602d
2018-03-05 23:23:28 +00:00
drh 8d43d8443d Merge the session fix from trunk.
FossilOrigin-Name: 6274cf1f397d36be9e9b65b1935a776c834e4512e0e89f82c132efd4d1e8ef82
2018-03-05 21:19:57 +00:00
dan 6344edda80 Fix another crash in the sessions module triggered by malformed input.
FossilOrigin-Name: 7e70c9b86af557e86152748ddf1da467e62817b35df1da0d7d3b67941b198897
2018-03-05 21:17:20 +00:00
drh ad7fd5d096 Improved command-line help for the -A option on the CLI.
FossilOrigin-Name: d937ac181c5c78b9e5068db4ff1dab6becdba8c22cd27a3cfa0d4c12da1ec7ad
2018-03-05 20:21:50 +00:00
drh 93b7731485 A new way of doing archive commands on the command-line for the CLI. The -A
option means that everything that follows is a ".archive" command, including
any suffix on the -A option.

FossilOrigin-Name: 9d8081fabc491ba75d26ea81b3548bd10aeeb3334b0ad1462d7ab656c8d7c35e
2018-03-05 20:20:22 +00:00
drh da57d9676a In the CLI, add a new command-line option "--archive" (also "--ar") that
passes all subsequent arguments to the ".archive" command.

FossilOrigin-Name: a5c4d30af1271dea2d322b0679fe963bbd0d5db6bba8904caf5e30e510d01832
2018-03-05 19:34:05 +00:00
drh f111203287 Merge session fixes from trunk.
FossilOrigin-Name: 99c02aeecf47bfa5be5ce38a7ec20818ea0f9fb960b136184e1cb6f8fb8b70e5
2018-03-05 18:20:35 +00:00
dan 9c42626e43 In sqlite3_checker, wrap the call to "SELECT checkfreelist()" in a
transaction.

FossilOrigin-Name: 02906e55d73ea3521ad1e6807cffed5c759147f7b2d89efc4add984e53e3ad49
2018-03-02 20:00:42 +00:00
dan f0cb61d6c2 In a checkpoint, figure out if it is possible to checkpoint any frames at all
before creating the wal-iterator.

FossilOrigin-Name: 044b0b65e716bffeddedbd1b0360c4c332f6d2359167c1d327a5ff96539474cb
2018-03-02 16:52:47 +00:00
dan 302ce47519 Optimize the obscure case of running a checkpoint against a very large wal
file for which a large percentage of the frames have already been checkpointed.

FossilOrigin-Name: 0f5057dffa9be1bccab04894709d25bf1f066c4b1aef50d67ee635d46d300a4d
2018-03-02 15:42:20 +00:00
drh b2194cea4e Allow the zSchema argument to sqlite3_serialize() to be NULL to mean the
main database.

FossilOrigin-Name: 5b01b9914fb612ceece34f40d45c7eb97c3504fc5a0a5ff0e67120bdee67f6ee
2018-03-01 22:18:26 +00:00
mistachkin 5e9825ecc4 Typo fixes in comments. No changes to code.
FossilOrigin-Name: 1293d4f64f322ee57510bdff497c54e0be2c9205217e1fd96887bba1f36bec40
2018-03-01 18:09:02 +00:00
dan e341ec699f Fix further crashes in sqlite3changeset_apply() caused by corrupt changeset
blobs.

FossilOrigin-Name: 2c01c72e357296d761493aac47329f15d87afcada2b39606fc018af0e0011bb5
2018-03-01 15:20:33 +00:00
drh 2825e4ebb1 Merge the latest enhancements from trunk.
FossilOrigin-Name: c8083de14b54fba1071385f8530d03d5684efd4963fde0f83ddc53ae3118a75b
2018-03-01 13:44:40 +00:00
dan dd8a4af8e7 Fix some crashes in the sqlite3changeset_apply() function that could be caused
by corrupt changeset blobs.

FossilOrigin-Name: 745a9a7fef0f28a57ea3f44899058993f6ecdedda52c81a09a4a9ce09c9004d6
2018-03-01 12:05:51 +00:00
drh bda30ce4d8 Enhance the sessions documentation to show the methods of the various objects.
FossilOrigin-Name: e01177754ad6d9e2d38adddddd2e2e212094dac1154bda5fcee61ca8b678ae0f
2018-02-28 22:21:29 +00:00
drh 6a8a629e6b Use <pre> around code snippets in the documentation for sessions
interfaces.  This is a documentation change only with no changes to code.

FossilOrigin-Name: c949b915e893e917315ce21092d4c4bbd3e1b88d5326928f71dcc2f18f300702
2018-02-28 21:50:00 +00:00
drh d7fd899eeb Fix a potential NULL pointer deref following OOM in the new IS TRUE
logic.

FossilOrigin-Name: 48775ec693c21927ff26448acc614dd67d56240fa263499da2a9fe405c546c32
2018-02-28 04:30:55 +00:00
drh 5597cd42b8 Add support for TRUE and FALSE keywords and for operators IS TRUE, IS FALSE,
IS NOT TRUE, and IS NOT FALSE.  If there is are columns named TRUE or FALSE,
then the keywords resolve to the column names, for compatibility.  The
behavior of the "DEFAULT true" phrase is changed to mean what it says,
rather than being an alias for "DEFAULT 'true'".

FossilOrigin-Name: 9a7f02c50e6c8a3dc3addf4e51b7e04bd31670d6ce58d26d55273c43b5ecc8b0
2018-02-27 15:40:59 +00:00
drh 96acafbea7 Clean up comments and variable names prior to merge.
FossilOrigin-Name: 6445519e91c4f98b4a9a45d5091d733c31497ebf0eb23a76edce3091f626035d
2018-02-27 14:49:25 +00:00
drh e39ef31cd6 Remove an unnecessary decision.
FossilOrigin-Name: adcb4665490404e8da2de128dd5df9aeed8e08893649dedb6788ebb5d957b400
2018-02-27 00:58:13 +00:00
drh 43c4ac8bfe Code simplifications. New test cases.
FossilOrigin-Name: 57508518ef9d003d259ba98dcc32e5104aca26731a7161808741fe10bc0830d0
2018-02-26 21:26:27 +00:00
drh 171d16bb21 Get the "DEFAULT true" and "DEFAULT false" phrases working correctly in
CREATE TABLE.

FossilOrigin-Name: 8002f87d96b3f885cd208e7d204907a33ba60c4057ce2338b71e2de41215b0e5
2018-02-26 20:15:54 +00:00
drh 3432821192 Enhance TreeView so that it can display the new IS TRUE expression trees.
FossilOrigin-Name: 7e38305e6f71c3353df3d11d099e255eefbacceafd7ed2ccaba257fe2e7b8c38
2018-02-26 19:03:25 +00:00
drh 8abed7b907 Refactor for correct NULL handling in the IS TRUE, IS FALSE, IS NOT TRUE,
and IS NOT FALSE operators.

FossilOrigin-Name: cf2abd59be9971a55bd3d6c5df374c6aaa23bf81819482b42f01ee2484dcd739
2018-02-26 18:49:05 +00:00
mistachkin 6bd4140d33 More tests pursuant to ticket [36fae083b450e3af857a459e20].
FossilOrigin-Name: c26f236da61aef7c7a8fe38f1c7f33eea894c8fae38de6a085d4cce933a70502
2018-02-26 17:03:03 +00:00
mistachkin f7e867c347 Fix heap issue in the shell on Win32 caused by allocator mismatch.
FossilOrigin-Name: 7b3a75519aa72a6b49a125ee84946ba2c0722dd6644ee0c80ba567eb85daf5c9
2018-02-26 16:49:20 +00:00
drh bc8f68a3a0 Merge the fix for determining truth of floating point values from trunk.
FossilOrigin-Name: 003dc140536d0dd4384252ae1b82827b5d8b2b399520f99549b9266a482009fb
2018-02-26 15:31:39 +00:00
drh 1fcfa7240f Always interpret non-zero floating-point values as true even if their
integer part is zero.  Fix for ticket [36fae083b450e3af857a459e20].

FossilOrigin-Name: a983fa857048c748112c2f805f13aadeae43b43b3d27fa55433a3699b51c9a0e
2018-02-26 15:27:31 +00:00
drh 007c843b0f Experimental implementation of IS TRUE and IS FALSE operators. All TRUE and
FALSE to act like constants if the names do not resolve to a column name.

FossilOrigin-Name: 40314bc999af08ab10e654241208842b4bb95b19858d11249444372250ea4160
2018-02-26 03:20:18 +00:00
mistachkin 5facffbc70 Fix harmless compiler warnings in the zipfile extension seen with MSVC.
FossilOrigin-Name: 15c587cf6ffc920dc37f67cacb4f0db6a603fb998a22a639f755387910516414
2018-02-23 13:38:54 +00:00
mistachkin fda0867873 Enable the JSON1 extension when compiling the test fixture with MSVC.
FossilOrigin-Name: e9e9f27b3d496531905ad7459cf60366ad3798f507266134dd6388cdec50fdc4
2018-02-23 13:38:20 +00:00
drh 4f46b58a2d For the "SQLite archive" link in the README.md file, point to the
CLI .archive command documentation, not the original "sqlar" website.

FossilOrigin-Name: 4290faf5f7223ebe35b8ed5c4f0ba2444c1764501cabc09a79000f9c1d0890c7
2018-02-22 18:30:53 +00:00
drh d6ec7a6ab3 Updates to the README.md file. Mention the ability to use SQLite-archives for
download.

FossilOrigin-Name: ab9a7ae4eec0aaa5e0b472998f6de7212055d93c163f0b66da60b956bcc45add
2018-02-22 18:28:19 +00:00
drh c0ec2f7762 Remove an unreachable branch in the walIndexPage() logic.
FossilOrigin-Name: 4e61a9731f5949dcf05c541106b56be16add04a7730613481fc8519d3e4f493b
2018-02-21 01:48:22 +00:00
drh 8d3e15eec4 Small performance improvement in sqltie3WalFindFrame().
FossilOrigin-Name: 52013cad0e6ce2d694f25e2984a76d438cef724f0e07c8bb9d3dce8a3caf4350
2018-02-21 01:05:37 +00:00
drh 4f4e49a98b Remove an unnecessary memset().
FossilOrigin-Name: e7b7f5884a78630c6ba6a217c36247397e62f1928d4b480df929efcfc4a01893
2018-02-21 00:48:02 +00:00
drh 2e178d7321 Make the walIndexPage() routine about 3x faster by factoring out the seldom
used reallocation logic into a separate subroutine.

FossilOrigin-Name: e2b107141cd97bd4ab240748a9ce43fc2ec950ea74610697a4a7a3d7a6441e6b
2018-02-20 22:20:57 +00:00
drh 7436f1e491 In the speed-check.sh script, make WAL mode the default. Add the --legacy
option to do DELETE mode.  Continue to use DELETE mode for long-term performance
graphs since WAL mode was not always available, but use WAL mode for 
day-to-day performance measurements.

FossilOrigin-Name: cd81613850c0458b4b5b2460b9b38ce7ff6e557f7add9615058bb96f5a344ccd
2018-02-20 17:02:31 +00:00
drh 3993678d3d Remove a superfluous "#if 1". No logic changes.
FossilOrigin-Name: caaffd32001ff44c31f2d6dbe921f9d294f869c2c4a81e943fdf3f43f8d9313c
2018-02-20 16:39:11 +00:00
drh cc398969e0 Optimize calls to sqlite3_mprintf("%z...") so that they attempt to append
text onto the end of the existing memory allocation rather than reallocating
and copying.

FossilOrigin-Name: 4bc8a48e644562f6e6192f4c6fc4a70f6bb59f8126ed6c6dc876bedf65d74cda
2018-02-20 15:23:37 +00:00
drh b0b6f8783c Remove a lot of the text describing extended format options from the
documentation on sqlite3_mprintf() and friends, since that information is
now covered by the separate printf.html document.  Provide links to that
other document.  No changes to code.

FossilOrigin-Name: 99eec556f065ad19548e48d1f4ae0a3767b4e82e1c83fa2365062e3c5e0071fb
2018-02-20 13:46:20 +00:00
drh 57a93fa38c Enhance the string formatter (used by printf()) so that the width and
precision of string substitution operators refer to characters instead of
bytes when the alternate-form-2 flag ("!") is used.  Also fix the %c
substition to always work within unicode, regardless of the 
alternate-form-2 flag.

FossilOrigin-Name: c883c4d33f4cd722982aca17eeb355d19eeed793991d923b5494d173b1d0c73a
2018-02-19 22:46:19 +00:00
drh a15a7c352c Printing a value of 0 using %c terminates the string.
FossilOrigin-Name: 255612f0a131f2f522cbca3cc5a1edcf7e38938abca25ba421e7e38a422db9c9
2018-02-19 21:58:16 +00:00
drh 57f29b7bfb More test cases for unicode handling in printf.
FossilOrigin-Name: ac188211119bfd77f43e4aba8acab733a56aac90b4c8a11f7ef8e6388582438f
2018-02-19 20:41:01 +00:00
drh cf7c8370d1 Test cases and a bug fix on the new unicode handling in %c.
FossilOrigin-Name: e41d64e95b9b6fec5dc329553822925e7d648a41912b420cfa1ba198736e6bab
2018-02-19 20:23:20 +00:00
drh 136102beda Fix the %c substitution in printf() so that it works with unicode characters.
FossilOrigin-Name: c35be1d9e9132fbadc74d207c1088e5a710a151c0835c38a63bf3c8e6fd711a0
2018-02-19 18:56:52 +00:00
drh 57e3ba7623 Make the alternate-form-2 flag ("!") change the meaning of width and precision
from bytes to characters for the %q, %Q, and %w extensions of printf().

FossilOrigin-Name: 391540acbea34eb88c75b1152b458d8936b3fdfff47633b9ec897775b015ba4c
2018-02-19 18:03:10 +00:00
drh 62856465f2 In the printf() library, measure width and precision in characters rather
than bytes if the "!" (alternate-form-2) flag is present on a %s or %z
substitution.

FossilOrigin-Name: ca31c6630422fca70e626dd38aae96296bd8535d491ca52391624a5e7e663636
2018-02-19 17:03:23 +00:00
drh 26f625fbf4 Only try to use the geteuid() interface on unix if HAVE_FCHOWN is defined.
This fixes the build for vxWorks, we are told.

FossilOrigin-Name: 38f654dc117bb11d61407327884b5c913cfaf920547bebc4ce5a4cf983e5c20e
2018-02-19 16:34:31 +00:00
drh a224ee2a1b Fix an assert so that it compares two CellInfo objects field by field
instead of using memcmp().  Memcmp() does not work on x86
because of uninitialized padding bytes.

FossilOrigin-Name: 88258770adead70fa101c74e266a37bb9aaffac0ba738a4b345617feb8c46477
2018-02-19 13:53:56 +00:00
drh e28eb64d09 Fix a memory leak in the processing of nested row values. This problem has
existed every since row values support was added (version 3.15.0, 2016-10-14)
but was only just now detected by OSSFuzz.

FossilOrigin-Name: 2df6bbf1b8ca881c8a465d6624de66fde4c5975ccae6b2f2dda392b137f577de
2018-02-18 17:50:03 +00:00
mistachkin 091881bbb0 Port mutex enhancments from check-in [f53b8a573b] to the Win32 implementation.
FossilOrigin-Name: 74bb7225d132c80fd5758bb8c120448e3b3e951d0ca2fa0c57cac0a9c6c27045
2018-02-18 00:54:06 +00:00
dan c551550808 Fix a data race causing a tsan complaint with SQLITE_ENABLE_API_ARMOR builds
on unix. The race condition is not dangerous in practice, it just upsets tsan.

FossilOrigin-Name: f53b8a573bfbb48780243d56ca8372165adb1b979731c43d46cd1f8eb7e593f3
2018-02-17 07:38:50 +00:00
drh 713f34ace9 Do not allow parameters or schema references inside of WITH clause of
triggers and views.  This fixes a bug discovered by OSSFuzz and present
since common-table-expressions were first added in 2014-02-03.

FossilOrigin-Name: b918d4b4e546d3903ff20efc3c8ca26dd9761cc8ed9ef7d2799b66ff9ae1ae51
2018-02-15 21:00:37 +00:00
drh f4bc6c43d7 Improve performance of editdist3() by keeping the costs in sorted order.
Also add a new regression test to editdist3().

FossilOrigin-Name: dc734c5b61464dfd6bfa7963f2ecce32e405a0c2ba1ef6f453ec9389da080256
2018-02-15 03:56:33 +00:00
drh 46e835a2c4 Reduce the number of calls to strncmp() required to run editDist3Core().
FossilOrigin-Name: afd6fbc01052ccfc9bd29fb8f934b291b8f56af44fcae870da7e1355fe95c29a
2018-02-15 03:05:56 +00:00
drh 501ea05630 Fix the --heap, --pagecache, --lookaside and other options to the command-line
shell that invoke sqlite3_config() so that they work again.

FossilOrigin-Name: 00707f2f2f746a6421f3e2de995e68cc8adba7225a04db6b28db52944e7e988e
2018-02-15 01:03:37 +00:00
drh ee269a60c9 Add the --readonly option to the ".open" command in the CLI.
FossilOrigin-Name: 06870bb15656b50b0e14d4364bb21afac76500e313ecf67aaef3688d603fd076
2018-02-14 23:27:43 +00:00
drh d9274a8ae3 Performance optimizations to the editdist3() function in the spellfix
extension.

FossilOrigin-Name: 70d304dcbac4c3fd5e3b96108bffea2ce6c0db19c847397d5c5e268bb90a981d
2018-02-14 20:58:36 +00:00
drh 0fae06fcb6 Disable assert() in the spellfix extension if not compiled with SQLITE_DEBUG.
FossilOrigin-Name: 3c53ee0fdea4cbf2590e2b289b021b0ef8b7ead2945db1bdfc767432d9447acb
2018-02-14 20:25:33 +00:00
drh 4e6e5cef6c New test cases for the editdist3() function in the spellfix extension.
FossilOrigin-Name: 2d3f1f22d53034576a0ec8d9c360fb19efbb05b2e95ad1b09d120fb1b7da33fd
2018-02-14 15:30:48 +00:00
drh e2d27e0259 Try to optimize spellfix1 by storing a NULL in the k1 column of %_vocab
if it would otherwise have the same value as the word column.

FossilOrigin-Name: b76ec7cb5841f9ad02b342271e91c5f5a598006f69df7953a6213c706e01f7a2
2018-02-14 14:13:09 +00:00
drh a9abfb1e6c Improved test cases for the [f484b65f3d6230593c34f] bug.
FossilOrigin-Name: 1f300514e6cdd32c755dc1b05dfa125b10eda2eb55a1024b66f66dbf5cf96289
2018-02-13 19:13:05 +00:00
drh 4d1c6845ff Fix an incorrect table lookup used to find the appropriate search operator
for a WHERE clause on a row-value inequality.  The incorrect table lookup
was causing an incorrect answer for the less-than operator.
Fix for ticket [f484b65f3d6230593c34f11]

FossilOrigin-Name: f3112e67cdb27c1aec8d2cee3cb91ade061d093e13505894698e26336898b336
2018-02-13 18:48:08 +00:00
drh d446e79545 Remove an unused variable from FTS4.
FossilOrigin-Name: 27ea783b281606196ad1e7e6e6dcbd80c75d4bafcf3e58756a71c213320e4db2
2018-02-13 16:30:19 +00:00
dan e84c498be1 Ensure that multiple updates of the same FTS4 row (i.e. the row with the same
rowid) within a single transaction are written to separate segments. Fix for
[d6ec09ec].

FossilOrigin-Name: d2a81a3752a8298ee65fddcf32dee2147ba6467f770315a41966b3533977aa64
2018-02-13 16:21:32 +00:00
drh c083cb4422 Updates to the speed-check.sh script for improvements to the --vdbeprofile
option.

FossilOrigin-Name: f89c8f8ecd67f72ee730a2a334dff69b406a3dd00f50abbb54c4dc86cfab1bd1
2018-02-12 20:50:28 +00:00
drh 35043cc32a When compiling with VDBE_PROFILE, add the sqlite3NProfileCnt global variable
which can be used to measure per-opcode values other than elapse time, if
non-zero.

FossilOrigin-Name: d44d5936428859b6d3e089d9835acb8ca1f3c0a85b59eeaa619170623e7dcc30
2018-02-12 20:27:34 +00:00
dan 1db7db1f03 Update test file func6.test so that it works with SQLITE_ENABLE_NULL_TRIM
builds.

FossilOrigin-Name: e128d72f1a565551d3b6fdb3807fcb1c2a2bf355f0c09d04562b62f49d01fdbc
2018-02-12 15:27:32 +00:00
drh 00c3ef2df9 Fix a possible infinite loop in VACUUM that can come up when the schema
has been carefully corrupted.  Problem discovered by OSSFuzz. Test cases
in TH3.

FossilOrigin-Name: 27754b74ddf6463c6f9c48ea0df3637945b5ea086b92a41ddeb55b9aaefea4c2
2018-02-12 13:30:34 +00:00
drh c86d82f27d Fix misplaced testcase() macros from the previous check-in.
FossilOrigin-Name: 3aed949a18a251c5795f21f0385c205a127502b7e9cf06bc7f4c763951cd7984
2018-02-10 02:31:30 +00:00
drh f313952097 Improve the performance of the built-in REPLACE() function in cases where
it does many substitutions that make the string larger.  OSSFuzz is reporting
intermittant timeouts when running a test where it does a REPLACE() on a 
930KB random blob. Perhaps this enhancement will fix that.

FossilOrigin-Name: fab2c2b07b5d3cd851db3e6f5c8a44155e32b0df22905ea33412b153b825a928
2018-02-09 23:25:14 +00:00
drh 510fea885e Add the zorder.c extension implementing zorder() and unzorder() SQL functions.
FossilOrigin-Name: a57a77dc0cc9fbaa9d5b134422f7a8cc8d4c2851ed3c2bdd449800c6a5d2aae0
2018-02-09 20:49:15 +00:00
dan 91347c066b Make the tests in func6.test more robust against implementation changes.
FossilOrigin-Name: b685d3231097fb90e7d61d9ac01cc560e8bf2671d49390ae7af5bfdbd6d04f11
2018-02-09 15:42:40 +00:00
drh 54cfb492b7 Fix a harmless compiler warning.
FossilOrigin-Name: a6c3115483d597fc77ab19fdcfd1d3437cad7e467081ad8c5315fb98c115eed9
2018-02-09 15:04:51 +00:00
mistachkin 2a86110a6c Enhance sqlite3ErrStr() to include several more error codes.
FossilOrigin-Name: ad5d3bdc739a0997786f94fb5789b726b9f53ff883226093924338fe5000922b
2018-02-08 01:00:11 +00:00
mistachkin b189e4101c Fix typo in comment. Skip tests added by check-in [4761db83b6] when running on Windows.
FossilOrigin-Name: 468a389cdc8b6f92c77b11f682e210ad8cce7e3dbc0df308a898f4115e85fce2
2018-02-07 18:45:00 +00:00
dan eab0e10304 In extensions rtree, fts3 and fts5, ensure that when dynamic buffers are bound
to persistent SQL statements using SQLITE_STATIC, the binding is replaced with
an SQL NULL before the buffer is freed. Otherwise, a user may obtain a pointer
to the persistent statement using sqlite3_next_stmt() and attempt to access
the freed buffer using sqlite3_expanded_sql() or similar.

FossilOrigin-Name: 2a5f813bc61f9e780f2ccbda425611f65ad523b6d486a1e5e2b9d5e9f1d260a2
2018-02-07 18:02:50 +00:00
dan fa68815fa3 When the final connection disconnects from a wal mode database, check that the
database file has not been moved or unlinked before deleting the wal and shm
files.

FossilOrigin-Name: 4761db83b6d3d57f281370899403c102e39ad0021d315dd6a6912d250436782a
2018-02-07 16:14:41 +00:00
mistachkin bc6b8d7359 Adjust the previous check-in, which modified the Win32 VFS, so that it works with SQLITE_OMIT_WAL.
FossilOrigin-Name: 36c2e67e82626f8d0a187c6c286c133ed659889e3b577469261b9dcd3b3ab75b
2018-02-05 21:02:47 +00:00
mistachkin 435666e26d Allocation the mutex used by the Win32 VFS only once at initialization, instead of every time it is needed.
FossilOrigin-Name: 535ed0ac5e8728ec91fc0a4cb54b820923d161cfd4e0e6aed6df6cdae365bc7d
2018-02-05 20:42:50 +00:00
drh 561158937b Allocation the mutex used by the unix VFS only once at initialization, instead
of every time it is needed.

FossilOrigin-Name: 5764dc160783f5c4017204b3e26a89d31240c868484ced8214c9ad872bd77bd4
2018-02-05 16:39:12 +00:00
dan d1317095b5 Fix another minor problem in walro2.test.
FossilOrigin-Name: ba0631de60ca38bf7efa6dbd86ec8774bf6f438c804155968e97f17eabe3b20a
2018-02-05 13:42:45 +00:00
dan 60d72b9bab Update test file walro2.test to account for systems with a page-size
(getpagesize()) larger than 32KB.

FossilOrigin-Name: d9e59cfb8476e1ec1ca458b8382172526c0557ab785f41e31971d03045c9344c
2018-02-05 13:28:51 +00:00
drh 4b18c1d53a In the CLI,
make sure sqlite3_initialize() is called correctly even for non-UTF8 hosts.

FossilOrigin-Name: a3591fb54178b8f124207ff16e3ef9e58a62585feb3a56ced2b862222aea19d8
2018-02-04 20:33:13 +00:00
mistachkin 97f9059eee Fix harmless compiler warning seen with MSVC.
FossilOrigin-Name: 63a914410b5750bd08836864ae456ff09549487c5ce49706fedffa3d4f973059
2018-02-04 01:30:54 +00:00
mistachkin 001f52ed7d Move variable declaration in zipfile extension to fix MSVC compiler error.
FossilOrigin-Name: ac6a32482e675871c3ce5ecc727e50e4bba649e80e3c55bf99025fed5667da94
2018-02-04 01:29:01 +00:00
dan 3944cf8de3 Remove the "include <io.h>" win32 dependency from the zipfile extension.
FossilOrigin-Name: cb3feb3bc33718625159eddbf8ef608cd641af84e97d433d6b11ba6da94dad2e
2018-02-02 16:28:19 +00:00
dan 1dff328119 Remove the time() dependency from the zipfile extension. Use SQLite VFS
methods instead.

FossilOrigin-Name: 0702fb5611c7cf0154c5490eeada66afc733731dff0fe030375bae6a72123a17
2018-02-02 16:20:41 +00:00
dan 668845bb0b Add a few more zipfile tests. No changes to code.
FossilOrigin-Name: 3f621545879ea39502cfaf2b61883f92c077070274b4fdf45524ded81cac3e63
2018-02-01 20:42:23 +00:00
dan 15daa6b53e Fix a problem triggered when a zipfile virtual table is created and written to
within the same transaction. And add other zipfile test.

FossilOrigin-Name: 48f1c556994d7f8f359c649a1da81eec02306106b68946a9a20b276742c4610d
2018-02-01 19:41:23 +00:00
drh 563ddbe54d New assert() statements to help ensure that no other errors similar
to [343634942dd54ab57b7] ever appear in the code.

FossilOrigin-Name: 5a70af1e9c567f12c997d25d0a305a8d42bf2cc92f2811e9d5fdde720665e213
2018-02-01 15:57:00 +00:00
dan c3ef23a1c9 Fix a memory leak that could follow an IO error in the zipfile extension. And
add other tests.

FossilOrigin-Name: e6bb750697c3c7ceb5ce41d216e8ef6a1d556822a3b55e0a007b4a03e194a7d9
2018-02-01 15:19:54 +00:00
drh 06b3bd5b7a When an index is based on a text representation of a numeric column in the
original table, make sure the indexed value uses the canonical text 
representation of the numeric value in the table.
Proposed fix for ticket [343634942dd54ab57b70].

FossilOrigin-Name: 88e2ce916791d488076584f3795a89eb4277fcb812af9e4c2f383815d55ff6f1
2018-02-01 01:13:33 +00:00
dan f8c3a2f3cf When creating a new archive entry, have zipfile store UTC instead of local
time in the legacy MS-DOS format timestamp field.

FossilOrigin-Name: b730d187f2202e5b5d31ed6c94c9bb04d7c289f7086a9b44b3d9050ea3586d3a
2018-01-31 20:18:26 +00:00
dan cfaffad65c Fix a test case in zipfile.test.
FossilOrigin-Name: 4eb5b24c64ee5907c18371f563b79fa0caf58285a62b8f09e639a690e6727eaa
2018-01-31 19:45:58 +00:00
dan 44091ed368 When creating a new archive entry, have zipfile store UTC instead of local
time in the legacy MS-DOS format timestamp field.

FossilOrigin-Name: e2114df18383d111dd5fbac902e08b42a7f4b2b2d6f7bf29574a3722e4a4dad5
2018-01-31 19:13:31 +00:00
drh 5cd253423b Improve the omit-left-join optimization so that it works in some cases
when the RHS is subject to a UNIQUE but not NOT NULL constraint.

FossilOrigin-Name: 02ba8a7ba7ba71cd7abd5dd3093ea486f53a025f6972bb444f2da37e0e2fc3b2
2018-01-31 16:50:27 +00:00
dan 4ea48144f9 Fix a failing assert() in the new code on this branch.
FossilOrigin-Name: 74d857d178dfadea7e07ba47439fe11aa9d282b54caf78cd6961e593b37406d0
2018-01-31 14:07:01 +00:00
drh 04a28c3b6d Changes to the autoconf tarball so that it does not try to use system() when
building on iOS.

FossilOrigin-Name: 32ed9c106710c74a12d60ec33027fd6a9335627c95642ba608593b2735714da6
2018-01-31 01:38:44 +00:00
dan 099fa84727 If a virtual table xColumn method sets an error message using
sqlite3_result_error(), use that message in preference to any error message
left in the sqlite3_vtab object.

FossilOrigin-Name: 71e3b715ad36c2132a587b84221be6359c31d7a17c3fba201b7ed3baf17922f1
2018-01-30 18:33:23 +00:00
dan 2f7260deba Add tests cases for the zipfile extension.
FossilOrigin-Name: 13b786dafd308b7aef42328f26fe64981c83d524e4bf82ceb7d58afc7146c7d3
2018-01-30 17:43:22 +00:00
dan fdcd9d4e6c Prevent users from creating zipfile() virtual tables without an argument.
FossilOrigin-Name: 81fdbe0cc5a360f818078d47a5888d0a29d555927da279a9a0213702d74ef09a
2018-01-30 14:07:55 +00:00
dan ea4125bbef Add unix-only tests to check that the "unzip" program can unpack archives
generated by the zipfile extension.

FossilOrigin-Name: 438c5c5237a801ae78809bf324bb9251fb50250addfc1f8e36659442b0e26ab6
2018-01-29 19:47:32 +00:00
dan f8c4b99a02 Add aggregate function zipfile() to the zipfile extension. For composing new
zip archives in memory.

FossilOrigin-Name: e364eeac76a8225146b37d801bc6cabe03e9abede5a1412ebe9d94a32d8838cc
2018-01-29 18:41:07 +00:00
dan 8433e7166b Update the omit-left-join optimization so that it works in some cases when the
RHS is subject to a UNIQUE but not NOT NULL constraint.

FossilOrigin-Name: 88411a402b29f19d69e0d06d9099eabb98c238ddb7c07ce110236316f008753e
2018-01-29 17:08:52 +00:00
dan 26e731cc88 Ensure the "unique-not-null" flag is set for automatic indexes on columns
declared with "col UNIQUE NOT NULL" (where the NOT NULL comes after the
UNIQUE).

FossilOrigin-Name: 8767f7b880f2e4112f75f0b6ef7be3f50ab1ae20e103e7d03d8bfe77e6c79438
2018-01-29 16:22:39 +00:00
dan a07aa8d397 Fix missing header comments and other code issues in zipfile.c.
FossilOrigin-Name: 6ea8ba312c38365d3e28cfb2a367d729dd2751d1d853843eea0e18126777a320
2018-01-27 18:55:18 +00:00
dan 26333ee3ca If a zipfile virtual table is created with no argument - "CREATE VIRTUAL TABLE
zzz USING zipfile()" - accumulate data in memory. Support "SELECT
zipfile_blob(z) FROM zzz LIMIT 1" to retrieve a zip archive image.

FossilOrigin-Name: e63185edfe0c316aa60c1fa085d032425ecc7db54536dfa5a977772eaf3c240e
2018-01-27 16:29:59 +00:00
drh 1822ebf9b1 Changes to avoid a harmless UB warning from clang.
FossilOrigin-Name: 19f5c1400054df10688ab448e7e23afef97cab4a7c7a3e411f7527509b515dd8
2018-01-27 14:25:27 +00:00
drh c9f3db33d5 New test case for ticket [ec32177c99ccac2b1] that works without the STAT4.
FossilOrigin-Name: 5259d4847f2b73f26b2385f9d8cff8fe0cabc54b4deab8477c87c8d1bb5535b1
2018-01-27 13:55:56 +00:00
drh 33f10207aa Proposed fix for the query planner problem of ticket
[ec32177c99ccac2b1].

FossilOrigin-Name: eef8cbef3c49e6331301a8f3f8a5fd12090b1e99e68487c2d405e53ef771f688
2018-01-27 05:40:10 +00:00
drh c86caa58cd Fix compiler warnings in zipfile.c.
FossilOrigin-Name: bed610d99b5322ee209b06966c0086e8c55f8a82be8d7693cfdeb4d728679721
2018-01-27 03:26:10 +00:00
drh 33f763d154 Fix the query planner so that it takes into account dependencies in the
arguments to table-valued functions in subexpressions in the WHERE clause.
Fix for ticket [80177f0c226ff54f6dd].

FossilOrigin-Name: 7daa687340e475972d6849f84fe1419a1f5700934f53fd80656849adc73d6d04
2018-01-26 22:41:59 +00:00
dan 8005d60587 If the argument to table function zipfile() is a blob (not text), assume that
it contains a zip file image to interpret, not the name of a file on disk.

FossilOrigin-Name: 029ebcd30cb261d949f7587ac54c23d7479796b6716fd4ca7512361b8f32de3e
2018-01-26 18:59:25 +00:00
drh 4eb57ceffc Improve text-to-integer conversion in boundary cases. The
sqlite3Atoi64() function always returns the minimum or maximum integer
if the magnitude of the text value is too large.  Trailing whitespace is
now ignored.

FossilOrigin-Name: ace0644a1a2a42a3ea42d44f00a31915b8a7e56c9ba90f90a6c02001f89f9c86
2018-01-26 18:37:34 +00:00
dan 8558ef2e19 Reorganize zipfile.c code to make it easier to add support for in-memory zip
archive processing.

FossilOrigin-Name: 30b9258294e3028ef4ea467e332e013995509544e9a23c8bbf5168772a7e895d
2018-01-25 20:50:46 +00:00
drh cad42838d7 Slightly smaller and faster implementation of OP_If and OP_IfNot.
FossilOrigin-Name: 6ab42934e2c4957b5d8927bf4434a9db07ab6078987a6a2d25f35cc468d21203
2018-01-25 01:20:29 +00:00
drh 9f8952390a When unpacking a sorter record, do so from right to left instead of left to
right, since by starting with the right-most column, the work done by
OP_Column opcodes is reduced.

FossilOrigin-Name: 8055e4f42446ceb5bcf752bbf41a73289c3ca759c56c9f779edc3d7f202b7881
2018-01-24 20:42:42 +00:00
dan 1a0e5b37b2 Reorganize spellfix.c to make it easier to edit automatically (e.g. using a
script). No changes to functionality.

FossilOrigin-Name: 090a64faaac579c6ed1cddb02d14e7089468a4aeaeec11e78d461790bcb6eb0a
2018-01-24 18:28:39 +00:00
drh da6bc6792f Rearrange fields of the BtCursor object so that it is smaller and requires less
initialization, for a small performance improvement.

FossilOrigin-Name: 0ddf5292cc0411ec6fcb7399ecf2904c899e0488404d3f65490fbe1db15efdf4
2018-01-24 16:04:21 +00:00
drh fe875027d7 Add the normalize.c extension.
FossilOrigin-Name: 16ebe558d2f0982f630c39b6c1b00d14d27011d454cced213f17c26491a2c06e
2018-01-24 15:07:37 +00:00
drh 31a13548f8 Merge changes from trunk.
FossilOrigin-Name: 6ef3de810d54563c227045b16197b8011ce285ea867261946f93b2de55344f29
2018-01-24 15:02:53 +00:00
drh a8519d79b9 Interchange the numeric codes for CURSOR_VALID and CURSOR_INVALID to obtain
a small size decrease and performance increase.

FossilOrigin-Name: e0f192ea6dda4fa0b243d58c8ce41932519141bcae0689a90318b4f866f54edd
2018-01-24 14:40:01 +00:00
drh 4d6d872c49 Adjust the fts3rank.test module so that it works on big-endian systems
(hopefully - I don't have a big-endian machine to test the change on.)

FossilOrigin-Name: e4766cabdf64d8e998048ae43154466fc9c3fad0b86102a42b65122abfcbbe55
2018-01-24 14:39:18 +00:00
drh a87f8ce262 Improved error message output when the btreeinfo.c extension is run in
a connection that lacks sqlite_dbpage support.

FossilOrigin-Name: 461b0b81b2acedb1b9ca520657518d6778417c375aeb58c41ead840b75a6d985
2018-01-24 13:15:56 +00:00
drh b9f4799b55 Prevent a harmless unused variable warning when compiling with
SQLITE_OMIT_TRACE.

FossilOrigin-Name: 61a44961b5811c993ae8d4f820a21a0ee739fe5e88cbfe5e4190e0091912ca19
2018-01-24 12:14:43 +00:00
drh 93117f0c4b Fix a formatting issue in sqlite3_prepare_v3() documentation. No changes
to code.

FossilOrigin-Name: 9e6066de84285252fb8999a8d8e02a46c5bb6c822e4f7421ad3911687357ee5d
2018-01-24 11:29:42 +00:00
drh 9ccc0fd1f9 Fix the sqlite3ext.h header file so that it correctly accesses the
new sqlite3_value_nochange() and sqlite3_vtab_collation() interfaces.

FossilOrigin-Name: 6185d190e250faae0d979a24cb1039c7fce178478ae75df8e4af1d94cd38c18e
2018-01-24 11:25:59 +00:00
dan 0aac5613d9 Update a couple of test scripts so that they work on F2FS file-systems that
support atomic transactions.

FossilOrigin-Name: 49e58e645e0c114c71935a3b7fa4771e8a23e28127efd2efe0f2f18813c8f391
2018-01-24 06:30:10 +00:00
drh 56f1774603 Make the shell functional even if compiled with SQLITE_OMIT_COMPLETE.
Omit the sqlite3_complete() call from the fuzzing interface if it is
compiled with SQLITE_OMIT_COMPLETE.

FossilOrigin-Name: c3e816cca4ddf0967c4c790cdde2345101dde3f2d854e62589f1ac1d7f3c60b8
2018-01-24 01:58:49 +00:00
drh 5347f3c111 Invoke the sqlite3_complete() interface from the fuzzer.
FossilOrigin-Name: 332bf84625d2034c9e1c029aa8243aa34088217e52e34e1f5472217743a31af3
2018-01-24 01:02:23 +00:00
drh 588049cc99 Increase the version number to 3.23.0 for the next development cycle.
FossilOrigin-Name: b58b60b2c0729b73c0ef35bd1a5aa90965d1c01043413ca45b412d8b68f59bce
2018-01-23 20:22:15 +00:00
drh 21d5978422 Remove an unreachable branch from sqlite3SkipAccumulatorLoad().
FossilOrigin-Name: 8b9c8eab60b692e45c55a718d76b70e63040416040696907463692cbf83fb0c5
2018-01-23 19:24:54 +00:00
drh d15046ac08 Work around a problem with GCC on 32-bit machines that cause the CAST
operator to generate a floating-point result for strings that could be
represented as very large integers.

FossilOrigin-Name: 1b02731962c21bb097a88801ece76ff441bf882519a821a246da84f4e2a33455
2018-01-23 17:33:42 +00:00
dan a916b57013 Fix a bug causing spurious "sub-select returns N columns expected 1" errors
in join queries with a term like "(a, b) IN (SELECT ...)" in the WHERE clause.

FossilOrigin-Name: 14dfd96f9bca2df5033b2d894bf63cc8bf450a45ca11df5e3bbb814fdf96b656
2018-01-23 16:38:57 +00:00
drh 61d04974f0 Fix the modification-time setting logic in the fileio.c extension on Windows
so that it works with utf8 filenames.

FossilOrigin-Name: f785b9041556912edbacdbfb3dfc38705058d7c10d874544295c25db54628bc2
2018-01-23 15:26:30 +00:00
dan b8fff29c68 In SQLITE_ENABLE_BATCH_ATOMIC_WRITE builds on F2FS file-systems, invoke
SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE if an SQLITE_FCNTL_COMMIT_ATOMIC_WRITE call
fails. Also, do not use an atomic transaction to create the initial database.
This is because if an error occurs while writing to the db file, any changes
to the file-size do not seem to be rolled back automatically. The only time
this matters is when the file was 0 bytes in size to start with.

FossilOrigin-Name: b3122db1545aeb48b7c28d480534b4b0fe04e83d5336225714c3cad926e5960e
2018-01-23 14:01:51 +00:00
drh 8d7f163015 Fix comment typos. No changes to code.
FossilOrigin-Name: 8e5e74c66b9cdb348392e3db2d9f32cfa20fcec35bf09d9e1f623e7ad875ec97
2018-01-23 13:30:38 +00:00
mistachkin 176b3a09b2 Skip defining WIN32_LEAN_AND_MEAN when it is already defined.
FossilOrigin-Name: 195f5323df800f7963df2ea251c497c72e4d7ff0b88a70f1fa60f13bb1a9fd3b
2018-01-23 07:11:05 +00:00
drh 7ea3469e53 Slightly faster implementation of the length() SQL function.
FossilOrigin-Name: 9a4199aedb039141a50a68943ef863d7df9637ada318793cce6c12b9d39bcdc5
2018-01-23 04:22:33 +00:00
drh f09ac0b336 Slightly faster function dispatch in the virtual machine by avoiding
unnecessary reinitialization of variables that are already correctly
initialized.

FossilOrigin-Name: edd4e6876cc08ab907bb21f075380de946562d4c56a04923760848b4b11536ac
2018-01-23 03:44:06 +00:00
mistachkin fa3d785580 Simplify one of the compiler warning fixes from the previous check-in.
FossilOrigin-Name: 012d7d49c571207087bbe24af05d639627b96df526bfcb2098a3e975b74d865d
2018-01-23 00:17:27 +00:00
mistachkin b71aa0955b Fix harmless compiler warnings seen with MSVC.
FossilOrigin-Name: 76a11a80e94d1e9c9645e6e348948f3fd508266d4569c85d80a3879862d0a819
2018-01-23 00:05:18 +00:00
drh 138d4f8de2 Version 3.22.0
FossilOrigin-Name: 0c55d179733b46d8d0ba4d88e01a25e10677046ee3da1d5b1581e86726f2171d
2018-01-22 18:45:57 +00:00
drh 8bfe66a9c4 Avoid unnecessary OOM detection warnings in a debugging routine.
FossilOrigin-Name: 395f8ea790e6e295800fa8927f0585b2419b9521ef4fd591d51d2a48db2a90c4
2018-01-22 15:45:12 +00:00
dan 3a9b9b7749 Fix a test case in walro2.test so that it works with encryption extensions
(when each page has a little less usable space available than usual).

FossilOrigin-Name: b79521d255a4aa2a7b4424f3498443f27d329ab5428171ba6b87c987f3ccdfc2
2018-01-22 15:20:59 +00:00
drh 88284b0dc3 On the walro2-X.4.2.2 test case, show the size as part of the test output.
FossilOrigin-Name: ac5091d7f870f1d0659a576723de454d544e5bfa2bdbba307d7c81eb5ab34e3b
2018-01-22 14:49:15 +00:00
dan 2f94935409 Allow the shell to be built from the configure script with
SQLITE_OMIT_VIRTUALTABLE defined.

FossilOrigin-Name: 136bf323e42dc90e1780199a381bcbb084b069eca5c7343ee6fc6e2550831536
2018-01-20 15:48:45 +00:00
dan 1a3a308616 Use a loop to avoid recursion in the heightOfSelect() function.
FossilOrigin-Name: 86de43595cb2ecebd680fe654affcfb9fbcfff6575c893293ae298124a357bfe
2018-01-18 19:00:54 +00:00
dan 5a7da86f5b Check for both zlib.h and -lz before enabling zlib support in the amalgamation
configure script.

FossilOrigin-Name: 8ecd13a1b38e58d4464585c388c1aa27d1f056dba0db239316623e81d3eb5284
2018-01-18 17:46:08 +00:00
drh 80db2d6521 Update the autoconf configure.ac script and Makefile.am templates so that
ZLIB is automatically detected and used.

FossilOrigin-Name: 41bfb6b8d61699d09a7e67d2289149abfbb9ce8e75e6ff8560546cad0d2e3f2b
2018-01-18 17:09:26 +00:00
dan b8a0fb75db Fix sessions module handling of sqlite_stat1 rows with (idx IS NULL).
FossilOrigin-Name: 0e916416331d7948b312a5dd58ac0c145030bb3b47a37dab2636564397249a86
2018-01-18 16:59:52 +00:00
dan cae5b9feac Clarify the handling of the sqlite_stat1 table by legacy versions of the
sessions module.

FossilOrigin-Name: dc7c48cb4126db9e25c73512cc743155293fe1c4c2516f8c84102228695b6e70
2018-01-18 16:56:19 +00:00
dan e3ca3831ba Add comments describing the special sqlite_stat1 handling to sqlite3session.h.
FossilOrigin-Name: 4431a3256f7436e34b3c33edc1f3e53df7eb3c87daec9bac8d038895d93ca7f2
2018-01-18 16:53:41 +00:00
drh 4b3931ef33 Fix to the documentation for sqlite3_trace_v2(). No changes to code.
FossilOrigin-Name: 6fbd0a11a66f8eb4d7820cb49c23bdcb917db98a22c29d76edea1eea6dab0a4e
2018-01-18 16:52:35 +00:00
dan d1cccf19b5 Fix sessions module conflict handling for the sqlite_stat1 table.
FossilOrigin-Name: f05ee74e05c401eb075a1ba65179662a08a5c3d5b55fc81f2acc841e841dd055
2018-01-18 16:42:11 +00:00
dan 1611e5a301 Simplify the sessions preupdate-hook logic for transforming NULL to X'' for
column sqlite_stat1.idx.

FossilOrigin-Name: 089d7cecaaa47db58320b216a111a5e56123d022008be6c81bc0746148bbdb58
2018-01-18 15:06:23 +00:00
drh 3dc9727782 Alternative implementation for the internal sqlite3Pow10() utility for MSVC,
which is more accurate on that platform.

FossilOrigin-Name: 469b96be5350ba2291518280ffe179b87aa7fbe701e2813ef63843922771517a
2018-01-17 21:14:17 +00:00
dan 3739f29807 Fix a problem in the sessions module with logging sqlite_stat1 rows for which
(idx IS NULL) is true.

FossilOrigin-Name: 25bf734be1b3883fccf12ac4d93d50289aa307fb60a52e0e32df12f7ee4edc7a
2018-01-17 20:57:20 +00:00
dan 61c758b53a Fix a problem causing the sessions module to occasionally lose track of rows
with composite primary keys when there are two rows with the same text value
in the leftmost column of the PK.

FossilOrigin-Name: 09aed13678374bf22087cd808808b711dc703b7c18bc8aaf704850611e17f5cd
2018-01-17 17:38:18 +00:00
dan 26893c98d2 Fix main.mk so that testfixture can be built either from the amalgamation or
from individual source files. No changes to code.

FossilOrigin-Name: a8aea925f8fde8f2dc5ff4b744d54aa2bf8916f3ee57f22d77fd1ddb5a35a9cc
2018-01-17 16:11:26 +00:00
drh b968518559 Fix harmless compiler warnings, mostly unused parameters for UDFs in the CLI.
FossilOrigin-Name: bfbeffab7735461acb3773242ba31dae15af9f8b0291c54a6734747bb1b36e66
2018-01-17 13:15:23 +00:00
dan f193937620 Omit the single test from zipfile.test that uses json functionality in
non-SQLITE_ENABLE_JSON1 builds.

FossilOrigin-Name: 6bb2a10fad71bf8cec6bca538db7b00be0d26418ab62b83092d3a6a68d1c0d9f
2018-01-17 12:58:11 +00:00
dan 30fe26c47f Update test file fts5fault6.test to account for test tokenizers implemented in
Tcl returning SQLITE_ERROR instead of SQLITE_NOMEM following an OOM error.

FossilOrigin-Name: c232f6424a858ede44940a927fe4e26ee99c6ab614aa6f63e13ba46e88dbb280
2018-01-17 12:57:07 +00:00
mistachkin 98e2cb8bd1 Simplifications to winOpenSharedMemory in the Win32 VFS.
FossilOrigin-Name: 3e04999dabb87715de46255b1a9b08d5dfa70d140e0a09a37ea2842d71c77caf
2018-01-17 01:40:57 +00:00
mistachkin 5685257b83 Corrections to error code handling in os_win.c, pursuant to walfault.test.
FossilOrigin-Name: 568192228c9578b8ea34c363e10ff28450045cda76248b2f0f89f84b3a57e680
2018-01-17 01:26:05 +00:00
mistachkin 824f28426a Fix duplicate test names in 'walfault.test'.
FossilOrigin-Name: 7274d05ff43fc9872f0e4857ae583689e4a6c429b7fa991dcc29744da3048879
2018-01-17 01:15:08 +00:00
dan 2879952faa Fix a problem causing zipfile to store 0 in place of the CRC32 value for
uncompressed files.

FossilOrigin-Name: ba44724bcca2e87788b7c6d8c5de7fa388360127bd894ee6a171fd66e794fcae
2018-01-16 21:09:00 +00:00
drh 8c9e30ba2f Remove an unused field from the internal definition of the sqlite3_context
object.

FossilOrigin-Name: 948a26b5a64d8a89c4ec7546ec4a4bee36e29e82edda677ca75424e7091325d0
2018-01-16 21:05:10 +00:00
drh 2d9e8c55da Fix compiler warning in the FTS5 test interface.
FossilOrigin-Name: 2ab4e8d5d82ab410c00f048c12555f2f40f9fd8bffda64ccbdd3dfe036727315
2018-01-16 21:00:58 +00:00
drh 4a4532bbb7 Make the new sqlite3_vtab_collation() interface accessible to loadable
extensions.

FossilOrigin-Name: f301db3c2343fd2086bc5b69a17b2d226175584ccd09549ebb2cb603590da487
2018-01-16 20:50:37 +00:00
dan 4bd387495f Fix a test problem causing an error in fts5fault9.test.
FossilOrigin-Name: 8e2048113fc6ed87fc7d5ba470261926aa0bd35474744bb2b99ea596bc468f02
2018-01-16 20:44:00 +00:00
drh eb0b6f364e Remove the unused SQLITE_CANTOPEN_DIRTYWAL result code.
FossilOrigin-Name: 3c786305fc6eaa6856ec6c71fc7969f61de266ba1bea0abf0ae133eb94e54b2d
2018-01-16 20:37:56 +00:00
dan 70bc717c0e Fix a makefile problem causing -DSQLITE_ENABLE_STMTVTAB builds to fail.
FossilOrigin-Name: 7f6e5bdf9021c31e8bde82c224bf53be3c93b79f7bb5c2802c54be8031cf89fb
2018-01-16 20:20:00 +00:00
drh 0ed2fd8a25 Move the ZLIB version announcement in the CLI out of the default banner
and put it in the ".version" command.

FossilOrigin-Name: 231679d6f8c0c3d957c8daa88b0743449b60b47159e114f4bc073a8612a73b2a
2018-01-16 20:05:27 +00:00
mistachkin fff5367c24 Show version of zlib in use when running the shell tool in interactive mode.
FossilOrigin-Name: a8906b527a8f7a2cec88cc3b05c063a2785f0d1d141e148d954fc7440972a484
2018-01-16 19:03:51 +00:00
dan 194a17bbb7 Change a cat in zipfile.c from (z_const Bytef*) to just (Bytef*). This allows the module to build with older versions of zlib.
FossilOrigin-Name: ac9af91d5a2927e71903461e7bbdd2c0168fde9a042853c8bcd4c7ebd0d51e0d
2018-01-16 17:33:09 +00:00
dan 0c2ba13e02 Fix a problem causing an infinite loop or other malfunction in some UPDATE
statements with an OR term in the WHERE clause.

FossilOrigin-Name: feb2c2b6f66b0f45490beb1642d99cdb89fa220e299a8c118929df557c814189
2018-01-16 13:37:43 +00:00
drh ded2d99d73 Disable the ".archive" command tests in shell8.test if the CLI is compiled without
ZLIB support.

FossilOrigin-Name: ce8bfe6c2b87090a2de1e04bc88fcb878597fe1f4ecd5df6d9d588a65601c901
2018-01-16 02:38:35 +00:00
dan 2d620070b9 Fix a problem in the zipfile module causing it to generate incorrect
checksums. Remove the ability to insert compressed data into a zip archive.

FossilOrigin-Name: b0b7d0363acf38c2178e2d3041d8ce2a0de061a51caa64670dbf539ee6d4356b
2018-01-15 19:00:35 +00:00
dan 89fa746941 Fix a zipfile problem with extracting zero length files compressed using
deflate.

FossilOrigin-Name: cf64087224aff1a2fe169d23996d9e5ed8d86459c655eb5d0bace0466a557ec6
2018-01-15 15:49:46 +00:00
drh a9be508a97 Fix an error in the setDeviceCharacteristics() procedure for the
(unsupported) QNX code in os_unix.c.

FossilOrigin-Name: 8151913a3987f4dd2d6efee046727f5fa9b6f11d5d3867ea8f512c03a212ac2b
2018-01-15 14:32:37 +00:00
drh b058d05452 Avoid excess stack usage when a VALUES clause with lots of rows occurs
within a scalar expression.  This fixes a problem discovered by OSSFuzz.

FossilOrigin-Name: a4fa0581ba7cfd45fabe0198f55b3c2c8ee3ecfd2825aeed91116f44e77d760b
2018-01-14 20:12:23 +00:00
drh eb54500419 Fix harmless compiler warnings in zipfile.c.
FossilOrigin-Name: 8f7a592f8c044d75b4615a95e27454100b10c2b26f4cafee97dec23343821130
2018-01-13 23:28:33 +00:00
dan f42884c307 Support UPDATE statements against zipfile virtual tables.
FossilOrigin-Name: f2d2a5df4f29b47212fd2411eae6545087b901a270655640c87ceb472e02a24c
2018-01-13 19:08:24 +00:00
drh cdb60978b9 Fully initialize the Mem object for serial-type 10, in case such a
serial-type is found in a corrupt database file.

FossilOrigin-Name: bd70a07d819a54346cb6c40fab681424c5af0dfb6bf29321a3de9fc99d285376
2018-01-13 14:28:00 +00:00
dan 098728fc9c Fix various problems in test scripts preventing "make test" from passing on
F2FS file-systems with the "atomic-write" feature.

FossilOrigin-Name: 6bedc7435d26c1f21c0d1b3a52daa0169fa5416b690a99347328dcafdcd78740
2018-01-13 14:02:16 +00:00
dan 2483a111db Fix a typo in crash8.test.
FossilOrigin-Name: c3dc7b8d9de94e46fae75fcc96ec68743205e0a2591e14391c394fff203004d1
2018-01-13 14:01:26 +00:00
dan 69aedc8db4 Fix various problems in test scripts preventing "make test" from passing on
F2FS file-systems with the "atomic-write" feature.

FossilOrigin-Name: 56d93d070d6b92d8a5a3fec1b09aae8911116c73d072fc5022f0b51668ed996b
2018-01-13 13:07:49 +00:00
mistachkin 2034353db4 Updates and minor typo fix for the README.
FossilOrigin-Name: bb196fcb677e962db4308c02097968615729a51fe4a1292e468aaf3e4bf522d3
2018-01-13 02:07:16 +00:00
drh 76506cd3a7 Add the new "nochange" APIs to the extension loading mechanism.
FossilOrigin-Name: cd7c42699e73b688dbed29ed5d243d06439d7dbe0ba8c42d8299e04cc0dd4464
2018-01-13 01:53:09 +00:00
drh 9df81a2989 Add the sqlite3_value_nochange() API, usable from within the xUpdate method
of a virtual table to discover whether or not a column was unchanged at the
SQL level.

FossilOrigin-Name: dec3ea4e4e6c4b1761ddc883a29eaa50dcd663ce6199667cc0ff82f7849d4f2a
2018-01-12 23:38:10 +00:00
drh 41fb367a2c Improved comments. Slightly tighter implementation, but no big changes.
FossilOrigin-Name: a1b3f28569f2a8d82b2931527fdfe191b421f3e1ea18ee30e04211e1ad645993
2018-01-12 23:18:38 +00:00
drh ce2fbd1b02 Add the experimental sqlite3_value_nochange() interface usable by xUpdate
methods of virtual tables to see if a column has actually changed values.

FossilOrigin-Name: 8b7be15ece9e2e83959bb0e21e240106fe1077431242c3cc6b81f1baa2382f40
2018-01-12 21:00:14 +00:00
drh 4ec6f3a075 Simplification to the implementation of OP_Insert.
FossilOrigin-Name: 6acbdba59e9df4313a6232d925a70390acdc43dfa380b4fba7bb8bd442d6e728
2018-01-12 19:33:18 +00:00
dan 5871318407 Fix error handling in sqlite3session_diff() when it is invoked for table
"sqlite_stat1".

FossilOrigin-Name: 874285e477dd9bd164e25ddb08b6b80daaa8cfd111b4180ecce59b1ce26f77a5
2018-01-12 19:20:15 +00:00
drh 84ebe2b303 Avoid an unnecessary branch when not using pre-update hooks.
FossilOrigin-Name: ec96707eb359c7e0597ee22e5ae017774366463dffa6bdb06e4438b09549f5c0
2018-01-12 18:46:52 +00:00
drh 3f975373ce Fix obsolete comments. No changes to code.
FossilOrigin-Name: ec39c99bea024ffce9b87bbf3d80087ff772f43f7fb7e238754c364f7db2a17b
2018-01-12 18:03:38 +00:00
dan f3e3dfe96c Include changes made to the sqlite_stat1 table in changesets
generated by the sessions module. sqlite_stat1 entries in such changesets are
ignored by legacy clients.

FossilOrigin-Name: 2064233533edec0308d0212fb08e72fd14c760a1c88452424cae298e9eaf4af8
2018-01-12 17:25:25 +00:00
dan 614efe2b4b Experimental change to include changes made to the sqlite_stat1 table in
changesets generated by the sessions module. sqlite_stat1 entries in such
changesets are ignored by legacy clients.

FossilOrigin-Name: bd46c4429693545eb16db85692fc591ac529796aa746f5f21df1ce4380619320
2018-01-12 16:44:29 +00:00
drh 6ac7303e1a Always use utimes() instead of utimensat() since the latter is not available
even on some recent unix systems.

FossilOrigin-Name: 30ed7a4b6408f0ca921abc4d8b7bb5404fc7708cedcd104b017b361054e7148c
2018-01-12 14:34:45 +00:00
dan f225059b8b Add a test to ensure that the sqlite3changeset_apply() function ignores tables
that do not have the expected primary keys.

FossilOrigin-Name: bf2daf06279e46bc37cc92ad1becec1b12d2aa804a14b101fca8b3a7fdb280c3
2018-01-12 12:02:02 +00:00
drh afd4eef575 Add the sqlite3_vtab_nochange() interface. Test cases are in TH3.
FossilOrigin-Name: a5d09dfaa337fa51d6e702c6aefe58824ab1e7d221c6e79166e2c6f9c7ab1501
2018-01-11 18:15:40 +00:00
dan 66a3a91aa6 Change zipfile to be a WITHOUT ROWID virtual table and table-valued function.
FossilOrigin-Name: 931201f64e04247ed613a0301fcc86c3a337c2ed162c6370a80c67a1dd919e7c
2018-01-11 17:33:48 +00:00
dan 5e9bbe1924 Add test cases for running multiple RBU operations within the same process
concurrently.

FossilOrigin-Name: 407b5ed35c178bb0dbc69c8b902652038a0653d55a58a7543f9d4857c6baf3ea
2018-01-11 16:16:03 +00:00
drh 91694dbdd2 Test cases for sqlite3_normalize().
FossilOrigin-Name: 658f42257d56a3562dfa8e55023c6e497f55c565cd751d942de3a9e0cb2fa708
2018-01-08 20:04:57 +00:00
drh d19866bb98 Special handling of the NULL keyword. Sometimes it is a literal, and sometimes
it is a keyword.

FossilOrigin-Name: db5d138e97f22ad4d4d11dbef96df93696ba0e557809066bc263ca3c3898f349
2018-01-08 19:29:28 +00:00
drh ef42481224 Add IN-operator normalizating and the SQLITE_NORMALIZE_CLI compile-time
option for generating a stand-alone program.

FossilOrigin-Name: d77dbb398afa80c1b3373c55f278491e83d5c80ddc22dbc303876bdcbc127df9
2018-01-08 19:18:27 +00:00
drh a41f2855e9 First code for an auxiliary function that will normalize an SQL statement.
FossilOrigin-Name: 84814aac81e54f03430f180926156ab0fc01e22bbce2bb228b698ea0d4a588ea
2018-01-08 16:54:26 +00:00
drh e616735cb1 Fix compiler warnings on Windows.
FossilOrigin-Name: 512b8e40c4ce2066d230b5f007bd704dc3577e21c55131ef07d90bf2fcf91b40
2018-01-03 23:54:18 +00:00
drh a5bb43518b New test cases and fixes for minor problems.
FossilOrigin-Name: e0da2cc382e0db33d0423372133115f52c77bd0093dbf816c7e88a0aad5f6582
2018-01-03 23:40:02 +00:00
drh 99abe5c478 Miscellaneous code and comment cleanup.
FossilOrigin-Name: fa6069fb3b0a4411fd6661dec7de40ece3064a2fe4b94ebfbda9e5e524e04e86
2018-01-03 22:48:38 +00:00
drh 3ec8665e22 Replace sqlite3_memdb_config() with sqlite3_deserialize(). Remove the
"db memdb" command from the TCL interface, replacing it with "db serialize"
and "db deserialize".

FossilOrigin-Name: 2f6e9df9f0c5a9e5b1acb99cfa9486850cc1822d35b0989e779a7a10f3b1f1ac
2018-01-03 19:03:31 +00:00
drh cb7d541d3a Replace the sqlite3_memdb_ptr() interface with the more general
sqlite3_serialize() interface.

FossilOrigin-Name: 8cf2ed4eff6d2e0958656e23384b05ead2128b678b0b69a591878af4190cd077
2018-01-03 16:49:52 +00:00
drh 4dcac40e3d Simplify the "sqlite3" command in the TCL interface. The filename is now
optional.  There is a new --memdb option with an argument that is the blob
to which the database content should be initialized.

FossilOrigin-Name: 47398ae77236a92f6b9345aa397361b6df127a9a2895c0771d506b0be10822b9
2018-01-03 13:20:02 +00:00
mistachkin 7de2c3e5ee Fix typo in the Makefile for MSVC.
FossilOrigin-Name: e5c6ade8ee596eaffd98d1d7ce9c7c968cd2d45f206603b894026e7ad7ac15b6
2018-01-03 12:39:35 +00:00
drh ac442f41c1 Add support for the "memdb" VFS and the sqlite3_memdb_ptr() and
sqlite3_memdb_config() interfaces, to enable an SQLite database to be
manipulated as an in-memory object.

FossilOrigin-Name: fb2ac2d2fa6374084f3325b41b257c7a3ace43aade4b666ec4be93b6b70dc39a
2018-01-03 01:28:46 +00:00
171 changed files with 10469 additions and 2280 deletions
+16 -4
View File
@@ -180,7 +180,7 @@ LIBOBJS0 = alter.lo analyze.lo attach.lo auth.lo \
func.lo global.lo hash.lo \
icu.lo insert.lo json1.lo legacy.lo loadext.lo \
main.lo malloc.lo mem0.lo mem1.lo mem2.lo mem3.lo mem5.lo \
memjournal.lo \
memdb.lo memjournal.lo \
mutex.lo mutex_noop.lo mutex_unix.lo mutex_w32.lo \
notify.lo opcodes.lo os.lo os_unix.lo os_win.lo \
pager.lo parse.lo pcache.lo pcache1.lo pragma.lo prepare.lo printf.lo \
@@ -240,6 +240,7 @@ SRC = \
$(TOP)/src/mem2.c \
$(TOP)/src/mem3.c \
$(TOP)/src/mem5.c \
$(TOP)/src/memdb.c \
$(TOP)/src/memjournal.c \
$(TOP)/src/msvc.h \
$(TOP)/src/mutex.c \
@@ -440,6 +441,7 @@ TESTSRC += \
$(TOP)/ext/misc/ieee754.c \
$(TOP)/ext/misc/mmapwarm.c \
$(TOP)/ext/misc/nextchar.c \
$(TOP)/ext/misc/normalize.c \
$(TOP)/ext/misc/percentile.c \
$(TOP)/ext/misc/regexp.c \
$(TOP)/ext/misc/remember.c \
@@ -590,6 +592,7 @@ SHELL_OPT += -DSQLITE_INTROSPECTION_PRAGMAS
FUZZERSHELL_OPT = -DSQLITE_ENABLE_JSON1
FUZZCHECK_OPT = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_MEMSYS5 -DSQLITE_OSS_FUZZ
FUZZCHECK_OPT += -DSQLITE_MAX_MEMORY=50000000
FUZZCHECK_OPT += -DSQLITE_PRINTF_PRECISION_LIMIT=1000
FUZZCHECK_SRC = $(TOP)/test/fuzzcheck.c $(TOP)/test/ossfuzz.c
DBFUZZ_OPT =
@@ -647,6 +650,9 @@ ossshell$(TEXE): $(TOP)/test/ossfuzz.c $(TOP)/test/ossshell.c sqlite3.c sqlite3.
$(LTLINK) -o $@ $(FUZZCHECK_OPT) $(TOP)/test/ossshell.c \
$(TOP)/test/ossfuzz.c sqlite3.c $(TLIBS)
sessionfuzz$(TEXE): $(TOP)/test/sessionfuzz.c sqlite3.c sqlite3.h
$(CC) $(CFLAGS) -I. -o $@ $(TOP)/test/sessionfuzz.c $(TLIBS)
dbfuzz$(TEXE): $(TOP)/test/dbfuzz.c sqlite3.c sqlite3.h
$(LTLINK) -o $@ $(DBFUZZ_OPT) $(TOP)/test/dbfuzz.c sqlite3.c $(TLIBS)
@@ -827,6 +833,9 @@ mem3.lo: $(TOP)/src/mem3.c $(HDR)
mem5.lo: $(TOP)/src/mem5.c $(HDR)
$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/mem5.c
memdb.lo: $(TOP)/src/memdb.c $(HDR)
$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/memdb.c
memjournal.lo: $(TOP)/src/memjournal.c $(HDR)
$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/memjournal.c
@@ -1160,14 +1169,17 @@ fulltestonly: $(TESTPROGS) fuzztest
./testfixture$(TEXE) $(TOP)/test/full.test
# Fuzz testing
fuzztest: fuzzcheck$(TEXE) $(FUZZDATA)
fuzztest: fuzzcheck$(TEXE) $(FUZZDATA) sessionfuzz$(TEXE) $(TOP)/test/sessionfuzz-data1.db
./fuzzcheck$(TEXE) $(FUZZDATA)
./sessionfuzz$(TEXE) run $(TOP)/test/sessionfuzz-data1.db
fastfuzztest: fuzzcheck$(TEXE) $(FUZZDATA)
fastfuzztest: fuzzcheck$(TEXE) $(FUZZDATA) sessionfuzz$(TEXE) $(TOP)/test/sessionfuzz-data1.db
./fuzzcheck$(TEXE) --limit-mem 100M $(FUZZDATA)
./sessionfuzz$(TEXE) run $(TOP)/test/sessionfuzz-data1.db
valgrindfuzz: fuzzcheck$(TEXT) $(FUZZDATA)
valgrindfuzz: fuzzcheck$(TEXT) $(FUZZDATA) sessionfuzz$(TEXE) $(TOP)/test/sessionfuzz-data1.db
valgrind ./fuzzcheck$(TEXE) --cell-size-check --limit-mem 10M --timeout 600 $(FUZZDATA)
valgrind ./sessionfuzz$(TEXE) run $(TOP)/test/sessionfuzz-data1.db
# The veryquick.test TCL tests.
#
+19 -11
View File
@@ -1186,7 +1186,7 @@ LIBOBJS0 = vdbe.lo parse.lo alter.lo analyze.lo attach.lo auth.lo \
func.lo global.lo hash.lo \
icu.lo insert.lo legacy.lo loadext.lo \
main.lo malloc.lo mem0.lo mem1.lo mem2.lo mem3.lo mem5.lo \
memjournal.lo \
memdb.lo memjournal.lo \
mutex.lo mutex_noop.lo mutex_unix.lo mutex_w32.lo \
notify.lo opcodes.lo os.lo os_unix.lo os_win.lo \
pager.lo pcache.lo pcache1.lo pragma.lo prepare.lo printf.lo \
@@ -1259,6 +1259,7 @@ SRC00 = \
$(TOP)\src\mem2.c \
$(TOP)\src\mem3.c \
$(TOP)\src\mem5.c \
$(TOP)\src\memdb.c \
$(TOP)\src\memjournal.c \
$(TOP)\src\mutex.c \
$(TOP)\src\mutex_noop.c \
@@ -1500,6 +1501,7 @@ TESTEXT = \
$(TOP)\ext\misc\ieee754.c \
$(TOP)\ext\misc\mmapwarm.c \
$(TOP)\ext\misc\nextchar.c \
$(TOP)\ext\misc\normalize.c \
$(TOP)\ext\misc\percentile.c \
$(TOP)\ext\misc\regexp.c \
$(TOP)\ext\misc\remember.c \
@@ -1614,12 +1616,11 @@ SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_RTREE
#
MPTESTER_COMPILE_OPTS = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_FTS5
FUZZERSHELL_COMPILE_OPTS = -DSQLITE_ENABLE_JSON1
FUZZCHECK_COMPILE_OPTS = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_MEMSYS5 -DSQLITE_OSS_FUZZ -DSQLITE_MAX_MEMORY=50000000
FUZZCHECK_COMPILE_OPTS = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_MEMSYS5 -DSQLITE_OSS_FUZZ -DSQLITE_MAX_MEMORY=50000000 -DSQLITE_PRINTF_PRECISION_LIMIT=1000
FUZZCHECK_SRC = $(TOP)\test\fuzzcheck.c $(TOP)\test\ossfuzz.c
OSSSHELL_SRC = $(TOP)\test\ossshell.c $(TOP)\test\ossfuzz.c
DBFUZZ_COMPILE_OPTS = -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION
KV_COMPILE_OPTS = -DSQLITE_THREADSAFE=0 -DSQLITE_DIRECT_OVERFLOW_READ
DBSELFTEST_COMPILE_OPTS = -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -DSQLITE_ENABLE_RTREE -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_FTS5
ST_COMPILE_OPTS = -DSQLITE_THREADSAFE=0
# Standard options to testfixture.
@@ -1687,7 +1688,7 @@ dbhash.exe: $(TOP)\tool\dbhash.c $(SQLITE3C) $(SQLITE3H)
$(LTLINK) $(NO_WARN) $(TOP)\tool\dbhash.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
scrub.exe: $(TOP)\ext\misc\scrub.c $(SQLITE3C) $(SQLITE3H)
$(LTLINK) $(NO_WARN) $(TOP)\ext\misc\scrub.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
$(LTLINK) $(NO_WARN) -DSCRUB_STANDALONE=1 $(TOP)\ext\misc\scrub.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
srcck1.exe: $(TOP)\tool\srcck1.c
$(BCC) $(NO_WARN) -Fe$@ $(TOP)\tool\srcck1.c
@@ -1707,6 +1708,9 @@ fuzzcheck.exe: $(FUZZCHECK_SRC) $(SQLITE3C) $(SQLITE3H)
ossshell.exe: $(OSSSHELL_SRC) $(SQLITE3C) $(SQLITE3H)
$(LTLINK) $(NO_WARN) $(FUZZCHECK_COMPILE_OPTS) $(OSSSHELL_SRC) $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
sessionfuzz.exe: zlib $(TOP)\test\sessionfuzz.c $(SQLITE3C) $(SQLITE3H)
$(LTLINK) $(NO_WARN) -I$(ZLIBINCDIR) $(TOP)\test\sessionfuzz.c /link $(LDFLAGS) $(LTLINKOPTS) /LIBPATH:$(ZLIBLIBDIR) $(ZLIBLIB)
mptester.exe: $(TOP)\mptest\mptest.c $(SQLITE3C) $(SQLITE3H)
$(LTLINK) $(NO_WARN) $(MPTESTER_COMPILE_OPTS) $(TOP)\mptest\mptest.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
@@ -1908,6 +1912,9 @@ mem3.lo: $(TOP)\src\mem3.c $(HDR)
mem5.lo: $(TOP)\src\mem5.c $(HDR)
$(LTCOMPILE) $(CORE_COMPILE_OPTS) -c $(TOP)\src\mem5.c
memdb.lo: $(TOP)\src\memdb.c $(HDR)
$(LTCOMPILE) $(CORE_COMPILE_OPTS) -c $(TOP)\src\memdb.c
memjournal.lo: $(TOP)\src\memjournal.c $(HDR)
$(LTCOMPILE) $(CORE_COMPILE_OPTS) -c $(TOP)\src\memjournal.c
@@ -2084,7 +2091,7 @@ keywordhash.h: $(TOP)\tool\mkkeywordhash.c mkkeywordhash.exe
# Source files that go into making shell.c
SHELL_SRC = \
$(TOP)\src\shell.c.in \
$(TOP)\ext\misc\appendvfs.c \
$(TOP)\ext\misc\appendvfs.c \
$(TOP)\ext\misc\shathree.c \
$(TOP)\ext\misc\fileio.c \
$(TOP)\ext\misc\completion.c \
@@ -2251,6 +2258,7 @@ TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_SERIES_CONSTRAINT_VERIFY=1
TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_DEFAULT_PAGE_SIZE=1024
TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_ENABLE_STMTVTAB
TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_ENABLE_DBPAGE_VTAB
TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_ENABLE_JSON1
TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) $(TEST_CCONV_OPTS)
TESTFIXTURE_SRC0 = $(TESTEXT) $(TESTSRC2)
@@ -2364,11 +2372,11 @@ sqlite3_checker.exe: sqlite3_checker.c $(LIBRESOBJS)
$(LTLINK) $(NO_WARN) -DBUILD_sqlite -I$(TCLINCDIR) sqlite3_checker.c \
/link $(LDFLAGS) $(LTLINKOPTS) $(TCLLIBPATHS) $(LTLIBPATHS) $(LIBRESOBJS) $(TCLLIBS) $(LTLIBS) $(TLIBS)
dbdump.exe: $(TOP)\ext\misc\dbdump.c $(SQLITE3C) $(SQLITE3H)
dbdump.exe: $(TOP)\ext\misc\dbdump.c $(SQLITE3C) $(SQLITE3H) $(LIBRESOBJS)
$(LTLINK) $(NO_WARN) -DDBDUMP_STANDALONE $(TOP)\ext\misc\dbdump.c $(SQLITE3C) \
/link $(LDFLAGS) $(LTLINKOPTS) $(LTLIBPATHS) $(LIBRESOBJS) $(LTLIBS)
testloadext.lo: $(TOP)\src\test_loadext.c
testloadext.lo: $(TOP)\src\test_loadext.c $(SQLITE3H)
$(LTCOMPILE) $(NO_WARN) -c $(TOP)\src\test_loadext.c
testloadext.dll: testloadext.lo
@@ -2421,9 +2429,6 @@ kvtest.exe: $(TOP)\test\kvtest.c $(SQLITE3C) $(SQLITE3H)
$(LTLINK) $(NO_WARN) $(KV_COMPILE_OPTS) \
$(TOP)\test\kvtest.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
dbselftest.exe: $(TOP)\test\dbselftest.c $(SQLITE3C) $(SQLITE3H)
$(LTLINK) $(NO_WARN) $(DBSELFTEST_COMPILE_OPTS) $(TOP)\test\dbselftest.c $(SQLITE3C)
rbu.exe: $(TOP)\ext\rbu\rbu.c $(TOP)\ext\rbu\sqlite3rbu.c $(SQLITE3C) $(SQLITE3H)
$(LTLINK) $(NO_WARN) -DSQLITE_ENABLE_RBU \
$(TOP)\ext\rbu\rbu.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
@@ -2463,7 +2468,10 @@ clean:
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 dbhash.exe 2>NUL
del /Q sqltclsh.exe 2>NUL
del /Q sqltclsh.* 2>NUL
del /Q dbfuzz.exe sessionfuzz.exe 2>NUL
del /Q kvtest.exe ossshell.exe scrub.exe 2>NUL
del /Q showshm.exe sqlite3_checker.* sqlite3_expert.exe 2>NUL
del /Q fts5.* fts5parse.* 2>NUL
del /Q lsm.h lsm1.c 2>NUL
# <</mark>>
+16 -15
View File
@@ -1,7 +1,7 @@
<h1 align="center">SQLite Source Repository</h1>
This repository contains the complete source code for the SQLite database
engine. Some test scripts are also include. However, many other test scripts
engine. Some test scripts are also included. However, many other test scripts
and most of the documentation are managed separately.
If you are reading this on a Git mirror someplace, you are doing it wrong.
@@ -14,15 +14,17 @@ SQLite sources are managed using the
[Fossil](https://www.fossil-scm.org/), a distributed version control system
that was specifically designed to support SQLite development.
If you do not want to use Fossil, you can download tarballs or ZIP
archives as follows:
archives or [SQLite archives](https://sqlite.org/cli.html#sqlar) as follows:
* Lastest trunk check-in:
<https://www.sqlite.org/src/tarball/sqlite.tar.gz> or
<https://www.sqlite.org/src/zip/sqlite.zip>.
* Lastest trunk check-in as
[Tarball](https://www.sqlite.org/src/tarball/sqlite.tar.gz),
[ZIP-archive](https://www.sqlite.org/src/zip/sqlite.zip), or
[SQLite-archive](https://www.sqlite.org/src/sqlar/sqlite.sqlar).
* Latest release:
<https://www.sqlite.org/src/tarball/sqlite.tar.gz?r=release> or
<https://www.sqlite.org/src/zip/sqlite.zip?r=release>.
* Latest release as
[Tarball](https://www.sqlite.org/src/tarball/sqlite.tar.gz?r=release),
[ZIP-archive](https://www.sqlite.org/src/zip/sqlite.zip?r=release), or
[SQLite-archive](https://www.sqlite.org/src/sqlar/sqlite.sqlar?r=release).
* For other check-ins, substitute an appropriate branch name or
tag or hash prefix for "release" in the URLs of the previous
@@ -104,7 +106,6 @@ recommended.
SQLite does not require [Tcl](http://www.tcl.tk/) to run, but a Tcl installation
is required by the makefiles (including those for MSVC). SQLite contains
a lot of generated code and Tcl is used to do much of that code generation.
The makefiles also require AWK.
## Source Code Tour
@@ -116,7 +117,7 @@ The **src/** also contains the "shell.c" file
which is the main program for the "sqlite3.exe"
[command-line shell](https://sqlite.org/cli.html) and
the "tclsqlite.c" file which implements the
[TCL bindings](https://sqlite.org/tclsqlite.html) for SQLite.
[Tcl bindings](https://sqlite.org/tclsqlite.html) for SQLite.
(Historical note: SQLite began as a Tcl
extension and only later escaped to the wild as an independent library.)
@@ -163,14 +164,14 @@ template for generating its parser.
Lemon also generates the **parse.h** header file, at the same time it
generates parse.c. But the parse.h header file is
modified further (to add additional symbols) using the ./addopcodes.awk
AWK script.
modified further (to add additional symbols) using the ./addopcodes.tcl
Tcl script.
The **opcodes.h** header file contains macros that define the numbers
corresponding to opcodes in the "VDBE" virtual machine. The opcodes.h
file is generated by the scanning the src/vdbe.c source file. The
AWK script at ./mkopcodeh.awk does this scan and generates opcodes.h.
A second AWK script, ./mkopcodec.awk, then scans opcodes.h to generate
Tcl script at ./mkopcodeh.tcl does this scan and generates opcodes.h.
A second Tcl script, ./mkopcodec.tcl, then scans opcodes.h to generate
the **opcodes.c** source file, which contains a reverse mapping from
opcode-number to opcode-name that is used for EXPLAIN output.
@@ -280,7 +281,7 @@ Key files:
* **test*.c** - Files in the src/ folder that begin with "test" go into
building the "testfixture.exe" program. The testfixture.exe program is
an enhanced TCL shell. The testfixture.exe program runs scripts in the
an enhanced Tcl shell. The testfixture.exe program runs scripts in the
test/ folder to validate the core SQLite code. The testfixture program
(and some other test programs too) is build and run when you type
"make test".
+1 -1
View File
@@ -1 +1 @@
3.22.0
3.23.0
+2 -2
View File
@@ -1,5 +1,5 @@
AM_CFLAGS = @THREADSAFE_FLAGS@ @DYNAMIC_EXTENSION_FLAGS@ @FTS5_FLAGS@ @JSON1_FLAGS@ @SESSION_FLAGS@ -DSQLITE_ENABLE_FTS3 -DSQLITE_ENABLE_RTREE
AM_CFLAGS = @THREADSAFE_FLAGS@ @DYNAMIC_EXTENSION_FLAGS@ @FTS5_FLAGS@ @JSON1_FLAGS@ @ZLIB_FLAGS@ @SESSION_FLAGS@ -DSQLITE_ENABLE_FTS3 -DSQLITE_ENABLE_RTREE
lib_LTLIBRARIES = libsqlite3.la
libsqlite3_la_SOURCES = sqlite3.c
@@ -10,7 +10,7 @@ sqlite3_SOURCES = shell.c sqlite3.h
EXTRA_sqlite3_SOURCES = sqlite3.c
sqlite3_LDADD = @EXTRA_SHELL_OBJ@ @READLINE_LIBS@
sqlite3_DEPENDENCIES = @EXTRA_SHELL_OBJ@
sqlite3_CFLAGS = $(AM_CFLAGS) -DSQLITE_ENABLE_EXPLAIN_COMMENTS -DSQLITE_ENABLE_DBPAGE_VTAB -DSQLITE_ENABLE_STMTVTAB -DSQLITE_ENABLE_DBSTAT_VTAB
sqlite3_CFLAGS = $(AM_CFLAGS) -DSQLITE_ENABLE_EXPLAIN_COMMENTS -DSQLITE_ENABLE_DBPAGE_VTAB -DSQLITE_ENABLE_STMTVTAB -DSQLITE_ENABLE_DBSTAT_VTAB $(SHELL_CFLAGS)
include_HEADERS = sqlite3.h sqlite3ext.h
+1
View File
@@ -931,6 +931,7 @@ LIBRESOBJS =
SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_EXPLAIN_COMMENTS -DSQLITE_ENABLE_STMTVTAB
SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_DBPAGE_VTAB -DSQLITE_ENABLE_DBSTAT_VTAB
SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_OFFSET_SQL_FUNC -DSQLITE_INTROSPECTION_PRAGMAS
SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_RTREE
!ENDIF
+7
View File
@@ -164,6 +164,13 @@ AC_SUBST(EXTRA_SHELL_OBJ)
#-----------------------------------------------------------------------
AC_CHECK_FUNCS(posix_fallocate)
AC_CHECK_HEADERS(zlib.h,[
AC_SEARCH_LIBS(deflate,z,[ZLIB_FLAGS="-DSQLITE_HAVE_ZLIB"])
])
AC_SUBST(ZLIB_FLAGS)
AC_SEARCH_LIBS(system,,,[SHELL_CFLAGS="-DSQLITE_NOHAVE_SYSTEM"])
AC_SUBST(SHELL_CFLAGS)
#-----------------------------------------------------------------------
# UPDATE: Maybe it's better if users just set CFLAGS before invoking
Vendored
+9 -9
View File
@@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.69 for sqlite 3.22.0.
# Generated by GNU Autoconf 2.69 for sqlite 3.23.0.
#
#
# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
@@ -726,8 +726,8 @@ MAKEFLAGS=
# Identity of this package.
PACKAGE_NAME='sqlite'
PACKAGE_TARNAME='sqlite'
PACKAGE_VERSION='3.22.0'
PACKAGE_STRING='sqlite 3.22.0'
PACKAGE_VERSION='3.23.0'
PACKAGE_STRING='sqlite 3.23.0'
PACKAGE_BUGREPORT=''
PACKAGE_URL=''
@@ -1465,7 +1465,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
\`configure' configures sqlite 3.22.0 to adapt to many kinds of systems.
\`configure' configures sqlite 3.23.0 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1530,7 +1530,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
short | recursive ) echo "Configuration of sqlite 3.22.0:";;
short | recursive ) echo "Configuration of sqlite 3.23.0:";;
esac
cat <<\_ACEOF
@@ -1655,7 +1655,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
sqlite configure 3.22.0
sqlite configure 3.23.0
generated by GNU Autoconf 2.69
Copyright (C) 2012 Free Software Foundation, Inc.
@@ -2074,7 +2074,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
It was created by sqlite $as_me 3.22.0, which was
It was created by sqlite $as_me 3.23.0, which was
generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@
@@ -12242,7 +12242,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
This file was extended by sqlite $as_me 3.22.0, which was
This file was extended by sqlite $as_me 3.23.0, which was
generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -12308,7 +12308,7 @@ _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\
sqlite config.status 3.22.0
sqlite config.status 3.23.0
configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\"
+2 -1
View File
@@ -93,8 +93,9 @@ int main(int argc, char **argv){
}else{
for(i=1; i<(argc-1); i++){
char *zArg = argv[i];
int nArg;
if( zArg[0]=='-' && zArg[1]=='-' && zArg[2]!=0 ) zArg++;
int nArg = (int)strlen(zArg);
nArg = (int)strlen(zArg);
if( nArg>=2 && 0==sqlite3_strnicmp(zArg, "-file", nArg) ){
if( ++i==(argc-1) ) option_requires_argument("-file");
rc = readSqlFromFile(p, argv[i], &zErr);
+15 -2
View File
@@ -507,6 +507,10 @@ static int expertUpdate(
sqlite3_value **azData,
sqlite_int64 *pRowid
){
(void)pVtab;
(void)nData;
(void)azData;
(void)pRowid;
return SQLITE_OK;
}
@@ -516,6 +520,7 @@ static int expertUpdate(
static int expertOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){
int rc = SQLITE_OK;
ExpertCsr *pCsr;
(void)pVTab;
pCsr = idxMalloc(&rc, sizeof(ExpertCsr));
*ppCursor = (sqlite3_vtab_cursor*)pCsr;
return rc;
@@ -565,6 +570,7 @@ static int expertNext(sqlite3_vtab_cursor *cur){
** Virtual table module xRowid method.
*/
static int expertRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
(void)cur;
*pRowid = 0;
return SQLITE_OK;
}
@@ -595,6 +601,10 @@ static int expertFilter(
sqlite3expert *pExpert = pVtab->pExpert;
int rc;
(void)idxNum;
(void)idxStr;
(void)argc;
(void)argv;
rc = sqlite3_finalize(pCsr->pData);
pCsr->pData = 0;
if( rc==SQLITE_OK ){
@@ -1005,7 +1015,7 @@ static int idxCreateFromWhere(
** Create candidate indexes in database [dbm] based on the data in
** linked-list pScan.
*/
static int idxCreateCandidates(sqlite3expert *p, char **pzErr){
static int idxCreateCandidates(sqlite3expert *p){
int rc = SQLITE_OK;
IdxScan *pIter;
@@ -1168,6 +1178,8 @@ static int idxAuthCallback(
const char *zTrigger
){
int rc = SQLITE_OK;
(void)z4;
(void)zTrigger;
if( eOp==SQLITE_INSERT || eOp==SQLITE_UPDATE || eOp==SQLITE_DELETE ){
if( sqlite3_stricmp(zDb, "main")==0 ){
sqlite3expert *p = (sqlite3expert*)pCtx;
@@ -1370,6 +1382,7 @@ static void idxSampleFunc(
struct IdxSampleCtx *p = (struct IdxSampleCtx*)sqlite3_user_data(pCtx);
int bRet;
(void)argv;
assert( argc==0 );
if( p->nRow==0.0 ){
bRet = 1;
@@ -1855,7 +1868,7 @@ int sqlite3_expert_analyze(sqlite3expert *p, char **pzErr){
/* Create candidate indexes within the in-memory database file */
if( rc==SQLITE_OK ){
rc = idxCreateCandidates(p, pzErr);
rc = idxCreateCandidates(p);
}
/* Generate the stat1 data */
+6 -3
View File
@@ -1908,6 +1908,7 @@ static int fts3WriteSegment(
sqlite3_bind_blob(pStmt, 2, z, n, SQLITE_STATIC);
sqlite3_step(pStmt);
rc = sqlite3_reset(pStmt);
sqlite3_bind_null(pStmt, 2);
}
return rc;
}
@@ -1964,6 +1965,7 @@ static int fts3WriteSegdir(
sqlite3_bind_blob(pStmt, 6, zRoot, nRoot, SQLITE_STATIC);
sqlite3_step(pStmt);
rc = sqlite3_reset(pStmt);
sqlite3_bind_null(pStmt, 6);
}
return rc;
}
@@ -3443,6 +3445,7 @@ static void fts3UpdateDocTotals(
sqlite3_bind_blob(pStmt, 2, pBlob, nBlob, SQLITE_STATIC);
sqlite3_step(pStmt);
*pRC = sqlite3_reset(pStmt);
sqlite3_bind_null(pStmt, 2);
sqlite3_free(a);
}
@@ -4631,6 +4634,7 @@ static int fts3TruncateSegment(
sqlite3_bind_int(pChomp, 4, iIdx);
sqlite3_step(pChomp);
rc = sqlite3_reset(pChomp);
sqlite3_bind_null(pChomp, 2);
}
}
@@ -4710,6 +4714,7 @@ static int fts3IncrmergeHintStore(Fts3Table *p, Blob *pHint){
sqlite3_bind_blob(pReplace, 2, pHint->a, pHint->n, SQLITE_STATIC);
sqlite3_step(pReplace);
rc = sqlite3_reset(pReplace);
sqlite3_bind_null(pReplace, 2);
}
return rc;
@@ -5524,7 +5529,6 @@ int sqlite3Fts3UpdateMethod(
){
Fts3Table *p = (Fts3Table *)pVtab;
int rc = SQLITE_OK; /* Return Code */
int isRemove = 0; /* True for an UPDATE or DELETE */
u32 *aSzIns = 0; /* Sizes of inserted documents */
u32 *aSzDel = 0; /* Sizes of deleted documents */
int nChng = 0; /* Net change in number of documents */
@@ -5622,7 +5626,6 @@ int sqlite3Fts3UpdateMethod(
if( sqlite3_value_type(apVal[0])!=SQLITE_NULL ){
assert( sqlite3_value_type(apVal[0])==SQLITE_INTEGER );
rc = fts3DeleteByRowid(p, apVal[0], &nChng, aSzDel);
isRemove = 1;
}
/* If this is an INSERT or UPDATE operation, insert the new record. */
@@ -5634,7 +5637,7 @@ int sqlite3Fts3UpdateMethod(
rc = FTS_CORRUPT_VTAB;
}
}
if( rc==SQLITE_OK && (!isRemove || *pRowid!=p->iPrevDocid ) ){
if( rc==SQLITE_OK ){
rc = fts3PendingTermsDocid(p, 0, iLangid, *pRowid);
}
if( rc==SQLITE_OK ){
+1 -1
View File
@@ -1676,7 +1676,7 @@ Fts5ExprPhrase *sqlite3Fts5ParseTerm(
** no token characters at all. (e.g ... MATCH '""'). */
sCtx.pPhrase = sqlite3Fts5MallocZero(&pParse->rc, sizeof(Fts5ExprPhrase));
}else if( sCtx.pPhrase->nTerm ){
sCtx.pPhrase->aTerm[sCtx.pPhrase->nTerm-1].bPrefix = bPrefix;
sCtx.pPhrase->aTerm[sCtx.pPhrase->nTerm-1].bPrefix = (u8)bPrefix;
}
pParse->apPhrase[pParse->nPhrase-1] = sCtx.pPhrase;
}
+4
View File
@@ -758,6 +758,7 @@ static void fts5DataWrite(Fts5Index *p, i64 iRowid, const u8 *pData, int nData){
sqlite3_bind_blob(p->pWriter, 2, pData, nData, SQLITE_STATIC);
sqlite3_step(p->pWriter);
p->rc = sqlite3_reset(p->pWriter);
sqlite3_bind_null(p->pWriter, 2);
}
/*
@@ -2386,6 +2387,7 @@ static void fts5SegIterSeekInit(
bDlidx = (val & 0x0001);
}
p->rc = sqlite3_reset(pIdxSelect);
sqlite3_bind_null(pIdxSelect, 2);
if( iPg<pSeg->pgnoFirst ){
iPg = pSeg->pgnoFirst;
@@ -3598,6 +3600,7 @@ static int fts5AllocateSegid(Fts5Index *p, Fts5Structure *pStruct){
sqlite3_bind_blob(pIdxSelect, 2, aBlob, 2, SQLITE_STATIC);
assert( sqlite3_step(pIdxSelect)!=SQLITE_ROW );
p->rc = sqlite3_reset(pIdxSelect);
sqlite3_bind_null(pIdxSelect, 2);
}
}
#endif
@@ -3724,6 +3727,7 @@ static void fts5WriteFlushBtree(Fts5Index *p, Fts5SegWriter *pWriter){
sqlite3_bind_int64(p->pIdxWriter, 3, bFlag + ((i64)pWriter->iBtPage<<1));
sqlite3_step(p->pIdxWriter);
p->rc = sqlite3_reset(p->pIdxWriter);
sqlite3_bind_null(p->pIdxWriter, 2);
}
pWriter->iBtPage = 0;
}
+2
View File
@@ -458,6 +458,7 @@ static int fts5StorageInsertDocsize(
sqlite3_bind_blob(pReplace, 2, pBuf->p, pBuf->n, SQLITE_STATIC);
sqlite3_step(pReplace);
rc = sqlite3_reset(pReplace);
sqlite3_bind_null(pReplace, 2);
}
}
return rc;
@@ -1118,6 +1119,7 @@ int sqlite3Fts5StorageConfigValue(
}
sqlite3_step(pReplace);
rc = sqlite3_reset(pReplace);
sqlite3_bind_null(pReplace, 1);
}
if( rc==SQLITE_OK && pVal ){
int iNew = p->pConfig->iCookie + 1;
+2 -2
View File
@@ -482,7 +482,7 @@ static int SQLITE_TCLAPI xF5tApi(
rc = p->pApi->xPhraseFirstColumn(p->pFts, iPhrase, &iter, &iCol);
if( rc!=SQLITE_OK ){
Tcl_AppendResult(interp, sqlite3ErrName(rc), 0);
Tcl_SetResult(interp, (char*)sqlite3ErrName(rc), TCL_VOLATILE);
return TCL_ERROR;
}
for( ; iCol>=0; p->pApi->xPhraseNextColumn(p->pFts, &iter, &iCol)){
@@ -924,7 +924,7 @@ static int SQLITE_TCLAPI f5tTokenizerReturn(
rc = p->xToken(p->pCtx, tflags, zToken, nToken, iStart, iEnd);
Tcl_SetResult(interp, (char*)sqlite3ErrName(rc), TCL_VOLATILE);
return TCL_OK;
return rc==SQLITE_OK ? TCL_OK : TCL_ERROR;
usage:
Tcl_WrongNumArgs(interp, 1, objv, "?-colocated? TEXT START END");
+1 -1
View File
@@ -593,5 +593,5 @@ do_execsql_test 22.1 {
}
expand_all_sql db
finish_test
+3 -3
View File
@@ -253,7 +253,7 @@ do_faultsim_test 5.2 -faults oom* -prep {
SELECT rowid, mit(matchinfo(t1, 'x')) FROM t1 WHERE t1 MATCH 'a AND c'
}
} -test {
faultsim_test_result [list 0 $::res]
faultsim_test_result [list 0 $::res] {1 {SQL logic error}}
}
do_faultsim_test 5.3 -faults oom* -prep {
@@ -264,7 +264,7 @@ do_faultsim_test 5.3 -faults oom* -prep {
SELECT count(*) FROM t1 WHERE t1 MATCH 'd AND e AND f'
}
} -test {
faultsim_test_result {0 29}
faultsim_test_result {0 29} {1 {SQL logic error}}
}
do_faultsim_test 5.4 -faults oom* -prep {
@@ -275,7 +275,7 @@ do_faultsim_test 5.4 -faults oom* -prep {
SELECT count(*) FROM t1 WHERE t1 MATCH 'x + e'
}
} -test {
faultsim_test_result {0 1}
faultsim_test_result {0 1} {1 {SQL logic error}}
}
#-------------------------------------------------------------------------
+6 -2
View File
@@ -24,6 +24,8 @@ ifcapable !fts5 {
foreach_detail_mode $testprefix {
if {"%DETAIL%" != "none"} continue
fts5_aux_test_functions db
do_execsql_test 1.0 {
@@ -98,14 +100,16 @@ do_faultsim_test 4.1 -faults oom-t* -body {
execsql { SELECT rowid, fts5_test_collist(t4) FROM t4('2') }
} -test {
faultsim_test_result \
{0 {1 {0.0 0.1 0.2} 2 {0.0 0.1 0.2} 3 {0.0 0.1 0.2}}} {1 SQLITE_NOMEM}
{0 {1 {0.0 0.1 0.2} 2 {0.0 0.1 0.2} 3 {0.0 0.1 0.2}}} \
{1 SQLITE_NOMEM} {1 SQLITE_ERROR} {1 {SQL logic error}}
}
do_faultsim_test 4.2 -faults oom-t* -body {
execsql { SELECT rowid, fts5_test_collist(t4) FROM t4('a5 OR b5 OR c5') }
} -test {
faultsim_test_result \
{0 {4 {0.0 0.1 0.2} 5 {1.0 1.1 1.2} 6 {2.0 2.1 2.2}}} {1 SQLITE_NOMEM}
{0 {4 {0.0 0.1 0.2} 5 {1.0 1.1 1.2} 6 {2.0 2.1 2.2}}} \
{1 SQLITE_NOMEM} {1 SQLITE_ERROR} {1 {SQL logic error}}
}
+2
View File
@@ -548,6 +548,8 @@ int sqlite3_appendvfs_init(
int rc = SQLITE_OK;
sqlite3_vfs *pOrig;
SQLITE_EXTENSION_INIT2(pApi);
(void)pzErrMsg;
(void)db;
pOrig = sqlite3_vfs_find(0);
apnd_vfs.iVersion = pOrig->iVersion;
apnd_vfs.pAppData = pOrig;
+2 -1
View File
@@ -339,7 +339,8 @@ static int binfoColumn(
sqlite3 *db = sqlite3_context_db_handle(ctx);
int rc = binfoCompute(db, pgno, pCsr);
if( rc ){
return rc;
pCursor->pVtab->zErrMsg = sqlite3_mprintf("%s", sqlite3_errmsg(db));
return SQLITE_ERROR;
}
}
switch( i ){
+14 -15
View File
@@ -293,7 +293,6 @@ static char **tableColumnList(DState *p, const char *zTab){
** ordinary column in the table. Verify that azRowid[j] is a valid
** name for the rowid before adding it to azCol[0]. WITHOUT ROWID
** tables will fail this last check */
int rc;
rc = sqlite3_table_column_metadata(p->db,0,zTab,azRowid[j],0,0,0,0,0);
if( rc==SQLITE_OK ) azCol[0] = azRowid[j];
break;
@@ -455,12 +454,12 @@ static int dump_callback(void *pArg, int nArg, char **azArg, char **azCol){
if( strcmp(zType, "table")==0 ){
DText sSelect;
DText sTable;
char **azCol;
char **azTCol;
int i;
int nCol;
azCol = tableColumnList(p, zTable);
if( azCol==0 ) return 0;
azTCol = tableColumnList(p, zTable);
if( azTCol==0 ) return 0;
initText(&sTable);
appendText(&sTable, "INSERT INTO ", 0);
@@ -473,12 +472,12 @@ static int dump_callback(void *pArg, int nArg, char **azArg, char **azCol){
** In other words: "INSERT INTO tab(rowid,a,b,c,...) VALUES(...)"
** instead of the usual "INSERT INTO tab VALUES(...)".
*/
if( azCol[0] ){
if( azTCol[0] ){
appendText(&sTable, "(", 0);
appendText(&sTable, azCol[0], 0);
for(i=1; azCol[i]; i++){
appendText(&sTable, azTCol[0], 0);
for(i=1; azTCol[i]; i++){
appendText(&sTable, ",", 0);
appendText(&sTable, azCol[i], quoteChar(azCol[i]));
appendText(&sTable, azTCol[i], quoteChar(azTCol[i]));
}
appendText(&sTable, ")", 0);
}
@@ -487,19 +486,19 @@ static int dump_callback(void *pArg, int nArg, char **azArg, char **azCol){
/* Build an appropriate SELECT statement */
initText(&sSelect);
appendText(&sSelect, "SELECT ", 0);
if( azCol[0] ){
appendText(&sSelect, azCol[0], 0);
if( azTCol[0] ){
appendText(&sSelect, azTCol[0], 0);
appendText(&sSelect, ",", 0);
}
for(i=1; azCol[i]; i++){
appendText(&sSelect, azCol[i], quoteChar(azCol[i]));
if( azCol[i+1] ){
for(i=1; azTCol[i]; i++){
appendText(&sSelect, azTCol[i], quoteChar(azTCol[i]));
if( azTCol[i+1] ){
appendText(&sSelect, ",", 0);
}
}
nCol = i;
if( azCol[0]==0 ) nCol--;
freeColumnList(azCol);
if( azTCol[0]==0 ) nCol--;
freeColumnList(azTCol);
appendText(&sSelect, " FROM ", 0);
appendText(&sSelect, zTable, quoteChar(zTable));
+121 -11
View File
@@ -86,6 +86,7 @@ SQLITE_EXTENSION_INIT1
# include <unistd.h>
# include <dirent.h>
# include <utime.h>
# include <sys/time.h>
#else
# include "windows.h"
# include <io.h>
@@ -158,6 +159,97 @@ static void ctxErrorMsg(sqlite3_context *ctx, const char *zFmt, ...){
va_end(ap);
}
#if defined(_WIN32)
/*
** This function is designed to convert a Win32 FILETIME structure into the
** number of seconds since the Unix Epoch (1970-01-01 00:00:00 UTC).
*/
static sqlite3_uint64 fileTimeToUnixTime(
LPFILETIME pFileTime
){
SYSTEMTIME epochSystemTime;
ULARGE_INTEGER epochIntervals;
FILETIME epochFileTime;
ULARGE_INTEGER fileIntervals;
memset(&epochSystemTime, 0, sizeof(SYSTEMTIME));
epochSystemTime.wYear = 1970;
epochSystemTime.wMonth = 1;
epochSystemTime.wDay = 1;
SystemTimeToFileTime(&epochSystemTime, &epochFileTime);
epochIntervals.LowPart = epochFileTime.dwLowDateTime;
epochIntervals.HighPart = epochFileTime.dwHighDateTime;
fileIntervals.LowPart = pFileTime->dwLowDateTime;
fileIntervals.HighPart = pFileTime->dwHighDateTime;
return (fileIntervals.QuadPart - epochIntervals.QuadPart) / 10000000;
}
/*
** This function attempts to normalize the time values found in the stat()
** buffer to UTC. This is necessary on Win32, where the runtime library
** appears to return these values as local times.
*/
static void statTimesToUtc(
const char *zPath,
struct stat *pStatBuf
){
HANDLE hFindFile;
WIN32_FIND_DATAW fd;
LPWSTR zUnicodeName;
extern LPWSTR sqlite3_win32_utf8_to_unicode(const char*);
zUnicodeName = sqlite3_win32_utf8_to_unicode(zPath);
if( zUnicodeName ){
memset(&fd, 0, sizeof(WIN32_FIND_DATA));
hFindFile = FindFirstFileW(zUnicodeName, &fd);
if( hFindFile!=NULL ){
pStatBuf->st_ctime = (time_t)fileTimeToUnixTime(&fd.ftCreationTime);
pStatBuf->st_atime = (time_t)fileTimeToUnixTime(&fd.ftLastAccessTime);
pStatBuf->st_mtime = (time_t)fileTimeToUnixTime(&fd.ftLastWriteTime);
FindClose(hFindFile);
}
sqlite3_free(zUnicodeName);
}
}
#endif
/*
** This function is used in place of stat(). On Windows, special handling
** is required in order for the included time to be returned as UTC. On all
** other systems, this function simply calls stat().
*/
static int fileStat(
const char *zPath,
struct stat *pStatBuf
){
#if defined(_WIN32)
int rc = stat(zPath, pStatBuf);
if( rc==0 ) statTimesToUtc(zPath, pStatBuf);
return rc;
#else
return stat(zPath, pStatBuf);
#endif
}
/*
** This function is used in place of lstat(). On Windows, special handling
** is required in order for the included time to be returned as UTC. On all
** other systems, this function simply calls lstat().
*/
static int fileLinkStat(
const char *zPath,
struct stat *pStatBuf
){
#if defined(_WIN32)
int rc = lstat(zPath, pStatBuf);
if( rc==0 ) statTimesToUtc(zPath, pStatBuf);
return rc;
#else
return lstat(zPath, pStatBuf);
#endif
}
/*
** Argument zFile is the name of a file that will be created and/or written
** by SQL function writefile(). This function ensures that the directory
@@ -189,7 +281,7 @@ static int makeDirectory(
if( i==nCopy ) break;
zCopy[i] = '\0';
rc2 = stat(zCopy, &sStat);
rc2 = fileStat(zCopy, &sStat);
if( rc2!=0 ){
if( mkdir(zCopy, mode & 0777) ) rc = SQLITE_ERROR;
}else{
@@ -231,7 +323,7 @@ static int writeFile(
** to do so using chmod(), it is not an error. */
struct stat sStat;
if( errno!=EEXIST
|| 0!=stat(zFile, &sStat)
|| 0!=fileStat(zFile, &sStat)
|| !S_ISDIR(sStat.st_mode)
|| ((sStat.st_mode&0777)!=(mode&0777) && 0!=chmod(zFile, mode&0777))
){
@@ -269,15 +361,23 @@ static int writeFile(
SYSTEMTIME currentTime;
LONGLONG intervals;
HANDLE hFile;
LPWSTR zUnicodeName;
extern LPWSTR sqlite3_win32_utf8_to_unicode(const char*);
GetSystemTime(&currentTime);
SystemTimeToFileTime(&currentTime, &lastAccess);
intervals = Int32x32To64(mtime, 10000000) + 116444736000000000;
lastWrite.dwLowDateTime = (DWORD)intervals;
lastWrite.dwHighDateTime = intervals >> 32;
hFile = CreateFile(
zFile, FILE_WRITE_ATTRIBUTES, 0, NULL, OPEN_EXISTING,
zUnicodeName = sqlite3_win32_utf8_to_unicode(zFile);
if( zUnicodeName==0 ){
return 1;
}
hFile = CreateFileW(
zUnicodeName, FILE_WRITE_ATTRIBUTES, 0, NULL, OPEN_EXISTING,
FILE_FLAG_BACKUP_SEMANTICS, NULL
);
sqlite3_free(zUnicodeName);
if( hFile!=INVALID_HANDLE_VALUE ){
BOOL bResult = SetFileTime(hFile, NULL, &lastAccess, &lastWrite);
CloseHandle(hFile);
@@ -285,7 +385,7 @@ static int writeFile(
}else{
return 1;
}
#elif defined(AT_FDCWD)
#elif defined(AT_FDCWD) && 0 /* utimensat() is not universally available */
/* Recent unix */
struct timespec times[2];
times[0].tv_nsec = times[1].tv_nsec = 0;
@@ -371,6 +471,7 @@ static void lsModeFunc(
int i;
int iMode = sqlite3_value_int(argv[0]);
char z[16];
(void)argc;
if( S_ISLNK(iMode) ){
z[0] = 'l';
}else if( S_ISREG(iMode) ){
@@ -436,7 +537,10 @@ static int fsdirConnect(
){
fsdir_tab *pNew = 0;
int rc;
(void)pAux;
(void)argc;
(void)argv;
(void)pzErr;
rc = sqlite3_declare_vtab(db, "CREATE TABLE x" FSDIR_SCHEMA);
if( rc==SQLITE_OK ){
pNew = (fsdir_tab*)sqlite3_malloc( sizeof(*pNew) );
@@ -460,6 +564,7 @@ static int fsdirDisconnect(sqlite3_vtab *pVtab){
*/
static int fsdirOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
fsdir_cursor *pCur;
(void)p;
pCur = sqlite3_malloc( sizeof(*pCur) );
if( pCur==0 ) return SQLITE_NOMEM;
memset(pCur, 0, sizeof(*pCur));
@@ -480,10 +585,12 @@ static void fsdirResetCursor(fsdir_cursor *pCur){
sqlite3_free(pLvl->zDir);
}
sqlite3_free(pCur->zPath);
sqlite3_free(pCur->aLvl);
pCur->aLvl = 0;
pCur->zPath = 0;
pCur->zBase = 0;
pCur->nBase = 0;
pCur->nLvl = 0;
pCur->iLvl = -1;
pCur->iRowid = 1;
}
@@ -495,7 +602,6 @@ static int fsdirClose(sqlite3_vtab_cursor *cur){
fsdir_cursor *pCur = (fsdir_cursor*)cur;
fsdirResetCursor(pCur);
sqlite3_free(pCur->aLvl);
sqlite3_free(pCur);
return SQLITE_OK;
}
@@ -556,7 +662,7 @@ static int fsdirNext(sqlite3_vtab_cursor *cur){
sqlite3_free(pCur->zPath);
pCur->zPath = sqlite3_mprintf("%s/%s", pLvl->zDir, pEntry->d_name);
if( pCur->zPath==0 ) return SQLITE_NOMEM;
if( lstat(pCur->zPath, &pCur->sStat) ){
if( fileLinkStat(pCur->zPath, &pCur->sStat) ){
fsdirSetErrmsg(pCur, "cannot stat file: %s", pCur->zPath);
return SQLITE_ERROR;
}
@@ -663,7 +769,7 @@ static int fsdirFilter(
){
const char *zDir = 0;
fsdir_cursor *pCur = (fsdir_cursor*)cur;
(void)idxStr;
fsdirResetCursor(pCur);
if( idxNum==0 ){
@@ -690,7 +796,7 @@ static int fsdirFilter(
if( pCur->zPath==0 ){
return SQLITE_NOMEM;
}
if( lstat(pCur->zPath, &pCur->sStat) ){
if( fileLinkStat(pCur->zPath, &pCur->sStat) ){
fsdirSetErrmsg(pCur, "cannot stat file: %s", pCur->zPath);
return SQLITE_ERROR;
}
@@ -721,8 +827,9 @@ static int fsdirBestIndex(
int i; /* Loop over constraints */
int idx4 = -1;
int idx5 = -1;
const struct sqlite3_index_constraint *pConstraint;
(void)tab;
pConstraint = pIdxInfo->aConstraint;
for(i=0; i<pIdxInfo->nConstraint; i++, pConstraint++){
if( pConstraint->usable==0 ) continue;
@@ -776,6 +883,9 @@ static int fsdirRegister(sqlite3 *db){
0, /* xRollback */
0, /* xFindMethod */
0, /* xRename */
0, /* xSavepoint */
0, /* xRelease */
0 /* xRollbackTo */
};
int rc = sqlite3_create_module(db, "fsdir", &fsdirModule, 0);
+707
View File
@@ -0,0 +1,707 @@
/*
** 2018-01-08
**
** The author disclaims copyright to this source code. In place of
** a legal notice, here is a blessing:
**
** May you do good and not evil.
** May you find forgiveness for yourself and forgive others.
** May you share freely, never taking more than you give.
**
******************************************************************************
**
** This file contains code to implement the sqlite3_normalize() function.
**
** char *sqlite3_normalize(const char *zSql);
**
** This function takes an SQL string as input and returns a "normalized"
** version of that string in memory obtained from sqlite3_malloc64(). The
** caller is responsible for ensuring that the returned memory is freed.
**
** If a memory allocation error occurs, this routine returns NULL.
**
** The normalization consists of the following transformations:
**
** (1) Convert every literal (string, blob literal, numeric constant,
** or "NULL" constant) into a ?
**
** (2) Remove all superfluous whitespace, including comments. Change
** all required whitespace to a single space character.
**
** (3) Lowercase all ASCII characters.
**
** (4) If an IN or NOT IN operator is followed by a list of 1 or more
** values, convert that list into "(?,?,?)".
**
** The purpose of normalization is two-fold:
**
** (1) Sanitize queries by removing potentially private or sensitive
** information contained in literals.
**
** (2) Identify structurally identical queries by comparing their
** normalized forms.
**
** Command-Line Utility
** --------------------
**
** This file also contains code for a command-line utility that converts
** SQL queries in text files into their normalized forms. To build the
** command-line program, compile this file with -DSQLITE_NORMALIZE_CLI
** and link it against the SQLite library.
*/
#include <sqlite3.h>
#include <string.h>
/*
** Implementation note:
**
** Much of the tokenizer logic is copied out of the tokenize.c source file
** of SQLite. That logic could be simplified for this particular application,
** but that would impose a risk of introducing subtle errors. It is best to
** keep the code as close to the original as possible.
**
** The tokenize code is in sync with the SQLite core as of 2018-01-08.
** Any future changes to the core tokenizer might require corresponding
** adjustments to the tokenizer logic in this module.
*/
/* Character classes for tokenizing
**
** In the sqlite3GetToken() function, a switch() on aiClass[c] is implemented
** using a lookup table, whereas a switch() directly on c uses a binary search.
** The lookup table is much faster. To maximize speed, and to ensure that
** a lookup table is used, all of the classes need to be small integers and
** all of them need to be used within the switch.
*/
#define CC_X 0 /* The letter 'x', or start of BLOB literal */
#define CC_KYWD 1 /* Alphabetics or '_'. Usable in a keyword */
#define CC_ID 2 /* unicode characters usable in IDs */
#define CC_DIGIT 3 /* Digits */
#define CC_DOLLAR 4 /* '$' */
#define CC_VARALPHA 5 /* '@', '#', ':'. Alphabetic SQL variables */
#define CC_VARNUM 6 /* '?'. Numeric SQL variables */
#define CC_SPACE 7 /* Space characters */
#define CC_QUOTE 8 /* '"', '\'', or '`'. String literals, quoted ids */
#define CC_QUOTE2 9 /* '['. [...] style quoted ids */
#define CC_PIPE 10 /* '|'. Bitwise OR or concatenate */
#define CC_MINUS 11 /* '-'. Minus or SQL-style comment */
#define CC_LT 12 /* '<'. Part of < or <= or <> */
#define CC_GT 13 /* '>'. Part of > or >= */
#define CC_EQ 14 /* '='. Part of = or == */
#define CC_BANG 15 /* '!'. Part of != */
#define CC_SLASH 16 /* '/'. / or c-style comment */
#define CC_LP 17 /* '(' */
#define CC_RP 18 /* ')' */
#define CC_SEMI 19 /* ';' */
#define CC_PLUS 20 /* '+' */
#define CC_STAR 21 /* '*' */
#define CC_PERCENT 22 /* '%' */
#define CC_COMMA 23 /* ',' */
#define CC_AND 24 /* '&' */
#define CC_TILDA 25 /* '~' */
#define CC_DOT 26 /* '.' */
#define CC_ILLEGAL 27 /* Illegal character */
static const unsigned char aiClass[] = {
/* x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xa xb xc xd xe xf */
/* 0x */ 27, 27, 27, 27, 27, 27, 27, 27, 27, 7, 7, 27, 7, 7, 27, 27,
/* 1x */ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
/* 2x */ 7, 15, 8, 5, 4, 22, 24, 8, 17, 18, 21, 20, 23, 11, 26, 16,
/* 3x */ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 19, 12, 14, 13, 6,
/* 4x */ 5, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
/* 5x */ 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 9, 27, 27, 27, 1,
/* 6x */ 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
/* 7x */ 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 27, 10, 27, 25, 27,
/* 8x */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
/* 9x */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
/* Ax */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
/* Bx */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
/* Cx */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
/* Dx */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
/* Ex */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
/* Fx */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2
};
/* An array to map all upper-case characters into their corresponding
** lower-case character.
**
** SQLite only considers US-ASCII (or EBCDIC) characters. We do not
** handle case conversions for the UTF character set since the tables
** involved are nearly as big or bigger than SQLite itself.
*/
static const unsigned char sqlite3UpperToLower[] = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 97, 98, 99,100,101,102,103,
104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,
122, 91, 92, 93, 94, 95, 96, 97, 98, 99,100,101,102,103,104,105,106,107,
108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,
126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,
144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,
162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,
180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,
198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,
216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,
234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,
252,253,254,255
};
/*
** The following 256 byte lookup table is used to support SQLites built-in
** equivalents to the following standard library functions:
**
** isspace() 0x01
** isalpha() 0x02
** isdigit() 0x04
** isalnum() 0x06
** 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.
** If x is a lower-case ASCII character, then its upper-case equivalent
** is (x - 0x20). Therefore toupper() can be implemented as:
**
** (x & ~(map[x]&0x20))
**
** The equivalent of tolower() is implemented using the sqlite3UpperToLower[]
** array. tolower() is used more often than toupper() by SQLite.
**
** Bit 0x40 is set if the character is non-alphanumeric and can be used in an
** SQLite identifier. Identifiers are alphanumerics, "_", "$", and any
** non-ASCII UTF character. Hence the test for whether or not a character is
** part of an identifier is 0x46.
*/
static const unsigned char sqlite3CtypeMap[256] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 00..07 ........ */
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, 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:;<=>? */
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, 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{|}~. */
0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /* 80..87 ........ */
0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /* 88..8f ........ */
0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /* 90..97 ........ */
0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /* 98..9f ........ */
0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /* a0..a7 ........ */
0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /* a8..af ........ */
0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /* b0..b7 ........ */
0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /* b8..bf ........ */
0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /* c0..c7 ........ */
0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /* c8..cf ........ */
0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /* d0..d7 ........ */
0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /* d8..df ........ */
0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /* e0..e7 ........ */
0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /* e8..ef ........ */
0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /* f0..f7 ........ */
0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40 /* f8..ff ........ */
};
#define sqlite3Toupper(x) ((x)&~(sqlite3CtypeMap[(unsigned char)(x)]&0x20))
#define sqlite3Isspace(x) (sqlite3CtypeMap[(unsigned char)(x)]&0x01)
#define sqlite3Isalnum(x) (sqlite3CtypeMap[(unsigned char)(x)]&0x06)
#define sqlite3Isalpha(x) (sqlite3CtypeMap[(unsigned char)(x)]&0x02)
#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)
/*
** If X is a character that can be used in an identifier then
** IdChar(X) will be true. Otherwise it is false.
**
** For ASCII, any character with the high-order bit set is
** allowed in an identifier. For 7-bit characters,
** sqlite3IsIdChar[X] must be 1.
**
** For EBCDIC, the rules are more complex but have the same
** end result.
**
** Ticket #1066. the SQL standard does not allow '$' in the
** middle of identifiers. But many SQL implementations do.
** SQLite will allow '$' in identifiers for compatibility.
** But the feature is undocumented.
*/
#define IdChar(C) ((sqlite3CtypeMap[(unsigned char)C]&0x46)!=0)
/*
** Ignore testcase() macros
*/
#define testcase(X)
/*
** Token values
*/
#define TK_SPACE 0
#define TK_NAME 1
#define TK_LITERAL 2
#define TK_PUNCT 3
#define TK_ERROR 4
#define TK_MINUS TK_PUNCT
#define TK_LP TK_PUNCT
#define TK_RP TK_PUNCT
#define TK_SEMI TK_PUNCT
#define TK_PLUS TK_PUNCT
#define TK_STAR TK_PUNCT
#define TK_SLASH TK_PUNCT
#define TK_REM TK_PUNCT
#define TK_EQ TK_PUNCT
#define TK_LE TK_PUNCT
#define TK_NE TK_PUNCT
#define TK_LSHIFT TK_PUNCT
#define TK_LT TK_PUNCT
#define TK_GE TK_PUNCT
#define TK_RSHIFT TK_PUNCT
#define TK_GT TK_PUNCT
#define TK_GE TK_PUNCT
#define TK_BITOR TK_PUNCT
#define TK_CONCAT TK_PUNCT
#define TK_COMMA TK_PUNCT
#define TK_BITAND TK_PUNCT
#define TK_BITNOT TK_PUNCT
#define TK_STRING TK_LITERAL
#define TK_ID TK_NAME
#define TK_ILLEGAL TK_ERROR
#define TK_DOT TK_PUNCT
#define TK_INTEGER TK_LITERAL
#define TK_FLOAT TK_LITERAL
#define TK_VARIABLE TK_LITERAL
#define TK_BLOB TK_LITERAL
/*
** Return the length (in bytes) of the token that begins at z[0].
** Store the token type in *tokenType before returning.
*/
static int sqlite3GetToken(const unsigned char *z, int *tokenType){
int i, c;
switch( aiClass[*z] ){ /* Switch on the character-class of the first byte
** of the token. See the comment on the CC_ defines
** above. */
case CC_SPACE: {
for(i=1; sqlite3Isspace(z[i]); i++){}
*tokenType = TK_SPACE;
return i;
}
case CC_MINUS: {
if( z[1]=='-' ){
for(i=2; (c=z[i])!=0 && c!='\n'; i++){}
*tokenType = TK_SPACE;
return i;
}
*tokenType = TK_MINUS;
return 1;
}
case CC_LP: {
*tokenType = TK_LP;
return 1;
}
case CC_RP: {
*tokenType = TK_RP;
return 1;
}
case CC_SEMI: {
*tokenType = TK_SEMI;
return 1;
}
case CC_PLUS: {
*tokenType = TK_PLUS;
return 1;
}
case CC_STAR: {
*tokenType = TK_STAR;
return 1;
}
case CC_SLASH: {
if( z[1]!='*' || z[2]==0 ){
*tokenType = TK_SLASH;
return 1;
}
for(i=3, c=z[2]; (c!='*' || z[i]!='/') && (c=z[i])!=0; i++){}
if( c ) i++;
*tokenType = TK_SPACE;
return i;
}
case CC_PERCENT: {
*tokenType = TK_REM;
return 1;
}
case CC_EQ: {
*tokenType = TK_EQ;
return 1 + (z[1]=='=');
}
case CC_LT: {
if( (c=z[1])=='=' ){
*tokenType = TK_LE;
return 2;
}else if( c=='>' ){
*tokenType = TK_NE;
return 2;
}else if( c=='<' ){
*tokenType = TK_LSHIFT;
return 2;
}else{
*tokenType = TK_LT;
return 1;
}
}
case CC_GT: {
if( (c=z[1])=='=' ){
*tokenType = TK_GE;
return 2;
}else if( c=='>' ){
*tokenType = TK_RSHIFT;
return 2;
}else{
*tokenType = TK_GT;
return 1;
}
}
case CC_BANG: {
if( z[1]!='=' ){
*tokenType = TK_ILLEGAL;
return 1;
}else{
*tokenType = TK_NE;
return 2;
}
}
case CC_PIPE: {
if( z[1]!='|' ){
*tokenType = TK_BITOR;
return 1;
}else{
*tokenType = TK_CONCAT;
return 2;
}
}
case CC_COMMA: {
*tokenType = TK_COMMA;
return 1;
}
case CC_AND: {
*tokenType = TK_BITAND;
return 1;
}
case CC_TILDA: {
*tokenType = TK_BITNOT;
return 1;
}
case CC_QUOTE: {
int delim = z[0];
testcase( delim=='`' );
testcase( delim=='\'' );
testcase( delim=='"' );
for(i=1; (c=z[i])!=0; i++){
if( c==delim ){
if( z[i+1]==delim ){
i++;
}else{
break;
}
}
}
if( c=='\'' ){
*tokenType = TK_STRING;
return i+1;
}else if( c!=0 ){
*tokenType = TK_ID;
return i+1;
}else{
*tokenType = TK_ILLEGAL;
return i;
}
}
case CC_DOT: {
if( !sqlite3Isdigit(z[1]) ){
*tokenType = TK_DOT;
return 1;
}
/* If the next character is a digit, this is a floating point
** number that begins with ".". Fall thru into the next case */
}
case CC_DIGIT: {
*tokenType = TK_INTEGER;
if( z[0]=='0' && (z[1]=='x' || z[1]=='X') && sqlite3Isxdigit(z[2]) ){
for(i=3; sqlite3Isxdigit(z[i]); i++){}
return i;
}
for(i=0; sqlite3Isdigit(z[i]); i++){}
if( z[i]=='.' ){
i++;
while( sqlite3Isdigit(z[i]) ){ i++; }
*tokenType = TK_FLOAT;
}
if( (z[i]=='e' || z[i]=='E') &&
( sqlite3Isdigit(z[i+1])
|| ((z[i+1]=='+' || z[i+1]=='-') && sqlite3Isdigit(z[i+2]))
)
){
i += 2;
while( sqlite3Isdigit(z[i]) ){ i++; }
*tokenType = TK_FLOAT;
}
while( IdChar(z[i]) ){
*tokenType = TK_ILLEGAL;
i++;
}
return i;
}
case CC_QUOTE2: {
for(i=1, c=z[0]; c!=']' && (c=z[i])!=0; i++){}
*tokenType = c==']' ? TK_ID : TK_ILLEGAL;
return i;
}
case CC_VARNUM: {
*tokenType = TK_VARIABLE;
for(i=1; sqlite3Isdigit(z[i]); i++){}
return i;
}
case CC_DOLLAR:
case CC_VARALPHA: {
int n = 0;
testcase( z[0]=='$' ); testcase( z[0]=='@' );
testcase( z[0]==':' ); testcase( z[0]=='#' );
*tokenType = TK_VARIABLE;
for(i=1; (c=z[i])!=0; i++){
if( IdChar(c) ){
n++;
}else if( c=='(' && n>0 ){
do{
i++;
}while( (c=z[i])!=0 && !sqlite3Isspace(c) && c!=')' );
if( c==')' ){
i++;
}else{
*tokenType = TK_ILLEGAL;
}
break;
}else if( c==':' && z[i+1]==':' ){
i++;
}else{
break;
}
}
if( n==0 ) *tokenType = TK_ILLEGAL;
return i;
}
case CC_KYWD: {
for(i=1; aiClass[z[i]]<=CC_KYWD; i++){}
if( IdChar(z[i]) ){
/* This token started out using characters that can appear in keywords,
** but z[i] is a character not allowed within keywords, so this must
** be an identifier instead */
i++;
break;
}
*tokenType = TK_ID;
return i;
}
case CC_X: {
testcase( z[0]=='x' ); testcase( z[0]=='X' );
if( z[1]=='\'' ){
*tokenType = TK_BLOB;
for(i=2; sqlite3Isxdigit(z[i]); i++){}
if( z[i]!='\'' || i%2 ){
*tokenType = TK_ILLEGAL;
while( z[i] && z[i]!='\'' ){ i++; }
}
if( z[i] ) i++;
return i;
}
/* If it is not a BLOB literal, then it must be an ID, since no
** SQL keywords start with the letter 'x'. Fall through */
}
case CC_ID: {
i = 1;
break;
}
default: {
*tokenType = TK_ILLEGAL;
return 1;
}
}
while( IdChar(z[i]) ){ i++; }
*tokenType = TK_ID;
return i;
}
char *sqlite3_normalize(const char *zSql){
char *z; /* The output string */
sqlite3_int64 nZ; /* Size of the output string in bytes */
sqlite3_int64 nSql; /* Size of the input string in bytes */
int i; /* Next character to read from zSql[] */
int j; /* Next slot to fill in on z[] */
int tokenType; /* Type of the next token */
int n; /* Size of the next token */
int k; /* Loop counter */
nSql = strlen(zSql);
nZ = nSql;
z = sqlite3_malloc64( nZ+2 );
if( z==0 ) return 0;
for(i=j=0; zSql[i]; i += n){
n = sqlite3GetToken((unsigned char*)zSql+i, &tokenType);
switch( tokenType ){
case TK_SPACE: {
break;
}
case TK_ERROR: {
sqlite3_free(z);
return 0;
}
case TK_LITERAL: {
z[j++] = '?';
break;
}
case TK_PUNCT:
case TK_NAME: {
if( n==4 && sqlite3_strnicmp(zSql+i,"NULL",4)==0 ){
if( (j>=3 && strncmp(z+j-2,"is",2)==0 && !IdChar(z[j-3]))
|| (j>=4 && strncmp(z+j-3,"not",3)==0 && !IdChar(z[j-4]))
){
/* NULL is a keyword in this case, not a literal value */
}else{
/* Here the NULL is a literal value */
z[j++] = '?';
break;
}
}
if( j>0 && IdChar(z[j-1]) && IdChar(zSql[i]) ) z[j++] = ' ';
for(k=0; k<n; k++){
z[j++] = sqlite3Tolower(zSql[i+k]);
}
break;
}
}
}
while( j>0 && z[j-1]==' ' ){ j--; }
if( i>0 && z[j-1]!=';' ){ z[j++] = ';'; }
z[j] = 0;
/* Make a second pass converting "in(...)" where the "..." is not a
** SELECT statement into "in(?,?,?)" */
for(i=0; i<j; i=n){
char *zIn = strstr(z+i, "in(");
int nParen;
if( zIn==0 ) break;
n = (int)(zIn-z)+3; /* Index of first char past "in(" */
if( n && IdChar(zIn[-1]) ) continue;
if( strncmp(zIn, "in(select",9)==0 && !IdChar(zIn[9]) ) continue;
if( strncmp(zIn, "in(with",7)==0 && !IdChar(zIn[7]) ) continue;
for(nParen=1, k=0; z[n+k]; k++){
if( z[n+k]=='(' ) nParen++;
if( z[n+k]==')' ){
nParen--;
if( nParen==0 ) break;
}
}
/* k is the number of bytes in the "..." within "in(...)" */
if( k<5 ){
z = sqlite3_realloc64(z, j+(5-k)+1);
if( z==0 ) return 0;
memmove(z+n+5, z+n+k, j-(n+k));
}else if( k>5 ){
memmove(z+n+5, z+n+k, j-(n+k));
}
j = j-k+5;
z[j] = 0;
memcpy(z+n, "?,?,?", 5);
}
return z;
}
/*
** For testing purposes, or to build a stand-alone SQL normalizer program,
** compile this one source file with the -DSQLITE_NORMALIZE_CLI and link
** it against any SQLite library. The resulting command-line program will
** run sqlite3_normalize() over the text of all files named on the command-
** line and show the result on standard output.
*/
#ifdef SQLITE_NORMALIZE_CLI
#include <stdio.h>
#include <stdlib.h>
/*
** Break zIn up into separate SQL statements and run sqlite3_normalize()
** on each one. Print the result of each run.
*/
static void normalizeFile(char *zIn){
int i;
if( zIn==0 ) return;
for(i=0; zIn[i]; i++){
char cSaved;
if( zIn[i]!=';' ) continue;
cSaved = zIn[i+1];
zIn[i+1] = 0;
if( sqlite3_complete(zIn) ){
char *zOut = sqlite3_normalize(zIn);
if( zOut ){
printf("%s\n", zOut);
sqlite3_free(zOut);
}else{
fprintf(stderr, "ERROR: %s\n", zIn);
}
zIn[i+1] = cSaved;
zIn += i+1;
i = -1;
}else{
zIn[i+1] = cSaved;
}
}
}
/*
** The main routine for "sql_normalize". Read files named on the
** command-line and run the text of each through sqlite3_normalize().
*/
int main(int argc, char **argv){
int i;
FILE *in;
char *zBuf = 0;
sqlite3_int64 sz, got;
for(i=1; i<argc; i++){
in = fopen(argv[i], "rb");
if( in==0 ){
fprintf(stderr, "cannot open \"%s\"\n", argv[i]);
continue;
}
fseek(in, 0, SEEK_END);
sz = ftell(in);
rewind(in);
zBuf = sqlite3_realloc64(zBuf, sz+1);
if( zBuf==0 ){
fprintf(stderr, "failed to malloc for %lld bytes\n", sz);
exit(1);
}
got = fread(zBuf, 1, sz, in);
fclose(in);
if( got!=sz ){
fprintf(stderr, "only able to read %lld of %lld bytes from \"%s\"\n",
got, sz, argv[i]);
}else{
zBuf[got] = 0;
normalizeFile(zBuf);
}
}
sqlite3_free(zBuf);
}
#endif /* SQLITE_NORMALIZE_CLI */
+2 -2
View File
@@ -131,7 +131,7 @@ static void scrubBackupWrite(ScrubState *p, int pgno, const u8 *pData){
scrubBackupErr(p, "write failed for page %d", pgno);
p->rcErr = SQLITE_IOERR;
}
if( pgno>p->iLastPage ) p->iLastPage = pgno;
if( (u32)pgno>p->iLastPage ) p->iLastPage = pgno;
}
/* Prepare a statement against the "db" database. */
@@ -459,7 +459,7 @@ static void scrubBackupBtree(ScrubState *p, int pgno, int iDepth){
nLocal = K<=X ? K : M;
if( pc+nLocal > p->szUsable-4 ){ ln=__LINE__; goto btree_corrupt; }
iChild = scrubBackupInt32(&a[pc+nLocal]);
scrubBackupOverflow(p, iChild, P-nLocal);
scrubBackupOverflow(p, iChild, (u32)(P-nLocal));
}
/* Walk the right-most tree */
+527 -424
View File
File diff suppressed because it is too large Load Diff
+1327 -693
View File
File diff suppressed because it is too large Load Diff
+102
View File
@@ -0,0 +1,102 @@
/*
** 2018-02-09
**
** The author disclaims copyright to this source code. In place of
** a legal notice, here is a blessing:
**
** May you do good and not evil.
** May you find forgiveness for yourself and forgive others.
** May you share freely, never taking more than you give.
**
******************************************************************************
**
** SQL functions for z-order (Morton code) transformations.
**
** zorder(X0,X0,..,xN) Generate an N+1 dimension Morton code
**
** unzorder(Z,N,I) Extract the I-th dimension from N-dimensional
** Morton code Z.
*/
#include "sqlite3ext.h"
SQLITE_EXTENSION_INIT1
#include <assert.h>
#include <string.h>
/*
** Functions: zorder(X0,X1,....)
**
** Convert integers X0, X1, ... into morton code.
**
** The output is a signed 64-bit integer. If any argument is too large,
** an error is thrown.
*/
static void zorderFunc(
sqlite3_context *context,
int argc,
sqlite3_value **argv
){
sqlite3_int64 z, x[63];
int i, j;
z = 0;
for(i=0; i<argc; i++){
x[i] = sqlite3_value_int64(argv[i]);
}
if( argc>0 ){
for(i=0; i<63; i++){
j = i%argc;
z |= (x[j]&1)<<i;
x[j] >>= 1;
}
}
sqlite3_result_int64(context, z);
for(i=0; i<argc; i++){
if( x[i] ){
sqlite3_result_error(context, "parameter too large", -1);
}
}
}
/*
** Functions: unzorder(Z,N,I)
**
** Assuming that Z is an N-dimensional Morton code, extract the I-th
** dimension.
*/
static void unzorderFunc(
sqlite3_context *context,
int argc,
sqlite3_value **argv
){
sqlite3_int64 z, n, i, x;
int j, k;
z = sqlite3_value_int64(argv[0]);
n = sqlite3_value_int64(argv[1]);
i = sqlite3_value_int64(argv[2]);
x = 0;
for(k=0, j=i; j<63; j+=n, k++){
x |= ((z>>j)&1)<<k;
}
sqlite3_result_int64(context, x);
}
#ifdef _WIN32
__declspec(dllexport)
#endif
int sqlite3_zorder_init(
sqlite3 *db,
char **pzErrMsg,
const sqlite3_api_routines *pApi
){
int rc = SQLITE_OK;
SQLITE_EXTENSION_INIT2(pApi);
(void)pzErrMsg; /* Unused parameter */
rc = sqlite3_create_function(db, "zorder", -1, SQLITE_UTF8, 0,
zorderFunc, 0, 0);
if( rc==SQLITE_OK ){
rc = sqlite3_create_function(db, "unzorder", 3, SQLITE_UTF8, 0,
unzorderFunc, 0, 0);
}
return rc;
}
+175
View File
@@ -0,0 +1,175 @@
# 2018 January 11
#
# 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 of multiple RBU operations running
# concurrently within the same process.
#
source [file join [file dirname [info script]] rbu_common.tcl]
set ::testprefix rbumulti
db close
sqlite3_shutdown
sqlite3_config_uri 1
autoinstall_test_functions
proc build_db {db} {
$db eval {
CREATE TABLE t1(a PRIMARY KEY, b, c);
CREATE INDEX i1 ON t1(b);
CREATE INDEX i2 ON t1(c);
WITH s(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<500 )
INSERT INTO t1
SELECT randomblob(10), randomblob(100), randomblob(100) FROM s;
}
}
proc build_rbu {db} {
$db eval {
CREATE TABLE data_t1(a, b, c, rbu_control);
WITH s(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<100 )
INSERT INTO data_t1
SELECT randomblob(10), randomblob(100), randomblob(100), 0 FROM s;
}
}
proc step_rbu2 {bOpenClose openr1 openr2} {
forcedelete teststate.db1
forcedelete teststate.db2
if {$bOpenClose!=0 && $bOpenClose!=1} { error $bOpenClose }
if {$bOpenClose==0} {
eval $openr1
eval $openr2
}
set b1 0
set b2 0
while {$b1==0 || $b2==0} {
if {$bOpenClose==1} {
if {$b1==0} { eval $openr1 teststate.db1 }
if {$b2==0} { eval $openr2 teststate.db2 }
}
if {$b1==0} {
set rc1 [r1 step]
if {$rc1 != "SQLITE_OK"} { set b1 1 }
}
if {$b2==0} {
set rc2 [r2 step]
if {$rc2 != "SQLITE_OK"} { set b2 1 }
}
if {$bOpenClose==1} {
if {$b1==0} { r1 close }
if {$b2==0} { r2 close }
}
}
set rc1 [r1 close]
set rc2 [r2 close]
list $rc1 $rc2
}
for {set i 0} {$i<=3} {incr i} {
if {$i & 0x01} {
sqlite3rbu_create_vfs -default myrbu ""
}
set bOpenClose [expr $i>>1]
forcedelete test.db
forcedelete test.db2
forcedelete rbu.db
forcedelete rbu.db2
do_test 1.$i.0 {
sqlite3 db test.db
sqlite3 db2 test.db2
build_db db
build_db db2
sqlite3 rbu1 rbu.db
sqlite3 rbu2 rbu.db2
build_rbu rbu1
build_rbu rbu2
rbu1 close
rbu2 close
} {}
set m1 [db eval {SELECT md5sum(a, b, c) FROM t1}]
set m2 [db2 eval {SELECT md5sum(a, b, c) FROM t1}]
do_test 1.$i.1 {
step_rbu2 $bOpenClose {
sqlite3rbu r1 test.db rbu.db
} {
sqlite3rbu r2 test.db2 rbu.db2
}
} {SQLITE_DONE SQLITE_DONE}
do_execsql_test -db db 1.$i.2.1 { PRAGMA integrity_check } ok
do_execsql_test -db db2 1.$i.2.2 { PRAGMA integrity_check } ok
do_execsql_test -db db 1.$i.3.1 { SELECT md5sum(a, b, c)==$m1 FROM t1 } 0
do_execsql_test -db db2 1.$i.3.2 { SELECT md5sum(a, b, c)==$m2 FROM t1 } 0
catch { db close }
catch { db2 close }
#-----------------------------------------------------------------------
forcedelete test.db2
forcedelete test.db
forcedelete rbu.db2
do_test 1.$i.4 {
sqlite3 db test.db
sqlite3 db2 test.db2
build_db db
build_db db2
sqlite3 rbu2 rbu.db2
build_rbu rbu2
rbu2 close
} {}
set m1 [db eval {SELECT md5sum(a, b, c) FROM t1}]
set m2 [db2 eval {SELECT md5sum(a, b, c) FROM t1}]
do_test 1.$i.5 {
step_rbu2 $bOpenClose {
sqlite3rbu_vacuum r1 test.db
} {
sqlite3rbu r2 test.db2 rbu.db2
}
} {SQLITE_DONE SQLITE_DONE}
do_execsql_test -db db 1.$i.6.1 { SELECT md5sum(a, b, c)==$m1 FROM t1 } 1
do_execsql_test -db db2 1.$i.6.2 { SELECT md5sum(a, b, c)==$m2 FROM t1 } 0
do_execsql_test -db db 1.$i.7.1 { PRAGMA integrity_check } ok
do_execsql_test -db db2 1.$i.7.2 { PRAGMA integrity_check } ok
catch { db close }
catch { db2 close }
if {$i & 0x01} {
sqlite3rbu_destroy_vfs myrbu
}
}
finish_test
+2
View File
@@ -220,7 +220,9 @@ if {[catch {sqlite3 db $file_to_analyze} res]} {
if {$bFreelistCheck || $bAll} {
puts -nonewline "freelist-check: "
flush stdout
db eval BEGIN
puts [db one {SELECT checkfreelist('main')}]
db eval END
}
if {$bSummary} {
set scale 0
+3 -1
View File
@@ -52,7 +52,8 @@
** child page.
*/
#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_RTREE)
#if !defined(SQLITE_CORE) \
|| (defined(SQLITE_ENABLE_RTREE) && !defined(SQLITE_OMIT_VIRTUALTABLE))
#ifndef SQLITE_CORE
#include "sqlite3ext.h"
@@ -784,6 +785,7 @@ static int nodeWrite(Rtree *pRtree, RtreeNode *pNode){
sqlite3_step(p);
pNode->isDirty = 0;
rc = sqlite3_reset(p);
sqlite3_bind_null(p, 2);
if( pNode->iNode==0 && rc==SQLITE_OK ){
pNode->iNode = sqlite3_last_insert_rowid(pRtree->db);
nodeHashInsert(pRtree, pNode);
+4
View File
@@ -15,6 +15,10 @@
*/
#include "sqlite3.h"
#ifdef SQLITE_OMIT_VIRTUALTABLE
# undef SQLITE_ENABLE_RTREE
#endif
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
+1
View File
@@ -609,4 +609,5 @@ do_execsql_test 15.2 {
COMMIT;
}
expand_all_sql db
finish_test
+1
View File
@@ -250,4 +250,5 @@ for {set nDim 1} {$nDim<=5} {incr nDim} {
do_rtree_integrity_test rtree4-$nDim.3 rx
}
expand_all_sql db
finish_test
+1
View File
@@ -79,4 +79,5 @@ do_test rtree5-1.13 {
} {2 2147483643 2147483647 -2147483648 -2147483643}
do_rtree_integrity_test rtree5-1.14 t1
expand_all_sql db
finish_test
+1 -1
View File
@@ -158,5 +158,5 @@ do_execsql_test rtree6-3.5 {
x1>0.5 AND x1>0.5 AND x1>0.5 AND x1>0.5 AND x1>1.1
} {}
expand_all_sql db
finish_test
+1
View File
@@ -59,6 +59,7 @@ do_test rtreeG-1.4log {
set ::log
} {}
expand_all_sql db
db close
sqlite3_shutdown
test_sqlite3_log
+77
View File
@@ -64,4 +64,81 @@ do_test 1.3 {
list [catch { sqlite3changeset_apply db $x xConflict } msg] $msg
} {1 SQLITE_CORRUPT}
#-------------------------------------------------------------------------
reset_db
do_execsql_test 2.0 {
CREATE TABLE t1(a INTEGER PRIMARY KEY,b,c,d);
CREATE TABLE t2(e TEXT PRIMARY KEY NOT NULL,f,g);
CREATE TABLE t3(w REAL PRIMARY KEY NOT NULL,x,y);
CREATE TABLE t4(z PRIMARY KEY) WITHOUT ROWID;
}
foreach {tn blob} {
1 54010174340012000000
2 54fefe8bcb0012000300
3 5480809280808001017434001200fb
4 50af9c939c9c9cb09c9c6400b09c9c6400
5 12000300
6 09847304
7 5401017434001208
8 54010174340012fc0386868600
9 54010174340012FC0386868600
10 548894FEFE
11 54010171340012E703ABFA7433FD1200
12 540101743400120003FFED00010000000000000002120002400C00000000000054040100000074310017000100000000000000050100000000000000030100000000000000040000010000000000000004010000000000000003001700010000000000000007030378797A01000000000000000F000001000000000000000F030378797A005403010000743200090003037838790100000000800000000200000000000000000900030378327902400C0000000000000304666F7572
13 540101743400120003001200010000000000000002120002400C0000000000005404010000007431001700010000000000000005010000000000000003010000000000000004000001000000000000000401000000000000000300170001000000000000000703FC87797A01000000000000000F000001000000000000000F030378797A005403010000743200090003037838790100000000800000000200000000000000000900030378327902400C0000000000000304666F7572
14 540101743400120003001200010000000000000002120002400C00000000000054040100000074310017000100000000000000050100000000000000030100000000000000040000010000000000000004010000000000000003001700010000000000000007030378797A01000000000000000F000001000000000000000F03FC87797A005403010000743200090003037838790100000000800000000200000000000000000900030378327902400C0000000000000304666F7572
15 540101743400120003001200010000000000000002120002400C00000000000054040100000074310017000100000000000000050100000000000000030100000000000000040000010000000000000004010000000000000003001700010000000000000007030378797A01000000000000000F000001000000000000000F030378797A005403010000743200090003FC8738790100000000800000000200000000000000000900030378327902400C0000000000000304666F7572
16 540101743400120003001200010000000000000002120002400C00000000000054040100000074310017000100000000000000050100000000000000030100000000000000040000010000000000000004010000000000000003001700010000000000000007030378797A01000000000000000F000001000000000000000F030378797A00540301000074320009000303783879010000000080000000020000000000000000090003FC87327902400C0000000000000304666F7572
17 540101743400120003FFE3000412F7010000E600000000021202120002400C0000000000005B0401000000743100171C0304646F750002400C000000000000540401000000D3310017000100000000000000050100000000000378797A405403000002F10100000100000000000004090001000100000007030378797A0100000000000D0007000001000000002300000F1B0378797A405403013900743200090003038C3879010000000000000000000002120002400C0000000000005B0401000000743117170003047C5E00FF
18 54010174340012000300120001000000E6FF100000120002401E00000000000054040100000074310017000100040000010000000000000004FFFF7FFF0000000000010000010000001000000007030378797A01000000000000000F000000000000FA0304666F7572
19 540101743400120003001200010000000000000002121B02400C00000000000054040000000074310017000100000000000000050100000000000000030100000000000000040000010000000000000004010000000000000003001700010000000000000007030378817A01000000000000000F000001000000000100000F030378797A005403010000743200090003FFE809000303780000000000000304666F7572
20 5401017D3400120003001200010000000000000002120002400CFC00000000005404010000007431001700010000000000000005010000000000000003010000000000000004000001000000000000000401000000000000000300170001000000000000000703FFFF797A01000000000000000F000001000000000000000F030378797A005403010000743200090003037838790100000000800000000200000000000000000900030378326C02400C0000000000000304666F7572
21 5401017434001200030012000100FFE20000000002120002400C00000000000054040100E0007431001700010000E99D000000020000000003FFE70009000303783279020004000001030000000000002117000003001700012701000100000000743100000100000000008000090003037F387901000000008000000002000000000400000009005303010A00FF7FFFFF00000000000304664F6572
22 540101743400120003FFFF7FFF0000000000000002120002400C00000000000054040100000074310017000100000000000000050100000000000000030100010000000000000000040000010000000000000004010000000000000003001700010000000000000007030378797A01000000000000000F000001000000000000000F030378797A005403010000743200090003037838790100000000800000000200000000000000000900030378327902400C0000000000000304666F7572
23 540101742700120100120003F5FF0300
24 5401017434E312540101743400120003FFFC00
25 540101743400540101743D3D3D3D3D3D3D3D3D3D3D3D3D3400120003FFED000300
26 5401017446EA5301743D1D3D3D01743D1D3D3DCF3D3D3D1A3D3D3D3D3400120003FFFF000000
27 540101743400540101743D3D3D3D3D3D3D3D3D3D251000120003FF81000000000000
28 540101340012000397FF3D7F3D3400120003001200540101743D3D3D3D3D3D393D3D3D12000300
29 500174340050010F74340012000300120003FFE5
30 5004007233E900177FEF0054257F0002EF001200031E12000300
31 5001015001015252525250010174340012EF039A9A0100E351525D52525252525252525252525252525252525250010174340012EF039A0100009A9A9A9A9A9BA3B200120003010040743400
32 5401017400123400120003FFFC00
33 540101743400120003001200010000000000004002120002400C0000000000005404010000007431001700010000000000000005010000000000000003010000000000000004000001000000000000000401000000000000000300170001000000000000000703FC87797A01000000000000000F000001000000000000000F030378797A005403010000743200090003037838790100000000800000000200000000000000000900030378327902400C0000000000000304666F7572
34 54040100000074310017000100000002000015050100000000000000030100000000140000040000010000000000000004010000000000000003001700010000000000000007030378797A01000000000000000F000001000000000000000F030378797A0054030100007432000900030378387901000000008E000000020000000000000000090003FFFF000002400C0000000000000304666F7572
35 540101743400120003001200010000000000000002120002400C00000000000050060100000074310017000100000000000000050100000000000000030100000003001700010000666F7572
36 540101743400120003001200010000000000000002120002400C00000000000050050100000074310017000100000000000000050100000000000000030100000003001700010000666F7572
37 540101743400120003001200010000000000000002120002400C00000000000050040100008074310017000100000000000000050100000000000000030100000003001700010000666F7572
38 540101743400120003001200010000000000000002120002400C00000000000050040100000074310017000000000000000000050100000000000000030100000003001700010000666F7572
39 540101743400120003001200010000000000000002120002400C00000000000050040100018074310017000100000000000000050100000000000000030100000003001700010000666F7572
40 540101743400120003001200010000000000000002120002400C0000000000005004FEFFFFFF74310017000100000000000000050100000000000000030100000003001700010000666F7572
41 540101743400120003001200010000000000000002120002400C00000000000050040100000074310017000004000000000000050100000000000000030100000003001700010000666F7572
42 540101743400120003001200010000000000000002120002400C0000000000005005FFFF050074310017000100000000000000050100000000000000030100000003001700010000666F7572
43 540101743400120003001200010000000000000002120002400C000000000000500401006E0074310017000300000000001221050100000000000000030100000003001700010000666F7572
44 540101743400120003001200010000000000020000120002400C00000000000050050100000074310017000100000000000000050100004000000000030100000025001700010000666F7572
45 540101743400120003001200010000000000ECFF02120002400C000000000000500401F9FF00743100170001000000000000000500E1000000000000030100000003000000000000666F7572
46 54010174340B0B0B0B0B0B0B0B0B0B0B0B0B0B0B00120003001200010000000000000002120002400C00000000000050040100000074310017010000000000000000050100FFE900000000030100000003007F00000000666F7572
47 54010103001200010000000000020002120002400C0000000000005004010000F374310017000100000000000000050100000000000000030100000003001700010000666F8E72
48 540101743400120003001200010000000000000002120002400C00000000000050030012000174310017000700000000000000050100002000000001000000000003001700010000666F7572
49 540101743400120004001200010000000000000002120002400C0000000000005004010000FC733100170001000000000000000501000000000000000301000000F6FF17000100007C6F7572
50 54010174FFDDFF8003001200010000100000000002120002400C000000000000500401000000743100170000000005010000000000000000000003010072
51 540101743200120003001200010000000000000002120002400C00000000000050040100001074310017000000000003010000120300170100000000000000050100000000000000030100000003001700010000666F7572
52 540101745401017434001200010000000000001702120002400C00000000000050040100001A74310017000100000000000100000100000000000000030100000003001700010000666F7572
53 540101743400120003001200010000000000000002120002400C000000000000500401000000743100170001000002400C00000000000050040110000074310017000000000000050100000000000000030100000003001700010000666F7572
54 540101743400120003001200010000000000000002120002400C000000000002120002400C00000000000050040100000074310017FF0050040100000074310017FF7F00000000000000050100000000000000030100000003001700010000666F7572
55 540101743400120003001200010000000000000002120002400C00000000000050040100000074310017000100010080000001000000020003010100000300170100000003001700010000666F7572
56 5487ffffff7f
} {
do_test 2.$tn {
set changeset [binary decode hex $blob]
#set fd [open x.change w+]
#fconfigure $fd -encoding binary -translation binary
#puts -nonewline $fd $changeset
#close $fd
list [catch { sqlite3changeset_apply db $changeset xConflict } msg] $msg
} {1 SQLITE_CORRUPT}
}
finish_test
+33
View File
@@ -221,5 +221,38 @@ do_test 4.2.2 {
} {1 {SQLITE_SCHEMA - table schemas do not match}}
S delete
do_test 4.3.1 {
sqlite3session S db main
S attach t4
execsql { CREATE TABLE t4(i PRIMARY KEY, b) }
list [catch { S diff ixua t4 } msg] $msg
} {1 {SQLITE_SCHEMA - table schemas do not match}}
S delete
do_catchsql_test 4.3.2 {
SELECT * FROM ixua.t4;
} {1 {no such table: ixua.t4}}
do_test 4.4.1 {
sqlite3session S db main
S attach sqlite_stat1
execsql { ANALYZE }
execsql { DROP TABLE ixua.sqlite_stat1 }
list [catch { S diff ixua sqlite_stat1 } msg] $msg
} {1 {SQLITE_SCHEMA - table schemas do not match}}
S delete
do_catchsql_test 4.4.2 {
SELECT * FROM ixua.sqlite_stat1;
} {1 {no such table: ixua.sqlite_stat1}}
do_test 4.5.1 {
sqlite3session S db main
S attach t8
list [catch { S diff ixua t8 } msg] $msg
} {0 {}}
S delete
do_catchsql_test 4.5.2 {
SELECT * FROM ixua.i8;
} {1 {no such table: ixua.i8}}
finish_test
+34
View File
@@ -173,5 +173,39 @@ do_test 4.3 {
compare_db db db2
} {}
#-------------------------------------------------------------------------
reset_db
catch { db2 close }
forcedelete test.db2
sqlite3 db2 test.db2
do_execsql_test 5.0.1 {
CREATE TABLE t1(a PRIMARY KEY, b, c);
CREATE TABLE t2(a, b, c PRIMARY KEY);
CREATE TABLE t3(a, b PRIMARY KEY, c);
}
do_execsql_test -db db2 5.0.2 {
CREATE TABLE t1(a PRIMARY KEY, b, c);
CREATE TABLE t2(a, b, c);
CREATE TABLE t3(a, b PRIMARY KEY, c);
}
do_test 5.1 {
do_then_apply_sql {
INSERT INTO t1 VALUES(1, 2, 3);
INSERT INTO t2 VALUES(4, 5, 6);
INSERT INTO t3 VALUES(7, 8, 9);
}
db2 eval {
SELECT * FROM t1;
SELECT * FROM t2;
SELECT * FROM t3;
}
} {1 2 3 7 8 9}
finish_test
+39
View File
@@ -0,0 +1,39 @@
# 2018 January 18
#
# 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.
#
#***********************************************************************
#
if {![info exists testdir]} {
set testdir [file join [file dirname [info script]] .. .. test]
}
source [file join [file dirname [info script]] session_common.tcl]
source $testdir/tester.tcl
ifcapable !session {finish_test; return}
set testprefix sessionH
forcedelete test.db2
sqlite3 db2 test.db2
do_test 1.0 {
do_common_sql {
CREATE TABLE t1(a, b, c, PRIMARY KEY(a, b));
}
do_then_apply_sql {
WITH s(i) AS (
VALUES(1) UNION ALL SELECT i+1 FROM s WHERe i<10000
)
INSERT INTO t1 SELECT 'abcde', randomblob(16), i FROM s;
}
compare_db db db2
} {}
finish_test
+4
View File
@@ -241,5 +241,9 @@ eval [string map [list %WR% $trailing] {
}]
}
catch { db close }
catch { db2 close }
sqlite3_shutdown
test_sqlite3_log
finish_test
+311
View File
@@ -0,0 +1,311 @@
# 2018 January 12
#
# 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.
#
#***********************************************************************
#
if {![info exists testdir]} {
set testdir [file join [file dirname [info script]] .. .. test]
}
source [file join [file dirname [info script]] session_common.tcl]
source $testdir/tester.tcl
ifcapable !session {finish_test; return}
set testprefix sessionstat1
do_execsql_test 1.0 {
CREATE TABLE t1(a PRIMARY KEY, b, c);
CREATE INDEX t1b ON t1(b);
CREATE INDEX t1c ON t1(c);
WITH s(i) AS (
SELECT 0 UNION ALL SELECT i+1 FROM s WHERE (i+1)<32
)
INSERT INTO t1 SELECT i, i%8, i%2 FROM s;
}
do_iterator_test 1.1 {} {
ANALYZE
} {
{INSERT sqlite_stat1 0 XX. {} {t t1 t sqlite_autoindex_t1_1 t {32 1}}}
{INSERT sqlite_stat1 0 XX. {} {t t1 t t1b t {32 4}}}
{INSERT sqlite_stat1 0 XX. {} {t t1 t t1c t {32 16}}}
}
do_execsql_test 1.2 {
WITH s(i) AS (
SELECT 32 UNION ALL SELECT i+1 FROM s WHERE (i+1)<64
)
INSERT INTO t1 SELECT i, i%8, i%2 FROM s;
}
do_iterator_test 1.3 {} {
ANALYZE
} {
{UPDATE sqlite_stat1 0 XX. {t t1 t sqlite_autoindex_t1_1 t {32 1}} {{} {} {} {} t {64 1}}}
{UPDATE sqlite_stat1 0 XX. {t t1 t t1b t {32 4}} {{} {} {} {} t {64 8}}}
{UPDATE sqlite_stat1 0 XX. {t t1 t t1c t {32 16}} {{} {} {} {} t {64 32}}}
}
do_iterator_test 1.5 {} {
DROP INDEX t1b;
} {
{DELETE sqlite_stat1 0 XX. {t t1 t t1b t {64 8}} {}}
}
do_iterator_test 1.6 {} {
DROP TABLE t1;
} {
{DELETE sqlite_stat1 0 XX. {t t1 t sqlite_autoindex_t1_1 t {64 1}} {}}
{DELETE sqlite_stat1 0 XX. {t t1 t t1c t {64 32}} {}}
}
#-------------------------------------------------------------------------
#
catch { db2 close }
forcedelete test.db2
sqlite3 db2 test.db2
do_test 2.0 {
do_common_sql {
CREATE TABLE t1(a PRIMARY KEY, b, c);
CREATE INDEX t1b ON t1(b);
CREATE INDEX t1c ON t1(c);
ANALYZE;
}
} {}
do_test 2.1 {
do_then_apply_sql {
WITH s(i) AS (
SELECT 0 UNION ALL SELECT i+1 FROM s WHERE (i+1)<32
)
INSERT INTO t1 SELECT i, i%8, i%2 FROM s;
ANALYZE;
}
} {}
do_execsql_test -db db2 2.2 {
SELECT * FROM sqlite_stat1
} {
t1 sqlite_autoindex_t1_1 {32 1}
t1 t1b {32 4}
t1 t1c {32 16}
}
do_test 2.3 {
do_then_apply_sql { DROP INDEX t1c }
} {}
do_execsql_test -db db2 2.4 {
SELECT * FROM sqlite_stat1
} {
t1 sqlite_autoindex_t1_1 {32 1}
t1 t1b {32 4}
}
do_test 2.3 {
do_then_apply_sql { DROP TABLE t1 }
} {}
do_execsql_test -db db2 2.4 {
SELECT * FROM sqlite_stat1
} {
}
do_execsql_test -db db2 2.5 { SELECT count(*) FROM t1 } 32
#-------------------------------------------------------------------------
db2 close
forcedelete test.db2
reset_db
sqlite3 db2 test.db2
do_test 3.0 {
do_common_sql {
CREATE TABLE t1(a, b, c);
ANALYZE;
DELETE FROM sqlite_stat1;
}
execsql {
INSERT INTO t1 VALUES(1, 1, 1);
INSERT INTO t1 VALUES(2, 2, 2);
INSERT INTO t1 VALUES(3, 3, 3);
INSERT INTO t1 VALUES(4, 4, 4);
}
} {}
do_iterator_test 3.1 {} {
ANALYZE
} {
{INSERT sqlite_stat1 0 XX. {} {t t1 b {} t 4}}
}
db null null
db2 null null
do_execsql_test 3.2 {
SELECT * FROM sqlite_stat1;
} {t1 null 4}
do_test 3.3 {
execsql { DELETE FROM sqlite_stat1 }
do_then_apply_sql { ANALYZE }
execsql { SELECT * FROM sqlite_stat1 } db2
} {t1 null 4}
do_test 3.4 {
execsql { INSERT INTO t1 VALUES(5,5,5) }
do_then_apply_sql { ANALYZE }
execsql { SELECT * FROM sqlite_stat1 } db2
} {t1 null 5}
do_test 3.5 {
do_then_apply_sql { DROP TABLE t1 }
execsql { SELECT * FROM sqlite_stat1 } db2
} {}
do_test 3.6.1 {
execsql {
CREATE TABLE t1(a, b, c);
CREATE TABLE t2(x, y, z);
INSERT INTO t1 VALUES(1,1,1), (2,2,2), (3,3,3), (4,4,4), (5,5,5);
INSERT INTO t2 SELECT * FROM t1;
DELETE FROM sqlite_stat1;
}
sqlite3session S db main
S attach sqlite_stat1
execsql { ANALYZE }
} {}
do_changeset_test 3.6.2 S {
{INSERT sqlite_stat1 0 XX. {} {t t2 b {} t 5}}
{INSERT sqlite_stat1 0 XX. {} {t t1 b {} t 5}}
}
do_changeset_invert_test 3.6.3 S {
{DELETE sqlite_stat1 0 XX. {t t2 b {} t 5} {}}
{DELETE sqlite_stat1 0 XX. {t t1 b {} t 5} {}}
}
do_test 3.6.4 { S delete } {}
proc sql_changeset_concat {args} {
foreach sql $args {
sqlite3session S db main
S attach sqlite_stat1
execsql $sql
set change [S changeset]
S delete
if {[info vars ret]!=""} {
set ret [sqlite3changeset_concat $ret $change]
} else {
set ret $change
}
}
changeset_to_list $ret
}
proc do_scc_test {tn args} {
uplevel [list \
do_test $tn [concat sql_changeset_concat [lrange $args 0 end-1]] \
[list {*}[ lindex $args end ]]
]
}
do_execsql_test 3.7.0 {
DELETE FROM sqlite_stat1;
}
do_scc_test 3.7.1 {
ANALYZE;
} {
INSERT INTO t2 VALUES(6,6,6);
ANALYZE;
} {
{INSERT sqlite_stat1 0 XX. {} {t t1 b {} t 5}}
{INSERT sqlite_stat1 0 XX. {} {t t2 b {} t 6}}
}
#-------------------------------------------------------------------------
catch { db2 close }
reset_db
forcedelete test.db2
sqlite3 db2 test.db2
do_test 4.1.0 {
do_common_sql {
CREATE TABLE t1(a, b);
CREATE INDEX i1 ON t1(a);
CREATE INDEX i2 ON t1(b);
INSERT INTO t1 VALUES(1,1), (2,2);
ANALYZE;
}
execsql { DELETE FROM sqlite_stat1 }
} {}
do_test 4.1.1 {
execsql { INSERT INTO t1 VALUES(3,3); }
set C [changeset_from_sql {ANALYZE}]
set ::c [list]
proc xConflict {args} {
lappend ::c $args
return "OMIT"
}
sqlite3changeset_apply db2 $C xConflict
set ::c
} [list {*}{
{INSERT sqlite_stat1 CONFLICT {t t1 t i1 t {3 1}} {t t1 t i1 t {2 1}}}
{INSERT sqlite_stat1 CONFLICT {t t1 t i2 t {3 1}} {t t1 t i2 t {2 1}}}
}]
do_execsql_test -db db2 4.1.2 {
SELECT * FROM sqlite_stat1 ORDER BY 1,2;
} {t1 i1 {2 1} t1 i2 {2 1}}
do_test 4.1.3 {
proc xConflict {args} {
return "REPLACE"
}
sqlite3changeset_apply db2 $C xConflict
execsql { SELECT * FROM sqlite_stat1 ORDER BY 1,2 } db2
} {t1 i1 {3 1} t1 i2 {3 1}}
do_test 4.2.0 {
do_common_sql {
DROP TABLE t1;
CREATE TABLE t3(x,y);
INSERT INTO t3 VALUES('a','a');
INSERT INTO t3 VALUES('b','b');
ANALYZE;
}
execsql { DELETE FROM sqlite_stat1 }
} {}
do_test 4.2.1 {
execsql { INSERT INTO t3 VALUES('c','c'); }
set C [changeset_from_sql {ANALYZE}]
set ::c [list]
proc xConflict {args} {
lappend ::c $args
return "OMIT"
}
sqlite3changeset_apply db2 $C xConflict
set ::c
} [list {*}{
{INSERT sqlite_stat1 CONFLICT {t t3 b {} t 3} {t t3 b {} t 2}}
}]
db2 null null
do_execsql_test -db db2 4.2.2 {
SELECT * FROM sqlite_stat1 ORDER BY 1,2;
} {t3 null 2}
do_test 4.2.3 {
proc xConflict {args} {
return "REPLACE"
}
sqlite3changeset_apply db2 $C xConflict
execsql { SELECT * FROM sqlite_stat1 ORDER BY 1,2 } db2
} {t3 null 3}
finish_test
+249 -56
View File
@@ -46,6 +46,7 @@ struct sqlite3_session {
int rc; /* Non-zero if an error has occurred */
void *pFilterCtx; /* First argument to pass to xTableFilter */
int (*xTableFilter)(void *pCtx, const char *zTab);
sqlite3_value *pZeroBlob; /* Value containing X'' */
sqlite3_session *pNext; /* Next session object on same db. */
SessionTable *pTable; /* List of attached tables */
SessionHook hook; /* APIs to grab new and old data with */
@@ -113,6 +114,7 @@ struct SessionTable {
SessionTable *pNext;
char *zName; /* Local name of table */
int nCol; /* Number of columns in table zName */
int bStat1; /* True if this is sqlite_stat1 */
const char **azCol; /* Column names */
u8 *abPK; /* Array of primary key flags */
int nEntry; /* Total number of entries in hash table */
@@ -496,6 +498,7 @@ static int sessionPreupdateHash(
h = sessionHashAppendBlob(h, n, z);
}else{
assert( eType==SQLITE_NULL );
assert( pTab->bStat1==0 || i!=1 );
*pbNullPK = 1;
}
}
@@ -838,7 +841,6 @@ static int sessionPreupdateEqual(
}
if( memcmp(a, z, n) ) return 0;
a += n;
break;
}
}
}
@@ -894,9 +896,7 @@ static int sessionGrowHash(int bPatchset, SessionTable *pTab){
/*
** This function queries the database for the names of the columns of table
** zThis, in schema zDb. It is expected that the table has nCol columns. If
** not, SQLITE_SCHEMA is returned and none of the output variables are
** populated.
** zThis, in schema zDb.
**
** Otherwise, if they are not NULL, variable *pnCol is set to the number
** of columns in the database table and variable *pzTab is set to point to a
@@ -917,9 +917,7 @@ static int sessionGrowHash(int bPatchset, SessionTable *pTab){
** *pabPK = {1, 0, 0, 1}
**
** All returned buffers are part of the same single allocation, which must
** be freed using sqlite3_free() by the caller. If pazCol was not NULL, then
** pointer *pazCol should be freed to release all memory. Otherwise, pointer
** *pabPK. It is illegal for both pazCol and pabPK to be NULL.
** be freed using sqlite3_free() by the caller
*/
static int sessionTableInfo(
sqlite3 *db, /* Database connection */
@@ -944,7 +942,23 @@ static int sessionTableInfo(
assert( pazCol && pabPK );
nThis = sqlite3Strlen30(zThis);
zPragma = sqlite3_mprintf("PRAGMA '%q'.table_info('%q')", zDb, zThis);
if( nThis==12 && 0==sqlite3_stricmp("sqlite_stat1", zThis) ){
rc = sqlite3_table_column_metadata(db, zDb, zThis, 0, 0, 0, 0, 0, 0);
if( rc==SQLITE_OK ){
/* For sqlite_stat1, pretend that (tbl,idx) is the PRIMARY KEY. */
zPragma = sqlite3_mprintf(
"SELECT 0, 'tbl', '', 0, '', 1 UNION ALL "
"SELECT 1, 'idx', '', 0, '', 2 UNION ALL "
"SELECT 2, 'stat', '', 0, '', 0"
);
}else if( rc==SQLITE_ERROR ){
zPragma = sqlite3_mprintf("");
}else{
return rc;
}
}else{
zPragma = sqlite3_mprintf("PRAGMA '%q'.table_info('%q')", zDb, zThis);
}
if( !zPragma ) return SQLITE_NOMEM;
rc = sqlite3_prepare_v2(db, zPragma, -1, &pStmt, 0);
@@ -1036,11 +1050,55 @@ static int sessionInitTable(sqlite3_session *pSession, SessionTable *pTab){
break;
}
}
if( 0==sqlite3_stricmp("sqlite_stat1", pTab->zName) ){
pTab->bStat1 = 1;
}
}
}
return (pSession->rc || pTab->abPK==0);
}
/*
** Versions of the four methods in object SessionHook for use with the
** sqlite_stat1 table. The purpose of this is to substitute a zero-length
** blob each time a NULL value is read from the "idx" column of the
** sqlite_stat1 table.
*/
typedef struct SessionStat1Ctx SessionStat1Ctx;
struct SessionStat1Ctx {
SessionHook hook;
sqlite3_session *pSession;
};
static int sessionStat1Old(void *pCtx, int iCol, sqlite3_value **ppVal){
SessionStat1Ctx *p = (SessionStat1Ctx*)pCtx;
sqlite3_value *pVal = 0;
int rc = p->hook.xOld(p->hook.pCtx, iCol, &pVal);
if( rc==SQLITE_OK && iCol==1 && sqlite3_value_type(pVal)==SQLITE_NULL ){
pVal = p->pSession->pZeroBlob;
}
*ppVal = pVal;
return rc;
}
static int sessionStat1New(void *pCtx, int iCol, sqlite3_value **ppVal){
SessionStat1Ctx *p = (SessionStat1Ctx*)pCtx;
sqlite3_value *pVal = 0;
int rc = p->hook.xNew(p->hook.pCtx, iCol, &pVal);
if( rc==SQLITE_OK && iCol==1 && sqlite3_value_type(pVal)==SQLITE_NULL ){
pVal = p->pSession->pZeroBlob;
}
*ppVal = pVal;
return rc;
}
static int sessionStat1Count(void *pCtx){
SessionStat1Ctx *p = (SessionStat1Ctx*)pCtx;
return p->hook.xCount(p->hook.pCtx);
}
static int sessionStat1Depth(void *pCtx){
SessionStat1Ctx *p = (SessionStat1Ctx*)pCtx;
return p->hook.xDepth(p->hook.pCtx);
}
/*
** This function is only called from with a pre-update-hook reporting a
** change on table pTab (attached to session pSession). The type of change
@@ -1057,6 +1115,7 @@ static void sessionPreupdateOneChange(
int iHash;
int bNull = 0;
int rc = SQLITE_OK;
SessionStat1Ctx stat1 = {0};
if( pSession->rc ) return;
@@ -1076,6 +1135,25 @@ static void sessionPreupdateOneChange(
return;
}
if( pTab->bStat1 ){
stat1.hook = pSession->hook;
stat1.pSession = pSession;
pSession->hook.pCtx = (void*)&stat1;
pSession->hook.xNew = sessionStat1New;
pSession->hook.xOld = sessionStat1Old;
pSession->hook.xCount = sessionStat1Count;
pSession->hook.xDepth = sessionStat1Depth;
if( pSession->pZeroBlob==0 ){
sqlite3_value *p = sqlite3ValueNew(0);
if( p==0 ){
rc = SQLITE_NOMEM;
goto error_out;
}
sqlite3ValueSetStr(p, 0, "", 0, SQLITE_STATIC);
pSession->pZeroBlob = p;
}
}
/* Calculate the hash-key for this change. If the primary key of the row
** includes a NULL value, exit early. Such changes are ignored by the
** session module. */
@@ -1165,6 +1243,9 @@ static void sessionPreupdateOneChange(
/* If an error has occurred, mark the session object as failed. */
error_out:
if( pTab->bStat1 ){
pSession->hook = stat1.hook;
}
if( rc!=SQLITE_OK ){
pSession->rc = rc;
}
@@ -1501,7 +1582,6 @@ int sqlite3session_diff(
if( abPK[i] ) bHasPk = 1;
}
}
}
sqlite3_free((char*)azCol);
if( bMismatch ){
@@ -1627,6 +1707,7 @@ void sqlite3session_delete(sqlite3_session *pSession){
}
}
sqlite3_mutex_leave(sqlite3_db_mutex(db));
sqlite3ValueFree(pSession->pZeroBlob);
/* Delete all attached table objects. And the contents of their
** associated hash-tables. */
@@ -2094,28 +2175,41 @@ static int sessionSelectStmt(
sqlite3_stmt **ppStmt /* OUT: Prepared SELECT statement */
){
int rc = SQLITE_OK;
int i;
const char *zSep = "";
SessionBuffer buf = {0, 0, 0};
char *zSql = 0;
int nSql = -1;
sessionAppendStr(&buf, "SELECT * FROM ", &rc);
sessionAppendIdent(&buf, zDb, &rc);
sessionAppendStr(&buf, ".", &rc);
sessionAppendIdent(&buf, zTab, &rc);
sessionAppendStr(&buf, " WHERE ", &rc);
for(i=0; i<nCol; i++){
if( abPK[i] ){
sessionAppendStr(&buf, zSep, &rc);
sessionAppendIdent(&buf, azCol[i], &rc);
sessionAppendStr(&buf, " = ?", &rc);
sessionAppendInteger(&buf, i+1, &rc);
zSep = " AND ";
if( 0==sqlite3_stricmp("sqlite_stat1", zTab) ){
zSql = sqlite3_mprintf(
"SELECT tbl, ?2, stat FROM %Q.sqlite_stat1 WHERE tbl IS ?1 AND "
"idx IS (CASE WHEN ?2=X'' THEN NULL ELSE ?2 END)", zDb
);
}else{
int i;
const char *zSep = "";
SessionBuffer buf = {0, 0, 0};
sessionAppendStr(&buf, "SELECT * FROM ", &rc);
sessionAppendIdent(&buf, zDb, &rc);
sessionAppendStr(&buf, ".", &rc);
sessionAppendIdent(&buf, zTab, &rc);
sessionAppendStr(&buf, " WHERE ", &rc);
for(i=0; i<nCol; i++){
if( abPK[i] ){
sessionAppendStr(&buf, zSep, &rc);
sessionAppendIdent(&buf, azCol[i], &rc);
sessionAppendStr(&buf, " IS ?", &rc);
sessionAppendInteger(&buf, i+1, &rc);
zSep = " AND ";
}
}
zSql = (char*)buf.aBuf;
nSql = buf.nBuf;
}
if( rc==SQLITE_OK ){
rc = sqlite3_prepare_v2(db, (char *)buf.aBuf, buf.nBuf, ppStmt, 0);
rc = sqlite3_prepare_v2(db, zSql, nSql, ppStmt, 0);
}
sqlite3_free(buf.aBuf);
sqlite3_free(zSql);
return rc;
}
@@ -2626,13 +2720,16 @@ static int sessionReadRecord(
if( abPK && abPK[i]==0 ) continue;
rc = sessionInputBuffer(pIn, 9);
if( rc==SQLITE_OK ){
eType = pIn->aData[pIn->iNext++];
}
assert( apOut[i]==0 );
if( eType ){
apOut[i] = sqlite3ValueNew(0);
if( !apOut[i] ) rc = SQLITE_NOMEM;
if( pIn->iNext>=pIn->nData ){
rc = SQLITE_CORRUPT_BKPT;
}else{
eType = pIn->aData[pIn->iNext++];
assert( apOut[i]==0 );
if( eType ){
apOut[i] = sqlite3ValueNew(0);
if( !apOut[i] ) rc = SQLITE_NOMEM;
}
}
}
if( rc==SQLITE_OK ){
@@ -2642,10 +2739,14 @@ static int sessionReadRecord(
pIn->iNext += sessionVarintGet(aVal, &nByte);
rc = sessionInputBuffer(pIn, nByte);
if( rc==SQLITE_OK ){
u8 enc = (eType==SQLITE_TEXT ? SQLITE_UTF8 : 0);
rc = sessionValueSetStr(apOut[i],&pIn->aData[pIn->iNext],nByte,enc);
if( nByte<0 || nByte>pIn->nData-pIn->iNext ){
rc = SQLITE_CORRUPT_BKPT;
}else{
u8 enc = (eType==SQLITE_TEXT ? SQLITE_UTF8 : 0);
rc = sessionValueSetStr(apOut[i],&pIn->aData[pIn->iNext],nByte,enc);
pIn->iNext += nByte;
}
}
pIn->iNext += nByte;
}
if( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT ){
sqlite3_int64 v = sessionGetI64(aVal);
@@ -2685,8 +2786,19 @@ static int sessionChangesetBufferTblhdr(SessionInput *pIn, int *pnByte){
rc = sessionInputBuffer(pIn, 9);
if( rc==SQLITE_OK ){
nRead += sessionVarintGet(&pIn->aData[pIn->iNext + nRead], &nCol);
rc = sessionInputBuffer(pIn, nRead+nCol+100);
nRead += nCol;
/* The hard upper limit for the number of columns in an SQLite
** database table is, according to sqliteLimit.h, 32676. So
** consider any table-header that purports to have more than 65536
** columns to be corrupt. This is convenient because otherwise,
** if the (nCol>65536) condition below were omitted, a sufficiently
** large value for nCol may cause nRead to wrap around and become
** negative. Leading to a crash. */
if( nCol<0 || nCol>65536 ){
rc = SQLITE_CORRUPT_BKPT;
}else{
rc = sessionInputBuffer(pIn, nRead+nCol+100);
nRead += nCol;
}
}
while( rc==SQLITE_OK ){
@@ -2763,11 +2875,15 @@ static int sessionChangesetReadTblhdr(sqlite3_changeset_iter *p){
int nByte;
int nVarint;
nVarint = sessionVarintGet(&p->in.aData[p->in.iNext], &p->nCol);
nCopy -= nVarint;
p->in.iNext += nVarint;
nByte = p->nCol * sizeof(sqlite3_value*) * 2 + nCopy;
p->tblhdr.nBuf = 0;
sessionBufferGrow(&p->tblhdr, nByte, &rc);
if( p->nCol>0 ){
nCopy -= nVarint;
p->in.iNext += nVarint;
nByte = p->nCol * sizeof(sqlite3_value*) * 2 + nCopy;
p->tblhdr.nBuf = 0;
sessionBufferGrow(&p->tblhdr, nByte, &rc);
}else{
rc = SQLITE_CORRUPT_BKPT;
}
}
if( rc==SQLITE_OK ){
@@ -2845,6 +2961,13 @@ static int sessionChangesetNext(
op = p->in.aData[p->in.iNext++];
}
if( p->zTab==0 ){
/* The first record in the changeset is not a table header. Must be a
** corrupt changeset. */
assert( p->in.iNext==1 );
return (p->rc = SQLITE_CORRUPT_BKPT);
}
p->op = op;
p->bIndirect = p->in.aData[p->in.iNext++];
if( p->op!=SQLITE_UPDATE && p->op!=SQLITE_DELETE && p->op!=SQLITE_INSERT ){
@@ -2887,9 +3010,9 @@ static int sessionChangesetNext(
** new.* to old.*, to accommodate the code that reads these arrays. */
for(i=0; i<p->nCol; i++){
assert( p->apValue[i]==0 );
assert( p->abPK[i]==0 || p->apValue[i+p->nCol] );
if( p->abPK[i] ){
p->apValue[i] = p->apValue[i+p->nCol];
if( p->apValue[i]==0 ) return (p->rc = SQLITE_CORRUPT_BKPT);
p->apValue[i+p->nCol] = 0;
}
}
@@ -3284,7 +3407,7 @@ struct SessionApplyCtx {
int nCol; /* Size of azCol[] and abPK[] arrays */
const char **azCol; /* Array of column names */
u8 *abPK; /* Boolean array - true if column is in PK */
int bStat1; /* True if table is sqlite_stat1 */
int bDeferConstraints; /* True to defer constraints */
SessionBuffer constraints; /* Deferred constraints are stored here */
};
@@ -3454,6 +3577,7 @@ static int sessionUpdateRow(
return rc;
}
/*
** Formulate and prepare an SQL statement to query table zTab by primary
** key. Assuming the following table structure:
@@ -3515,6 +3639,47 @@ static int sessionInsertRow(
return rc;
}
static int sessionPrepare(sqlite3 *db, sqlite3_stmt **pp, const char *zSql){
return sqlite3_prepare_v2(db, zSql, -1, pp, 0);
}
/*
** Prepare statements for applying changes to the sqlite_stat1 table.
** These are similar to those created by sessionSelectRow(),
** sessionInsertRow(), sessionUpdateRow() and sessionDeleteRow() for
** other tables.
*/
static int sessionStat1Sql(sqlite3 *db, SessionApplyCtx *p){
int rc = sessionSelectRow(db, "sqlite_stat1", p);
if( rc==SQLITE_OK ){
rc = sessionPrepare(db, &p->pInsert,
"INSERT INTO main.sqlite_stat1 VALUES(?1, "
"CASE WHEN length(?2)=0 AND typeof(?2)='blob' THEN NULL ELSE ?2 END, "
"?3)"
);
}
if( rc==SQLITE_OK ){
rc = sessionPrepare(db, &p->pUpdate,
"UPDATE main.sqlite_stat1 SET "
"tbl = CASE WHEN ?2 THEN ?3 ELSE tbl END, "
"idx = CASE WHEN ?5 THEN ?6 ELSE idx END, "
"stat = CASE WHEN ?8 THEN ?9 ELSE stat END "
"WHERE tbl=?1 AND idx IS "
"CASE WHEN length(?4)=0 AND typeof(?4)='blob' THEN NULL ELSE ?4 END "
"AND (?10 OR ?8=0 OR stat IS ?7)"
);
}
if( rc==SQLITE_OK ){
rc = sessionPrepare(db, &p->pDelete,
"DELETE FROM main.sqlite_stat1 WHERE tbl=?1 AND idx IS "
"CASE WHEN length(?2)=0 AND typeof(?2)='blob' THEN NULL ELSE ?2 END "
"AND (?4 OR stat IS ?3)"
);
}
assert( rc==SQLITE_OK );
return rc;
}
/*
** A wrapper around sqlite3_bind_value() that detects an extra problem.
** See comments in the body of this function for details.
@@ -3572,7 +3737,13 @@ static int sessionBindRow(
if( !abPK || abPK[i] ){
sqlite3_value *pVal;
(void)xValue(pIter, i, &pVal);
rc = sessionBindValue(pStmt, i+1, pVal);
if( pVal==0 ){
/* The value in the changeset was "undefined". This indicates a
** corrupt changeset blob. */
rc = SQLITE_CORRUPT_BKPT;
}else{
rc = sessionBindValue(pStmt, i+1, pVal);
}
}
}
return rc;
@@ -3845,11 +4016,25 @@ static int sessionApplyOneOp(
}else{
assert( op==SQLITE_INSERT );
rc = sessionBindRow(pIter, sqlite3changeset_new, nCol, 0, p->pInsert);
if( rc!=SQLITE_OK ) return rc;
if( p->bStat1 ){
/* Check if there is a conflicting row. For sqlite_stat1, this needs
** to be done using a SELECT, as there is no PRIMARY KEY in the
** database schema to throw an exception if a duplicate is inserted. */
rc = sessionSeekToRow(p->db, pIter, p->abPK, p->pSelect);
if( rc==SQLITE_ROW ){
rc = SQLITE_CONSTRAINT;
sqlite3_reset(p->pSelect);
}
}
if( rc==SQLITE_OK ){
rc = sessionBindRow(pIter, sqlite3changeset_new, nCol, 0, p->pInsert);
if( rc!=SQLITE_OK ) return rc;
sqlite3_step(p->pInsert);
rc = sqlite3_reset(p->pInsert);
}
sqlite3_step(p->pInsert);
rc = sqlite3_reset(p->pInsert);
if( (rc&0xff)==SQLITE_CONSTRAINT ){
rc = sessionConflictHandler(
SQLITE_CHANGESET_CONFLICT, p, pIter, xConflict, pCtx, pbReplace
@@ -4082,12 +4267,20 @@ static int sessionChangesetApply(
}
else{
sApply.nCol = nCol;
if((rc = sessionSelectRow(db, zTab, &sApply))
|| (rc = sessionUpdateRow(db, zTab, &sApply))
|| (rc = sessionDeleteRow(db, zTab, &sApply))
|| (rc = sessionInsertRow(db, zTab, &sApply))
){
break;
if( 0==sqlite3_stricmp(zTab, "sqlite_stat1") ){
if( (rc = sessionStat1Sql(db, &sApply) ) ){
break;
}
sApply.bStat1 = 1;
}else{
if((rc = sessionSelectRow(db, zTab, &sApply))
|| (rc = sessionUpdateRow(db, zTab, &sApply))
|| (rc = sessionDeleteRow(db, zTab, &sApply))
|| (rc = sessionInsertRow(db, zTab, &sApply))
){
break;
}
sApply.bStat1 = 0;
}
}
nTab = sqlite3Strlen30(zTab);
+65 -1
View File
@@ -13,16 +13,23 @@ extern "C" {
/*
** CAPI3REF: Session Object Handle
**
** An instance of this object is a [session] that can be used to
** record changes to a database.
*/
typedef struct sqlite3_session sqlite3_session;
/*
** CAPI3REF: Changeset Iterator Handle
**
** An instance of this object acts as a cursor for iterating
** over the elements of a [changeset] or [patchset].
*/
typedef struct sqlite3_changeset_iter sqlite3_changeset_iter;
/*
** CAPI3REF: Create A New Session Object
** CONSTRUCTOR: sqlite3_session
**
** Create a new session object attached to database handle db. If successful,
** a pointer to the new object is written to *ppSession and SQLITE_OK is
@@ -59,6 +66,7 @@ int sqlite3session_create(
/*
** CAPI3REF: Delete A Session Object
** DESTRUCTOR: sqlite3_session
**
** Delete a session object previously allocated using
** [sqlite3session_create()]. Once a session object has been deleted, the
@@ -74,6 +82,7 @@ void sqlite3session_delete(sqlite3_session *pSession);
/*
** CAPI3REF: Enable Or Disable A Session Object
** METHOD: sqlite3_session
**
** Enable or disable the recording of changes by a session object. When
** enabled, a session object records changes made to the database. When
@@ -93,6 +102,7 @@ int sqlite3session_enable(sqlite3_session *pSession, int bEnable);
/*
** CAPI3REF: Set Or Clear the Indirect Change Flag
** METHOD: sqlite3_session
**
** Each change recorded by a session object is marked as either direct or
** indirect. A change is marked as indirect if either:
@@ -122,6 +132,7 @@ int sqlite3session_indirect(sqlite3_session *pSession, int bIndirect);
/*
** CAPI3REF: Attach A Table To A Session Object
** METHOD: sqlite3_session
**
** If argument zTab is not NULL, then it is the name of a table to attach
** to the session object passed as the first argument. All subsequent changes
@@ -147,6 +158,35 @@ int sqlite3session_indirect(sqlite3_session *pSession, int bIndirect);
**
** SQLITE_OK is returned if the call completes without error. Or, if an error
** occurs, an SQLite error code (e.g. SQLITE_NOMEM) is returned.
**
** <h3>Special sqlite_stat1 Handling</h3>
**
** As of SQLite version 3.22.0, the "sqlite_stat1" table is an exception to
** some of the rules above. In SQLite, the schema of sqlite_stat1 is:
** <pre>
** &nbsp; CREATE TABLE sqlite_stat1(tbl,idx,stat)
** </pre>
**
** Even though sqlite_stat1 does not have a PRIMARY KEY, changes are
** recorded for it as if the PRIMARY KEY is (tbl,idx). Additionally, changes
** are recorded for rows for which (idx IS NULL) is true. However, for such
** rows a zero-length blob (SQL value X'') is stored in the changeset or
** patchset instead of a NULL value. This allows such changesets to be
** manipulated by legacy implementations of sqlite3changeset_invert(),
** concat() and similar.
**
** The sqlite3changeset_apply() function automatically converts the
** zero-length blob back to a NULL value when updating the sqlite_stat1
** table. However, if the application calls sqlite3changeset_new(),
** sqlite3changeset_old() or sqlite3changeset_conflict on a changeset
** iterator directly (including on a changeset iterator passed to a
** conflict-handler callback) then the X'' value is returned. The application
** must translate X'' to NULL itself if required.
**
** Legacy (older than 3.22.0) versions of the sessions module cannot capture
** changes made to the sqlite_stat1 table. Legacy versions of the
** sqlite3changeset_apply() function silently ignore any modifications to the
** sqlite_stat1 table that are part of a changeset or patchset.
*/
int sqlite3session_attach(
sqlite3_session *pSession, /* Session object */
@@ -155,6 +195,7 @@ int sqlite3session_attach(
/*
** CAPI3REF: Set a table filter on a Session Object.
** METHOD: sqlite3_session
**
** The second argument (xFilter) is the "filter callback". For changes to rows
** in tables that are not attached to the Session object, the filter is called
@@ -173,6 +214,7 @@ void sqlite3session_table_filter(
/*
** CAPI3REF: Generate A Changeset From A Session Object
** METHOD: sqlite3_session
**
** Obtain a changeset containing changes to the tables attached to the
** session object passed as the first argument. If successful,
@@ -282,7 +324,8 @@ int sqlite3session_changeset(
);
/*
** CAPI3REF: Load The Difference Between Tables Into A Session
** CAPI3REF: Load The Difference Between Tables Into A Session
** METHOD: sqlite3_session
**
** If it is not already attached to the session object passed as the first
** argument, this function attaches table zTbl in the same manner as the
@@ -347,6 +390,7 @@ int sqlite3session_diff(
/*
** CAPI3REF: Generate A Patchset From A Session Object
** METHOD: sqlite3_session
**
** The differences between a patchset and a changeset are that:
**
@@ -398,6 +442,7 @@ int sqlite3session_isempty(sqlite3_session *pSession);
/*
** CAPI3REF: Create An Iterator To Traverse A Changeset
** CONSTRUCTOR: sqlite3_changeset_iter
**
** Create an iterator used to iterate through the contents of a changeset.
** If successful, *pp is set to point to the iterator handle and SQLITE_OK
@@ -438,6 +483,7 @@ int sqlite3changeset_start(
/*
** CAPI3REF: Advance A Changeset Iterator
** METHOD: sqlite3_changeset_iter
**
** This function may only be used with iterators created by function
** [sqlite3changeset_start()]. If it is called on an iterator passed to
@@ -462,6 +508,7 @@ int sqlite3changeset_next(sqlite3_changeset_iter *pIter);
/*
** CAPI3REF: Obtain The Current Operation From A Changeset Iterator
** METHOD: sqlite3_changeset_iter
**
** The pIter argument passed to this function may either be an iterator
** passed to a conflict-handler by [sqlite3changeset_apply()], or an iterator
@@ -496,6 +543,7 @@ int sqlite3changeset_op(
/*
** CAPI3REF: Obtain The Primary Key Definition Of A Table
** METHOD: sqlite3_changeset_iter
**
** For each modified table, a changeset includes the following:
**
@@ -527,6 +575,7 @@ int sqlite3changeset_pk(
/*
** CAPI3REF: Obtain old.* Values From A Changeset Iterator
** METHOD: sqlite3_changeset_iter
**
** The pIter argument passed to this function may either be an iterator
** passed to a conflict-handler by [sqlite3changeset_apply()], or an iterator
@@ -557,6 +606,7 @@ int sqlite3changeset_old(
/*
** CAPI3REF: Obtain new.* Values From A Changeset Iterator
** METHOD: sqlite3_changeset_iter
**
** The pIter argument passed to this function may either be an iterator
** passed to a conflict-handler by [sqlite3changeset_apply()], or an iterator
@@ -590,6 +640,7 @@ int sqlite3changeset_new(
/*
** CAPI3REF: Obtain Conflicting Row Values From A Changeset Iterator
** METHOD: sqlite3_changeset_iter
**
** This function should only be used with iterator objects passed to a
** conflict-handler callback by [sqlite3changeset_apply()] with either
@@ -617,6 +668,7 @@ int sqlite3changeset_conflict(
/*
** CAPI3REF: Determine The Number Of Foreign Key Constraint Violations
** METHOD: sqlite3_changeset_iter
**
** This function may only be called with an iterator passed to an
** SQLITE_CHANGESET_FOREIGN_KEY conflict handler callback. In this case
@@ -633,6 +685,7 @@ int sqlite3changeset_fk_conflicts(
/*
** CAPI3REF: Finalize A Changeset Iterator
** METHOD: sqlite3_changeset_iter
**
** This function is used to finalize an iterator allocated with
** [sqlite3changeset_start()].
@@ -649,6 +702,7 @@ int sqlite3changeset_fk_conflicts(
** to that error is returned by this function. Otherwise, SQLITE_OK is
** returned. This is to allow the following pattern (pseudo-code):
**
** <pre>
** sqlite3changeset_start();
** while( SQLITE_ROW==sqlite3changeset_next() ){
** // Do something with change.
@@ -657,6 +711,7 @@ int sqlite3changeset_fk_conflicts(
** if( rc!=SQLITE_OK ){
** // An error has occurred
** }
** </pre>
*/
int sqlite3changeset_finalize(sqlite3_changeset_iter *pIter);
@@ -704,6 +759,7 @@ int sqlite3changeset_invert(
** sqlite3_changegroup object. Calling it produces similar results as the
** following code fragment:
**
** <pre>
** sqlite3_changegroup *pGrp;
** rc = sqlite3_changegroup_new(&pGrp);
** if( rc==SQLITE_OK ) rc = sqlite3changegroup_add(pGrp, nA, pA);
@@ -714,6 +770,7 @@ int sqlite3changeset_invert(
** *ppOut = 0;
** *pnOut = 0;
** }
** </pre>
**
** Refer to the sqlite3_changegroup documentation below for details.
*/
@@ -729,11 +786,15 @@ int sqlite3changeset_concat(
/*
** CAPI3REF: Changegroup Handle
**
** A changegroup is an object used to combine two or more
** [changesets] or [patchsets]
*/
typedef struct sqlite3_changegroup sqlite3_changegroup;
/*
** CAPI3REF: Create A New Changegroup Object
** CONSTRUCTOR: sqlite3_changegroup
**
** An sqlite3_changegroup object is used to combine two or more changesets
** (or patchsets) into a single changeset (or patchset). A single changegroup
@@ -771,6 +832,7 @@ int sqlite3changegroup_new(sqlite3_changegroup **pp);
/*
** CAPI3REF: Add A Changeset To A Changegroup
** METHOD: sqlite3_changegroup
**
** Add all changes within the changeset (or patchset) in buffer pData (size
** nData bytes) to the changegroup.
@@ -848,6 +910,7 @@ int sqlite3changegroup_add(sqlite3_changegroup*, int nData, void *pData);
/*
** CAPI3REF: Obtain A Composite Changeset From A Changegroup
** METHOD: sqlite3_changegroup
**
** Obtain a buffer containing a changeset (or patchset) representing the
** current contents of the changegroup. If the inputs to the changegroup
@@ -878,6 +941,7 @@ int sqlite3changegroup_output(
/*
** CAPI3REF: Delete A Changegroup Object
** DESTRUCTOR: sqlite3_changegroup
*/
void sqlite3changegroup_delete(sqlite3_changegroup*);
+16 -5
View File
@@ -65,7 +65,7 @@ LIBOBJ+= vdbe.o parse.o \
fts3_write.o fts5.o func.o global.o hash.o \
icu.o insert.o json1.o legacy.o loadext.o \
main.o malloc.o mem0.o mem1.o mem2.o mem3.o mem5.o \
memjournal.o \
memdb.o memjournal.o \
mutex.o mutex_noop.o mutex_unix.o mutex_w32.o \
notify.o opcodes.o os.o os_unix.o os_win.o \
pager.o pcache.o pcache1.o pragma.o prepare.o printf.o \
@@ -118,6 +118,7 @@ SRC = \
$(TOP)/src/mem2.c \
$(TOP)/src/mem3.c \
$(TOP)/src/mem5.c \
$(TOP)/src/memdb.c \
$(TOP)/src/memjournal.c \
$(TOP)/src/msvc.h \
$(TOP)/src/mutex.c \
@@ -361,6 +362,7 @@ TESTSRC += \
$(TOP)/ext/misc/ieee754.c \
$(TOP)/ext/misc/mmapwarm.c \
$(TOP)/ext/misc/nextchar.c \
$(TOP)/ext/misc/normalize.c \
$(TOP)/ext/misc/percentile.c \
$(TOP)/ext/misc/regexp.c \
$(TOP)/ext/misc/remember.c \
@@ -373,7 +375,7 @@ TESTSRC += \
$(TOP)/ext/misc/zipfile.c \
$(TOP)/ext/fts5/fts5_tcl.c \
$(TOP)/ext/fts5/fts5_test_mi.c \
$(TOP)/ext/fts5/fts5_test_tok.c
$(TOP)/ext/fts5/fts5_test_tok.c
#TESTSRC += $(TOP)/ext/fts2/fts2_tokenizer.c
@@ -422,6 +424,7 @@ TESTSRC2 = \
$(TOP)/ext/fts3/fts3_tokenizer.c \
$(TOP)/ext/fts3/fts3_write.c \
$(TOP)/ext/async/sqlite3async.c \
$(TOP)/ext/misc/stmt.c \
$(TOP)/ext/session/sqlite3session.c \
$(TOP)/ext/session/test_session.c
@@ -517,6 +520,7 @@ SHELL_OPT += -DSQLITE_INTROSPECTION_PRAGMAS
FUZZERSHELL_OPT = -DSQLITE_ENABLE_JSON1
FUZZCHECK_OPT = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_MEMSYS5
FUZZCHECK_OPT += -DSQLITE_MAX_MEMORY=50000000
FUZZCHECK_OPT += -DSQLITE_PRINTF_PRECISION_LIMIT=1000
DBFUZZ_OPT =
KV_OPT = -DSQLITE_THREADSAFE=0 -DSQLITE_DIRECT_OVERFLOW_READ
ST_OPT = -DSQLITE_THREADSAFE=0
@@ -571,6 +575,9 @@ ossshell$(EXE): $(TOP)/test/ossfuzz.c $(TOP)/test/ossshell.c sqlite3.c sqlite3.h
-DSQLITE_ENABLE_MEMSYS5 $(FUZZCHECK_OPT) \
$(TOP)/test/ossfuzz.c $(TOP)/test/ossshell.c sqlite3.c $(TLIBS) $(THREADLIB)
sessionfuzz$(EXE): $(TOP)/test/sessionfuzz.c sqlite3.c sqlite3.h
$(TCC) -o sessionfuzz$(EXE) $(TOP)/test/sessionfuzz.c -lz $(TLIBS) $(THREADLIB)
mptester$(EXE): sqlite3.c $(TOP)/mptest/mptest.c
$(TCCX) -o $@ -I. $(TOP)/mptest/mptest.c sqlite3.c \
$(TLIBS) $(THREADLIB)
@@ -891,14 +898,17 @@ fulltestonly: $(TESTPROGS) fuzztest
queryplantest: testfixture$(EXE) sqlite3$(EXE)
./testfixture$(EXE) $(TOP)/test/permutations.test queryplanner $(TESTOPTS)
fuzztest: fuzzcheck$(EXE) $(FUZZDATA)
fuzztest: fuzzcheck$(EXE) $(FUZZDATA) sessionfuzz$(EXE) $(TOP)/test/sessionfuzz-data1.db
./fuzzcheck$(EXE) $(FUZZDATA)
./sessionfuzz run $(TOP)/test/sessionfuzz-data1.db
fastfuzztest: fuzzcheck$(EXE) $(FUZZDATA)
fastfuzztest: fuzzcheck$(EXE) $(FUZZDATA) sessionfuzz$(EXE) $(TOP)/test/sessionfuzz-data1.db
./fuzzcheck$(EXE) --limit-mem 100M $(FUZZDATA)
./sessionfuzz run $(TOP)/test/sessionfuzz-data1.db
valgrindfuzz: fuzzcheck$(EXE) $(FUZZDATA)
valgrindfuzz: fuzzcheck$(EXE) $(FUZZDATA) sessionfuzz$(EXE) $(TOP)/test/sessionfuzz-data1.db
valgrind ./fuzzcheck$(EXE) --cell-size-check --limit-mem 10M --timeout 600 $(FUZZDATA)
valgrind ./sessionfuzz run $(TOP)/test/sessionfuzz-data1.db
# The veryquick.test TCL tests.
#
@@ -1062,6 +1072,7 @@ clean:
rm -f mptester mptester.exe
rm -f fuzzershell fuzzershell.exe
rm -f fuzzcheck fuzzcheck.exe
rm -f sessionfuzz
rm -f sqldiff sqldiff.exe
rm -f fts5.* fts5parse.*
rm -f lsm.h lsm1.c
+175 -163
View File
@@ -1,22 +1,22 @@
C Add\sthe\ssqlite3_vtab_nochange()\smethod\swhich\svirtual\stable\simplementations\ncan\suse\sto\soptimize\sUPDATEs.
D 2018-01-11T17:04:26.957
C Fix\shandling\sof\s"UPDATE\sOR\sREPLACE"\sstatements\srun\son\szipfile\svirtual\stables.
D 2018-03-20T13:26:01.034
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F Makefile.in 38f84f301cbef443b2d269f67a74b8cc536469831f70df7c3e912acc04932cc2
F Makefile.in 7016fc56c6b9bfe5daac4f34be8be38d8c0b5fab79ccbfb764d3b23bf1c6fff3
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
F Makefile.msc ede26e3fb675e0b3b07627640ce5917154a6ee7f8f2c97424eb5ab5f651cbd56
F README.md eeae1e552f93ef72ef7c5b8f6647b368a001c28820ad1df179d3dae602bef681
F VERSION 0c10cdfed866fdd2d80434f64f042c3330f1daaed12e54287beb104f04b3faaf
F Makefile.msc bdcad21b027a56a73e54a1121cfb9edd0a35c0abfa53aa12c2f996006ff99960
F README.md 1d5342ebda97420f114283e604e5fe99b0da939d63b76d492eabbaae23488276
F VERSION cdf91ac446255ecf3d8f6d8c3ee40d64123235ae5b3cef29d344e61b45ec3759
F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50
F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2
F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90
F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2
F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903
F autoconf/Makefile.am 66c0befa511f0d95ba229e180067cf0357a9ebf8b3201b06d683c5ba6220fb39
F autoconf/Makefile.msc 2c50a59319af7da4eaca8c13e3240881b1bc245fd175845a055faab7d03d6e67
F autoconf/Makefile.am 2c274948734e03c51790ff51468f91db8d570bcca864284d9c6d6e777264cd7e
F autoconf/Makefile.msc 1223d1520e0b833041ad87b377fae61cc3e08d14c5aae4c1a9e36249225bd4e6
F autoconf/README.first 6c4f34fe115ff55d4e8dbfa3cecf04a0188292f7
F autoconf/README.txt 4f04b0819303aabaa35fff5f7b257fb0c1ef95f1
F autoconf/configure.ac 8dd08ca564279fff091c9bfdd2599d8f992c9f1f70c5396de2126ad2bd1b3bed
F autoconf/configure.ac 18fca06f884213be062dd5e07c5297079cc45893d9cd3f522ce426e715033e3d
F autoconf/tea/Makefile.in b438a7020446c8a8156e8d97c8914a04833da6fd
F autoconf/tea/README 3e9a3c060f29a44344ab50aec506f4db903fb873
F autoconf/tea/aclocal.m4 52c47aac44ce0ddb1f918b6993e8beb8eee88f43
@@ -32,7 +32,7 @@ F autoconf/tea/win/rules.vc c511f222b80064096b705dbeb97060ee1d6b6d63
F config.guess 226d9a188c6196f3033ffc651cbc9dcee1a42977
F config.h.in 6376abec766e9a0785178b1823b5a587e9f1ccbc
F config.sub 9ebe4c3b3dab6431ece34f16828b594fb420da55
F configure 9af547be0e0e1a8fca8553b82599b5a3be1528a3d78deb68cb49d3b611215cb7 x
F configure 2c71f331b463e987567a2dd942f728534f1aa7a174551e08a7b31b328e9da4ff x
F configure.ac d4529ebb26ae046269334f1dac65f2b1d6927c2efe22b2ec24dce24dfe4f83dd
F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad
F doc/lemon.html 278113807f49d12d04179a93fab92b5b917a08771152ca7949d34e928efa3941
@@ -43,9 +43,9 @@ F ext/async/README.txt e12275968f6fde133a80e04387d0e839b0c51f91
F ext/async/sqlite3async.c 0f3070cc3f5ede78f2b9361fb3b629ce200d7d74
F ext/async/sqlite3async.h f489b080af7e72aec0e1ee6f1d98ab6cf2e4dcef
F ext/expert/README.md b321c2762bb93c18ea102d5a5f7753a4b8bac646cb392b3b437f633caf2020c3
F ext/expert/expert.c 4791c5e064aea81b2b829fa95228b22283380ee370ea88a1e580103b75516ebf
F ext/expert/expert.c d548d603a4cc9e61f446cc179c120c6713511c413f82a4a32b1e1e69d3f086a4
F ext/expert/expert1.test fd21496d8e52c817a7741f467f42b0502c0ac7e07dcdd1d6e15a3e8154ed4e41
F ext/expert/sqlite3expert.c 55ea02e9fcc014f4252e8a8c78d2bddc6d7ef62f9cb54ee283a659516eabb711
F ext/expert/sqlite3expert.c 1dfa561e64dc0f89d56b96e6afda87468c34b43604c2df50c47e3f4362778fb2
F ext/expert/sqlite3expert.h af6354f8ee5c9e025024e63fec3bd640a802afcc3099a44d804752cf0791d811
F ext/expert/test_expert.c d56c194b769bdc90cf829a14c9ecbc1edca9c850b837a4d0b13be14095c32a72
F ext/fts1/README.txt 20ac73b006a70bcfd80069bdaf59214b6cf1db5e
@@ -96,7 +96,7 @@ F ext/fts3/fts3_tokenizer.h 64c6ef6c5272c51ebe60fc607a896e84288fcbc3
F ext/fts3/fts3_tokenizer1.c 5c98225a53705e5ee34824087478cf477bdb7004
F ext/fts3/fts3_unicode.c 525a3bd9a7564603c5c061b7de55403a565307758a94600e8a2f6b00d1c40d9d
F ext/fts3/fts3_unicode2.c cc04fc672bfd42b1e650398cb0bf71f64f9aae032cfe75bbcfe75b9cf966029c
F ext/fts3/fts3_write.c a3f7bf869622d1d0aa66661ba71d88e6f9646d69a2c335f40a0addf25974db47
F ext/fts3/fts3_write.c b583dede85eb0c3c3026f8d7ccb781ea4e845ae583754fecb2ca425b5907d87d
F ext/fts3/fts3speed.tcl b54caf6a18d38174f1a6e84219950d85e98bb1e9
F ext/fts3/mkfts3amal.tcl 252ecb7fe6467854f2aa237bf2c390b74e71f100
F ext/fts3/tool/fts3cov.sh c331d006359456cf6f8f953e37f2b9c7d568f3863f00bb5f7eb87fea4ac01b73
@@ -111,12 +111,12 @@ F ext/fts5/fts5Int.h eda28e3a0a5d87c412e8355fe35da875b04cb389908c8eb0d867ad662ad
F ext/fts5/fts5_aux.c ca666a3bbe07c5a3bbe9fffaea19c935a1efaf337333e28bad7bdd1971ffd093
F ext/fts5/fts5_buffer.c 1dd1ec0446b3acfc2d7d407eb894762a461613e2695273f48e449bfd13e973ff
F ext/fts5/fts5_config.c 5af9c360e99669d29f06492c370892394aba0857
F ext/fts5/fts5_expr.c 01048018d21524e2c302b063ff5c3cdcf546e03297215e577205d85b47499deb
F ext/fts5/fts5_expr.c c23a2e4c14c401a147c4a730460e5b37057627bf4be95515ee281cd87f4d277c
F ext/fts5/fts5_hash.c 32be400cf761868c9db33efe81a06eb19a17c5402ad477ee9efb51301546dd55
F ext/fts5/fts5_index.c 5fe14375a29e8a7aa8f3e863babe180a19269206c254c8f47b216821d4ac1e15
F ext/fts5/fts5_index.c 22b71d0e9e4b3ddd123a39ae27174e0012da2806f91b64087a68584f13f189de
F ext/fts5/fts5_main.c 24868f88ab2a865defbba7a92eebeb726cc991eb092b71b5f5508f180c72605b
F ext/fts5/fts5_storage.c fb5ef3c27073f67ade2e1bea08405f9e43f68f5f3676ed0ab7013bce5ba10be6
F ext/fts5/fts5_tcl.c b470467be4c5cab2d8b026992c05d86cd2293e7d8c4a10ba56d5f4f707981097
F ext/fts5/fts5_storage.c 4bec8a1b3905978b22a67bca5f4a3cfdb94af234cf51efb36f4f2d733d278634
F ext/fts5/fts5_tcl.c 39bcbae507f594aad778172fa914cad0f585bf92fd3b078c686e249282db0d95
F ext/fts5/fts5_test_mi.c 65864ba1e5c34a61d409c4c587e0bbe0466eb4f8f478d85dc42a92caad1338e6
F ext/fts5/fts5_test_tok.c ffd657dd67e7fcdb31bf63fb60b6d867299a581d0f46e97086abacd66c2a9b26
F ext/fts5/fts5_tokenize.c 2ce7b44183538ec46b7907726262ee43ffdd39a8
@@ -126,7 +126,7 @@ F ext/fts5/fts5_vocab.c 1cd79854cb21543e66507b25b0578bc1b20aa6a1349b7feceb8e8fed
F ext/fts5/fts5parse.y eb526940f892ade5693f22ffd6c4f2702543a9059942772526eac1fde256bb05
F ext/fts5/mkportersteps.tcl 5acf962d2e0074f701620bb5308155fa1e4a63ba
F ext/fts5/test/fts5_common.tcl b01c584144b5064f30e6c648145a2dd6bc440841
F ext/fts5/test/fts5aa.test cba3fae6466446980caf1b9f5f26df77f95a999d35db7d932d6e82ae7ba0ede9
F ext/fts5/test/fts5aa.test 6e2fdb0ee667c05f41921e7ec345cae874be651670900918e9ccc539514b9356
F ext/fts5/test/fts5ab.test 9205c839332c908aaad2b01ab8670ece8b161e8f2ec8a9fabf18ca9385880bb7
F ext/fts5/test/fts5ac.test a7aa7e1fefc6e1918aa4d3111d5c44a09177168e962c5fd2cca9620de8a7ed6d
F ext/fts5/test/fts5ad.test e8cf959dfcd57c8e46d6f5f25665686f3b6627130a9a981371dafdf6482790de
@@ -165,10 +165,10 @@ F ext/fts5/test/fts5fault2.test 69c8fdbef830cd0d450908d4504d5bb86609e255af99c421
F ext/fts5/test/fts5fault3.test da2f9e3e56ff5740d68ebdd6877c97089e7ed28ddff28a0da87a6afea27e5522
F ext/fts5/test/fts5fault4.test 1c1db5fcfe59401e7833146100f1d8de284a0a686fac31ddac9fb56c459f725b
F ext/fts5/test/fts5fault5.test a336e4e11847de24c9497f80cce18e00bb3fab7fb11f97d04eb9af898900a762
F ext/fts5/test/fts5fault6.test 8a3c61402e36960ba46a419e73121fcefdc9160e0c04b6f5318c7fb0e3180dbc
F ext/fts5/test/fts5fault6.test a0fc0a8f99e4b16500c31dfc7e38e1defe0f1693ac47650517ac7b723b1956f8
F ext/fts5/test/fts5fault7.test 0acbec416edb24b8881f154e99c31e9ccf73f539cfcd164090be139e9e97ed4c
F ext/fts5/test/fts5fault8.test 318238659d35f82ad215ecb57ca4c87486ea85d45dbeedaee42f148ff5105ee2
F ext/fts5/test/fts5fault9.test 0111b229388bdf251b91cfead68580227801dd30960a19aa8fe9021a1e73cb6d
F ext/fts5/test/fts5fault9.test 098e6b894bbdf9b2192f994a30f4043673fb3f338b6b8ab1624c704422f39119
F ext/fts5/test/fts5faultA.test be4487576bff8c22cee6597d1893b312f306504a8c6ccd3c53ca85af12290c8c
F ext/fts5/test/fts5faultB.test e6d04f9ea7b21be1d89abb8df2cb4baf65b0453b744d5a805fcd3ef45ff86a7e
F ext/fts5/test/fts5faultD.test cc5d1225556e356615e719c612e845d41bff7d5a
@@ -268,32 +268,33 @@ F ext/lsm1/tool/mklsm1c.tcl f31561bbee5349f0a554d1ad7236ac1991fc09176626f529f607
F ext/misc/README.md d6dd0fe1d8af77040216798a6a2b0c46c73054d2f0ea544fbbcdccf6f238c240
F ext/misc/amatch.c 6db4607cb17c54b853a2d7c7c36046d004853f65b9b733e6f019d543d5dfae87
F ext/misc/anycollseq.c 5ffdfde9829eeac52219136ad6aa7cd9a4edb3b15f4f2532de52f4a22525eddb
F ext/misc/appendvfs.c 4c65f0b79686ae5a483134233d7fd912f0f2d4fd76023404f96f2290fff13b19
F ext/misc/btreeinfo.c d7fd9a2fe2fa33ba28488e2fce703ebecc759219ea9e0bb3b254784866c0a676
F ext/misc/appendvfs.c 3777f22ec1057dc4e5fd89f2fbddcc7a29fbeef1ad038c736c54411bb1967af7
F ext/misc/btreeinfo.c 78c8c57d325185ccc04b7679e5b020e34a4d9c87453e6b7ac943d0a26cee3256
F ext/misc/carray.c ed96c218ea940b85c9a274c4d9c59fe9491c299147a38a8bba537687bd6c6005
F ext/misc/closure.c 0d2a038df8fbae7f19de42e7c7d71f2e4dc88704
F ext/misc/completion.c 52c3f01523e3e387eb321b4739a89d1fe47cbe6025aa1f2d8d3685e9e365df0f
F ext/misc/compress.c dd4f8a6d0baccff3c694757db5b430f3bbd821d8686d1fc24df55cf9f035b189
F ext/misc/csv.c 1a009b93650732e22334edc92459c4630b9fa703397cbb3c8ca279921a36ca11
F ext/misc/dbdump.c 3509fa6b8932d04e932d6b6b827b6a82ca362781b8e8f3c77336f416793e215e
F ext/misc/dbdump.c 22018e00eb50e9ebf9067c92d4e7162dc5006a3efc4e0c19bc3829825a1043b0
F ext/misc/eval.c f971962e92ebb8b0a4e6b62949463ee454d88fa2
F ext/misc/fileio.c 1194228c96d6b7a374e93602e2ba1899b42d0fc4d4c5253962fb13e1c9ed1f77
F ext/misc/fileio.c da441efc13c0fa96a41b168bb8aa1014b12d36f3a0d619a2b77b3bdf2a3ccf5e
F ext/misc/fuzzer.c 7c64b8197bb77b7d64eff7cac7848870235d4c25
F ext/misc/ieee754.c f190d0cc5182529acb15babd177781be1ac1718c
F ext/misc/json1.c dbe086615b9546c156bf32b9378fc09383b58bd17513b866cfd24c1e15281984
F ext/misc/memvfs.c ab36f49e02ebcdf85a1e08dc4d8599ea8f343e073ac9e0bca18a98b7e1ec9567
F ext/misc/mmapwarm.c 70b618f2d0bde43fae288ad0b7498a629f2b6f61b50a27e06fae3cd23c83af29
F ext/misc/nextchar.c 35c8b8baacb96d92abbb34a83a997b797075b342
F ext/misc/normalize.c 19262ef3ef29d4de2f281b423326865c8916c63d0cb09f1dc98d24d5c1e8ba64
F ext/misc/percentile.c 92699c8cd7d517ff610e6037e56506f8904dae2e
F ext/misc/regexp.c a68d25c659bd2d893cd1215667bbf75ecb9dc7d4
F ext/misc/remember.c add730f0f7e7436cd15ea3fd6a90fd83c3f706ab44169f7f048438b7d6baa69c
F ext/misc/rot13.c 540a169cb0d74f15522a8930b0cccdcb37a4fd071d219a5a083a319fc6e8db77
F ext/misc/scrub.c 1c5bfb8b0cd18b602fcb55755e84abf0023ac2fb
F ext/misc/scrub.c db9fff56fed322ca587d73727c6021b11ae79ce3f31b389e1d82891d144f22ad
F ext/misc/series.c f3c0dba5c5c749ce1782b53076108f87cf0b71041eb6023f727a9c50681da564
F ext/misc/sha1.c 0b9e9b855354910d3ca467bf39099d570e73db56
F ext/misc/shathree.c 9e960ba50483214c6a7a4b1517f8d8cef799e9db381195178c3fd3ad207e10c0
F ext/misc/showauth.c 732578f0fe4ce42d577e1c86dc89dd14a006ab52
F ext/misc/spellfix.c 41cf26c6b89fcaa8798ae10ae64d39c1f1d9d6995152e545bd491c13058b8fac
F ext/misc/spellfix.c b3a644285cb008f3c10ed4cf04e17adcbc7d62c3911c79d786dfc91c177534f0
F ext/misc/sqlar.c 57d5bc45cd5492208e451f697404be88f8612527d64c9d42f96b325b64983d74
F ext/misc/stmt.c 6f16443abb3551e3f5813bb13ba19a30e7032830015b0f92fe0c0453045c0a11
F ext/misc/totype.c 4a167594e791abeed95e0a8db028822b5e8fe512
@@ -303,7 +304,8 @@ F ext/misc/vfsstat.c bf10ef0bc51e1ad6756629e1edb142f7a8db1178
F ext/misc/vtablog.c 31d0d8f4406795679dcd3a67917c213d3a2a5fb3ea5de35f6e773491ed7e13c9
F ext/misc/vtshim.c 1976e6dd68dd0d64508c91a6dfab8e75f8aaf6cd
F ext/misc/wholenumber.c 784b12543d60702ebdd47da936e278aa03076212
F ext/misc/zipfile.c cbf9dfaf94c25dfd835e79c1474fdc75517a45a37916dec66623b0937af10e51
F ext/misc/zipfile.c 316c771140fe54c17729138f139c7d94b13674b375ccfbb1e6e30202d835e8c8
F ext/misc/zorder.c b0ff58fa643afa1d846786d51ea8d5c4b6b35aa0254ab5a82617db92f3adda64
F ext/rbu/rbu.c ea7d1b7eb44c123a2a619332e19fe5313500705c4a58aaa1887905c0d83ffc2e
F ext/rbu/rbu1.test 43836fac8c7179a358eaf38a8a1ef3d6e6285842
F ext/rbu/rbu10.test 1846519a438697f45e9dcb246908af81b551c29e1078d0304fae83f1fed7e9ee
@@ -330,6 +332,7 @@ F ext/rbu/rbufault2.test 9a7f19edd6ea35c4c9f807d8a3db0a03a5670c06
F ext/rbu/rbufault3.test 0913c1aeaee266d9c36c33179341a5a504aad7d423d1979cfec43c8346a29899
F ext/rbu/rbufault4.test 34e70701cbec51571ffbd9fbf9d4e0f2ec495ca7
F ext/rbu/rbufts.test a2bbd202c9321fba15fb4a62a90add7d70e07bd8404e1e598135adbfff8a0508
F ext/rbu/rbumulti.test 2cf153ab3d5861ff26517dc6cbaec430787a59f1d50e8771fe7a7529a0551cf1
F ext/rbu/rbuprogress.test 1849d4e0e50616edf5ce75ce7db86622e656b5cf
F ext/rbu/rburesume.test 8acb77f4a422ff55acfcfc9cc15a5cb210b1de83
F ext/rbu/rbusave.test 0f43b6686084f426ddd040b878426452fd2c2f48
@@ -343,20 +346,20 @@ F ext/repair/README.md 92f5e8aae749a4dae14f02eea8e1bb42d4db2b6ce5e83dbcdd6b14469
F ext/repair/checkfreelist.c 0dbae18c1b552f58d64f8969e4fb1e7f11930c60a8c2a9a8d50b7f15bdfd54bd
F ext/repair/checkindex.c 7d28c01a2e012ac64257d230fc452b2cafb78311a91a343633d01d95220f66f3
F ext/repair/sqlite3_checker.c.in 4a5a3af3f450fe503e5a2985e98516dc2a6b9ad247449e284c1cf140fc91720f
F ext/repair/sqlite3_checker.tcl cc69e7fbc163f94da4a6400609be001543442d9f8f57a797d1eeb7b897585730
F ext/repair/sqlite3_checker.tcl a9a2caa9660567257c177a91124d8c0dccdfa341e25c51e6da7f1fd9e601eafa
F ext/repair/test/README.md 34b2f542cf5be7bffe479242b33ee3492cea30711e447cc4a1a86cb5915f419e
F ext/repair/test/checkfreelist01.test 3e8aa6aeb4007680c94a8d07b41c339aa635cc78249442da72ff3f8297398a69
F ext/repair/test/checkindex01.test 6945d0ffc0c1dc993b2ce88036b26e0f5d6fcc65da70fc9df27c2647bb358b0f
F ext/repair/test/test.tcl 686d76d888dffd021f64260abf29a55c57b2cedfa7fc69150b42b1d6119aac3c
F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761
F ext/rtree/rtree.c 2111f685ae07988622c241f819b56fea60782f56e32f97e334473c59f6083481
F ext/rtree/rtree.h 834dbcb82dc85b2481cde6a07cdadfddc99e9b9e
F ext/rtree/rtree1.test 82a353747fcab1083d114b2ac84723dfefdbf86c1a6e1df57bf588c7d4285436
F ext/rtree/rtree.c bc61010e978b5b8ae6dbb90274a2fbb5db5ff5e2880b5c6e8abd48eea77264db
F ext/rtree/rtree.h 4a690463901cb5e6127cf05eb8e642f127012fd5003830dbc974eca5802d9412
F ext/rtree/rtree1.test 47e2095bebea6813754fd7afa6a20e2b7b4ebcd5cb7dbcb6932b6c9f86bbf972
F ext/rtree/rtree2.test 5f25b01acd03470067a2d52783b2eb0a50bf836803d4342d20ca39e541220fe2
F ext/rtree/rtree3.test 2cafe8265d1ff28f206fce88d114f208349df482
F ext/rtree/rtree4.test 67b021858ba4334c8d49b3449476942c2ce0e5ef7123538f2e9dd508ed03a12d
F ext/rtree/rtree5.test 8aaa4bcdc42f718fe165572f5623e4732831aca95a2bc32482d33d4d2cf1325d
F ext/rtree/rtree6.test 773a90db2dce6a8353dd0d5b64bca69b29761196
F ext/rtree/rtree4.test 304de65d484540111b896827e4261815e5dca4ce28eeecd58be648cd73452c4b
F ext/rtree/rtree5.test 49c9041d713d54560b315c2c7ef7207ee287eba1b20f8266968a06f2e55d3142
F ext/rtree/rtree6.test 916a641d2beac01b9880871ff07612d56c1e466190a27c82ab36ffd58be03b9f
F ext/rtree/rtree7.test c8fb2e555b128dd0f0bdb520c61380014f497f8a23c40f2e820acc9f9e4fdce5
F ext/rtree/rtree8.test 649f5a37ec656028a4a32674b9b1183104285a7625a09d2a8f52a1cef72c93f2
F ext/rtree/rtree9.test c646f12c8c1c68ef015c6c043d86a0c42488e2e68ed1bb1b0771a7ca246cbabf
@@ -366,7 +369,7 @@ F ext/rtree/rtreeC.test d9d06dda1aee68b4dc227dfcc899f335f8b621e9d1920ee3d4e5dab8
F ext/rtree/rtreeD.test fe46aa7f012e137bd58294409b16c0d43976c3bb92c8f710481e577c4a1100dc
F ext/rtree/rtreeE.test e65d3fc625da1800b412fc8785817327d43ccfec5f5973912d8c9e471928caa9
F ext/rtree/rtreeF.test 81ffa7ef51c4e4618d497a57328c265bf576990c7070633b623b23cd450ed331
F ext/rtree/rtreeG.test fd3af1ca944a0bdb0cbb5455a4905c9f012e2fffcab6b791f07afa0dcbbcae0e
F ext/rtree/rtreeG.test 1b9ca6e3effb48f4161edaa463ddeaa8fca4b2526d084f9cbf5dbe4e0184939c
F ext/rtree/rtree_perf.tcl 6c18c1f23cd48e0f948930c98dfdd37dfccb5195
F ext/rtree/rtree_util.tcl db734b4c5e75fed6acc56d9701f2235345acfdec750b5fc7b587936f5f6bceed
F ext/rtree/rtreecheck.test 4d29103d1e16fcbf90135d1c637b833688492b063b2971dfb5dc6ba76555cfee
@@ -378,7 +381,7 @@ F ext/session/changeset.c 4ccbaa4531944c24584bf6a61ba3a39c62b6267a
F ext/session/session1.test 736d7ff178662f0b717c37f46531b84a5ce0210ccb0c4edf629c55dbcbbc3ea1
F ext/session/session2.test 284de45abae4cc1082bc52012ee81521d5ac58e0
F ext/session/session3.test ce9ce3dfa489473987f899e9f6a0f2db9bde3479
F ext/session/session4.test 457b02bdc349eb01151e54de014df77abd3c08c8
F ext/session/session4.test 3eea8058643e5adbd3293a5c553255c35e774ed90e7cbec09c9b010d176ad396
F ext/session/session5.test 716bc6fafd625ce60dfa62ae128971628c1a1169
F ext/session/session6.test 443789bc2fca12e4f7075cf692c60b8a2bea1a26
F ext/session/session8.test 8e194b3f655d861ca36de5d4de53f702751bab3b
@@ -386,19 +389,21 @@ F ext/session/session9.test 5409d90d8141881d08285ed1c2c0d8d10fb92069
F ext/session/sessionA.test 1feeab0b8e03527f08f2f1defb442da25480138f
F ext/session/sessionB.test 886252dcb7e692e62ef7e357456200912e367823
F ext/session/sessionC.test 97556f5164ac29f2344b24bd7de6a3a35a95c390
F ext/session/sessionD.test d4744c78334162851d2a2f285c7e603e31b49aa2
F ext/session/sessionD.test d3617e29aa15c9413aee5286d99587633245d58d2ad28f3f331c822735418a22
F ext/session/sessionE.test 0a616c4ad8fd2c05f23217ebb6212ef80b7fef30f5f086a6633a081f93e84637
F ext/session/sessionF.test c2f178d4dfd723a5fd94a730ea2ccb44c669e3ce
F ext/session/sessionG.test 01ef705096a9d3984eebdcca79807a211dee1b60
F ext/session/sessionG.test 63f9a744341d670775af29e4f19c1ef09a4810798400f28cd76704803a2e56ff
F ext/session/sessionH.test 332b60e4c2e0a680105e11936201cabe378216f307e2747803cea56fa7d9ebae
F ext/session/session_common.tcl 7776eda579773113b30c7abfd4545c445228cb73
F ext/session/session_speed_test.c edc1f96fd5e0e4b16eb03e2a73041013d59e8723
F ext/session/sessionat.test feb7d22b3124882064b9d9df69f5484a9bb8c123dc9ddc6ffcd357521848139f
F ext/session/sessionat.test efe88965e74ff1bc2af9c310b28358c02d420c1fb2705cc7a28f0c1cc142c3ec
F ext/session/sessiondiff.test ad13dd65664bae26744e1f18eb3cbd5588349b7e9118851d8f9364248d67bcec
F ext/session/sessionfault.test da273f2712b6411e85e71465a1733b8501dbf6f7
F ext/session/sessionfault2.test 04aa0bc9aa70ea43d8de82c4f648db4de1e990b0
F ext/session/sessionstat1.test 41cd97c2e48619a41cdf8ae749e1b25f34719de638689221aa43971be693bf4e
F ext/session/sessionwor.test 2f3744236dc8b170a695b7d8ddc8c743c7e79fdc
F ext/session/sqlite3session.c cc127222a9ea6f4eaa31281aa9da924f5244f6099be0ee526c950684fb3513a6
F ext/session/sqlite3session.h cb4d860101ba6d3ac810f18684539b766d24d668fa2436cdde90d711af9464fb
F ext/session/sqlite3session.c 9edfaaa74977ddecd7bbd94e8f844d9b0f6eec22d1d547e806361670db814c1e
F ext/session/sqlite3session.h 2e1584b030fbd841cefdce15ba984871978d305f586da2d1972f6e1958fa10b1
F ext/session/test_session.c eb0bd6c1ea791c1d66ee4ef94c16500dad936386
F ext/userauth/sqlite3userauth.h 7f3ea8c4686db8e40b0a0e7a8e0b00fac13aa7a3
F ext/userauth/user-auth.txt e6641021a9210364665fe625d067617d03f27b04
@@ -406,7 +411,7 @@ F ext/userauth/userauth.c 3410be31283abba70255d71fd24734e017a4497f
F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x
F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8
F magic.txt 8273bf49ba3b0c8559cb2774495390c31fd61c60
F main.mk fc0edb268998a049ce70ee3dc056b2a96cc8aa4ef0c6da296700d7081d167627
F main.mk 63668484c95454af7fc04a384da27ac556f27368d6d0c345e405e1677c66768f
F mkso.sh fd21c06b063bb16a5d25deea1752c2da6ac3ed83
F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271
F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504
@@ -419,81 +424,82 @@ F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b
F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786
F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a
F src/alter.c cf7a8af45cb0ace672f47a1b29ab24092a9e8cd8d945a9974e3b5d925f548594
F src/analyze.c 0d0ccf7520a201d8747ea2f02c92c26e26f801bc161f714f27b9f7630dde0421
F src/attach.c 84c477e856b24c2b9a0983b438a707c0cf4d616cee7a425401d418e58afec24c
F src/analyze.c 6b42e36a5dcc2703a771f2411bd5e99524bd62c7ecde209bb88dfb04c72f046e
F src/attach.c f6f212c43dddba79dfcb723fb9470785f3ff55bde8953cd9d2546f3022070a41
F src/auth.c 6277d63837357549fe14e723490d6dc1a38768d71c795c5eb5c0f8a99f918f73
F src/backup.c faf17e60b43233c214aae6a8179d24503a61e83b
F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33
F src/btmutex.c 0e9ce2d56159b89b9bc8e197e023ee11e39ff8ca
F src/btree.c 0a1f63b50ab1ac5d4b1637c30cb1ae123fbc162ec8cb6336ddb9491a0bc1e363
F src/btree.c 18a53540aa35dbdf77f715ea928422a4ed9011dc16ea7b50f803fd1617fcc4f5
F src/btree.h 0866c0a08255142ea0e754aabd211c843cab32045c978a592a43152405ed0c84
F src/btreeInt.h 55b702efce17e5d1941865464227d3802cfc9c7c832fac81d4c94dced47a71fc
F src/build.c 9f9647454f236cab097f266ae970f899b53c71cadab6756c47e2b2e81392c2a1
F src/btreeInt.h 620ab4c7235f43572cf3ac2ac8723cbdf68073be4d29da24897c7b77dda5fd96
F src/build.c 8b53aacc26944bb7fd9ab5ddeedecb4cc7c4b84df3a420cf6d2b8f772ad421df
F src/callback.c fe677cb5f5abb02f7a772a62a98c2f516426081df68856e8f2d5f950929b966a
F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e
F src/ctime.c ff1be3eed7bdd75aaca61ca8dc848f7c9f850ef2fb9cb56f2734e922a098f9c0
F src/date.c ebe1dc7c8a347117bb02570f1a931c62dd78f4a2b1b516f4837d45b7d6426957
F src/dbpage.c 8db4c97f630e7d83f884ea75caf1ffd0988c160e9d530194d93721c80821e0f6
F src/dbstat.c 7a4ba8518b6369ef3600c49cf9c918ad979acba610b2aebef1b656d649b96720
F src/delete.c 74667ad914ac143731a444a1bacf29ceb18f6eded8a0dd17aafae80baa07f8bb
F src/expr.c ad6e7a9c34a4bab9d10cc857d647ae7ce370a633b5c0bfa71f1c29b81ae364b8
F src/delete.c 20c8788451dc737a967c87ea53ad43544d617f5b57d32ccce8bd52a0daf9e89b
F src/expr.c 904f85e5f5fa232488cbb662fcf3306ae203728751468670fb9840a9b1886abc
F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007
F src/fkey.c d617daf66b5515e2b42c1405b2b4984c30ca50fb705ab164271a9bf66c69e331
F src/func.c bd528d5ed68ce5cbf78a762e3b735fa75009f7197ff07fab07fd771f35ebaa1b
F src/global.c ac3094f1dc59fbeb919aef7cc0cc827a8459d1fb1adb7972ef75bd9e0c10b75b
F src/func.c 94f42cba2cc1c34aeaa441022ba0170ec3fec4bba54db4e0ded085c6dc0fdc51
F src/global.c 01506976bd75e5e7b977207a6a05062e2dd0050012f8071be06bbea22ec6d69a
F src/hash.c a12580e143f10301ed5166ea4964ae2853d3905a511d4e0c44497245c7ce1f7a
F src/hash.h ab34c5c54a9e9de2e790b24349ba5aab3dbb4fd4
F src/hwtime.h 747c1bbe9df21a92e9c50f3bbec1de841dc5e5da
F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71
F src/insert.c 14686083cedc198540b15a79586cdd4be2acf6d5fa97627e355f817ab07e9fee
F src/legacy.c 134ab3e3fae00a0f67a5187981d6935b24b337bcf0f4b3e5c9fa5763da95bf4e
F src/loadext.c 55bcc3c741059a1056859e8adaf133aa179e22be12215c0936b2f354ef71209b
F src/main.c 26918d50dd4a61b8f6f210320a522f46b5e7e592335b6aa664ab15b80b7c239b
F src/loadext.c f6e4e416a736369f9e80eba609f0acda97148a8b0453784d670c78d3eed2f302
F src/main.c c1e97e4c6fffff1fb1a6f1c48807386819af78657b4ae4acfd6d6d17353b8277
F src/malloc.c 07295435093ce354c6d9063ac05a2eeae28bd251d2e63c48b3d67c12c76f7e18
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
F src/mem1.c c12a42539b1ba105e3707d0e628ad70e611040d8f5e38cf942cee30c867083de
F src/mem2.c f1940d9e91948dd6a908fbb9ce3835c36b5d83c3
F src/mem3.c 8768ac94694f31ffaf8b4d0ea5dc08af7010a35a
F src/mem5.c 9bf955937b07f8c32541c8a9991f33ce3173d944
F src/memdb.c 2bcebf99f77270e4b30ee5fad749347a6296db1662b3a196593e5410780aea85
F src/memjournal.c 6f3d36a0a8f72f48f6c3c722f04301ac64f2515435fa42924293e46fc7994661
F src/msvc.h 4942752b6a253116baaa8de75256c51a459a5e81
F src/mutex.c b021263554c8a3995e9d53193b8194b96d1ed28e06c3b532dd7f7d29cf0c7d53
F src/mutex.h 779d588e3b7756ec3ecf7d78cde1d84aba414f85
F src/mutex_noop.c 9d4309c075ba9cc7249e19412d3d62f7f94839c4
F src/mutex_unix.c 27bb6cc49485ee46711a6580ab7b3f1402211d23
F src/mutex_w32.c a898fa969823b100c0f5fdc57e54c9a1e419ab4d
F src/mutex_unix.c aaf9ebc3f89df28483c52208497a99a02cc3650011422fc9d4c57e4392f7fe58
F src/mutex_w32.c 7670d770c94bbfe8289bec9d7f1394c5a00a57c37f892aab6b6612d085255235
F src/notify.c 9711a7575036f0d3040ba61bc6e217f13a9888e7
F src/os.c 22d31db3ca5a96a408fbf1ceeaaebcaf64c87024d2ff9fe1cf2ddbec3e75c104
F src/os.h 48388821692e87da174ea198bf96b1b2d9d83be5dfc908f673ee21fafbe0d432
F src/os_common.h b2f4707a603e36811d9b1a13278bffd757857b85
F src/os_setup.h 0dbaea40a7d36bf311613d31342e0b99e2536586
F src/os_unix.c ecdffdc7fc25c07e42908be7c5ea30456fee6263e0d54cdf204557945b445da2
F src/os_win.c 0a4afa35cc8e812000df3ea2f64b476131b39e29e75d8007d0504726e4761de4
F src/os_unix.c 928586cbde31890538854f1657463392d63b2d7794f577774573ae53ec283d7b
F src/os_win.c eb03c6d52f893bcd7fdd4c6006674c13c1b5e49543fec98d605201af2997171c
F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a
F src/pager.c 9b9cb4e06c03d43d62480a7a685a012d645fcf3a39e7767ccb505fb41ee083ec
F src/pager.c 3e3b659b6b3f40b5a5efef6b8890ced490c397a81d96feb5266fde1f7362e608
F src/pager.h 581698f2177e8bd4008fe4760898ce20b6133d1df22139b9101b5155f900df7a
F src/parse.y 4e750e1b261ff9f1d0b6b5d40a829c66d691899f48953fde839d8b52d41aa148
F src/pcache.c 7ae91a4557a43d77d449accbfdc68846e6516f8e2eda46e8bbe4536fb669b201
F src/parse.y 3be4b2b5e33ef7dab3128b765898ee786fc6cd698a7f053f756a68f2f238f0aa
F src/pcache.c 135ef0bc6fb2e3b7178d49ab5c9176254c8a691832c1bceb1156b2fbdd0869bd
F src/pcache.h 072f94d29281cffd99e46c1539849f248c4b56ae7684c1f36626797fee375170
F src/pcache1.c 716975564c15eb6679e97f734cec1bfd6c16ac3d4010f05f1f8e509fc7d19880
F src/pragma.c bea56df3ae0637768c0da4fbbb8f2492f780980d95000034a105ff291bf7ca69
F src/pragma.h bb83728944b42f6d409c77f5838a8edbdb0fe83046c5496ffc9602b40340a324
F src/prepare.c 259f4e7960c47082c9653f3d5f0c294abd68bb9c3aab86de7630700cba1c20fb
F src/printf.c 9506b4b96e59c0467047155f09015750cb2878aeda3d39e5610c1192ddc3c41c
F src/prepare.c b086fea6a1952db88beca31fdd621201ee5e4ce3f02905248cc3035a8174aa89
F src/printf.c d3b7844ddeb11fbbdd38dd84d09c9c1ac171d21fb038473c3aa97981201cc660
F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384
F src/resolve.c bbee7e31d369a18a2f4836644769882e9c5d40ef4a3af911db06410b65cb3730
F src/resolve.c 66c73fcb7719b8ff0e841b58338f13604ff3e2b50a723f9b8f383595735262f6
F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac
F src/select.c 8b22abe193e4d8243befa2038e4ae2405802fed1c446e5e502d11f652e09ba74
F src/shell.c.in b87abffd0db09203ad8a133d56fe8f154ace5ec0a14197a153fb7d80b1438c01
F src/sqlite.h.in f83e63a48fb31fefc69c83bbe8700b4b44acdd64e440219087b0f14e35eeb8d4
F src/select.c f02352ac5cbb6fad3804add825743b924cfb6c742ba2e8666d726828a9985d73
F src/shell.c.in 9b7e7ac1ccdbc045e285e745ff6d21dbec6ce91330f2bdd5db50d5c39f40679e
F src/sqlite.h.in 2619d00bccc0454e875bce5e90b1dc986f87975c267dd7bbbe251f1be297d2f3
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
F src/sqlite3ext.h c02d628cca67f3889c689d82d25c3eb45e2c155db08e4c6089b5840d64687d34
F src/sqliteInt.h fd8702c65994d7de3e2d8f7d85d958731da1ed29476571fdfa2290fd8ec0bf80
F src/sqlite3ext.h 83a3c4ce93d650bedfd1aa558cb85a516bd6d094445ee989740827d0d944368d
F src/sqliteInt.h 2ef60a6d9a50e6eef224e9eae71b29a9fb91c301e882d9fbbb77afd50b6cf815
F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b
F src/status.c 9737ed017279a9e0c5da748701c3c7bf1e8ae0dae459aad20dd64fcff97a7e35
F src/status.c 46e7aec11f79dad50965a5ca5fa9de009f7d6bde08be2156f1538a0a296d4d0e
F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34
F src/tclsqlite.c 1833388c01e3b77f4c712185ee7250b9423ee0981ce6ae7e401e47db0319a696
F src/test1.c b52f9e7fe62016d357c3266fcfa0793cc1883d3cb2b11dfa39fcba2e70b0305c
F src/tclsqlite.c 916a92de77ec5cbe27818ca194d8cf0c58aa7ad5b87527098f6aa5a6068800ce
F src/test1.c 1ab7cbbb6693e08364c1a9241e2aee17f8c4925e4cc52396be77ae6845a05828
F src/test2.c 3efb99ab7f1fc8d154933e02ae1378bac9637da5
F src/test3.c b8434949dfb8aff8dfa082c8b592109e77844c2135ed3c492113839b6956255b
F src/test4.c 18ec393bb4d0ad1de729f0b94da7267270f3d8e6
@@ -508,7 +514,7 @@ F src/test_backup.c bf5da90c9926df0a4b941f2d92825a01bbe090a0
F src/test_bestindex.c 78809f11026f18a93fcfd798d9479cba37e1201c830260bf1edc674b2fa9b857
F src/test_blob.c ae4a0620b478548afb67963095a7417cd06a4ec0a56adb453542203bfdcb31ce
F src/test_btree.c 8b2dc8b8848cf3a4db93f11578f075e82252a274
F src/test_config.c cc8a1d44648d9392a14f4ecfc841d027daaf61f952b9f70792edf11373aaa3dd
F src/test_config.c 097c6189803886a1fb26ec37d8bc62b90512cb53ab79a1fb6d35196c1ec42ded
F src/test_delete.c e2fe07646dff6300b48d49b2fee2fe192ed389e834dd635e3b3bac0ce0bf9f8f
F src/test_demovfs.c a0c3bdd45ed044115c2c9f7779e56eafff18741e
F src/test_devsym.c 1960abbb234b97e9b920f07e99503fc04b443f62bbc3c6ff2c2cea2133e3b8a2
@@ -520,7 +526,7 @@ F src/test_intarray.c 988fc61cb0ff539f4172c0d95f15287c92516f64
F src/test_intarray.h f3b7672f5d1056eac563c0d6ea8480a660b1475c
F src/test_journal.c 619f2aa10e0d7a5f87c0f06825bc61dfce1c6b9c7f3ad990fb13de6c3b8874a3
F src/test_loadext.c 337056bae59f80b9eb00ba82088b39d0f4fe6dfd
F src/test_malloc.c 4f06a805de86be5216a127b3777ca2d5a1ff99d1a9238374ce136a47411be36c
F src/test_malloc.c 5201422e2403e66a7a9c2b7d8df806acd8d2a0429822adb7e932f324e7b5b3c6
F src/test_md5.c 7268e1e8c399d4a5e181b64ac20e1e6f3bc4dd9fc87abac02db145a3d951fa8c
F src/test_multiplex.c e054459f7633f3ff8ce1245da724f9a8be189e4e
F src/test_multiplex.h 5436d03f2d0501d04f3ed50a75819e190495b635
@@ -542,34 +548,34 @@ F src/test_thread.c 911d15fb14e19c0c542bdc8aabf981c2f10a4858
F src/test_vfs.c f0186261a24de2671d080bcd8050732f0cb64f6e
F src/test_vfstrace.c bab9594adc976cbe696ff3970728830b4c5ed698
F src/test_windirent.c a895e2c068a06644eef91a7f0a32182445a893b9a0f33d0cdb4283dca2486ac1
F src/test_windirent.h 8782864172ba5ae52c5c313c70faeadb324ff74de9c3dcc6b56a557dccaa1de6
F src/test_windirent.h 90dfbe95442c9762357fe128dc7ae3dc199d006de93eb33ba3972e0a90484215
F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9
F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c
F src/tokenize.c 5b0c661a85f783d35b9883830736eeb63be4aefc4f6b7d9cd081d48782c041e2
F src/treeview.c eae35972ff44f67064de2eaf35f04afe94e7aea3271a8b3bcebb3f954880fec3
F src/treeview.c e0d62678314abf0e1e6d09ea405f4de3f404a17b4641c2169c304b5edf509320
F src/trigger.c a34539c69433276d37b0da9a89c117726ff2d292c0902895af1f393a983cd3a1
F src/update.c 8bd52c38d6d426925be4488ee106db26d9ee344406315671ed246ddace8d6091
F src/update.c a90a32ffc0100265b0693dbbdbe490756447af181f5ea2c138cce515b08c8795
F src/utf.c 810fbfebe12359f10bc2a011520a6e10879ab2a163bcb26c74768eab82ea62a5
F src/util.c 7315e97a8dc2c8e19ca64196c652cf0a65d13fd0a211b2cec082062372dc6261
F src/vacuum.c 90839322fd5f00df9617eb21b68beda9b6e2a2937576b0d65985e4aeb1c53739
F src/vdbe.c 4d0666741d884dfaceb6ac5bbededbd947068e4b742163898feea84a027dace6
F src/vdbe.h d50cadf12bcf9fb99117ef392ce1ea283aa429270481426b6e8b0280c101fd97
F src/vdbeInt.h a0969c14950bcc61b2dfa19c6f62b42c5012013fcda342ca927a192ed37e6592
F src/vdbeapi.c f519346f6db99a1eb3f85ca3ae8aede9ff9c4d90fec809dae7cb946786b2e270
F src/vdbeaux.c 7ae48b180e5dd5d282e6752d155f1ab7929196d8e6577b82742044188152ca85
F src/util.c d9eb0a6c4aae1b00a7369eadd7ca0bbe946cb4c953b6751aa20d357c2f482157
F src/vacuum.c 762ee9bbf8733d87d8cd06f58d950e881982e416f8c767334a40ffd341b6bff5
F src/vdbe.c 88d8e0797bf49624d056014f34f302a7370cc119915cc0ece8f2b7bf5e7c30fb
F src/vdbe.h 134beb7a12a6213c00eba58febaede33447cc4441bc568a0d9c144b33fc3720a
F src/vdbeInt.h 95f7adfdc5c8f1353321f55a6c5ec00a90877e3b85af5159e393afb41ff54110
F src/vdbeapi.c 29d2baf9c1233131ec467d7bed1b7c8a03c27579048d768c4b04acf427838858
F src/vdbeaux.c 2756ac68ac259c416554100598fc291870063288cd7e1af22847f57b3e130e56
F src/vdbeblob.c f5c70f973ea3a9e915d1693278a5f890dc78594300cf4d54e64f2b0917c94191
F src/vdbemem.c 8478f7fb1948bf8fdeec7c2cb59ea58155c31258b9cd43c56d485e03ed40bd07
F src/vdbemem.c 414e28d3a7e2a8bee2bb247de115dcbc68e3cbac284d5862d077002f7a93bce1
F src/vdbesort.c 731a09e5cb9e96b70c394c1b7cf3860fbe84acca7682e178615eb941a3a0ef2f
F src/vdbetrace.c 48e11ebe040c6b41d146abed2602e3d00d621d7ebe4eb29b0a0f1617fd3c2f6c
F src/vtab.c 0e4885495172e1bdf54b12cce23b395ac74ef5729031f15e1bc1e3e6b360ed1a
F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9
F src/wal.c 5a3f464edd64596f601683ed321d12e6fd93c5fb9afdfb3653d6ffd0fee9c48f
F src/wal.c aa9cffc7a2bad6b826a86c8562dd4978398720ed41cb8ee7aa9d054eb8b456a0
F src/wal.h 8de5d2d3de0956d6f6cb48c83a4012d5f227b8fe940f3a349a4b7e85ebcb492a
F src/walker.c da987a20d40145c0a03c07d8fefcb2ed363becc7680d0500d9c79915591f5b1f
F src/where.c 36b92103f726609cc3dbe07c619426bd6886bede455de56ccff54c8e567f5582
F src/where.c 7cae47e813393d70c6d327fdf000fcb30f76b1b0b5a5b52ff6402e0c658de32c
F src/whereInt.h 82c04c5075308abbac59180c8bad5ecb45b07453981f60a53f3c7dee21e1e971
F src/wherecode.c af1e79154aaa88cd802d6f2e5b945f67eaca7c958d1525fbf8ee19d5bd7b9020
F src/whereexpr.c 427ea8e96ec24f2a7814c67b8024ad664a9c7656264c4566c34743cb23186e46
F src/wherecode.c e1aaadd8fec650037cfbf27d1b3470338fb3b58fec34d11082df16fe9a08fbd7
F src/whereexpr.c 53532be687e12f3cd314f1e204cd4fbdac7ad250e918a182b048121e16e828ae
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd
F test/affinity3.test 6a101af2fc945ce2912f6fe54dd646018551710d
@@ -669,7 +675,7 @@ F test/capi3b.test efb2b9cfd127efa84433cd7a2d72ce0454ae0dc4
F test/capi3c.test 7ebed1d8fa2f3190149d556fe8cff5a006be62af437c5c4640db614470126098
F test/capi3d.test 485048dc5cd07bc68011e4917ad035ad6047ab82
F test/capi3e.test 3d49c01ef2a1a55f41d73cba2b23b5059ec460fe
F test/cast.test 4c275cbdc8202d6f9c54a3596701719868ac7dc3
F test/cast.test 5ceb920718d280b61163500a7d29e0e0a86458b1cbd92d96f962c9d970aa3857
F test/cffault.test 9d6b20606afe712374952eec4f8fd74b1a8097ef
F test/check.test 33a698e8c63613449d85d624a38ef669bf20331daabebe3891c9405dd6df463a
F test/close.test 799ea4599d2f5704b0a30f477d17c2c760d8523fa5d0c8be4a7df2a8cad787d8
@@ -722,7 +728,7 @@ F test/crash4.test fe2821baf37168dc59dd733dcf7dba2a401487bc
F test/crash5.test 05dd3aa9dbb751a22d5cdaf22a9c49b6667aa219
F test/crash6.test 4c56f1e40d0291e1110790a99807aa875b1647ba
F test/crash7.test 1a194c4900a255258cf94b7fcbfd29536db572df
F test/crash8.test a63907617d8e74fb54b4bff23eca8a4435625245
F test/crash8.test 64366e459c28dd62edfb7ad87253a409c7533b92d16fcc479a6a8131bdcc3100
F test/crashM.test d95f59046fa749b0d0822edf18a717788c8f318d
F test/crashtest1.c 09c1c7d728ccf4feb9e481671e29dda5669bbcc2
F test/createtab.test b5de160630b209c4b8925bdcbbaf48cc90b67fe8
@@ -735,14 +741,14 @@ F test/date.test 9b73bbeb1b82d9c1f44dec5cf563bf7da58d2373
F test/date2.test 74c234bece1b016e94dd4ef9c8cc7a199a8806c0e2291cab7ba64bace6350b10
F test/dbfuzz.c 73047c920d6210e5912c87cdffd9a1c281d4252e
F test/dbpage.test dbf50a4d361f9e45a979432c727506065113124478a7d2db12074fa655e65d6c
F test/dbstatus.test 73149851b3aff14fc6db478e58f9083a66422cf5
F test/dbstatus2.test e93ab03bfae6d62d4d935f20de928c19ca0ed0ab
F test/dbstatus.test c15fa97f743dac7ce996814c84b56317e138895ee15ce27f15b608aa6924c90a
F test/dbstatus2.test f5fe0afed3fa45e57cfa70d1147606c20d2ba23feac78e9a172f2fe8ab5b78ef
F test/default.test 0cb49b1c315a0d81c81d775e407f66906a2a604d
F test/delete.test acc38fca8ee4851467705b1c2cfea64cd26667e5
F test/delete2.test 3a03f2cca1f9a67ec469915cb8babd6485db43fa
F test/delete3.test 555e84a00a99230b7d049d477a324a631126a6ab
F test/delete4.test 21d2113217eeaacac2d99defe14fe6611615ae86
F test/delete_db.test c70a43629dd4d3e1dd03fdaf7a22153af6a69d92
F test/delete_db.test 096d828493c7907f9ea11a7098ea6a0f73edba89406487d5d6cc2228dc4ab8b0
F test/descidx1.test 6d03b44c8538fe0eb4924e19fba10cdd8f3c9240
F test/descidx2.test 9f1a0c83fd57f8667c82310ca21b30a350888b5d
F test/descidx3.test 09ddbe3f5295f482d2f8b687cf6db8bad7acd9a2
@@ -783,14 +789,14 @@ F test/enc4.test c8f1ce3618508fd0909945beb8b8831feef2c020
F test/eqp.test 3fe051af50921284189d1970eb653f9fcf5117d2
F test/errmsg.test eae9f091eb39ce7e20305de45d8e5d115b68fa856fba4ea6757b6ca3705ff7f9
F test/eval.test a64c9105d6ff163df7cf09d6ac29cdad5922078c
F test/exclusive.test 9a57bd66e39144b888ca75c309914fcdefb4e3f9
F test/exclusive.test 1206b87e192497d78c7f35552e86a9d05421498da300fb1cce5ca5351ccde3c3
F test/exclusive2.test 984090e8e9d1b331d2e8111daf6e5d61dda0bef7
F test/exec.test e949714dc127eaa5ecc7d723efec1ec27118fdd7
F test/exists.test 79a75323c78f02bbe9c251ea502a092f9ef63dac
F test/expr.test 66a2c9ac34f74f036faa4092f5402c7d3162fc93
F test/expr.test 7cb55e80aeb41d65fec968c08212505123063fea60bdc355d764d747670e9eea
F test/extension01.test 00d13cec817f331a687a243e0e5a2d87b0e358c9
F test/extraquick.test cb254400bd42bfb777ff675356aabf3287978f79
F test/fallocate.test 87b5e43c872b7e69cd80b7b8813eb102b571a75d45dda24e38b65537bcc85733
F test/fallocate.test 07416bd593a116d5893cb244f45a94d5c6fe030561df3bd972e6135f8106e509
F test/filectrl.test 6e871c2d35dead1d9a88e176e8d2ca094fec6bb3
F test/filefmt.test f393e80c4b8d493b7a7f8f3809a8425bbf4292af1f5140f01cb1427798a2bbd4
F test/fkey1.test d11dbb8a93ead9b5c46ae5d02da016d61245d47662fb2d844c99214f6163f768
@@ -841,7 +847,7 @@ F test/fts2r.test b154c30b63061d8725e320fba1a39e2201cadd5e
F test/fts2token.test d8070b241a15ff13592a9ae4a8b7c171af6f445a
F test/fts3.test 672a040ea57036fb4b6fdc09027c18d7d24ab654
F test/fts3_common.tcl 99cf6659b87c0f74f55963c2aea03b3a7d66ceb0
F test/fts3aa.test 39b65c11913d277c91d7426c62cfc1d147d1b4e9a48fecd9e38f60d0b5a5f505
F test/fts3aa.test f267fcd6aca30fc70b81e5d82b68b34b38f581896020b57ed49e9777c7ebd85f
F test/fts3ab.test 7f6cf260ae80dda064023df8e8e503e9a412b91f
F test/fts3ac.test 636ed7486043055d4f126a0e385f2d5a82ebbf63
F test/fts3ad.test e40570cb6f74f059129ad48bcef3d7cbc20dda49
@@ -891,7 +897,7 @@ F test/fts3offsets.test b85fd382abdc78ebce721d8117bd552dfb75094c
F test/fts3prefix.test fa794eaab0bdae466494947b0b153d7844478ab2
F test/fts3prefix2.test e1f0a822ca661dced7f12ce392e14eaf65609dce
F test/fts3query.test f33eb71a1fe1084ea585eeb7ee76b390729f5170
F test/fts3rank.test e4d2e16a28c98cae95001a75e2b4b05b19b051ffd6aaab15491c5e0595127b9b
F test/fts3rank.test cd99bc83a3c923c8d52afd90d86979cf05fc41849f892faeac3988055ef37b99
F test/fts3rnd.test 1320d8826a845e38a96e769562bf83d7a92a15d0
F test/fts3shared.test 57e26a801f21027b7530da77db54286a6fe4997e
F test/fts3snippet.test 01a4231816e03a0660ae53ba2404fe69012fe0db
@@ -913,23 +919,23 @@ F test/fts4merge2.test 5faa558d1b672f82b847d2a337465fa745e46891
F test/fts4merge3.test 8d9ccb4a3d41c4c617a149d6c4b13ad02de797d0
F test/fts4merge4.test d895b1057a7798b67e03455d0fa50e9ea836c47b
F test/fts4noti.test 5553d7bb2e20bf4a06b23e849352efc022ce6309
F test/fts4onepass.test 7319d61a2ed1325fc54afd0c060a0513b462303a
F test/fts4onepass.test d69ddc4ee3415e40b0c5d1d0408488a87614d4f63ba9c44f3e52db541d6b7cc7
F test/fts4opt.test fd6a11684b965e1999564ae763797b7fb9e34c96
F test/fts4unicode.test ceca76422abc251818cb25dabe33d3c3970da5f7c90e1540f190824e6b3a7c95
F test/full.test 6b3c8fb43c6beab6b95438c1675374b95fab245d
F test/func.test ae97561957aba6ca9e3a7b8a13aac41830d701ef
F test/func.test 09dda479bcfc568f99f3070413e9672a8eeedc1be9c5d819bf55d4788c2583b7
F test/func2.test 772d66227e4e6684b86053302e2d74a2500e1e0f
F test/func3.test d202a7606d23f90988a664e88e268aed1087c11c
F test/func4.test 6beacdfcb0e18c358e6c2dcacf1b65d1fa80955f
F test/func5.test cdd224400bc3e48d891827cc913a57051a426fa4
F test/func6.test a4281c8fcd42b56f7a60f28e8e4d444e8b2256f9e82658b7ab87699f8318f564
F test/func6.test 90e42b64c4f9fb6f04f44cb8a1da586c8542502e926b19c76504fe74ff2a9b7c
F test/fuzz-oss1.test e58330d01cbbd8215ee636b17a03fe220b37dbfa
F test/fuzz.test 96083052bf5765e4518c1ba686ce2bab785670d1
F test/fuzz2.test 76dc35b32b6d6f965259508508abce75a6c4d7e1
F test/fuzz3.test 9c813e6613b837cb7a277b0383cd66bfa07042b4cf0317157c35852f30043c31
F test/fuzz_common.tcl a87dfbb88c2a6b08a38e9a070dabd129e617b45b
F test/fuzz_malloc.test 328f70aaca63adf29b4c6f06505ed0cf57ca7c26
F test/fuzzcheck.c 2152602232c96d9c790eff3013e1369ce59de3203fa0b75bc613531448454e61
F test/fuzzcheck.c 5eb86c6ac96833ee622f45bf47e8045999c1b4b10d05e4eb809894a4b39f2f84
F test/fuzzdata1.db 7ee3227bad0e7ccdeb08a9e6822916777073c664
F test/fuzzdata2.db f03a420d3b822cc82e4f894ca957618fbe9c4973
F test/fuzzdata3.db c6586d3e3cef0fbc18108f9bb649aa77bfc38aba
@@ -943,7 +949,7 @@ F test/genesis.tcl 1e2e2e8e5cc4058549a154ff1892fe5c9de19f98
F test/having.test e4098a4b8962f9596035c3b87a8928a10648acc509f1bb8d6f96413bbf79a1b3
F test/hexlit.test 4a6a5f46e3c65c4bf1fa06f5dd5a9507a5627751
F test/hidden.test 23c1393a79e846d68fd902d72c85d5e5dcf98711
F test/hook.test dbc0b87756e1e20e7497b56889c9e9cd2f8cc2b5
F test/hook.test 1604b3b2f5931430087540404555c1b6be3618600b81558657c66b533ed70b13
F test/hook2.test b9ff3b8c6519fb67f33192f1afe86e7782ee4ac8
F test/icu.test 41aa8847745a879b897a7febea0f8f9efc8e67fe8bf680589b6e07c7b0a1569a
F test/ieee754.test 806fc0ce7f305f57e3331eaceeddcfec9339e607
@@ -974,7 +980,7 @@ F test/index7.test 7feababe16f2091b229c22aff2bcc1d4d6b9d2bb
F test/index8.test bc2e3db70e8e62459aaa1bd7e4a9b39664f8f9d7
F test/index9.test 0aa3e509dddf81f93380396e40e9bb386904c1054924ba8fa9bcdfe85a8e7721
F test/indexedby.test faa585e315e868f09bce0eb39c41d6134649b13d2801638294d3ae616edf1609
F test/indexexpr1.test ace1ad489adc25325ad298434f13b1a515b36bf5dca9fe2a4b66cdf17aea3fa0
F test/indexexpr1.test 635261197bcdc19b9b2c59bbfa7227d525c00e9587faddb2d293c44d287ce60e
F test/indexexpr2.test 13247bac49143196556eb3f65e97ef301bd3e993f4511558b5db322ddc370ea6
F test/indexfault.test 31d4ab9a7d2f6e9616933eb079722362a883eb1d
F test/init.test 15c823093fdabbf7b531fe22cf037134d09587a7
@@ -990,30 +996,31 @@ F test/interrupt.test 16ea879ec728cb76414c148c5f24afd5d1f91054
F test/interrupt2.test e4408ca770a6feafbadb0801e54a0dcd1a8d108d
F test/intpkey.test ac71107a49a06492b69b82aafaf225400598d3c8
F test/io.test f95bca1783b01ea7761671560d023360d2dfa4cc
F test/ioerr.test 2a24bd6ed5a8b062e64bfe1f6cf94fb25e92210d
F test/ioerr.test 470fcc78e9cd352d162baf782fe301ea807d764241f58a48fc58109c2dfcdb6b
F test/ioerr2.test 2593563599e2cc6b6b4fcf5878b177bdd5d8df26
F test/ioerr3.test d3cec5e1a11ad6d27527d0d38573fbff14c71bdd
F test/ioerr4.test f130fe9e71008577b342b8874d52984bd04ede2c
F test/ioerr5.test 2edfa4fb0f896f733071303b42224df8bedd9da4
F test/ioerr6.test a395a6ab144b26a9e3e21059a1ab6a7149cca65b
F test/istrue.test 2d89873d72248b7a0ef7b5457120100cce75a19181bcf4b30e90a3f96a5c5558
F test/join.test 442c462eea85cf065d70a663c626b780a95af6e11585d909bb63b87598afe678
F test/join2.test 1a0c26399910b015d9f8f95b884e9a079fd2cfdccd65f7b1603846508cae0dc6
F test/join2.test f1b5ba94ba70a791df2d99e61adcebf62edacad1eca57881c97eb3e2ca718595
F test/join3.test 6f0c774ff1ba0489e6c88a3e77b9d3528fb4fda0
F test/join4.test 1a352e4e267114444c29266ce79e941af5885916
F test/join5.test bc98ea4b4e5003f5b1453701ebb8cd7d1c01a550
F test/join6.test cfe6503791ceb0cbb509966740286ec423cbf10b
F test/journal1.test 69abc726c51b4a0409189f9a85191205297c0577
F test/journal1.test c7b768041b7f494471531e17abc2f4f5ebf9e5096984f43ed17c4eb80ba34497
F test/journal2.test 9dac6b4ba0ca79c3b21446bbae993a462c2397c4
F test/journal3.test ff8af941f9e06161d3db1b46bb9f965ff0e7f307
F test/jrnlmode.test 7864d59cf7f6e552b9b99ba0f38acd167edc10fa
F test/jrnlmode2.test 81610545a4e6ed239ea8fa661891893385e23a1d
F test/journal3.test c9c29883f5bf535ae82ae21c472df6263806a22e467b6db7cd0d6d545305b4f6
F test/jrnlmode.test a6693f2bed4541a21e703aaa37bb3e10de154130645952933b82b2dec0a8b539
F test/jrnlmode2.test 8759a1d4657c064637f8b079592651530db738419e1d649c6df7048cd724363d
F test/jrnlmode3.test 556b447a05be0e0963f4311e95ab1632b11c9eaa
F test/json101.test d7cdf3e6731d41e0c4bde1c88806abd17f1f478486a1409933c1d8eac9120095
F test/json101.test 24e97954e3bd6404f3715888c7f8f835e36e19c7ae6513b5d9ab2d381498962d
F test/json102.test eeb54efa221e50b74a2d6fb9259963b48d7414dca3ce2fdfdeed45cb28487bc1
F test/json103.test c5f6b85e69de05f6b3195f9f9d5ce9cd179099a0
F test/json104.test 877d5845f6303899b7889ea5dd1bea99076e3100574d5c536082245c5805dcaa
F test/keyword1.test 37ef6bba5d2ed5b07ecdd6810571de2956599dff
F test/kvtest.c fcb38ffe3db028a3138b4818fc098359c80dc51a0d1278a91c99c554cc1abb92
F test/kvtest.c 23452e653e6b0254dc2fd1d242d4c7c65644504de8951d7d60f7e4291c52c231
F test/lastinsert.test 42e948fd6442f07d60acbd15d33fb86473e0ef63
F test/laststmtchanges.test ae613f53819206b3222771828d024154d51db200
F test/like.test 11cfd7d4ef8625389df9efc46735ff0b0b41d5e62047ef0f3bc24c380d28a7a6
@@ -1026,7 +1033,7 @@ F test/loadext2.test 0408380b57adca04004247179837a18e866a74f7
F test/lock.test be4fe08118fb988fed741f429b7dd5d65e1c90db
F test/lock2.test 5242d8ac4e2d59c403aebff606af449b455aceff
F test/lock3.test f271375930711ae044080f4fe6d6eda930870d00
F test/lock4.test e175ae13865bc87680607563bafba21f31a26f12
F test/lock4.test 27143363eda1622f03c133efc8db808fc331afd973486cb571ea71cd717d37b8
F test/lock5.test c6c5e0ebcb21c61a572870cc86c0cb9f14cede38
F test/lock6.test ad5b387a3a8096afd3c68a55b9535056431b0cf5
F test/lock7.test 49f1eaff1cdc491cc5dee3669f3c671d9f172431
@@ -1034,8 +1041,8 @@ F test/lock_common.tcl 7ffb45accf6ee91c736df9bafe0806a44358f035
F test/lookaside.test b17c99ae3aef96a8c9fa6f6be33cc75b93d657cb791d3827302b6835b71941f7
F test/main.test 6bbb3999fd461eb8fb335cbab97409a3d7f91bbb8da60635e8be3e4a04a77772
F test/make-where7.tcl 05c16b5d4f5d6512881dfec560cb793915932ef9
F test/malloc.test 21c213365f2cca95ab2d7dc078dc8525f96065f8
F test/malloc3.test e3b32c724b5a124b57cb0ed177f675249ad0c66a
F test/malloc.test 18dd1c4188c81ca79cf123527c71b19ee0c31feb9947fdffb0dc6ceb1436816a
F test/malloc3.test 6e88bae6312854a4adb4ecc2a6a5ea8c59b4db778b724ba718e1c43fc8c3c136
F test/malloc4.test 957337613002b7058a85116493a262f679f3a261
F test/malloc5.test f6eb6eca07a4c75f2897bf43a404689b6295bb95ab2e07d4b52eda743f925a27
F test/malloc6.test 2f039d9821927eacae43e1831f815e157659a151
@@ -1060,6 +1067,7 @@ F test/malloc_common.tcl aac62499b76be719fac31e7a3e54a7fd53272e7f
F test/manydb.test 28385ae2087967aa05c38624cec7d96ec74feb3e
F test/mem5.test c6460fba403c5703141348cd90de1c294188c68f
F test/memdb.test c1f2a343ad14398d5d6debda6ea33e80d0dafcc7
F test/memdb1.test fbe47f36c12725ebdd2760f846371e6eb09f403bd7236fbdddb21aa6e3c652b4
F test/memleak.test 10b9c6c57e19fc68c32941495e9ba1c50123f6e2
F test/memsubsys1.test 9e7555a22173b8f1c96c281ce289b338fcba2abe8b157f8798ca195bbf1d347e
F test/memsubsys2.test 3e4a8d0c05fd3e5fa92017c64666730a520c7e08
@@ -1073,7 +1081,7 @@ F test/misc3.test cf3dda47d5dda3e53fc5804a100d3c82be736c9d
F test/misc4.test 0d8be3466adf123a7791a66ba2bc8e8d229e87f3
F test/misc5.test 60e1fc758a93cacd19eb2fafcd1d40d150a05047546c7a92389c98047d621901
F test/misc6.test 953cc693924d88e6117aeba16f46f0bf5abede91
F test/misc7.test 859894e3192257ce2fc4063b5438b220e352286974b387e485050f0ad1f665d6
F test/misc7.test 567e223b6497da2226a0340befaf2d663c91ad57a48aede21a35a984a2882d41
F test/misc8.test ba03aaa08f02d62fbb8d3b2f5595c1b33aa9bbc5
F test/misuse.test 9e7f78402005e833af71dcab32d048003869eca5abcaccc985d4f8dc1d86bcc7
F test/mjournal.test 9d86e697dcbc5da2c4e8caba9b176b5765fe65e80c88c278b8c09a917e436795
@@ -1090,12 +1098,13 @@ F test/multiplex4.test e8ae4c4bd70606a5727743241f13b5701990abe4
F test/mutex1.test ea2cc74d97f077b9e74c84cbd024f14d79a8126f
F test/mutex2.test bfeaeac2e73095b2ac32285d2756e3a65e681660
F test/nan.test 437d40e6d0778b050d7750726c0cbd2c9936b81962926e8f8c48ca698f00f4d1
F test/nockpt.test 9a436a7213ba5ef7a32304998d386d3ea3f76c9d
F test/nockpt.test 8c43b25af63b0bd620cf1b003529e37b6f1dc53bd22690e96a1bd73f78dde53a
F test/nolock.test f196cf8b8fbea4e2ca345140a2b3f3b0da45c76e
F test/normalize.test 501630ab49b0b26b65c74124bf03e3374c1b57fa97aae750f84803609141d167
F test/notify1.test 669b2b743618efdc18ca4b02f45423d5d2304abf
F test/notify2.test 2ecabaa1305083856b7c39cf32816b612740c161
F test/notify3.test 10ff25cde502e72a92053a2f215d64bece4ef934
F test/notnull.test f8fcf58669ddba79274daa2770d61dfad8274f62
F test/notnull.test b6999231221df3534827e45e2005dd7a815fdd5f2c2e1afb9be21ead410816f8
F test/null.test 0dcce4f04284ec66108c503327ad6d224c0752b3
F test/numcast.test 5d126f7f581432e86a90d1e35cac625164aec4a1
F test/numindex1.test 20a5450d4b056e48cd5db30e659f13347a099823
@@ -1111,14 +1120,14 @@ F test/orderby7.test 3d1383d52ade5b9eb3a173b3147fdd296f0202da
F test/orderby8.test 23ef1a5d72bd3adcc2f65561c654295d1b8047bd
F test/orderby9.test 87fb9548debcc2cd141c5299002dd94672fa76a3
F test/oserror.test b32dc34f2363ef18532e3a0a7358e3e7e321974f
F test/ossfuzz.c 7f5cc87a0280a5854c1bfa7d5c4d07d34731f08ec34dc9c916aa35ed292b1468
F test/ossshell.c 296ab63067841bd1b1e97b46a0b2af48ee7f69d50d1a723008bee12dd7122622
F test/ossfuzz.c c4c4547e2c92ac52f10038b073a03248251a23c1c559728f63a18aeca0e79f03
F test/ossshell.c f125c5bd16e537a2549aa579b328dd1c59905e7ab1338dfc210e755bb7b69f17
F test/ovfl.test 199c482696defceacee8c8e0e0ef36da62726b2f
F test/pager1.test 8149b2a8986fee667ab6a8171ab310be19e77ae215bebad0e90c857b0df1935c
F test/pager1.test f596d3bd53ce96e1d87d44d223d2ae6c8867dd782c425e5eb28b5721fa6aaa97
F test/pager2.test 67b8f40ae98112bcdba1f2b2d03ea83266418c71
F test/pager3.test 3856d9c80839be0668efee1b74811b1b7f7fc95f
F test/pager3.test 4e9a83d6ca0838d7c602c9eb93d1357562d9059c1e02ffb138a8271020838370
F test/pager4.test a122e9e6925d5b23b31e3dfef8c6a44bbf19590e
F test/pagerfault.test 263c5442c06caf0b9b9e3fe42acdeb11f254dcebe533f69f401aaef9111eaf20
F test/pagerfault.test 63c5da625562c66345ab4528790327ca63db2f6f9cbae2aba8cb7c51de3d1628
F test/pagerfault2.test caf4c7facb914fd3b03a17b31ae2b180c8d6ca1f
F test/pagerfault3.test 1003fcda009bf48a8e22a516e193b6ef0dd1bbd8
F test/pageropt.test 84e4cc5cbca285357f7906e99b21be4f2bf5abc0
@@ -1135,7 +1144,7 @@ F test/pragma4.test 3046501bee2f652dc2a4f9c87781e2741361d6864439c8381aba6c3b774b
F test/pragma5.test 824ce6ced5d6b7ec71abe37fc6005ff836fe39d638273dc5192b39864b9ee983
F test/pragmafault.test 275edaf3161771d37de60e5c2b412627ac94cef11739236bec12ed1258b240f8
F test/printf.test b3ff34e73d59124140eaf89f7672e21bc2ca5fcc
F test/printf2.test 9e6db85f81c63f2367c34a9d7db384088bd374ad
F test/printf2.test 30b5dd0b4b992dc5626496846ecce17ff592cacbcb11c3e589f3ac4d7e129dae
F test/progress.test ebab27f670bd0d4eb9d20d49cef96e68141d92fb
F test/ptrchng.test ef1aa72d6cf35a2bbd0869a649b744e9d84977fc
F test/pushdown.test 5e72c51c5e33253ed639ccee1e01ce62d62b6eee5ca893cd82334e4ee7b1d7fc
@@ -1154,13 +1163,13 @@ F test/regexp2.test 40e894223b3d6672655481493f1be12012f2b33c
F test/reindex.test 44edd3966b474468b823d481eafef0c305022254
F test/releasetest.tcl 6aaa853f7a7bbdc458d4cb42c0425228729b0f3e5769e9b41088c08eee999a49 x
F test/resolver01.test f4022acafda7f4d40eca94dbf16bc5fc4ac30ceb
F test/rollback.test f580934279800d480a19176c6b44909df31ce7ad45267ea475a541daa522f3d3
F test/rollback.test 06680159bc6746d0f26276e339e3ae2f951c64812468308838e0a3362d911eaa
F test/rollback2.test 8435d6ff0f13f51d2a4181c232e706005fa90fc5
F test/rollbackfault.test 0e646aeab8840c399cfbfa43daab46fd609cf04a
F test/rowallock.test 3f88ec6819489d0b2341c7a7528ae17c053ab7cc
F test/rowhash.test 0bc1d31415e4575d10cacf31e1a66b5cc0f8be81
F test/rowid.test 5b7509f384f4f6fae1af3c8c104c8ca299fea18d
F test/rowvalue.test 44f3492f415cc9f374e8388a5eb61503eaca5230
F test/rowvalue.test 32861d6a933ded868035f2ec79aeb993a2a46eb7a6d282ae13415a4c2e369463
F test/rowvalue2.test 060d238b7e5639a7c5630cb5e63e311b44efef2b
F test/rowvalue3.test 3068f508753af69884b12125995f023da0dbb256
F test/rowvalue4.test 4b556d7de161a0dd8cff095c336e913986398bea
@@ -1203,9 +1212,11 @@ F test/selectC.test e25243f8ca503e06f252eb0218976d07cfeceac3
F test/selectD.test b0f02a04ef7737decb24e08be2c39b9664b43394
F test/selectE.test a8730ca330fcf40ace158f134f4fe0eb00c7edbf
F test/selectF.test 21c94e6438f76537b72532fa9fd4710cdd455fc3
F test/selectG.test e8600e379589e85e9fefd2fe4d44a4cdd63f6982
F test/selectG.test 089f7d3d7e6db91566f00b036cb353107a2cca6220eb1cb264085a836dae8840
F test/server1.test 46803bd3fe8b99b30dbc5ff38ffc756f5c13a118
F test/session.test 78fa2365e93d3663a6e933f86e7afc395adf18be
F test/sessionfuzz-data1.db 1f8d5def831f19b1c74571037f0d53a588ea49a6c4ca2a028fc0c27ef896dbcb
F test/sessionfuzz.c b0fcdcf757451957e17396a3af5171f1fdf9b2babc81da9fa35675df46c4729a
F test/shared.test 1da9dbad400cee0d93f252ccf76e1ae007a63746
F test/shared2.test 03eb4a8d372e290107d34b6ce1809919a698e879
F test/shared3.test ab693f9b6e156b8bfb2a0ad94f29fe69602a5d38
@@ -1214,7 +1225,7 @@ F test/shared6.test 866bb4982c45ce216c61ded5e8fde4e7e2f3ffa9
F test/shared7.test a81e99f83e6c51b02ac99c96fb3a2a7b5978c956
F test/shared8.test 00a07bf5e1337ecf72e94542bdefdc330d7a2538
F test/shared9.test 5f2a8f79b4d6c7d107a01ffa1ed05ae7e6333e21
F test/sharedA.test 0cdf1a76dfa00e6beee66af5b534b1e8df2720f5
F test/sharedA.test 49d87ec54ab640fbbc3786ee3c01de94aaa482a3a9f834ad3fe92770eb69e281
F test/sharedB.test 16cc7178e20965d75278f410943109b77b2e645e
F test/shared_err.test 32634e404a3317eeb94abc7a099c556a346fdb8fb3858dbe222a4cbb8926a939
F test/sharedlock.test 5ede3c37439067c43b0198f580fd374ebf15d304
@@ -1225,7 +1236,7 @@ F test/shell4.test 89ad573879a745974ff2df20ff97c5d6ffffbd5d
F test/shell5.test 23939a4c51f0421330ea61dbd3c74f9c215f5f8d3d1a94846da6ffc777a35458
F test/shell6.test 1ceb51b2678c472ba6cf1e5da96679ce8347889fe2c3bf93a0e0fa73f00b00d3
F test/shell7.test 115132f66d0463417f408562cc2cf534f6bbc6d83a6d50f0072a9eb171bae97f
F test/shell8.test c836470ccde867e1f438a7acad7560805cc04f9dbab84cb55d92925942b76247
F test/shell8.test 96be02ea0c21f05b24c1883d7b711a1fa8525a68ab7b636aacf6057876941013
F test/shortread1.test bb591ef20f0fd9ed26d0d12e80eee6d7ac8897a3
F test/show_speedtest1_rtree.tcl 32e6c5f073d7426148a6936a0408f4b5b169aba5
F test/shrink.test 1b4330b1fd9e818c04726d45cb28db73087535ce
@@ -1254,17 +1265,18 @@ F test/speed2.test 53177056baf6556dcbdcf032bbdfc41c1aa74ded
F test/speed3.test 694affeb9100526007436334cf7d08f3d74b85ef
F test/speed4.test abc0ad3399dcf9703abed2fff8705e4f8e416715
F test/speed4p.explain 6b5f104ebeb34a038b2f714150f51d01143e59aa
F test/speed4p.test 0e51908951677de5a969b723e03a27a1c45db38b
F test/speed4p.test 377a0c48e5a92e0b11c1c5ebb1bc9d83a7312c922bc0cb05970ef5d6a96d1f0c
F test/speedtest1.c a5faf4cbe5769eee4b721b3875cb3f12520a9b99d9026b1063b47c39603375b8
F test/spellfix.test f9c1f431e2c096c8775fec032952320c0e4700db
F test/spellfix.test 951a6405d49d1a23d6b78027d3877b4a33eeb8221dcab5704b499755bb4f552e
F test/spellfix2.test dfc8f519a3fc204cb2dfa8b4f29821ae90f6f8c3
F test/spellfix3.test 0f9efaaa502a0e0a09848028518a6fb096c8ad33
F test/spellfix4.test 51c7c26514ade169855c66bcf130bd5acfb4d7fd090cc624645ab275ae6a41fb
F test/sqldiff1.test 28cd737cf1b0078b1ec1bbf425e674c47785835e
F test/sqllimits1.test a74ee2a3740b9f9c2437c246d8fb77354862a142
F test/sqllog.test 6af6cb0b09f4e44e1917e06ce85be7670302517a
F test/stat.test f8f1279ffffabe6df825723af18cc6e0ae70a893
F test/statfault.test f525a7bf633e50afd027700e9a486090684b1ac1
F test/stmt.test 64844332db69cf1a735fcb3e11548557fc95392f
F test/stmt.test 54ed2cc0764bf3e48a058331813c3dbd19fc1d0827c3d8369914a5d8f564ec75
F test/stmtvtab1.test 6873dfb24f8e79cbb5b799b95c2e4349060eb7a3b811982749a84b359468e2d5
F test/subjournal.test 8d4e2572c0ee9a15549f0d8e40863161295107e52f07a3e8012a2e1fdd093c49
F test/subquery.test d7268d193dd33d5505df965399d3a594e76ae13f
@@ -1277,25 +1289,25 @@ F test/swarmvtab.test 9a3fd5ab3e9b3c976ad1b3d7646aab725114f2ac26b59395d0778b33ba
F test/swarmvtab2.test c948cb2fdfc5b01d85e8f6d6504854202dc1a0782ab2a0ed61538f27cbd0aa5c
F test/swarmvtab3.test 6cb664669630fcec4102a09333e52068734858fd2761eee3b0465c14cdbcee29
F test/swarmvtabfault.test 00aec54665909490f5c383f3cae3b5d18bd97c12490b429ff8752a3027acfa42
F test/symlink.test c9ebe7330d228249e447038276bfc8a7b22f4849
F test/sync.test 2f84bdbc2b2df1fcb0220575b4b9f8cea94b7529
F test/sync2.test 6be8ed007fa063b147773c1982b5bdba97a32badc536bdc6077eff5cf8710ece
F test/symlink.test 0d816670325536b8973ec08d32b45136baddb80bd45fd178e0ce7a9e8153f3e7
F test/sync.test 89539f4973c010eda5638407e71ca7fddbcd8e0594f4c9980229f804d4333092
F test/sync2.test 8f9f7d4f6d5be8ca8941a8dadcc4299e558cb6a1ff653a9469146c7a76ef2039
F test/syscall.test a39d9a36f852ae6e4800f861bc2f2e83f68bbc2112d9399931ecfadeabd2d69d
F test/sysfault.test c9f2b0d8d677558f74de750c75e12a5454719d04
F test/tabfunc01.test c47171c36b3d411df2bd49719dcaa5d034f8d277477fd41d253940723b969a51
F test/table.test b708f3e5fa2542fa51dfab21fc07b36ea445cb2f
F test/tableapi.test 2674633fa95d80da917571ebdd759a14d9819126
F test/tableopts.test dba698ba97251017b7c80d738c198d39ab747930
F test/tclsqlite.test c3d7ac9449634b9f17fd048a3c0212e88a7448be810a9c5bd051acc1ffa00d2f
F test/tempdb.test bd92eba8f20e16a9136e434e20b280794de3cdb6
F test/tclsqlite.test 5337e8890b96dad1ee541b15fbeec32e6bac2fe7fa096f91089057385aadba9b
F test/tempdb.test 4cdaa23ddd8acb4d79cbb1b68ccdfd09b0537aaba909ca69a876157c2a2cbd08
F test/tempdb2.test 27e41ed540b2f9b056c2e77e9bddc1b875358507
F test/tempfault.test 0c0d349c9a99bf5f374655742577f8712c647900
F test/temptable.test d2c9b87a54147161bcd1822e30c1d1cd891e5b30
F test/temptable2.test cd396beb41117a5302fff61767c35fa4270a0d5e
F test/temptable3.test d11a0974e52b347e45ee54ef1923c91ed91e4637
F test/temptrigger.test 38f0ca479b1822d3117069e014daabcaacefffcc
F test/tester.tcl 3ed81b9e1d9718a8d9603596c8a877793d054294053c4277a3d3897eabab3866
F test/thread001.test 9f22fd3525a307ff42a326b6bc7b0465be1745a5
F test/tester.tcl 94901a4625d9a2229666dd5c44120ddf7f0fb639470710ef74a4cefc7b039e07
F test/thread001.test b61a29dd87cf669f5f6ac96124a7c97d71b0c80d9012746072055877055cf9ef
F test/thread002.test e630504f8a06c00bf8bbe68528774dd96aeb2e58
F test/thread003.test ee4c9efc3b86a6a2767516a37bd64251272560a7
F test/thread004.test f51dfc3936184aaf73ee85f315224baad272a87f
@@ -1414,7 +1426,7 @@ F test/tkt3357.test 77c37c6482b526fe89941ce951c22d011f5922ed
F test/tkt3419.test 1bbf36d7ea03b638c15804251287c2391f5c1f6b
F test/tkt3424.test 61f831bd2b071bd128fa5d00fbda57e656ca5812
F test/tkt3442.test 53840ec5325bb94544792aad4c20476f81dc26b1
F test/tkt3457.test 44e980fe5334753dcc27b94fa4deabc485a92f74
F test/tkt3457.test 5651e2cbb94645b677ec663160b9e192b87b7d365aecdfb24e19f749575a6fc2
F test/tkt3461.test 228ea328a5a21e8663f80ee3d212a6ad92549a19
F test/tkt3493.test 1686cbde85f8721fc1bdc0ee72f2ef2f63139218
F test/tkt3508.test d75704db9501625c7f7deec119fcaf1696aefb7d
@@ -1452,7 +1464,7 @@ F test/tokenize.test ce430a7aed48fc98301611429595883fdfcab5d7
F test/tpch01.test 04adbf8d8300fa60a222f28d901abd76e7be6dd4
F test/trace.test a659a9862957f4789e37a92b3bf6d2caf5c86b02cdeefc41e850ae53acf6992a
F test/trace2.test f5cb67ad3bc09e0c58e8cca78dfd0b5639259983
F test/trace3.test 56ab944fddacf628b118cc298503fc45c2e50ab0
F test/trace3.test 1dff966888773ff1bfea01c080caf15417892b3f998408fe920c4791f7337144
F test/trans.test 6e1b4c6a42dba31bd65f8fa5e61a2708e08ddde6
F test/trans2.test 62bd045bfc7a1c14c5ba83ba64d21ade31583f76
F test/trans3.test 91a100e5412b488e22a655fe423a14c26403ab94
@@ -1488,7 +1500,7 @@ F test/unique2.test 3674e9f2a3f1fbbfd4772ac74b7a97090d0f77d2
F test/unixexcl.test d936ba2b06794018e136418addd59a2354eeae97
F test/unordered.test ca7adce0419e4ca0c50f039885e76ed2c531eda8
F test/update.test 6c68446b8a0a33d522a7c72b320934596a2d7d32
F test/update2.test fffc92e72ae568fe048588762e650cd8ccbd8c8b6e4fe9099231766bfe4b51de
F test/update2.test 5e67667e1c54017d964e626db765cf8bedcf87483c184f4c575bdb8c1dd2313e
F test/uri.test 3481026f00ade6dfe8adb7acb6e1e47b04369568
F test/uri2.test 9d3ba7a53ee167572d53a298ee4a5d38ec4a8fb7
F test/userauth01.test e740a2697a7b40d7c5003a7d7edaee16acd349a9
@@ -1497,7 +1509,7 @@ F test/vacuum.test ce91c39f7f91a4273bf620efad21086b5aa6ef1d
F test/vacuum2.test aa048abee196c16c9ba308465494009057b79f9b
F test/vacuum3.test 77ecdd54592b45a0bcb133339f99f1ae0ae94d0d
F test/vacuum4.test 7ea76b769fffeb41f925303b04cbcf5a5bbeabe55e4c60ae754ff24eeeb7c010
F test/vacuum5.test c87234e8ca4107f349da4edbeda3e4ea5adc93f3
F test/vacuum5.test 263b144d537e92ad8e9ca8a73cc6e1583f41cfd0dda9432b87f7806174a2f48c
F test/vacuummem.test 7b42abb3208bd82dd23a7536588396f295a314f2
F test/varint.test bbce22cda8fc4d135bcc2b589574be8410614e62
F test/veryquick.test 57ab846bacf7b90cf4e9a672721ea5c5b669b661
@@ -1524,7 +1536,7 @@ F test/vtab_alter.test 736e66fb5ec7b4fee58229aa3ada2f27ec58bc58c00edae4836890c37
F test/vtab_err.test 0d4d8eb4def1d053ac7c5050df3024fd47a3fbd8
F test/vtab_shared.test 5253bff2355a9a3f014c15337da7e177ab0ef8ad
F test/wal.test 613efec03e517e1775d86b993a54877d2e29a477
F test/wal2.test 2d81ffe2a02d9e5c7447b266f7153716cfcba7aecda5ed832db4544617399e29
F test/wal2.test 155b9efa999bdb38ce1cd729b9a4fcdbffd6b88be27f039bad1d2929d287d918
F test/wal3.test 2a93004bc0fb2b5c29888964024695bade278ab2
F test/wal4.test 4744e155cd6299c6bd99d3eab1c82f77db9cdb3c
F test/wal5.test 9c11da7aeccd83a46d79a556ad11a18d3cb15aa9
@@ -1542,19 +1554,19 @@ F test/walcrash.test 21038858cc552077b0522f50b0fa87e38139306a
F test/walcrash2.test a0edab4e5390f03b99a790de89aad15d6ec70b36
F test/walcrash3.test e426aa58122d20f2b9fbe9a507f9eb8cab85b8af
F test/walcrash4.test e7b6e7639a950a0cca8e210e248c8dad4d63bf20
F test/walfault.test 1f8389f7709877e9b4cc679033d71d6fe529056b
F test/walfault.test 09b8ad7e52d2f54bce50e31aa7ea51412bb9f70ac13c74e669ddcd8b48b0d98d
F test/walhook.test ed00a40ba7255da22d6b66433ab61fab16a63483
F test/walmode.test 4022fe03ae6e830583672caa101f046438a0473c
F test/walmode.test cd6e7cff618eaaa5910ce57c3657aa50110397f86213886a2400afb9bfec7b7b
F test/walnoshm.test 84ca10c544632a756467336b7c3b864d493ee496
F test/waloverwrite.test dad2f26567f1b45174e54fbf9a8dc1cb876a7f03
F test/walpersist.test 8c6b7e3ec1ba91b5e4dc4e0921d6d3f87cd356a6
F test/walprotocol.test a112aba0b79e3adeaa485fed09484b32c654e97df58e454aa8489ac2cd57bf84
F test/walro.test cb438d05ba0d191f10b688e39c4f0cd5b71569a1d1f4440e5bdf3c6880e08c20
F test/walro2.test 5cd57d192ee334c3894330303b5f8cb6789fef49b2c83ad1b50b9b132d0f7ae1
F test/walro2.test 0e79dd15cbdb4f482c01ea248373669c732414a726b357d04846a816afafb768
F test/walrofault.test c70cb6e308c443867701856cce92ad8288cd99488fa52afab77cca6cfd51af68
F test/walshared.test 0befc811dcf0b287efae21612304d15576e35417
F test/walslow.test c05c68d4dc2700a982f89133ce103a1a84cc285f
F test/walthread.test de8dbaf6d9e41481c460ba31ca61e163d7348f8e
F test/walthread.test 14b20fcfa6ae152f5d8e12f5dc8a8a724b7ef189f5d8ef1e2ceab79f2af51747
F test/where.test f0c325563acde44f2c4ea6ba348e9e29f7121757
F test/where2.test 478d2170637b9211f593120648858593bf2445a1
F test/where3.test 54cdeb02157acc979de41530b804ae7b09552bf1
@@ -1569,7 +1581,7 @@ F test/whereB.test 0def95db3bdec220a731c7e4bec5930327c1d8c5
F test/whereC.test cae295158703cb3fc23bf1a108a9ab730efff0f6
F test/whereD.test 711d4df58d6d4fb9b3f5ce040b818564198be002
F test/whereE.test b3a055eef928c992b0a33198a7b8dc10eea5ad2f
F test/whereF.test d44b58338fe5ddd7286023e9bedb255aa264a6c4d2168b49591b167371c675c7
F test/whereF.test 3d9412b1199d3e2bed34fcb76b4c48d0bf4df95d27e3f8dd27b6f8b4716d0d89
F test/whereG.test dde4c52a97385a55be6a7cd46be8373f0cf35501
F test/whereH.test e4b07f7a3c2f5d31195cd33710054c78667573b2
F test/whereI.test eab5b226bbc344ac70d7dc09b963a064860ae6d7
@@ -1587,6 +1599,7 @@ F test/win32nolock.test ac4f08811a562e45a5755e661f45ca85892bdbbc
F test/with1.test ca08e291249a810a2ec9b72ceef5575e07d5925b360fcf6652ae6fe06ac4dced
F test/with2.test e0030e2f0267a910d6c0e4f46f2dfe941c1cc0d4f659ba69b3597728e7e8f1ab
F test/with3.test e71604a0e53cba82bc04c703987cb1d6751ec0b6
F test/with4.test 257be66c0c67fee1defbbac0f685c3465e2cad037f21ce65f23f86084f198205
F test/withM.test 693b61765f2b387b5e3e24a4536e2e82de15ff64
F test/without_rowid1.test 06b7215130882d6a072233820dd364c874c4fd69221e8fc756ec471009192874
F test/without_rowid2.test af260339f79d13cb220288b67cd287fbcf81ad99
@@ -1597,12 +1610,14 @@ F test/without_rowid6.test 1f99644e6508447fb050f73697350c7ceca3392e
F test/wordcount.c cb589cec469a1d90add05b1f8cee75c7210338d87a5afd65260ed5c0f4bbf8ac
F test/writecrash.test f1da7f7adfe8d7f09ea79b42e5ca6dcc41102f27f8e334ad71539501ddd910cc
F test/zeroblob.test 3857870fe681b8185654414a9bccfde80b62a0fa
F test/zerodamage.test e59a56443d6298ecf7435f618f0b27654f0c849e
F test/zipfile.test e7132ca60031ca5d1df684cf644952bb3f253de3671a5b502780c5de3126a453
F test/zerodamage.test 9c41628db7e8d9e8a0181e59ea5f189df311a9f6ce99cc376dc461f66db6f8dc
F test/zipfile.test 2a923f6ead6a0f9b61d936881f3ee2aeaabe15fc65c196456f58ea9b4b450f9b
F test/zipfile2.test fc2f08d5ec19c18c83289fbed32e378dc5116519972166e57a244da7bf2e5805
F test/zipfilefault.test 44d4d7a7f7cca7521d569d7f71026b241d65a6b1757aa409c1a168827edbbc2c
F tool/GetFile.cs a15e08acb5dd7539b75ba23501581d7c2b462cb5
F tool/GetTclKit.bat 8995df40c4209808b31f24de0b58f90930239a234f7591e3675d45bfbb990c5d
F tool/Replace.cs 02c67258801c2fb5f63231e0ac0f220b4b36ba91
F tool/addopcodes.tcl 7181c041d495e3f26acc36d15c86923ed722285f9015f017f41a3efdb9a0dab4
F tool/addopcodes.tcl 0288d5b26b9b35f4cb5affb76eec63f1dfce117bbc2020066708069ef60b86ff
F tool/build-all-msvc.bat c12328d06c45fec8baada5949e3d5af54bf8c887 x
F tool/build-shell.sh 950f47c6174f1eea171319438b93ba67ff5bf367
F tool/cg_anno.tcl f95b0006c52cf7f0496b506343415b6ee3cdcdd3 x
@@ -1617,7 +1632,7 @@ F tool/genfkey.test 4196a8928b78f51d54ef58e99e99401ab2f0a7e5
F tool/getlock.c f4c39b651370156cae979501a7b156bdba50e7ce
F tool/kvtest-speed.sh 4761a9c4b3530907562314d7757995787f7aef8f
F tool/lemon.c 7f7735326ca9c3b48327b241063cee52d35d44e20ebe1b3624a81658052a4d39
F tool/lempar.c dddd4f592b8bad36aec4500d456c5db5fe42fefc4ee384913880439d8917f87a
F tool/lempar.c 468a155e8729cfbccfe1d85bf60d064f1dab76167a51149ec5c7928a2de63953
F tool/libvers.c caafc3b689638a1d88d44bc5f526c2278760d9b9
F tool/loadfts.c c3c64e4d5e90e8ba41159232c2189dba4be7b862
F tool/logest.c 11346aa019e2e77a00902aa7d0cabd27bd2e8cca
@@ -1629,13 +1644,13 @@ F tool/mkkeywordhash.c 2e852ac0dfdc5af18886dc1ce7e9676d11714ae3df0a282dc7d90b3a0
F tool/mkmsvcmin.tcl 8baf26690b80d861d0ac341b29880eec6ade39e4f11fe690271ded9cb90563a3
F tool/mkopcodec.tcl d1b6362bd3aa80d5520d4d6f3765badf01f6c43c
F tool/mkopcodeh.tcl 4ee2a30ccbd900dc4d5cdb61bdab87cd2166cd2affcc78c9cc0b8d22a65b2eee
F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e
F tool/mkopts.tcl 680f785fdb09729fd9ac50632413da4eadbdf9071535e3f26d03795828ab07fa
F tool/mkpragmatab.tcl 2144bc8550a6471a029db262a132d2df4b9e0db61b90398bf64f5b7b3f8d92cd
F tool/mkshellc.tcl 1f45770aea226ac093a9c72f718efbb88a2a2833409ec2e1c4cecae4202626f5
F tool/mksourceid.c d458f9004c837bee87a6382228ac20d3eae3c49ea3b0a5aace936f8b60748d3b
F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97
F tool/mksqlite3c-noext.tcl fef88397668ae83166735c41af99d79f56afaabb
F tool/mksqlite3c.tcl 1fb69d39166f52d802a70ec37d99bca51d011c8ab30be27bc495be493196ae41
F tool/mksqlite3c.tcl a03cee30de81a2e67b93e5c659f24113a003677c557daeb008205c8e6d4345d6
F tool/mksqlite3h.tcl f92f994d9709aeb9e2b6e6f9fc8b069d2f55202c8e23f453edc44390a25982dc
F tool/mksqlite3internalh.tcl eb994013e833359137eb53a55acdad0b5ae1049b
F tool/mkvsix.tcl b9e0777a213c23156b6542842c238479e496ebf5
@@ -1655,7 +1670,7 @@ F tool/showstat4.c 0682ebea7abf4d3657f53c4a243f2e7eab48eab344ed36a94bb75dcd19a5c
F tool/showwal.c ad9d768f96ca6199ad3a8c9562d679680bd032dd01204ea3e5ea6fb931d81847
F tool/soak1.tcl 8d407956e1a45b485a8e072470a3e629a27037fe
F tool/spaceanal.tcl 4bfd19aad7eb3ce0372ef0255f58035e0bba4ff5e9acfd763a10c6fb365c8dec
F tool/speed-check.sh 9ae425da8819e54e780cf494fc6d8175dfb16e109ae3214a45a5c9bb2b74e2c4
F tool/speed-check.sh 4ff9b095cf1a7643f0264e7fb7d23f0b12b7cce587a9de315877c378e90eeaf4
F tool/speedtest.tcl 06c76698485ccf597b9e7dbb1ac70706eb873355
F tool/speedtest16.c ecb6542862151c3e6509bbc00509b234562ae81e
F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
@@ -1697,10 +1712,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 4f68bed3b9a63a349a2a2d7f26609491577e9717034ad86af404cf9eed9d6aaf
R ca3c0ce043db4afb0303f36904592ef8
T *branch * sqlite3_vtab_nochange
T *sym-sqlite3_vtab_nochange *
T -sym-trunk *
U drh
Z 5a280540fff60985c8c72fc104fac16d
P 7834cf6c28c63f6ca0e29a508c0f6e3ec9c5c48715344c2db99a9866e92ef205
R 0676d2c36dd5dc602d3c6343c630c1e9
U dan
Z 67bd751f2f713e6278cdb7ebdf4ff3a3
+1 -1
View File
@@ -1 +1 @@
d444b1ff39f0a1673a977b8047e1e14a49d461c9934be080d27c2392a830c1c0
9a5ef341de2bd2fc4657a510f48159f7876f58d340b457b4272a71d389f88da3
+25
View File
@@ -234,6 +234,10 @@ static void openStatTable(
"DELETE FROM %Q.%s WHERE %s=%Q",
pDb->zDbSName, zTab, zWhereType, zWhere
);
#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
}else if( db->xPreUpdateCallback ){
sqlite3NestedParse(pParse, "DELETE FROM %Q.%s", pDb->zDbSName, zTab);
#endif
}else{
/* The sqlite_stat[134] table already exists. Delete all rows. */
sqlite3VdbeAddOp2(v, OP_Clear, aRoot[i], iDb);
@@ -998,6 +1002,9 @@ static void analyzeOneTable(
int regIdxname = iMem++; /* Register containing index name */
int regStat1 = iMem++; /* Value for the stat column of sqlite_stat1 */
int regPrev = iMem; /* MUST BE LAST (see below) */
#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
Table *pStat1 = 0;
#endif
pParse->nMem = MAX(pParse->nMem, iMem);
v = sqlite3GetVdbe(pParse);
@@ -1023,6 +1030,18 @@ static void analyzeOneTable(
}
#endif
#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
if( db->xPreUpdateCallback ){
pStat1 = (Table*)sqlite3DbMallocZero(db, sizeof(Table) + 13);
if( pStat1==0 ) return;
pStat1->zName = (char*)&pStat1[1];
memcpy(pStat1->zName, "sqlite_stat1", 13);
pStat1->nCol = 3;
pStat1->iPKey = -1;
sqlite3VdbeAddOp4(pParse->pVdbe, OP_Noop, 0, 0, 0,(char*)pStat1,P4_DYNBLOB);
}
#endif
/* Establish a read-lock on the table at the shared-cache level.
** Open a read-only cursor on the table. Also allocate a cursor number
** to use for scanning indexes (iIdxCur). No index cursor is opened at
@@ -1224,6 +1243,9 @@ static void analyzeOneTable(
sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 3, regTemp, "BBB", 0);
sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur, regNewRowid);
sqlite3VdbeAddOp3(v, OP_Insert, iStatCur, regTemp, regNewRowid);
#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
sqlite3VdbeChangeP4(v, -1, (char*)pStat1, P4_TABLE);
#endif
sqlite3VdbeChangeP5(v, OPFLAG_APPEND);
/* Add the entries to the stat3 or stat4 table. */
@@ -1287,6 +1309,9 @@ static void analyzeOneTable(
sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur, regNewRowid);
sqlite3VdbeAddOp3(v, OP_Insert, iStatCur, regTemp, regNewRowid);
sqlite3VdbeChangeP5(v, OPFLAG_APPEND);
#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
sqlite3VdbeChangeP4(v, -1, (char*)pStat1, P4_TABLE);
#endif
sqlite3VdbeJumpHere(v, jZeroRows);
}
}
+105 -69
View File
@@ -55,6 +55,10 @@ static int resolveAttachExpr(NameContext *pName, Expr *pExpr)
**
** If the optional "KEY z" syntax is omitted, an SQL NULL is passed as the
** third argument.
**
** If the db->init.reopenMemdb flags is set, then instead of attaching a
** new database, close the database on db->init.iDb and reopen it as an
** empty MemDB.
*/
static void attachFunc(
sqlite3_context *context,
@@ -75,65 +79,85 @@ static void attachFunc(
sqlite3_vfs *pVfs;
UNUSED_PARAMETER(NotUsed);
zFile = (const char *)sqlite3_value_text(argv[0]);
zName = (const char *)sqlite3_value_text(argv[1]);
if( zFile==0 ) zFile = "";
if( zName==0 ) zName = "";
/* Check for the following errors:
**
** * Too many attached databases,
** * Transaction currently open
** * Specified database name already being used.
*/
if( db->nDb>=db->aLimit[SQLITE_LIMIT_ATTACHED]+2 ){
zErrDyn = sqlite3MPrintf(db, "too many attached databases - max %d",
db->aLimit[SQLITE_LIMIT_ATTACHED]
);
goto attach_error;
}
for(i=0; i<db->nDb; i++){
char *z = db->aDb[i].zDbSName;
assert( z && zName );
if( sqlite3StrICmp(z, zName)==0 ){
zErrDyn = sqlite3MPrintf(db, "database %s is already in use", zName);
#ifdef SQLITE_ENABLE_DESERIALIZE
# define REOPEN_AS_MEMDB(db) (db->init.reopenMemdb)
#else
# define REOPEN_AS_MEMDB(db) (0)
#endif
if( REOPEN_AS_MEMDB(db) ){
/* This is not a real ATTACH. Instead, this routine is being called
** from sqlite3_deserialize() to close database db->init.iDb and
** reopen it as a MemDB */
pVfs = sqlite3_vfs_find("memdb");
if( pVfs==0 ) return;
pNew = &db->aDb[db->init.iDb];
if( pNew->pBt ) sqlite3BtreeClose(pNew->pBt);
pNew->pBt = 0;
pNew->pSchema = 0;
rc = sqlite3BtreeOpen(pVfs, "x", db, &pNew->pBt, 0, SQLITE_OPEN_MAIN_DB);
}else{
/* This is a real ATTACH
**
** Check for the following errors:
**
** * Too many attached databases,
** * Transaction currently open
** * Specified database name already being used.
*/
if( db->nDb>=db->aLimit[SQLITE_LIMIT_ATTACHED]+2 ){
zErrDyn = sqlite3MPrintf(db, "too many attached databases - max %d",
db->aLimit[SQLITE_LIMIT_ATTACHED]
);
goto attach_error;
}
for(i=0; i<db->nDb; i++){
char *z = db->aDb[i].zDbSName;
assert( z && zName );
if( sqlite3StrICmp(z, zName)==0 ){
zErrDyn = sqlite3MPrintf(db, "database %s is already in use", zName);
goto attach_error;
}
}
/* Allocate the new entry in the db->aDb[] array and initialize the schema
** hash tables.
*/
if( db->aDb==db->aDbStatic ){
aNew = sqlite3DbMallocRawNN(db, sizeof(db->aDb[0])*3 );
if( aNew==0 ) return;
memcpy(aNew, db->aDb, sizeof(db->aDb[0])*2);
}else{
aNew = sqlite3DbRealloc(db, db->aDb, sizeof(db->aDb[0])*(db->nDb+1) );
if( aNew==0 ) return;
}
db->aDb = aNew;
pNew = &db->aDb[db->nDb];
memset(pNew, 0, sizeof(*pNew));
/* Open the database file. If the btree is successfully opened, use
** it to obtain the database schema. At this point the schema may
** or may not be initialized.
*/
flags = db->openFlags;
rc = sqlite3ParseUri(db->pVfs->zName, zFile, &flags, &pVfs, &zPath, &zErr);
if( rc!=SQLITE_OK ){
if( rc==SQLITE_NOMEM ) sqlite3OomFault(db);
sqlite3_result_error(context, zErr, -1);
sqlite3_free(zErr);
return;
}
assert( pVfs );
flags |= SQLITE_OPEN_MAIN_DB;
rc = sqlite3BtreeOpen(pVfs, zPath, db, &pNew->pBt, 0, flags);
sqlite3_free( zPath );
db->nDb++;
}
/* Allocate the new entry in the db->aDb[] array and initialize the schema
** hash tables.
*/
if( db->aDb==db->aDbStatic ){
aNew = sqlite3DbMallocRawNN(db, sizeof(db->aDb[0])*3 );
if( aNew==0 ) return;
memcpy(aNew, db->aDb, sizeof(db->aDb[0])*2);
}else{
aNew = sqlite3DbRealloc(db, db->aDb, sizeof(db->aDb[0])*(db->nDb+1) );
if( aNew==0 ) return;
}
db->aDb = aNew;
pNew = &db->aDb[db->nDb];
memset(pNew, 0, sizeof(*pNew));
/* Open the database file. If the btree is successfully opened, use
** it to obtain the database schema. At this point the schema may
** or may not be initialized.
*/
flags = db->openFlags;
rc = sqlite3ParseUri(db->pVfs->zName, zFile, &flags, &pVfs, &zPath, &zErr);
if( rc!=SQLITE_OK ){
if( rc==SQLITE_NOMEM ) sqlite3OomFault(db);
sqlite3_result_error(context, zErr, -1);
sqlite3_free(zErr);
return;
}
assert( pVfs );
flags |= SQLITE_OPEN_MAIN_DB;
rc = sqlite3BtreeOpen(pVfs, zPath, db, &pNew->pBt, 0, flags);
sqlite3_free( zPath );
db->nDb++;
db->skipBtreeMutex = 0;
if( rc==SQLITE_CONSTRAINT ){
rc = SQLITE_ERROR;
@@ -160,7 +184,7 @@ static void attachFunc(
sqlite3BtreeLeave(pNew->pBt);
}
pNew->safety_level = SQLITE_DEFAULT_SYNCHRONOUS+1;
pNew->zDbSName = sqlite3DbStrDup(db, zName);
if( !REOPEN_AS_MEMDB(db) ) pNew->zDbSName = sqlite3DbStrDup(db, zName);
if( rc==SQLITE_OK && pNew->zDbSName==0 ){
rc = SQLITE_NOMEM_BKPT;
}
@@ -200,13 +224,15 @@ static void attachFunc(
/* If the file was opened successfully, read the schema for the new database.
** If this fails, or if opening the file failed, then close the file and
** remove the entry from the db->aDb[] array. i.e. put everything back the way
** we found it.
** remove the entry from the db->aDb[] array. i.e. put everything back the
** way we found it.
*/
if( rc==SQLITE_OK ){
sqlite3BtreeEnterAll(db);
db->init.iDb = 0;
rc = sqlite3Init(db, &zErrDyn);
sqlite3BtreeLeaveAll(db);
assert( zErrDyn==0 || rc!=SQLITE_OK );
}
#ifdef SQLITE_USER_AUTHENTICATION
if( rc==SQLITE_OK ){
@@ -218,21 +244,23 @@ static void attachFunc(
}
#endif
if( rc ){
int iDb = db->nDb - 1;
assert( iDb>=2 );
if( db->aDb[iDb].pBt ){
sqlite3BtreeClose(db->aDb[iDb].pBt);
db->aDb[iDb].pBt = 0;
db->aDb[iDb].pSchema = 0;
}
sqlite3ResetAllSchemasOfConnection(db);
db->nDb = iDb;
if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ){
sqlite3OomFault(db);
sqlite3DbFree(db, zErrDyn);
zErrDyn = sqlite3MPrintf(db, "out of memory");
}else if( zErrDyn==0 ){
zErrDyn = sqlite3MPrintf(db, "unable to open database: %s", zFile);
if( !REOPEN_AS_MEMDB(db) ){
int iDb = db->nDb - 1;
assert( iDb>=2 );
if( db->aDb[iDb].pBt ){
sqlite3BtreeClose(db->aDb[iDb].pBt);
db->aDb[iDb].pBt = 0;
db->aDb[iDb].pSchema = 0;
}
sqlite3ResetAllSchemasOfConnection(db);
db->nDb = iDb;
if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ){
sqlite3OomFault(db);
sqlite3DbFree(db, zErrDyn);
zErrDyn = sqlite3MPrintf(db, "out of memory");
}else if( zErrDyn==0 ){
zErrDyn = sqlite3MPrintf(db, "unable to open database: %s", zFile);
}
}
goto attach_error;
}
@@ -504,6 +532,14 @@ int sqlite3FixSelect(
if( sqlite3FixExpr(pFix, pSelect->pLimit) ){
return 1;
}
if( pSelect->pWith ){
int i;
for(i=0; i<pSelect->pWith->nCte; i++){
if( sqlite3FixSelect(pFix, pSelect->pWith->a[i].pSelect) ){
return 1;
}
}
}
pSelect = pSelect->pPrior;
}
return 0;
+20 -9
View File
@@ -123,9 +123,12 @@ int sqlite3_enable_shared_cache(int enable){
*/
#ifdef SQLITE_DEBUG
int corruptPageError(int lineno, MemPage *p){
char *zMsg = sqlite3_mprintf("database corruption page %d of %s",
char *zMsg;
sqlite3BeginBenignMalloc();
zMsg = sqlite3_mprintf("database corruption page %d of %s",
(int)p->pgno, sqlite3PagerFilename(p->pBt->pPager, 0)
);
sqlite3EndBenignMalloc();
if( zMsg ){
sqlite3ReportError(SQLITE_CORRUPT, lineno, zMsg);
}
@@ -4342,7 +4345,7 @@ int sqlite3BtreeCursorSize(void){
** of run-time by skipping the initialization of those elements.
*/
void sqlite3BtreeCursorZero(BtCursor *p){
memset(p, 0, offsetof(BtCursor, iPage));
memset(p, 0, offsetof(BtCursor, BTCURSOR_FIRST_UNINIT));
}
/*
@@ -4385,11 +4388,19 @@ int sqlite3BtreeCloseCursor(BtCursor *pCur){
** Using this cache reduces the number of calls to btreeParseCell().
*/
#ifndef NDEBUG
static int cellInfoEqual(CellInfo *a, CellInfo *b){
if( a->nKey!=b->nKey ) return 0;
if( a->pPayload!=b->pPayload ) return 0;
if( a->nPayload!=b->nPayload ) return 0;
if( a->nLocal!=b->nLocal ) return 0;
if( a->nSize!=b->nSize ) return 0;
return 1;
}
static void assertCellInfo(BtCursor *pCur){
CellInfo info;
memset(&info, 0, sizeof(info));
btreeParseCell(pCur->pPage, pCur->ix, &info);
assert( CORRUPT_DB || memcmp(&info, &pCur->info, sizeof(info))==0 );
assert( CORRUPT_DB || cellInfoEqual(&info, &pCur->info) );
}
#else
#define assertCellInfo(x)
@@ -4665,14 +4676,15 @@ static int accessPayload(
*/
if( (pCur->curFlags & BTCF_ValidOvfl)==0 ){
int nOvfl = (pCur->info.nPayload-pCur->info.nLocal+ovflSize-1)/ovflSize;
if( nOvfl>pCur->nOvflAlloc ){
if( pCur->aOverflow==0
|| nOvfl*(int)sizeof(Pgno) > sqlite3MallocSize(pCur->aOverflow)
){
Pgno *aNew = (Pgno*)sqlite3Realloc(
pCur->aOverflow, nOvfl*2*sizeof(Pgno)
);
if( aNew==0 ){
return SQLITE_NOMEM_BKPT;
}else{
pCur->nOvflAlloc = nOvfl*2;
pCur->aOverflow = aNew;
}
}
@@ -6186,9 +6198,8 @@ static void freePage(MemPage *pPage, int *pRC){
}
/*
** Free any overflow pages associated with the given Cell. Write the
** local Cell size (the number of bytes on the original page, omitting
** overflow) into *pnSize.
** Free any overflow pages associated with the given Cell. Store
** size information about the cell in pInfo.
*/
static int clearCell(
MemPage *pPage, /* The page that contains the Cell */
@@ -7392,7 +7403,7 @@ static int balance_nonroot(
}
/* Load b.apCell[] with pointers to all cells in pOld. If pOld
** constains overflow cells, include them in the b.apCell[] array
** contains overflow cells, include them in the b.apCell[] array
** in the correct spot.
**
** Note that when there are multiple overflow cells, it is always the
+11 -11
View File
@@ -503,20 +503,20 @@ struct BtCursor {
u8 curFlags; /* zero or more BTCF_* flags defined below */
u8 curPagerFlags; /* Flags to send to sqlite3PagerGet() */
u8 hints; /* As configured by CursorSetHints() */
int nOvflAlloc; /* Allocated size of aOverflow[] array */
Btree *pBtree; /* The Btree to which this cursor belongs */
BtShared *pBt; /* The BtShared this cursor points to */
BtCursor *pNext; /* Forms a linked list of all cursors */
Pgno *aOverflow; /* Cache of overflow page locations */
CellInfo info; /* A parse of the cell we are pointing at */
i64 nKey; /* Size of pKey, or last integer key */
void *pKey; /* Saved key that was cursor last known position */
Pgno pgnoRoot; /* The root page of this tree */
int skipNext; /* Prev() is noop if negative. Next() is noop if positive.
** Error code if eState==CURSOR_FAULT */
Btree *pBtree; /* The Btree to which this cursor belongs */
Pgno *aOverflow; /* Cache of overflow page locations */
void *pKey; /* Saved key that was cursor last known position */
/* All fields above are zeroed when the cursor is allocated. See
** sqlite3BtreeCursorZero(). Fields that follow must be manually
** initialized. */
#define BTCURSOR_FIRST_UNINIT pBt /* Name of first uninitialized field */
BtShared *pBt; /* The BtShared this cursor points to */
BtCursor *pNext; /* Forms a linked list of all cursors */
CellInfo info; /* A parse of the cell we are pointing at */
i64 nKey; /* Size of pKey, or last integer key */
Pgno pgnoRoot; /* The root page of this tree */
i8 iPage; /* Index of current page in apPage */
u8 curIntKey; /* Value of apPage[0]->intKey */
u16 ix; /* Current index for apPage[iPage] */
@@ -566,8 +566,8 @@ struct BtCursor {
** Do nothing else with this cursor. Any attempt to use the cursor
** should return the error code stored in BtCursor.skipNext
*/
#define CURSOR_INVALID 0
#define CURSOR_VALID 1
#define CURSOR_VALID 0
#define CURSOR_INVALID 1
#define CURSOR_SKIPNEXT 2
#define CURSOR_REQUIRESEEK 3
#define CURSOR_FAULT 4
+22 -4
View File
@@ -1118,10 +1118,24 @@ void sqlite3AddColumn(Parse *pParse, Token *pName, Token *pType){
*/
void sqlite3AddNotNull(Parse *pParse, int onError){
Table *p;
Column *pCol;
p = pParse->pNewTable;
if( p==0 || NEVER(p->nCol<1) ) return;
p->aCol[p->nCol-1].notNull = (u8)onError;
pCol = &p->aCol[p->nCol-1];
pCol->notNull = (u8)onError;
p->tabFlags |= TF_HasNotNull;
/* Set the uniqNotNull flag on any UNIQUE or PK indexes already created
** on this column. */
if( pCol->colFlags & COLFLAG_UNIQUE ){
Index *pIdx;
for(pIdx=p->pIndex; pIdx; pIdx=pIdx->pNext){
assert( pIdx->nKeyCol==1 && pIdx->onError!=OE_None );
if( pIdx->aiColumn[0]==p->nCol-1 ){
pIdx->uniqNotNull = 1;
}
}
}
}
/*
@@ -1856,8 +1870,6 @@ void sqlite3EndTable(
p = pParse->pNewTable;
if( p==0 ) return;
assert( !db->init.busy || !pSelect );
/* If the db->init.busy is 1 it means we are reading the SQL off the
** "sqlite_master" or "sqlite_temp_master" table on the disk.
** So do not write to the disk again. Extract the root page number
@@ -1868,6 +1880,10 @@ void sqlite3EndTable(
** table itself. So mark it read-only.
*/
if( db->init.busy ){
if( pSelect ){
sqlite3ErrorMsg(pParse, "");
return;
}
p->tnum = db->init.newTnum;
if( p->tnum==1 ) p->tabFlags |= TF_Readonly;
}
@@ -3085,7 +3101,9 @@ void sqlite3CreateIndex(
*/
if( pList==0 ){
Token prevCol;
sqlite3TokenInit(&prevCol, pTab->aCol[pTab->nCol-1].zName);
Column *pCol = &pTab->aCol[pTab->nCol-1];
pCol->colFlags |= COLFLAG_UNIQUE;
sqlite3TokenInit(&prevCol, pCol->zName);
pList = sqlite3ExprListAppend(pParse, 0,
sqlite3ExprAlloc(db, TK_ID, &prevCol, 0));
if( pList==0 ) goto exit_create_index;
+1 -1
View File
@@ -760,7 +760,7 @@ void sqlite3GenerateRowDelete(
u8 p5 = 0;
sqlite3GenerateRowIndexDelete(pParse, pTab, iDataCur, iIdxCur,0,iIdxNoSeek);
sqlite3VdbeAddOp2(v, OP_Delete, iDataCur, (count?OPFLAG_NCHANGE:0));
if( pParse->nested==0 ){
if( pParse->nested==0 || 0==sqlite3_stricmp(pTab->zName, "sqlite_stat1") ){
sqlite3VdbeAppendP4(v, (char*)pTab, P4_TABLE);
}
if( eMode!=ONEPASS_OFF ){
+90 -4
View File
@@ -658,15 +658,15 @@ static void heightOfExprList(ExprList *p, int *pnHeight){
}
}
}
static void heightOfSelect(Select *p, int *pnHeight){
if( p ){
static void heightOfSelect(Select *pSelect, int *pnHeight){
Select *p;
for(p=pSelect; p; p=p->pPrior){
heightOfExpr(p->pWhere, pnHeight);
heightOfExpr(p->pHaving, pnHeight);
heightOfExpr(p->pLimit, pnHeight);
heightOfExprList(p->pEList, pnHeight);
heightOfExprList(p->pGroupBy, pnHeight);
heightOfExprList(p->pOrderBy, pnHeight);
heightOfSelect(p->pPrior, pnHeight);
}
}
@@ -1732,6 +1732,34 @@ int sqlite3SelectWalkFail(Walker *pWalker, Select *NotUsed){
return WRC_Abort;
}
/*
** If the input expression is an ID with the name "true" or "false"
** then convert it into an TK_TRUEFALSE term. Return non-zero if
** the conversion happened, and zero if the expression is unaltered.
*/
int sqlite3ExprIdToTrueFalse(Expr *pExpr){
assert( pExpr->op==TK_ID || pExpr->op==TK_STRING );
if( sqlite3StrICmp(pExpr->u.zToken, "true")==0
|| sqlite3StrICmp(pExpr->u.zToken, "false")==0
){
pExpr->op = TK_TRUEFALSE;
return 1;
}
return 0;
}
/*
** The argument must be a TK_TRUEFALSE Expr node. Return 1 if it is TRUE
** and 0 if it is FALSE.
*/
int sqlite3ExprTruthValue(const Expr *pExpr){
assert( pExpr->op==TK_TRUEFALSE );
assert( sqlite3StrICmp(pExpr->u.zToken,"true")==0
|| sqlite3StrICmp(pExpr->u.zToken,"false")==0 );
return pExpr->u.zToken[4]==0;
}
/*
** These routines are Walker callbacks used to check expressions to
** see if they are "constant" for some definition of constant. The
@@ -1779,6 +1807,12 @@ static int exprNodeIsConstant(Walker *pWalker, Expr *pExpr){
return WRC_Abort;
}
case TK_ID:
/* Convert "true" or "false" in a DEFAULT clause into the
** appropriate TK_TRUEFALSE operator */
if( sqlite3ExprIdToTrueFalse(pExpr) ){
return WRC_Prune;
}
/* Fall thru */
case TK_COLUMN:
case TK_AGG_FUNCTION:
case TK_AGG_COLUMN:
@@ -2764,7 +2798,6 @@ int sqlite3CodeSubselect(
pSel->pLimit = sqlite3PExpr(pParse, TK_LIMIT, pLimit, 0);
}
pSel->iLimit = 0;
pSel->selFlags &= ~SF_MultiValue;
if( sqlite3Select(pParse, pSel, &dest) ){
return 0;
}
@@ -3544,6 +3577,10 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){
codeInteger(pParse, pExpr, 0, target);
return target;
}
case TK_TRUEFALSE: {
sqlite3VdbeAddOp2(v, OP_Integer, sqlite3ExprTruthValue(pExpr), target);
return target;
}
#ifndef SQLITE_OMIT_FLOATING_POINT
case TK_FLOAT: {
assert( !ExprHasProperty(pExpr, EP_IntValue) );
@@ -3699,6 +3736,18 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){
sqlite3VdbeAddOp2(v, op, r1, inReg);
break;
}
case TK_TRUTH: {
int isTrue; /* IS TRUE or IS NOT TRUE */
int bNormal; /* IS TRUE or IS FALSE */
r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, &regFree1);
testcase( regFree1==0 );
isTrue = sqlite3ExprTruthValue(pExpr->pRight);
bNormal = pExpr->op2==TK_IS;
testcase( isTrue && bNormal);
testcase( !isTrue && bNormal);
sqlite3VdbeAddOp4Int(v, OP_IsTrue, r1, inReg, !isTrue, isTrue ^ bNormal);
break;
}
case TK_ISNULL:
case TK_NOTNULL: {
int addr;
@@ -4474,6 +4523,23 @@ void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){
sqlite3ExprIfFalse(pParse, pExpr->pLeft, dest, jumpIfNull);
break;
}
case TK_TRUTH: {
int isNot; /* IS NOT TRUE or IS NOT FALSE */
int isTrue; /* IS TRUE or IS NOT TRUE */
testcase( jumpIfNull==0 );
isNot = pExpr->op2==TK_ISNOT;
isTrue = sqlite3ExprTruthValue(pExpr->pRight);
testcase( isTrue && isNot );
testcase( !isTrue && isNot );
if( isTrue ^ isNot ){
sqlite3ExprIfTrue(pParse, pExpr->pLeft, dest,
isNot ? SQLITE_JUMPIFNULL : 0);
}else{
sqlite3ExprIfFalse(pParse, pExpr->pLeft, dest,
isNot ? SQLITE_JUMPIFNULL : 0);
}
break;
}
case TK_IS:
case TK_ISNOT:
testcase( op==TK_IS );
@@ -4628,6 +4694,26 @@ void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){
sqlite3ExprIfTrue(pParse, pExpr->pLeft, dest, jumpIfNull);
break;
}
case TK_TRUTH: {
int isNot; /* IS NOT TRUE or IS NOT FALSE */
int isTrue; /* IS TRUE or IS NOT TRUE */
testcase( jumpIfNull==0 );
isNot = pExpr->op2==TK_ISNOT;
isTrue = sqlite3ExprTruthValue(pExpr->pRight);
testcase( isTrue && isNot );
testcase( !isTrue && isNot );
if( isTrue ^ isNot ){
/* IS TRUE and IS NOT FALSE */
sqlite3ExprIfFalse(pParse, pExpr->pLeft, dest,
isNot ? 0 : SQLITE_JUMPIFNULL);
}else{
/* IS FALSE and IS NOT TRUE */
sqlite3ExprIfTrue(pParse, pExpr->pLeft, dest,
isNot ? 0 : SQLITE_JUMPIFNULL);
}
break;
}
case TK_IS:
case TK_ISNOT:
testcase( pExpr->op==TK_IS );
+37 -24
View File
@@ -35,6 +35,8 @@ static CollSeq *sqlite3GetFuncCollSeq(sqlite3_context *context){
** iteration of the aggregate loop.
*/
static void sqlite3SkipAccumulatorLoad(sqlite3_context *context){
assert( context->isError<=0 );
context->isError = -1;
context->skipFlag = 1;
}
@@ -101,8 +103,6 @@ static void lengthFunc(
int argc,
sqlite3_value **argv
){
int len;
assert( argc==1 );
UNUSED_PARAMETER(argc);
switch( sqlite3_value_type(argv[0]) ){
@@ -114,13 +114,17 @@ static void lengthFunc(
}
case SQLITE_TEXT: {
const unsigned char *z = sqlite3_value_text(argv[0]);
const unsigned char *z0;
unsigned char c;
if( z==0 ) return;
len = 0;
while( *z ){
len++;
SQLITE_SKIP_UTF8(z);
z0 = z;
while( (c = *z)!=0 ){
z++;
if( c>=0xc0 ){
while( (*z & 0xc0)==0x80 ){ z++; z0++; }
}
}
sqlite3_result_int(context, len);
sqlite3_result_int(context, (int)(z-z0));
break;
}
default: {
@@ -1195,6 +1199,8 @@ static void replaceFunc(
i64 nOut; /* Maximum size of zOut */
int loopLimit; /* Last zStr[] that might match zPattern[] */
int i, j; /* Loop counters */
unsigned cntExpand; /* Number zOut expansions */
sqlite3 *db = sqlite3_context_db_handle(context);
assert( argc==3 );
UNUSED_PARAMETER(argc);
@@ -1226,33 +1232,40 @@ static void replaceFunc(
return;
}
loopLimit = nStr - nPattern;
cntExpand = 0;
for(i=j=0; i<=loopLimit; i++){
if( zStr[i]!=zPattern[0] || memcmp(&zStr[i], zPattern, nPattern) ){
zOut[j++] = zStr[i];
}else{
u8 *zOld;
sqlite3 *db = sqlite3_context_db_handle(context);
nOut += nRep - nPattern;
testcase( nOut-1==db->aLimit[SQLITE_LIMIT_LENGTH] );
testcase( nOut-2==db->aLimit[SQLITE_LIMIT_LENGTH] );
if( nOut-1>db->aLimit[SQLITE_LIMIT_LENGTH] ){
sqlite3_result_error_toobig(context);
sqlite3_free(zOut);
return;
}
zOld = zOut;
zOut = sqlite3_realloc64(zOut, (int)nOut);
if( zOut==0 ){
sqlite3_result_error_nomem(context);
sqlite3_free(zOld);
return;
if( nRep>nPattern ){
nOut += nRep - nPattern;
testcase( nOut-1==db->aLimit[SQLITE_LIMIT_LENGTH] );
testcase( nOut-2==db->aLimit[SQLITE_LIMIT_LENGTH] );
if( nOut-1>db->aLimit[SQLITE_LIMIT_LENGTH] ){
sqlite3_result_error_toobig(context);
sqlite3_free(zOut);
return;
}
cntExpand++;
if( (cntExpand&(cntExpand-1))==0 ){
/* Grow the size of the output buffer only on substitutions
** whose index is a power of two: 1, 2, 4, 8, 16, 32, ... */
u8 *zOld;
zOld = zOut;
zOut = sqlite3_realloc64(zOut, (int)nOut + (nOut - nStr - 1));
if( zOut==0 ){
sqlite3_result_error_nomem(context);
sqlite3_free(zOld);
return;
}
}
}
memcpy(&zOut[j], zRep, nRep);
j += nRep;
i += nPattern-1;
}
}
assert( j+nStr-i+1==nOut );
assert( j+nStr-i+1<=nOut );
memcpy(&zOut[j], &zStr[i], nStr-i);
j += nStr - i;
assert( j<=nOut );
+7
View File
@@ -258,6 +258,13 @@ const Token sqlite3IntTokens[] = {
{ "1", 1 }
};
#ifdef VDBE_PROFILE
/*
** The following performance counter can be used in place of
** sqlite3Hwtime() for profiling. This is a no-op on standard builds.
*/
sqlite3_uint64 sqlite3NProfileCnt = 0;
#endif
/*
** The value of the "pending" byte must be 0x40000000 (1 byte past the
+5 -1
View File
@@ -430,7 +430,11 @@ static const sqlite3_api_routines sqlite3Apis = {
sqlite3_prepare16_v3,
sqlite3_bind_pointer,
sqlite3_result_pointer,
sqlite3_value_pointer
sqlite3_value_pointer,
/* Version 3.22.0 and later */
sqlite3_vtab_nochange,
sqlite3_value_nochange,
sqlite3_vtab_collation
};
/*
+16 -1
View File
@@ -239,6 +239,11 @@ int sqlite3_initialize(void){
sqlite3GlobalConfig.isPCacheInit = 1;
rc = sqlite3OsInit();
}
#ifdef SQLITE_ENABLE_DESERIALIZE
if( rc==SQLITE_OK ){
rc = sqlite3MemdbInit();
}
#endif
if( rc==SQLITE_OK ){
sqlite3PCacheBufferSetup( sqlite3GlobalConfig.pPage,
sqlite3GlobalConfig.szPage, sqlite3GlobalConfig.nPage);
@@ -271,7 +276,7 @@ int sqlite3_initialize(void){
#ifndef NDEBUG
#ifndef SQLITE_OMIT_FLOATING_POINT
/* This section of code's only "output" is via assert() statements. */
if ( rc==SQLITE_OK ){
if( rc==SQLITE_OK ){
u64 x = (((u64)1)<<63)-1;
double y;
assert(sizeof(x)==8);
@@ -1438,6 +1443,8 @@ const char *sqlite3ErrStr(int rc){
/* SQLITE_FORMAT */ 0,
/* SQLITE_RANGE */ "column index out of range",
/* SQLITE_NOTADB */ "file is not a database",
/* SQLITE_NOTICE */ "notification message",
/* SQLITE_WARNING */ "warning message",
};
const char *zErr = "unknown error";
switch( rc ){
@@ -1445,6 +1452,14 @@ const char *sqlite3ErrStr(int rc){
zErr = "abort due to ROLLBACK";
break;
}
case SQLITE_ROW: {
zErr = "another row available";
break;
}
case SQLITE_DONE: {
zErr = "no more rows available";
break;
}
default: {
rc &= 0xff;
if( ALWAYS(rc>=0) && rc<ArraySize(aMsg) && aMsg[rc]!=0 ){
+589
View File
@@ -0,0 +1,589 @@
/*
** 2016-09-07
**
** The author disclaims copyright to this source code. In place of
** a legal notice, here is a blessing:
**
** May you do good and not evil.
** May you find forgiveness for yourself and forgive others.
** May you share freely, never taking more than you give.
**
******************************************************************************
**
** This file implements in-memory VFS. A database is held as a contiguous
** block of memory.
**
** This file also implements interface sqlite3_serialize() and
** sqlite3_deserialize().
*/
#ifdef SQLITE_ENABLE_DESERIALIZE
#include "sqliteInt.h"
/*
** Forward declaration of objects used by this utility
*/
typedef struct sqlite3_vfs MemVfs;
typedef struct MemFile MemFile;
/* Access to a lower-level VFS that (might) implement dynamic loading,
** access to randomness, etc.
*/
#define ORIGVFS(p) ((sqlite3_vfs*)((p)->pAppData))
/* An open file */
struct MemFile {
sqlite3_file base; /* IO methods */
sqlite3_int64 sz; /* Size of the file */
sqlite3_int64 szMax; /* Space allocated to aData */
unsigned char *aData; /* content of the file */
int nMmap; /* Number of memory mapped pages */
unsigned mFlags; /* Flags */
int eLock; /* Most recent lock against this file */
};
/*
** Methods for MemFile
*/
static int memdbClose(sqlite3_file*);
static int memdbRead(sqlite3_file*, void*, int iAmt, sqlite3_int64 iOfst);
static int memdbWrite(sqlite3_file*,const void*,int iAmt, sqlite3_int64 iOfst);
static int memdbTruncate(sqlite3_file*, sqlite3_int64 size);
static int memdbSync(sqlite3_file*, int flags);
static int memdbFileSize(sqlite3_file*, sqlite3_int64 *pSize);
static int memdbLock(sqlite3_file*, int);
/* static int memdbCheckReservedLock(sqlite3_file*, int *pResOut);// not used */
static int memdbFileControl(sqlite3_file*, int op, void *pArg);
/* static int memdbSectorSize(sqlite3_file*); // not used */
static int memdbDeviceCharacteristics(sqlite3_file*);
static int memdbFetch(sqlite3_file*, sqlite3_int64 iOfst, int iAmt, void **pp);
static int memdbUnfetch(sqlite3_file*, sqlite3_int64 iOfst, void *p);
/*
** Methods for MemVfs
*/
static int memdbOpen(sqlite3_vfs*, const char *, sqlite3_file*, int , int *);
/* static int memdbDelete(sqlite3_vfs*, const char *zName, int syncDir); */
static int memdbAccess(sqlite3_vfs*, const char *zName, int flags, int *);
static int memdbFullPathname(sqlite3_vfs*, const char *zName, int, char *zOut);
static void *memdbDlOpen(sqlite3_vfs*, const char *zFilename);
static void memdbDlError(sqlite3_vfs*, int nByte, char *zErrMsg);
static void (*memdbDlSym(sqlite3_vfs *pVfs, void *p, const char*zSym))(void);
static void memdbDlClose(sqlite3_vfs*, void*);
static int memdbRandomness(sqlite3_vfs*, int nByte, char *zOut);
static int memdbSleep(sqlite3_vfs*, int microseconds);
/* static int memdbCurrentTime(sqlite3_vfs*, double*); */
static int memdbGetLastError(sqlite3_vfs*, int, char *);
static int memdbCurrentTimeInt64(sqlite3_vfs*, sqlite3_int64*);
static sqlite3_vfs memdb_vfs = {
2, /* iVersion */
0, /* szOsFile (set when registered) */
1024, /* mxPathname */
0, /* pNext */
"memdb", /* zName */
0, /* pAppData (set when registered) */
memdbOpen, /* xOpen */
0, /* memdbDelete, */ /* xDelete */
memdbAccess, /* xAccess */
memdbFullPathname, /* xFullPathname */
memdbDlOpen, /* xDlOpen */
memdbDlError, /* xDlError */
memdbDlSym, /* xDlSym */
memdbDlClose, /* xDlClose */
memdbRandomness, /* xRandomness */
memdbSleep, /* xSleep */
0, /* memdbCurrentTime, */ /* xCurrentTime */
memdbGetLastError, /* xGetLastError */
memdbCurrentTimeInt64 /* xCurrentTimeInt64 */
};
static const sqlite3_io_methods memdb_io_methods = {
3, /* iVersion */
memdbClose, /* xClose */
memdbRead, /* xRead */
memdbWrite, /* xWrite */
memdbTruncate, /* xTruncate */
memdbSync, /* xSync */
memdbFileSize, /* xFileSize */
memdbLock, /* xLock */
memdbLock, /* xUnlock - same as xLock in this case */
0, /* memdbCheckReservedLock, */ /* xCheckReservedLock */
memdbFileControl, /* xFileControl */
0, /* memdbSectorSize,*/ /* xSectorSize */
memdbDeviceCharacteristics, /* xDeviceCharacteristics */
0, /* xShmMap */
0, /* xShmLock */
0, /* xShmBarrier */
0, /* xShmUnmap */
memdbFetch, /* xFetch */
memdbUnfetch /* xUnfetch */
};
/*
** Close an memdb-file.
**
** The pData pointer is owned by the application, so there is nothing
** to free.
*/
static int memdbClose(sqlite3_file *pFile){
MemFile *p = (MemFile *)pFile;
if( p->mFlags & SQLITE_DESERIALIZE_FREEONCLOSE ) sqlite3_free(p->aData);
return SQLITE_OK;
}
/*
** Read data from an memdb-file.
*/
static int memdbRead(
sqlite3_file *pFile,
void *zBuf,
int iAmt,
sqlite_int64 iOfst
){
MemFile *p = (MemFile *)pFile;
if( iOfst+iAmt>p->sz ){
memset(zBuf, 0, iAmt);
if( iOfst<p->sz ) memcpy(zBuf, p->aData+iOfst, p->sz - iOfst);
return SQLITE_IOERR_SHORT_READ;
}
memcpy(zBuf, p->aData+iOfst, iAmt);
return SQLITE_OK;
}
/*
** Try to enlarge the memory allocation to hold at least sz bytes
*/
static int memdbEnlarge(MemFile *p, sqlite3_int64 newSz){
unsigned char *pNew;
if( (p->mFlags & SQLITE_DESERIALIZE_RESIZEABLE)==0 || p->nMmap>0 ){
return SQLITE_FULL;
}
pNew = sqlite3_realloc64(p->aData, newSz);
if( pNew==0 ) return SQLITE_NOMEM;
p->aData = pNew;
p->szMax = newSz;
return SQLITE_OK;
}
/*
** Write data to an memdb-file.
*/
static int memdbWrite(
sqlite3_file *pFile,
const void *z,
int iAmt,
sqlite_int64 iOfst
){
MemFile *p = (MemFile *)pFile;
if( iOfst+iAmt>p->sz ){
int rc;
if( iOfst+iAmt>p->szMax
&& (rc = memdbEnlarge(p, (iOfst+iAmt)*2))!=SQLITE_OK
){
return rc;
}
if( iOfst>p->sz ) memset(p->aData+p->sz, 0, iOfst-p->sz);
p->sz = iOfst+iAmt;
}
memcpy(p->aData+iOfst, z, iAmt);
return SQLITE_OK;
}
/*
** Truncate an memdb-file.
**
** In rollback mode (which is always the case for memdb, as it does not
** support WAL mode) the truncate() method is only used to reduce
** the size of a file, never to increase the size.
*/
static int memdbTruncate(sqlite3_file *pFile, sqlite_int64 size){
MemFile *p = (MemFile *)pFile;
if( NEVER(size>p->sz) ) return SQLITE_FULL;
p->sz = size;
return SQLITE_OK;
}
/*
** Sync an memdb-file.
*/
static int memdbSync(sqlite3_file *pFile, int flags){
return SQLITE_OK;
}
/*
** Return the current file-size of an memdb-file.
*/
static int memdbFileSize(sqlite3_file *pFile, sqlite_int64 *pSize){
MemFile *p = (MemFile *)pFile;
*pSize = p->sz;
return SQLITE_OK;
}
/*
** Lock an memdb-file.
*/
static int memdbLock(sqlite3_file *pFile, int eLock){
MemFile *p = (MemFile *)pFile;
p->eLock = eLock;
return SQLITE_OK;
}
#if 0 /* Never used because memdbAccess() always returns false */
/*
** Check if another file-handle holds a RESERVED lock on an memdb-file.
*/
static int memdbCheckReservedLock(sqlite3_file *pFile, int *pResOut){
*pResOut = 0;
return SQLITE_OK;
}
#endif
/*
** File control method. For custom operations on an memdb-file.
*/
static int memdbFileControl(sqlite3_file *pFile, int op, void *pArg){
MemFile *p = (MemFile *)pFile;
int rc = SQLITE_NOTFOUND;
if( op==SQLITE_FCNTL_VFSNAME ){
*(char**)pArg = sqlite3_mprintf("memdb(%p,%lld)", p->aData, p->sz);
rc = SQLITE_OK;
}
return rc;
}
#if 0 /* Not used because of SQLITE_IOCAP_POWERSAFE_OVERWRITE */
/*
** Return the sector-size in bytes for an memdb-file.
*/
static int memdbSectorSize(sqlite3_file *pFile){
return 1024;
}
#endif
/*
** Return the device characteristic flags supported by an memdb-file.
*/
static int memdbDeviceCharacteristics(sqlite3_file *pFile){
return SQLITE_IOCAP_ATOMIC |
SQLITE_IOCAP_POWERSAFE_OVERWRITE |
SQLITE_IOCAP_SAFE_APPEND |
SQLITE_IOCAP_SEQUENTIAL;
}
/* Fetch a page of a memory-mapped file */
static int memdbFetch(
sqlite3_file *pFile,
sqlite3_int64 iOfst,
int iAmt,
void **pp
){
MemFile *p = (MemFile *)pFile;
p->nMmap++;
*pp = (void*)(p->aData + iOfst);
return SQLITE_OK;
}
/* Release a memory-mapped page */
static int memdbUnfetch(sqlite3_file *pFile, sqlite3_int64 iOfst, void *pPage){
MemFile *p = (MemFile *)pFile;
p->nMmap--;
return SQLITE_OK;
}
/*
** Open an mem file handle.
*/
static int memdbOpen(
sqlite3_vfs *pVfs,
const char *zName,
sqlite3_file *pFile,
int flags,
int *pOutFlags
){
MemFile *p = (MemFile*)pFile;
if( (flags & SQLITE_OPEN_MAIN_DB)==0 ){
return ORIGVFS(pVfs)->xOpen(ORIGVFS(pVfs), zName, pFile, flags, pOutFlags);
}
memset(p, 0, sizeof(*p));
p->mFlags = SQLITE_DESERIALIZE_RESIZEABLE | SQLITE_DESERIALIZE_FREEONCLOSE;
assert( pOutFlags!=0 ); /* True because flags==SQLITE_OPEN_MAIN_DB */
*pOutFlags = flags | SQLITE_OPEN_MEMORY;
p->base.pMethods = &memdb_io_methods;
return SQLITE_OK;
}
#if 0 /* Only used to delete rollback journals, master journals, and WAL
** files, none of which exist in memdb. So this routine is never used */
/*
** Delete the file located at zPath. If the dirSync argument is true,
** ensure the file-system modifications are synced to disk before
** returning.
*/
static int memdbDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){
return SQLITE_IOERR_DELETE;
}
#endif
/*
** Test for access permissions. Return true if the requested permission
** is available, or false otherwise.
**
** With memdb, no files ever exist on disk. So always return false.
*/
static int memdbAccess(
sqlite3_vfs *pVfs,
const char *zPath,
int flags,
int *pResOut
){
*pResOut = 0;
return SQLITE_OK;
}
/*
** Populate buffer zOut with the full canonical pathname corresponding
** to the pathname in zPath. zOut is guaranteed to point to a buffer
** of at least (INST_MAX_PATHNAME+1) bytes.
*/
static int memdbFullPathname(
sqlite3_vfs *pVfs,
const char *zPath,
int nOut,
char *zOut
){
sqlite3_snprintf(nOut, zOut, "%s", zPath);
return SQLITE_OK;
}
/*
** Open the dynamic library located at zPath and return a handle.
*/
static void *memdbDlOpen(sqlite3_vfs *pVfs, const char *zPath){
return ORIGVFS(pVfs)->xDlOpen(ORIGVFS(pVfs), zPath);
}
/*
** Populate the buffer zErrMsg (size nByte bytes) with a human readable
** utf-8 string describing the most recent error encountered associated
** with dynamic libraries.
*/
static void memdbDlError(sqlite3_vfs *pVfs, int nByte, char *zErrMsg){
ORIGVFS(pVfs)->xDlError(ORIGVFS(pVfs), nByte, zErrMsg);
}
/*
** Return a pointer to the symbol zSymbol in the dynamic library pHandle.
*/
static void (*memdbDlSym(sqlite3_vfs *pVfs, void *p, const char *zSym))(void){
return ORIGVFS(pVfs)->xDlSym(ORIGVFS(pVfs), p, zSym);
}
/*
** Close the dynamic library handle pHandle.
*/
static void memdbDlClose(sqlite3_vfs *pVfs, void *pHandle){
ORIGVFS(pVfs)->xDlClose(ORIGVFS(pVfs), pHandle);
}
/*
** Populate the buffer pointed to by zBufOut with nByte bytes of
** random data.
*/
static int memdbRandomness(sqlite3_vfs *pVfs, int nByte, char *zBufOut){
return ORIGVFS(pVfs)->xRandomness(ORIGVFS(pVfs), nByte, zBufOut);
}
/*
** Sleep for nMicro microseconds. Return the number of microseconds
** actually slept.
*/
static int memdbSleep(sqlite3_vfs *pVfs, int nMicro){
return ORIGVFS(pVfs)->xSleep(ORIGVFS(pVfs), nMicro);
}
#if 0 /* Never used. Modern cores only call xCurrentTimeInt64() */
/*
** Return the current time as a Julian Day number in *pTimeOut.
*/
static int memdbCurrentTime(sqlite3_vfs *pVfs, double *pTimeOut){
return ORIGVFS(pVfs)->xCurrentTime(ORIGVFS(pVfs), pTimeOut);
}
#endif
static int memdbGetLastError(sqlite3_vfs *pVfs, int a, char *b){
return ORIGVFS(pVfs)->xGetLastError(ORIGVFS(pVfs), a, b);
}
static int memdbCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *p){
return ORIGVFS(pVfs)->xCurrentTimeInt64(ORIGVFS(pVfs), p);
}
/*
** Translate a database connection pointer and schema name into a
** MemFile pointer.
*/
static MemFile *memdbFromDbSchema(sqlite3 *db, const char *zSchema){
MemFile *p = 0;
int rc = sqlite3_file_control(db, zSchema, SQLITE_FCNTL_FILE_POINTER, &p);
if( rc ) return 0;
if( p->base.pMethods!=&memdb_io_methods ) return 0;
return p;
}
/*
** Return the serialization of a database
*/
unsigned char *sqlite3_serialize(
sqlite3 *db, /* The database connection */
const char *zSchema, /* Which database within the connection */
sqlite3_int64 *piSize, /* Write size here, if not NULL */
unsigned int mFlags /* Maybe SQLITE_SERIALIZE_NOCOPY */
){
MemFile *p;
int iDb;
Btree *pBt;
sqlite3_int64 sz;
int szPage = 0;
sqlite3_stmt *pStmt = 0;
unsigned char *pOut;
char *zSql;
int rc;
#ifdef SQLITE_ENABLE_API_ARMOR
if( !sqlite3SafetyCheckOk(db) ){
(void)SQLITE_MISUSE_BKPT;
return 0;
}
#endif
if( zSchema==0 ) zSchema = db->aDb[0].zDbSName;
p = memdbFromDbSchema(db, zSchema);
iDb = sqlite3FindDbName(db, zSchema);
if( piSize ) *piSize = -1;
if( iDb<0 ) return 0;
if( p ){
if( piSize ) *piSize = p->sz;
if( mFlags & SQLITE_SERIALIZE_NOCOPY ){
pOut = p->aData;
}else{
pOut = sqlite3_malloc64( p->sz );
if( pOut ) memcpy(pOut, p->aData, p->sz);
}
return pOut;
}
pBt = db->aDb[iDb].pBt;
if( pBt==0 ) return 0;
szPage = sqlite3BtreeGetPageSize(pBt);
zSql = sqlite3_mprintf("PRAGMA \"%w\".page_count", zSchema);
rc = zSql ? sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0) : SQLITE_NOMEM;
sqlite3_free(zSql);
if( rc ) return 0;
rc = sqlite3_step(pStmt);
if( rc!=SQLITE_ROW ){
pOut = 0;
}else{
sz = sqlite3_column_int64(pStmt, 0)*szPage;
if( piSize ) *piSize = sz;
if( mFlags & SQLITE_SERIALIZE_NOCOPY ){
pOut = 0;
}else{
pOut = sqlite3_malloc64( sz );
if( pOut ){
int nPage = sqlite3_column_int(pStmt, 0);
Pager *pPager = sqlite3BtreePager(pBt);
int pgno;
for(pgno=1; pgno<=nPage; pgno++){
DbPage *pPage = 0;
unsigned char *pTo = pOut + szPage*(sqlite3_int64)(pgno-1);
rc = sqlite3PagerGet(pPager, pgno, (DbPage**)&pPage, 0);
if( rc==SQLITE_OK ){
memcpy(pTo, sqlite3PagerGetData(pPage), szPage);
}else{
memset(pTo, 0, szPage);
}
sqlite3PagerUnref(pPage);
}
}
}
}
sqlite3_finalize(pStmt);
return pOut;
}
/* Convert zSchema to a MemDB and initialize its content.
*/
int sqlite3_deserialize(
sqlite3 *db, /* The database connection */
const char *zSchema, /* Which DB to reopen with the deserialization */
unsigned char *pData, /* The serialized database content */
sqlite3_int64 szDb, /* Number bytes in the deserialization */
sqlite3_int64 szBuf, /* Total size of buffer pData[] */
unsigned mFlags /* Zero or more SQLITE_DESERIALIZE_* flags */
){
MemFile *p;
char *zSql;
sqlite3_stmt *pStmt = 0;
int rc;
int iDb;
#ifdef SQLITE_ENABLE_API_ARMOR
if( !sqlite3SafetyCheckOk(db) ){
return SQLITE_MISUSE_BKPT;
}
if( szDb<0 ) return SQLITE_MISUSE_BKPT;
if( szBuf<0 ) return SQLITE_MISUSE_BKPT;
#endif
sqlite3_mutex_enter(db->mutex);
if( zSchema==0 ) zSchema = db->aDb[0].zDbSName;
iDb = sqlite3FindDbName(db, zSchema);
if( iDb<0 ){
rc = SQLITE_ERROR;
goto end_deserialize;
}
zSql = sqlite3_mprintf("ATTACH x AS %Q", zSchema);
rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0);
sqlite3_free(zSql);
if( rc ) goto end_deserialize;
db->init.iDb = (u8)iDb;
db->init.reopenMemdb = 1;
rc = sqlite3_step(pStmt);
db->init.reopenMemdb = 0;
if( rc!=SQLITE_DONE ){
rc = SQLITE_ERROR;
goto end_deserialize;
}
p = memdbFromDbSchema(db, zSchema);
if( p==0 ){
rc = SQLITE_ERROR;
}else{
p->aData = pData;
p->sz = szDb;
p->szMax = szBuf;
p->mFlags = mFlags;
rc = SQLITE_OK;
}
end_deserialize:
sqlite3_finalize(pStmt);
sqlite3_mutex_leave(db->mutex);
return rc;
}
/*
** This routine is called when the extension is loaded.
** Register the new VFS.
*/
int sqlite3MemdbInit(void){
sqlite3_vfs *pLower = sqlite3_vfs_find(0);
int sz = pLower->szOsFile;
memdb_vfs.pAppData = pLower;
/* In all known configurations of SQLite, the size of a default
** sqlite3_file is greater than the size of a memdb sqlite3_file.
** Should that ever change, remove the following NEVER() */
if( NEVER(sz<sizeof(MemFile)) ) sz = sizeof(MemFile);
memdb_vfs.szOsFile = sz;
return sqlite3_vfs_register(&memdb_vfs, 0);
}
#endif /* SQLITE_ENABLE_DESERIALIZE */
+23 -16
View File
@@ -50,11 +50,12 @@ struct sqlite3_mutex {
#endif
};
#if SQLITE_MUTEX_NREF
#define SQLITE3_MUTEX_INITIALIZER {PTHREAD_MUTEX_INITIALIZER,0,0,(pthread_t)0,0}
# define SQLITE3_MUTEX_INITIALIZER(id) \
{PTHREAD_MUTEX_INITIALIZER,id,0,(pthread_t)0,0}
#elif defined(SQLITE_ENABLE_API_ARMOR)
#define SQLITE3_MUTEX_INITIALIZER { PTHREAD_MUTEX_INITIALIZER, 0 }
# define SQLITE3_MUTEX_INITIALIZER(id) { PTHREAD_MUTEX_INITIALIZER, id }
#else
#define SQLITE3_MUTEX_INITIALIZER { PTHREAD_MUTEX_INITIALIZER }
#define SQLITE3_MUTEX_INITIALIZER(id) { PTHREAD_MUTEX_INITIALIZER }
#endif
/*
@@ -151,18 +152,18 @@ static int pthreadMutexEnd(void){ return SQLITE_OK; }
*/
static sqlite3_mutex *pthreadMutexAlloc(int iType){
static sqlite3_mutex staticMutexes[] = {
SQLITE3_MUTEX_INITIALIZER,
SQLITE3_MUTEX_INITIALIZER,
SQLITE3_MUTEX_INITIALIZER,
SQLITE3_MUTEX_INITIALIZER,
SQLITE3_MUTEX_INITIALIZER,
SQLITE3_MUTEX_INITIALIZER,
SQLITE3_MUTEX_INITIALIZER,
SQLITE3_MUTEX_INITIALIZER,
SQLITE3_MUTEX_INITIALIZER,
SQLITE3_MUTEX_INITIALIZER,
SQLITE3_MUTEX_INITIALIZER,
SQLITE3_MUTEX_INITIALIZER
SQLITE3_MUTEX_INITIALIZER(2),
SQLITE3_MUTEX_INITIALIZER(3),
SQLITE3_MUTEX_INITIALIZER(4),
SQLITE3_MUTEX_INITIALIZER(5),
SQLITE3_MUTEX_INITIALIZER(6),
SQLITE3_MUTEX_INITIALIZER(7),
SQLITE3_MUTEX_INITIALIZER(8),
SQLITE3_MUTEX_INITIALIZER(9),
SQLITE3_MUTEX_INITIALIZER(10),
SQLITE3_MUTEX_INITIALIZER(11),
SQLITE3_MUTEX_INITIALIZER(12),
SQLITE3_MUTEX_INITIALIZER(13)
};
sqlite3_mutex *p;
switch( iType ){
@@ -180,6 +181,9 @@ static sqlite3_mutex *pthreadMutexAlloc(int iType){
pthread_mutexattr_settype(&recursiveAttr, PTHREAD_MUTEX_RECURSIVE);
pthread_mutex_init(&p->mutex, &recursiveAttr);
pthread_mutexattr_destroy(&recursiveAttr);
#endif
#if SQLITE_MUTEX_NREF || defined(SQLITE_ENABLE_API_ARMOR)
p->id = SQLITE_MUTEX_RECURSIVE;
#endif
}
break;
@@ -188,6 +192,9 @@ static sqlite3_mutex *pthreadMutexAlloc(int iType){
p = sqlite3MallocZero( sizeof(*p) );
if( p ){
pthread_mutex_init(&p->mutex, 0);
#if SQLITE_MUTEX_NREF || defined(SQLITE_ENABLE_API_ARMOR)
p->id = SQLITE_MUTEX_FAST;
#endif
}
break;
}
@@ -203,7 +210,7 @@ static sqlite3_mutex *pthreadMutexAlloc(int iType){
}
}
#if SQLITE_MUTEX_NREF || defined(SQLITE_ENABLE_API_ARMOR)
if( p ) p->id = iType;
assert( p==0 || p->id==iType );
#endif
return p;
}
+17 -17
View File
@@ -40,7 +40,7 @@ struct sqlite3_mutex {
#ifdef SQLITE_DEBUG
volatile int nRef; /* Number of enterances */
volatile DWORD owner; /* Thread holding this mutex */
volatile int trace; /* True to trace changes */
volatile LONG trace; /* True to trace changes */
#endif
};
@@ -52,10 +52,10 @@ struct sqlite3_mutex {
#define SQLITE_W32_MUTEX_INITIALIZER { 0 }
#ifdef SQLITE_DEBUG
#define SQLITE3_MUTEX_INITIALIZER { SQLITE_W32_MUTEX_INITIALIZER, 0, \
#define SQLITE3_MUTEX_INITIALIZER(id) { SQLITE_W32_MUTEX_INITIALIZER, id, \
0L, (DWORD)0, 0 }
#else
#define SQLITE3_MUTEX_INITIALIZER { SQLITE_W32_MUTEX_INITIALIZER, 0 }
#define SQLITE3_MUTEX_INITIALIZER(id) { SQLITE_W32_MUTEX_INITIALIZER, id }
#endif
#ifdef SQLITE_DEBUG
@@ -98,18 +98,18 @@ void sqlite3MemoryBarrier(void){
** Initialize and deinitialize the mutex subsystem.
*/
static sqlite3_mutex winMutex_staticMutexes[] = {
SQLITE3_MUTEX_INITIALIZER,
SQLITE3_MUTEX_INITIALIZER,
SQLITE3_MUTEX_INITIALIZER,
SQLITE3_MUTEX_INITIALIZER,
SQLITE3_MUTEX_INITIALIZER,
SQLITE3_MUTEX_INITIALIZER,
SQLITE3_MUTEX_INITIALIZER,
SQLITE3_MUTEX_INITIALIZER,
SQLITE3_MUTEX_INITIALIZER,
SQLITE3_MUTEX_INITIALIZER,
SQLITE3_MUTEX_INITIALIZER,
SQLITE3_MUTEX_INITIALIZER
SQLITE3_MUTEX_INITIALIZER(2),
SQLITE3_MUTEX_INITIALIZER(3),
SQLITE3_MUTEX_INITIALIZER(4),
SQLITE3_MUTEX_INITIALIZER(5),
SQLITE3_MUTEX_INITIALIZER(6),
SQLITE3_MUTEX_INITIALIZER(7),
SQLITE3_MUTEX_INITIALIZER(8),
SQLITE3_MUTEX_INITIALIZER(9),
SQLITE3_MUTEX_INITIALIZER(10),
SQLITE3_MUTEX_INITIALIZER(11),
SQLITE3_MUTEX_INITIALIZER(12),
SQLITE3_MUTEX_INITIALIZER(13)
};
static int winMutex_isInit = 0;
@@ -239,15 +239,15 @@ static sqlite3_mutex *winMutexAlloc(int iType){
}
#endif
p = &winMutex_staticMutexes[iType-2];
p->id = iType;
#ifdef SQLITE_DEBUG
#ifdef SQLITE_WIN32_MUTEX_TRACE_STATIC
p->trace = 1;
InterlockedCompareExchange(&p->trace, 1, 0);
#endif
#endif
break;
}
}
assert( p==0 || p->id==iType );
return p;
}
+11 -7
View File
@@ -468,7 +468,11 @@ static struct unix_syscall {
#endif
#define osFchown ((int(*)(int,uid_t,gid_t))aSyscall[20].pCurrent)
#if defined(HAVE_FCHOWN)
{ "geteuid", (sqlite3_syscall_ptr)geteuid, 0 },
#else
{ "geteuid", (sqlite3_syscall_ptr)0, 0 },
#endif
#define osGeteuid ((uid_t(*)(void))aSyscall[21].pCurrent)
#if !defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0
@@ -696,15 +700,16 @@ static int robust_open(const char *z, int f, mode_t m){
** assert( unixMutexHeld() );
** unixEnterLeave()
*/
static sqlite3_mutex *unixBigLock = 0;
static void unixEnterMutex(void){
sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_VFS1));
sqlite3_mutex_enter(unixBigLock);
}
static void unixLeaveMutex(void){
sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_VFS1));
sqlite3_mutex_leave(unixBigLock);
}
#ifdef SQLITE_DEBUG
static int unixMutexHeld(void) {
return sqlite3_mutex_held(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_VFS1));
return sqlite3_mutex_held(unixBigLock);
}
#endif
@@ -3950,7 +3955,7 @@ static void setDeviceCharacteristics(unixFile *pFile){
pFile->sectorSize = SQLITE_DEFAULT_SECTOR_SIZE;
pFile->deviceCharacteristics = 0;
if( fstatvfs(pFile->h, &fsInfo) == -1 ) {
return pFile->sectorSize;
return;
}
if( !strcmp(fsInfo.f_basetype, "tmp") ) {
@@ -4175,12 +4180,10 @@ static int unixShmSystemLock(
if( pShmNode->h>=0 ){
/* Initialize the locking parameters */
memset(&f, 0, sizeof(f));
f.l_type = lockType;
f.l_whence = SEEK_SET;
f.l_start = ofst;
f.l_len = n;
rc = osFcntl(pShmNode->h, F_SETLK, &f);
rc = (rc!=(-1)) ? SQLITE_OK : SQLITE_BUSY;
}
@@ -5846,7 +5849,6 @@ static int unixOpen(
randomnessPid = osGetpid(0);
sqlite3_randomness(0,0);
}
memset(p, 0, sizeof(unixFile));
if( eType==SQLITE_OPEN_MAIN_DB ){
@@ -7721,6 +7723,7 @@ int sqlite3_os_init(void){
for(i=0; i<(sizeof(aVfs)/sizeof(sqlite3_vfs)); i++){
sqlite3_vfs_register(&aVfs[i], i==0);
}
unixBigLock = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_VFS1);
return SQLITE_OK;
}
@@ -7732,6 +7735,7 @@ int sqlite3_os_init(void){
** This routine is a no-op for unix.
*/
int sqlite3_os_end(void){
unixBigLock = 0;
return SQLITE_OK;
}
+39 -27
View File
@@ -3631,15 +3631,16 @@ static SYSTEM_INFO winSysInfo;
** assert( winShmMutexHeld() );
** winShmLeaveMutex()
*/
static sqlite3_mutex *winBigLock = 0;
static void winShmEnterMutex(void){
sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_VFS1));
sqlite3_mutex_enter(winBigLock);
}
static void winShmLeaveMutex(void){
sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_VFS1));
sqlite3_mutex_leave(winBigLock);
}
#ifndef NDEBUG
static int winShmMutexHeld(void) {
return sqlite3_mutex_held(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_VFS1));
return sqlite3_mutex_held(winBigLock);
}
#endif
@@ -3865,7 +3866,6 @@ static int winOpenSharedMemory(winFile *pDbFd){
struct winShm *p; /* The connection to be opened */
winShmNode *pShmNode = 0; /* The underlying mmapped file */
int rc = SQLITE_OK; /* Result code */
int rc2 = SQLITE_ERROR; /* winOpen result code */
winShmNode *pNew; /* Newly allocated winShmNode */
int nName; /* Size of zName in bytes */
@@ -3899,6 +3899,9 @@ static int winOpenSharedMemory(winFile *pDbFd){
if( pShmNode ){
sqlite3_free(pNew);
}else{
int inFlags = SQLITE_OPEN_WAL;
int outFlags = 0;
pShmNode = pNew;
pNew = 0;
((winFile*)(&pShmNode->hFile))->h = INVALID_HANDLE_VALUE;
@@ -3914,25 +3917,19 @@ static int winOpenSharedMemory(winFile *pDbFd){
}
if( 0==sqlite3_uri_boolean(pDbFd->zPath, "readonly_shm", 0) ){
rc2 = winOpen(pDbFd->pVfs,
pShmNode->zFilename,
(sqlite3_file*)&pShmNode->hFile,
SQLITE_OPEN_WAL|SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE,
0);
inFlags |= SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE;
}else{
inFlags |= SQLITE_OPEN_READONLY;
}
if( rc2!=SQLITE_OK ){
rc2 = winOpen(pDbFd->pVfs,
pShmNode->zFilename,
(sqlite3_file*)&pShmNode->hFile,
SQLITE_OPEN_WAL|SQLITE_OPEN_READONLY,
0);
if( rc2!=SQLITE_OK ){
rc = winLogError(rc2, osGetLastError(), "winOpenShm",
pShmNode->zFilename);
goto shm_open_err;
}
pShmNode->isReadonly = 1;
rc = winOpen(pDbFd->pVfs, pShmNode->zFilename,
(sqlite3_file*)&pShmNode->hFile,
inFlags, &outFlags);
if( rc!=SQLITE_OK ){
rc = winLogError(rc, osGetLastError(), "winOpenShm",
pShmNode->zFilename);
goto shm_open_err;
}
if( outFlags==SQLITE_OPEN_READONLY ) pShmNode->isReadonly = 1;
rc = winLockSharedMemory(pShmNode);
if( rc!=SQLITE_OK && rc!=SQLITE_READONLY_CANTINIT ) goto shm_open_err;
@@ -5118,8 +5115,10 @@ static int winOpen(
&extendedParameters);
if( h!=INVALID_HANDLE_VALUE ) break;
if( isReadWrite ){
int isRO = 0;
int rc2 = winAccess(pVfs, zName, SQLITE_ACCESS_READ, &isRO);
int rc2, isRO = 0;
sqlite3BeginBenignMalloc();
rc2 = winAccess(pVfs, zName, SQLITE_ACCESS_READ, &isRO);
sqlite3EndBenignMalloc();
if( rc2==SQLITE_OK && isRO ) break;
}
}while( winRetryIoerr(&cnt, &lastErrno) );
@@ -5133,8 +5132,10 @@ static int winOpen(
NULL);
if( h!=INVALID_HANDLE_VALUE ) break;
if( isReadWrite ){
int isRO = 0;
int rc2 = winAccess(pVfs, zName, SQLITE_ACCESS_READ, &isRO);
int rc2, isRO = 0;
sqlite3BeginBenignMalloc();
rc2 = winAccess(pVfs, zName, SQLITE_ACCESS_READ, &isRO);
sqlite3EndBenignMalloc();
if( rc2==SQLITE_OK && isRO ) break;
}
}while( winRetryIoerr(&cnt, &lastErrno) );
@@ -5151,8 +5152,10 @@ static int winOpen(
NULL);
if( h!=INVALID_HANDLE_VALUE ) break;
if( isReadWrite ){
int isRO = 0;
int rc2 = winAccess(pVfs, zName, SQLITE_ACCESS_READ, &isRO);
int rc2, isRO = 0;
sqlite3BeginBenignMalloc();
rc2 = winAccess(pVfs, zName, SQLITE_ACCESS_READ, &isRO);
sqlite3EndBenignMalloc();
if( rc2==SQLITE_OK && isRO ) break;
}
}while( winRetryIoerr(&cnt, &lastErrno) );
@@ -6060,6 +6063,10 @@ int sqlite3_os_init(void){
sqlite3_vfs_register(&winLongPathNolockVfs, 0);
#endif
#ifndef SQLITE_OMIT_WAL
winBigLock = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_VFS1);
#endif
return SQLITE_OK;
}
@@ -6070,6 +6077,11 @@ int sqlite3_os_end(void){
sleepObj = NULL;
}
#endif
#ifndef SQLITE_OMIT_WAL
winBigLock = 0;
#endif
return SQLITE_OK;
}
+65 -42
View File
@@ -699,7 +699,7 @@ struct Pager {
char *zJournal; /* Name of the journal file */
int (*xBusyHandler)(void*); /* Function to call when busy */
void *pBusyHandlerArg; /* Context argument for xBusyHandler */
int aStat[3]; /* Total cache hits, misses and writes */
int aStat[4]; /* Total cache hits, misses, writes, spills */
#ifdef SQLITE_TEST
int nRead; /* Database pages read */
#endif
@@ -727,6 +727,7 @@ struct Pager {
#define PAGER_STAT_HIT 0
#define PAGER_STAT_MISS 1
#define PAGER_STAT_WRITE 2
#define PAGER_STAT_SPILL 3
/*
** The following global variables hold counters used for
@@ -1213,7 +1214,7 @@ static int jrnlBufferSize(Pager *pPager){
#endif
#ifdef SQLITE_ENABLE_BATCH_ATOMIC_WRITE
if( dc&SQLITE_IOCAP_BATCH_ATOMIC ){
if( pPager->dbSize>0 && (dc&SQLITE_IOCAP_BATCH_ATOMIC) ){
return -1;
}
#endif
@@ -4102,6 +4103,30 @@ static void pagerFreeMapHdrs(Pager *pPager){
}
}
/* Verify that the database file has not be deleted or renamed out from
** under the pager. Return SQLITE_OK if the database is still where it ought
** to be on disk. Return non-zero (SQLITE_READONLY_DBMOVED or some other error
** code from sqlite3OsAccess()) if the database has gone missing.
*/
static int databaseIsUnmoved(Pager *pPager){
int bHasMoved = 0;
int rc;
if( pPager->tempFile ) return SQLITE_OK;
if( pPager->dbSize==0 ) return SQLITE_OK;
assert( pPager->zFilename && pPager->zFilename[0] );
rc = sqlite3OsFileControl(pPager->fd, SQLITE_FCNTL_HAS_MOVED, &bHasMoved);
if( rc==SQLITE_NOTFOUND ){
/* If the HAS_MOVED file-control is unimplemented, assume that the file
** has not been moved. That is the historical behavior of SQLite: prior to
** version 3.8.3, it never checked */
rc = SQLITE_OK;
}else if( rc==SQLITE_OK && bHasMoved ){
rc = SQLITE_READONLY_DBMOVED;
}
return rc;
}
/*
** Shutdown the page cache. Free all memory and close all files.
@@ -4118,8 +4143,7 @@ static void pagerFreeMapHdrs(Pager *pPager){
** to the caller.
*/
int sqlite3PagerClose(Pager *pPager, sqlite3 *db){
u8 *pTmp = (u8 *)pPager->pTmpSpace;
u8 *pTmp = (u8*)pPager->pTmpSpace;
assert( db || pagerUseWal(pPager)==0 );
assert( assert_pager_state(pPager) );
disable_simulated_io_errors();
@@ -4128,11 +4152,17 @@ int sqlite3PagerClose(Pager *pPager, sqlite3 *db){
/* pPager->errCode = 0; */
pPager->exclusiveMode = 0;
#ifndef SQLITE_OMIT_WAL
assert( db || pPager->pWal==0 );
sqlite3WalClose(pPager->pWal, db, pPager->walSyncFlags, pPager->pageSize,
(db && (db->flags & SQLITE_NoCkptOnClose) ? 0 : pTmp)
);
pPager->pWal = 0;
{
u8 *a = 0;
assert( db || pPager->pWal==0 );
if( db && 0==(db->flags & SQLITE_NoCkptOnClose)
&& SQLITE_OK==databaseIsUnmoved(pPager)
){
a = pTmp;
}
sqlite3WalClose(pPager->pWal, db, pPager->walSyncFlags, pPager->pageSize,a);
pPager->pWal = 0;
}
#endif
pager_reset(pPager);
if( MEMDB ){
@@ -4589,6 +4619,7 @@ static int pagerStress(void *p, PgHdr *pPg){
return SQLITE_OK;
}
pPager->aStat[PAGER_STAT_SPILL]++;
pPg->pDirty = 0;
if( pagerUseWal(pPager) ){
/* Write a single frame for this page to the log. */
@@ -4694,6 +4725,11 @@ int sqlite3PagerOpen(
int rc = SQLITE_OK; /* Return code */
int tempFile = 0; /* True for temp files (incl. in-memory files) */
int memDb = 0; /* True if this is an in-memory file */
#ifdef SQLITE_ENABLE_DESERIALIZE
int memJM = 0; /* Memory journal mode */
#else
# define memJM 0
#endif
int readOnly = 0; /* True if this is a read-only file */
int journalFileSize; /* Bytes to allocate for each journal fd */
char *zPathname = 0; /* Full path to database file */
@@ -4821,7 +4857,10 @@ int sqlite3PagerOpen(
int fout = 0; /* VFS flags returned by xOpen() */
rc = sqlite3OsOpen(pVfs, pPager->zFilename, pPager->fd, vfsFlags, &fout);
assert( !memDb );
readOnly = (fout&SQLITE_OPEN_READONLY);
#ifdef SQLITE_ENABLE_DESERIALIZE
memJM = (fout&SQLITE_OPEN_MEMORY)!=0;
#endif
readOnly = (fout&SQLITE_OPEN_READONLY)!=0;
/* If the file was successfully opened for read/write access,
** choose a default page size in case we have to create the
@@ -4952,7 +4991,7 @@ act_like_temp_file:
setSectorSize(pPager);
if( !useJournal ){
pPager->journalMode = PAGER_JOURNALMODE_OFF;
}else if( memDb ){
}else if( memDb || memJM ){
pPager->journalMode = PAGER_JOURNALMODE_MEMORY;
}
/* pPager->xBusyHandler = 0; */
@@ -4967,30 +5006,6 @@ act_like_temp_file:
}
/* Verify that the database file has not be deleted or renamed out from
** under the pager. Return SQLITE_OK if the database is still were it ought
** to be on disk. Return non-zero (SQLITE_READONLY_DBMOVED or some other error
** code from sqlite3OsAccess()) if the database has gone missing.
*/
static int databaseIsUnmoved(Pager *pPager){
int bHasMoved = 0;
int rc;
if( pPager->tempFile ) return SQLITE_OK;
if( pPager->dbSize==0 ) return SQLITE_OK;
assert( pPager->zFilename && pPager->zFilename[0] );
rc = sqlite3OsFileControl(pPager->fd, SQLITE_FCNTL_HAS_MOVED, &bHasMoved);
if( rc==SQLITE_NOTFOUND ){
/* If the HAS_MOVED file-control is unimplemented, assume that the file
** has not been moved. That is the historical behavior of SQLite: prior to
** version 3.8.3, it never checked */
rc = SQLITE_OK;
}else if( rc==SQLITE_OK && bHasMoved ){
rc = SQLITE_READONLY_DBMOVED;
}
return rc;
}
/*
** This function is called after transitioning from PAGER_UNLOCK to
@@ -6499,8 +6514,9 @@ int sqlite3PagerCommitPhaseOne(
if( bBatch ){
if( rc==SQLITE_OK ){
rc = sqlite3OsFileControl(fd, SQLITE_FCNTL_COMMIT_ATOMIC_WRITE, 0);
}else{
sqlite3OsFileControl(fd, SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE, 0);
}
if( rc!=SQLITE_OK ){
sqlite3OsFileControlHint(fd, SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE, 0);
}
}
@@ -6724,8 +6740,12 @@ int *sqlite3PagerStats(Pager *pPager){
#endif
/*
** Parameter eStat must be either SQLITE_DBSTATUS_CACHE_HIT or
** SQLITE_DBSTATUS_CACHE_MISS. Before returning, *pnVal is incremented by the
** Parameter eStat must be one of SQLITE_DBSTATUS_CACHE_HIT, _MISS, _WRITE,
** or _WRITE+1. The SQLITE_DBSTATUS_CACHE_WRITE+1 case is a translation
** of SQLITE_DBSTATUS_CACHE_SPILL. The _SPILL case is not contiguous because
** it was added later.
**
** Before returning, *pnVal is incremented by the
** current cache hit or miss count, according to the value of eStat. If the
** reset parameter is non-zero, the cache hit or miss count is zeroed before
** returning.
@@ -6735,15 +6755,18 @@ void sqlite3PagerCacheStat(Pager *pPager, int eStat, int reset, int *pnVal){
assert( eStat==SQLITE_DBSTATUS_CACHE_HIT
|| eStat==SQLITE_DBSTATUS_CACHE_MISS
|| eStat==SQLITE_DBSTATUS_CACHE_WRITE
|| eStat==SQLITE_DBSTATUS_CACHE_WRITE+1
);
assert( SQLITE_DBSTATUS_CACHE_HIT+1==SQLITE_DBSTATUS_CACHE_MISS );
assert( SQLITE_DBSTATUS_CACHE_HIT+2==SQLITE_DBSTATUS_CACHE_WRITE );
assert( PAGER_STAT_HIT==0 && PAGER_STAT_MISS==1 && PAGER_STAT_WRITE==2 );
assert( PAGER_STAT_HIT==0 && PAGER_STAT_MISS==1
&& PAGER_STAT_WRITE==2 && PAGER_STAT_SPILL==3 );
*pnVal += pPager->aStat[eStat - SQLITE_DBSTATUS_CACHE_HIT];
eStat -= SQLITE_DBSTATUS_CACHE_HIT;
*pnVal += pPager->aStat[eStat];
if( reset ){
pPager->aStat[eStat - SQLITE_DBSTATUS_CACHE_HIT] = 0;
pPager->aStat[eStat] = 0;
}
}
+4
View File
@@ -313,6 +313,10 @@ ccons ::= DEFAULT MINUS(A) term(X) scanpt(Z). {
}
ccons ::= DEFAULT scanpt id(X). {
Expr *p = tokenExpr(pParse, TK_STRING, X);
if( p ){
sqlite3ExprIdToTrueFalse(p);
testcase( p->op==TK_TRUEFALSE && sqlite3ExprTruthValue(p) );
}
sqlite3AddDefaultValue(pParse,p,X.z,X.z+X.n);
}
+1 -1
View File
@@ -431,7 +431,7 @@ int sqlite3PcacheFetchStress(
sqlite3_log(SQLITE_FULL,
"spill page %d making room for %d - cache used: %d/%d",
pPg->pgno, pgno,
sqlite3GlobalConfig.pcache.xPagecount(pCache->pCache),
sqlite3GlobalConfig.pcache2.xPagecount(pCache->pCache),
numberOfCachePages(pCache));
#endif
pcacheTrace(("%p.SPILL %d\n",pCache,pPg->pgno));
+1 -1
View File
@@ -29,7 +29,7 @@ static void corruptSchema(
char *z;
if( zObj==0 ) zObj = "?";
z = sqlite3MPrintf(db, "malformed database schema (%s)", zObj);
if( zExtra ) z = sqlite3MPrintf(db, "%z - %s", z, zExtra);
if( zExtra && zExtra[0] ) z = sqlite3MPrintf(db, "%z - %s", z, zExtra);
sqlite3DbFree(db, *pData->pzErrMsg);
*pData->pzErrMsg = z;
}
+86 -15
View File
@@ -206,6 +206,11 @@ void sqlite3VXPrintf(
PrintfArguments *pArgList = 0; /* Arguments for SQLITE_PRINTF_SQLFUNC */
char buf[etBUFSIZE]; /* Conversion buffer */
/* pAccum never starts out with an empty buffer that was obtained from
** malloc(). This precondition is required by the mprintf("%z...")
** optimization. */
assert( pAccum->nChar>0 || (pAccum->printfFlags&SQLITE_PRINTF_MALLOCED)==0 );
bufpt = 0;
if( (pAccum->printfFlags & SQLITE_PRINTF_SQLFUNC)!=0 ){
pArgList = va_arg(ap, PrintfArguments*);
@@ -624,9 +629,38 @@ void sqlite3VXPrintf(
case etCHARX:
if( bArgList ){
bufpt = getTextArg(pArgList);
c = bufpt ? bufpt[0] : 0;
length = 1;
if( bufpt ){
buf[0] = c = *(bufpt++);
if( (c&0xc0)==0xc0 ){
while( length<4 && (bufpt[0]&0xc0)==0x80 ){
buf[length++] = *(bufpt++);
}
}
}else{
buf[0] = 0;
}
}else{
c = va_arg(ap,int);
unsigned int ch = va_arg(ap,unsigned int);
if( ch<0x00080 ){
buf[0] = ch & 0xff;
length = 1;
}else if( ch<0x00800 ){
buf[0] = 0xc0 + (u8)((ch>>6)&0x1f);
buf[1] = 0x80 + (u8)(ch & 0x3f);
length = 2;
}else if( ch<0x10000 ){
buf[0] = 0xe0 + (u8)((ch>>12)&0x0f);
buf[1] = 0x80 + (u8)((ch>>6) & 0x3f);
buf[2] = 0x80 + (u8)(ch & 0x3f);
length = 3;
}else{
buf[0] = 0xf0 + (u8)((ch>>18) & 0x07);
buf[1] = 0x80 + (u8)((ch>>12) & 0x3f);
buf[2] = 0x80 + (u8)((ch>>6) & 0x3f);
buf[3] = 0x80 + (u8)(ch & 0x3f);
length = 4;
}
}
if( precision>1 ){
width -= precision-1;
@@ -634,12 +668,13 @@ void sqlite3VXPrintf(
sqlite3AppendChar(pAccum, width-1, ' ');
width = 0;
}
sqlite3AppendChar(pAccum, precision-1, c);
while( precision-- > 1 ){
sqlite3StrAccumAppend(pAccum, buf, length);
}
}
length = 1;
buf[0] = c;
bufpt = buf;
break;
flag_altform2 = 1;
goto adjust_width_for_utf8;
case etSTRING:
case etDYNSTRING:
if( bArgList ){
@@ -651,17 +686,45 @@ void sqlite3VXPrintf(
if( bufpt==0 ){
bufpt = "";
}else if( xtype==etDYNSTRING ){
if( pAccum->nChar==0 && pAccum->mxAlloc && width==0 && precision<0 ){
/* Special optimization for sqlite3_mprintf("%z..."):
** Extend an existing memory allocation rather than creating
** a new one. */
assert( (pAccum->printfFlags&SQLITE_PRINTF_MALLOCED)==0 );
pAccum->zText = bufpt;
pAccum->nAlloc = sqlite3DbMallocSize(pAccum->db, bufpt);
pAccum->nChar = 0x7fffffff & (int)strlen(bufpt);
pAccum->printfFlags |= SQLITE_PRINTF_MALLOCED;
length = 0;
break;
}
zExtra = bufpt;
}
if( precision>=0 ){
for(length=0; length<precision && bufpt[length]; length++){}
if( flag_altform2 ){
/* Set length to the number of bytes needed in order to display
** precision characters */
unsigned char *z = (unsigned char*)bufpt;
while( precision-- > 0 && z[0] ){
SQLITE_SKIP_UTF8(z);
}
length = (int)(z - (unsigned char*)bufpt);
}else{
for(length=0; length<precision && bufpt[length]; length++){}
}
}else{
length = 0x7fffffff & (int)strlen(bufpt);
}
adjust_width_for_utf8:
if( flag_altform2 && width>0 ){
/* Adjust width to account for extra bytes in UTF-8 characters */
int ii = length - 1;
while( ii>=0 ) if( (bufpt[ii--] & 0xc0)==0x80 ) width++;
}
break;
case etSQLESCAPE: /* Escape ' characters */
case etSQLESCAPE2: /* Escape ' and enclose in '...' */
case etSQLESCAPE3: { /* Escape " characters */
case etSQLESCAPE: /* %q: Escape ' characters */
case etSQLESCAPE2: /* %Q: Escape ' and enclose in '...' */
case etSQLESCAPE3: { /* %w: Escape " characters */
int i, j, k, n, isnull;
int needQuote;
char ch;
@@ -675,9 +738,17 @@ void sqlite3VXPrintf(
}
isnull = escarg==0;
if( isnull ) escarg = (xtype==etSQLESCAPE2 ? "NULL" : "(NULL)");
/* For %q, %Q, and %w, the precision is the number of byte (or
** characters if the ! flags is present) to use from the input.
** Because of the extra quoting characters inserted, the number
** of output characters may be larger than the precision.
*/
k = precision;
for(i=n=0; k!=0 && (ch=escarg[i])!=0; i++, k--){
if( ch==q ) n++;
if( flag_altform2 && (ch&0xc0)==0xc0 ){
while( (escarg[i+1]&0xc0)==0x80 ){ i++; }
}
}
needQuote = !isnull && xtype==etSQLESCAPE2;
n += i + 3;
@@ -700,10 +771,7 @@ void sqlite3VXPrintf(
if( needQuote ) bufpt[j++] = q;
bufpt[j] = 0;
length = j;
/* The precision in %q and %Q means how many input characters to
** consume, not the length of the output...
** if( precision>=0 && precision<length ) length = precision; */
break;
goto adjust_width_for_utf8;
}
case etTOKEN: {
Token *pToken;
@@ -742,7 +810,10 @@ void sqlite3VXPrintf(
/*
** The text of the conversion is pointed to by "bufpt" and is
** "length" characters long. The field width is "width". Do
** the output.
** the output. Both length and width are in bytes, not characters,
** at this point. If the "!" flag was present on string conversions
** indicating that width and precision should be expressed in characters,
** then the values have been translated prior to reaching this point.
*/
width -= length;
if( width>0 ){
+28 -7
View File
@@ -431,10 +431,16 @@ static int lookupName(
** Because no reference was made to outer contexts, the pNC->nRef
** fields are not changed in any context.
*/
if( cnt==0 && zTab==0 && ExprHasProperty(pExpr,EP_DblQuoted) ){
pExpr->op = TK_STRING;
pExpr->pTab = 0;
return WRC_Prune;
if( cnt==0 && zTab==0 ){
assert( pExpr->op==TK_ID );
if( ExprHasProperty(pExpr,EP_DblQuoted) ){
pExpr->op = TK_STRING;
pExpr->pTab = 0;
return WRC_Prune;
}
if( sqlite3ExprIdToTrueFalse(pExpr) ){
return WRC_Prune;
}
}
/*
@@ -783,15 +789,30 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
notValid(pParse, pNC, "parameters", NC_IsCheck|NC_PartIdx|NC_IdxExpr);
break;
}
case TK_IS:
case TK_ISNOT: {
Expr *pRight;
assert( !ExprHasProperty(pExpr, EP_Reduced) );
/* Handle special cases of "x IS TRUE", "x IS FALSE", "x IS NOT TRUE",
** and "x IS NOT FALSE". */
if( (pRight = pExpr->pRight)->op==TK_ID ){
int rc = resolveExprStep(pWalker, pRight);
if( rc==WRC_Abort ) return WRC_Abort;
if( pRight->op==TK_TRUEFALSE ){
pExpr->op2 = pExpr->op;
pExpr->op = TK_TRUTH;
return WRC_Continue;
}
}
/* Fall thru */
}
case TK_BETWEEN:
case TK_EQ:
case TK_NE:
case TK_LT:
case TK_LE:
case TK_GT:
case TK_GE:
case TK_IS:
case TK_ISNOT: {
case TK_GE: {
int nLeft, nRight;
if( pParse->db->mallocFailed ) break;
assert( pExpr->pLeft!=0 );
+13 -5
View File
@@ -1266,12 +1266,15 @@ static void generateSortTail(
iSortTab = iTab;
bSeq = 1;
}
for(i=0, iCol=nKey+bSeq; i<nSortData; i++){
for(i=0, iCol=nKey+bSeq-1; i<nSortData; i++){
if( aOutEx[i].u.x.iOrderByCol==0 ) iCol++;
}
for(i=nSortData-1; i>=0; i--){
int iRead;
if( aOutEx[i].u.x.iOrderByCol ){
iRead = aOutEx[i].u.x.iOrderByCol-1;
}else{
iRead = iCol++;
iRead = iCol--;
}
sqlite3VdbeAddOp3(v, OP_Column, iSortTab, iRead, regRow+i);
VdbeComment((v, "%s", aOutEx[i].zName ? aOutEx[i].zName : aOutEx[i].zSpan));
@@ -2184,9 +2187,14 @@ static int multiSelectOrderBy(
** on a VALUES clause.
**
** Because the Select object originates from a VALUES clause:
** (1) It has no LIMIT or OFFSET
** (1) There is no LIMIT or OFFSET or else there is a LIMIT of exactly 1
** (2) All terms are UNION ALL
** (3) There is no ORDER BY clause
**
** The "LIMIT of exactly 1" case of condition (1) comes about when a VALUES
** clause occurs within scalar expression (ex: "SELECT (VALUES(1),(2),(3))").
** The sqlite3CodeSubselect will have added the LIMIT 1 clause in tht case.
** Since the limit is exactly 1, we only need to evalutes the left-most VALUES.
*/
static int multiSelectValues(
Parse *pParse, /* Parsing context */
@@ -2194,13 +2202,13 @@ static int multiSelectValues(
SelectDest *pDest /* What to do with query results */
){
Select *pPrior;
Select *pRightmost = p;
int nRow = 1;
int rc = 0;
assert( p->selFlags & SF_MultiValue );
do{
assert( p->selFlags & SF_Values );
assert( p->op==TK_ALL || (p->op==TK_SELECT && p->pPrior==0) );
assert( p->pLimit==0 );
assert( p->pNext==0 || p->pEList->nExpr==p->pNext->pEList->nExpr );
if( p->pPrior==0 ) break;
assert( p->pPrior->pNext==p );
@@ -2212,7 +2220,7 @@ static int multiSelectValues(
p->pPrior = 0;
rc = sqlite3Select(pParse, p, pDest);
p->pPrior = pPrior;
if( rc ) break;
if( rc || pRightmost->pLimit ) break;
p->nSelectRow = nRow;
p = p->pNext;
}
+289 -125
View File
@@ -865,6 +865,7 @@ static void shellModuleSchema(
){
const char *zName = (const char*)sqlite3_value_text(apVal[0]);
char *zFake = shellFakeSchema(sqlite3_context_db_handle(pCtx), 0, zName);
UNUSED_PARAMETER(nVal);
if( zFake ){
sqlite3_result_text(pCtx, sqlite3_mprintf("/* %s */", zFake),
-1, sqlite3_free);
@@ -909,6 +910,7 @@ static void shellAddSchemaName(
const char *zSchema = (const char*)sqlite3_value_text(apVal[1]);
const char *zName = (const char*)sqlite3_value_text(apVal[2]);
sqlite3 *db = sqlite3_context_db_handle(pCtx);
UNUSED_PARAMETER(nVal);
if( zIn!=0 && strncmp(zIn, "CREATE ", 7)==0 ){
for(i=0; i<(int)(sizeof(aPrefix)/sizeof(aPrefix[0])); i++){
int n = strlen30(aPrefix[i]);
@@ -1067,6 +1069,7 @@ struct ShellState {
#define SHELL_OPEN_NORMAL 1 /* Normal database file */
#define SHELL_OPEN_APPENDVFS 2 /* Use appendvfs */
#define SHELL_OPEN_ZIPFILE 3 /* Use the zipfile virtual table */
#define SHELL_OPEN_READONLY 4 /* Open a normal database read-only */
/*
** These are the allowed shellFlgs values
@@ -1152,6 +1155,7 @@ static void shellPutsFunc(
sqlite3_value **apVal
){
ShellState *p = (ShellState*)sqlite3_user_data(pCtx);
(void)nVal;
utf8_printf(p->out, "%s\n", sqlite3_value_text(apVal[0]));
sqlite3_result_value(pCtx, apVal[0]);
}
@@ -1172,6 +1176,7 @@ static void shellPutsFunc(
**
** Also throw an error if the EDITOR program returns a non-zero exit code.
*/
#ifndef SQLITE_NOHAVE_SYSTEM
static void editFunc(
sqlite3_context *context,
int argc,
@@ -1269,9 +1274,10 @@ static void editFunc(
goto edit_func_end;
}
if( bBin ){
sqlite3_result_blob(context, p, sz, sqlite3_free);
sqlite3_result_blob64(context, p, sz, sqlite3_free);
}else{
sqlite3_result_text(context, (const char*)p, sz, sqlite3_free);
sqlite3_result_text64(context, (const char*)p, sz,
sqlite3_free, SQLITE_UTF8);
}
p = 0;
@@ -1281,6 +1287,7 @@ edit_func_end:
sqlite3_free(zTempFile);
sqlite3_free(p);
}
#endif /* SQLITE_NOHAVE_SYSTEM */
/*
** Save or restore the current output mode
@@ -2266,29 +2273,52 @@ static int display_stats(
){
int iCur;
int iHiwtr;
FILE *out;
if( pArg==0 || pArg->out==0 ) return 0;
out = pArg->out;
if( pArg && pArg->out ){
displayStatLine(pArg, "Memory Used:",
"%lld (max %lld) bytes", SQLITE_STATUS_MEMORY_USED, bReset);
displayStatLine(pArg, "Number of Outstanding Allocations:",
"%lld (max %lld)", SQLITE_STATUS_MALLOC_COUNT, bReset);
if( pArg->shellFlgs & SHFLG_Pagecache ){
displayStatLine(pArg, "Number of Pcache Pages Used:",
"%lld (max %lld) pages", SQLITE_STATUS_PAGECACHE_USED, bReset);
if( pArg->pStmt && (pArg->statsOn & 2) ){
int nCol, i, x;
sqlite3_stmt *pStmt = pArg->pStmt;
char z[100];
nCol = sqlite3_column_count(pStmt);
raw_printf(out, "%-36s %d\n", "Number of output columns:", nCol);
for(i=0; i<nCol; i++){
sqlite3_snprintf(sizeof(z),z,"Column %d %nname:", i, &x);
utf8_printf(out, "%-36s %s\n", z, sqlite3_column_name(pStmt,i));
sqlite3_snprintf(30, z+x, "declared type:");
utf8_printf(out, "%-36s %s\n", z, sqlite3_column_decltype(pStmt, i));
#ifdef SQLITE_ENABLE_COLUMN_METADATA
sqlite3_snprintf(30, z+x, "database name:");
utf8_printf(out, "%-36s %s\n", z, sqlite3_column_database_name(pStmt,i));
sqlite3_snprintf(30, z+x, "table name:");
utf8_printf(out, "%-36s %s\n", z, sqlite3_column_table_name(pStmt,i));
sqlite3_snprintf(30, z+x, "origin name:");
utf8_printf(out, "%-36s %s\n", z, sqlite3_column_origin_name(pStmt,i));
#endif
}
}
displayStatLine(pArg, "Number of Pcache Overflow Bytes:",
"%lld (max %lld) bytes", SQLITE_STATUS_PAGECACHE_OVERFLOW, bReset);
displayStatLine(pArg, "Largest Allocation:",
"%lld bytes", SQLITE_STATUS_MALLOC_SIZE, bReset);
displayStatLine(pArg, "Largest Pcache Allocation:",
"%lld bytes", SQLITE_STATUS_PAGECACHE_SIZE, bReset);
#ifdef YYTRACKMAXSTACKDEPTH
displayStatLine(pArg, "Deepest Parser Stack:",
"%lld (max %lld)", SQLITE_STATUS_PARSER_STACK, bReset);
#endif
}
if( pArg && pArg->out && db ){
displayStatLine(pArg, "Memory Used:",
"%lld (max %lld) bytes", SQLITE_STATUS_MEMORY_USED, bReset);
displayStatLine(pArg, "Number of Outstanding Allocations:",
"%lld (max %lld)", SQLITE_STATUS_MALLOC_COUNT, bReset);
if( pArg->shellFlgs & SHFLG_Pagecache ){
displayStatLine(pArg, "Number of Pcache Pages Used:",
"%lld (max %lld) pages", SQLITE_STATUS_PAGECACHE_USED, bReset);
}
displayStatLine(pArg, "Number of Pcache Overflow Bytes:",
"%lld (max %lld) bytes", SQLITE_STATUS_PAGECACHE_OVERFLOW, bReset);
displayStatLine(pArg, "Largest Allocation:",
"%lld bytes", SQLITE_STATUS_MALLOC_SIZE, bReset);
displayStatLine(pArg, "Largest Pcache Allocation:",
"%lld bytes", SQLITE_STATUS_PAGECACHE_SIZE, bReset);
#ifdef YYTRACKMAXSTACKDEPTH
displayStatLine(pArg, "Deepest Parser Stack:",
"%lld (max %lld)", SQLITE_STATUS_PARSER_STACK, bReset);
#endif
if( db ){
if( pArg->shellFlgs & SHFLG_Lookaside ){
iHiwtr = iCur = -1;
sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_USED,
@@ -2323,6 +2353,9 @@ static int display_stats(
sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_WRITE, &iCur, &iHiwtr, 1);
raw_printf(pArg->out, "Page cache writes: %d\n", iCur);
iHiwtr = iCur = -1;
sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_SPILL, &iCur, &iHiwtr, 1);
raw_printf(pArg->out, "Page cache spills: %d\n", iCur);
iHiwtr = iCur = -1;
sqlite3_db_status(db, SQLITE_DBSTATUS_SCHEMA_USED, &iCur, &iHiwtr, bReset);
raw_printf(pArg->out, "Schema Heap Usage: %d bytes\n",
iCur);
@@ -2332,7 +2365,7 @@ static int display_stats(
iCur);
}
if( pArg && pArg->out && db && pArg->pStmt ){
if( pArg->pStmt ){
iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_FULLSCAN_STEP,
bReset);
raw_printf(pArg->out, "Fullscan Steps: %d\n", iCur);
@@ -2342,6 +2375,12 @@ static int display_stats(
raw_printf(pArg->out, "Autoindex Inserts: %d\n", iCur);
iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_VM_STEP, bReset);
raw_printf(pArg->out, "Virtual Machine Steps: %d\n", iCur);
iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_REPREPARE, bReset);
raw_printf(pArg->out, "Reprepare operations: %d\n", iCur);
iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_RUN, bReset);
raw_printf(pArg->out, "Number of times run: %d\n", iCur);
iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_MEMUSED, bReset);
raw_printf(pArg->out, "Memory used by prepared stmt: %d\n", iCur);
}
#ifdef __linux__
@@ -2557,8 +2596,7 @@ static void restore_debug_trace_modes(void){
*/
static void exec_prepared_stmt(
ShellState *pArg, /* Pointer to ShellState */
sqlite3_stmt *pStmt, /* Statment to run */
int (*xCallback)(void*,int,char**,char**,int*) /* Callback function */
sqlite3_stmt *pStmt /* Statment to run */
){
int rc;
@@ -2568,54 +2606,47 @@ static void exec_prepared_stmt(
rc = sqlite3_step(pStmt);
/* if we have a result set... */
if( SQLITE_ROW == rc ){
/* if we have a callback... */
if( xCallback ){
/* allocate space for col name ptr, value ptr, and type */
int nCol = sqlite3_column_count(pStmt);
void *pData = sqlite3_malloc64(3*nCol*sizeof(const char*) + 1);
if( !pData ){
rc = SQLITE_NOMEM;
}else{
char **azCols = (char **)pData; /* Names of result columns */
char **azVals = &azCols[nCol]; /* Results */
int *aiTypes = (int *)&azVals[nCol]; /* Result types */
int i, x;
assert(sizeof(int) <= sizeof(char *));
/* save off ptrs to column names */
for(i=0; i<nCol; i++){
azCols[i] = (char *)sqlite3_column_name(pStmt, i);
}
do{
/* extract the data and data types */
for(i=0; i<nCol; i++){
aiTypes[i] = x = sqlite3_column_type(pStmt, i);
if( x==SQLITE_BLOB && pArg && pArg->cMode==MODE_Insert ){
azVals[i] = "";
}else{
azVals[i] = (char*)sqlite3_column_text(pStmt, i);
}
if( !azVals[i] && (aiTypes[i]!=SQLITE_NULL) ){
rc = SQLITE_NOMEM;
break; /* from for */
}
} /* end for */
/* if data and types extracted successfully... */
if( SQLITE_ROW == rc ){
/* call the supplied callback with the result row data */
if( xCallback(pArg, nCol, azVals, azCols, aiTypes) ){
rc = SQLITE_ABORT;
}else{
rc = sqlite3_step(pStmt);
}
}
} while( SQLITE_ROW == rc );
sqlite3_free(pData);
}
/* allocate space for col name ptr, value ptr, and type */
int nCol = sqlite3_column_count(pStmt);
void *pData = sqlite3_malloc64(3*nCol*sizeof(const char*) + 1);
if( !pData ){
rc = SQLITE_NOMEM;
}else{
char **azCols = (char **)pData; /* Names of result columns */
char **azVals = &azCols[nCol]; /* Results */
int *aiTypes = (int *)&azVals[nCol]; /* Result types */
int i, x;
assert(sizeof(int) <= sizeof(char *));
/* save off ptrs to column names */
for(i=0; i<nCol; i++){
azCols[i] = (char *)sqlite3_column_name(pStmt, i);
}
do{
rc = sqlite3_step(pStmt);
} while( rc == SQLITE_ROW );
/* extract the data and data types */
for(i=0; i<nCol; i++){
aiTypes[i] = x = sqlite3_column_type(pStmt, i);
if( x==SQLITE_BLOB && pArg && pArg->cMode==MODE_Insert ){
azVals[i] = "";
}else{
azVals[i] = (char*)sqlite3_column_text(pStmt, i);
}
if( !azVals[i] && (aiTypes[i]!=SQLITE_NULL) ){
rc = SQLITE_NOMEM;
break; /* from for */
}
} /* end for */
/* if data and types extracted successfully... */
if( SQLITE_ROW == rc ){
/* call the supplied callback with the result row data */
if( shell_callback(pArg, nCol, azVals, azCols, aiTypes) ){
rc = SQLITE_ABORT;
}else{
rc = sqlite3_step(pStmt);
}
}
} while( SQLITE_ROW == rc );
sqlite3_free(pData);
}
}
}
@@ -2761,17 +2792,15 @@ static int expertDotCommand(
** and callback data argument.
*/
static int shell_exec(
sqlite3 *db, /* An open database */
const char *zSql, /* SQL to be evaluated */
int (*xCallback)(void*,int,char**,char**,int*), /* Callback function */
/* (not the same as sqlite3_exec) */
ShellState *pArg, /* Pointer to ShellState */
const char *zSql, /* SQL to be evaluated */
char **pzErrMsg /* Error msg written here */
){
sqlite3_stmt *pStmt = NULL; /* Statement to execute. */
int rc = SQLITE_OK; /* Return Code */
int rc2;
const char *zLeftover; /* Tail of unprocessed SQL */
sqlite3 *db = pArg->db;
if( pzErrMsg ){
*pzErrMsg = NULL;
@@ -2842,7 +2871,7 @@ static int shell_exec(
if( rc==SQLITE_OK ){
pArg->cMode = MODE_Explain;
explain_data_prepare(pArg, pExplain);
exec_prepared_stmt(pArg, pExplain, xCallback);
exec_prepared_stmt(pArg, pExplain);
explain_data_delete(pArg);
}
sqlite3_finalize(pExplain);
@@ -2868,7 +2897,7 @@ static int shell_exec(
}
}
exec_prepared_stmt(pArg, pStmt, xCallback);
exec_prepared_stmt(pArg, pStmt);
explain_data_delete(pArg);
/* print usage stats if stats on */
@@ -3131,11 +3160,11 @@ static int dump_callback(void *pArg, int nArg, char **azArg, char **azNotUsed){
savedMode = p->mode;
p->zDestTable = sTable.z;
p->mode = p->cMode = MODE_Insert;
rc = shell_exec(p->db, sSelect.z, shell_callback, p, 0);
rc = shell_exec(p, sSelect.z, 0);
if( (rc&0xff)==SQLITE_CORRUPT ){
raw_printf(p->out, "/****** CORRUPTION ERROR *******/\n");
toggleSelectOrder(p->db);
shell_exec(p->db, sSelect.z, shell_callback, p, 0);
shell_exec(p, sSelect.z, 0);
toggleSelectOrder(p->db);
}
p->zDestTable = savedDestTable;
@@ -3252,6 +3281,7 @@ static char zHelp[] =
" on the output.\n"
".open ?OPTIONS? ?FILE? Close existing database and reopen FILE\n"
" The --new option starts with an empty file\n"
" Other options: --readonly --append --zip\n"
".output ?FILE? Send output to FILE or stdout\n"
".print STRING... Print literal STRING\n"
".prompt MAIN CONTINUE Replace the standard prompts\n"
@@ -3269,10 +3299,14 @@ static char zHelp[] =
".session CMD ... Create or control sessions\n"
#endif
".sha3sum ?OPTIONS...? Compute a SHA3 hash of database content\n"
#ifndef SQLITE_NOHAVE_SYSTEM
".shell CMD ARGS... Run CMD ARGS... in a system shell\n"
#endif
".show Show the current values for various settings\n"
".stats ?on|off? Show stats or turn stats on or off\n"
#ifndef SQLITE_NOHAVE_SYSTEM
".system CMD ARGS... Run CMD ARGS... in a system shell\n"
#endif
".tables ?TABLE? List names of tables\n"
" If TABLE specified, only list tables matching\n"
" LIKE pattern TABLE.\n"
@@ -3401,13 +3435,21 @@ static int session_filter(void *pCtx, const char *zTab){
/*
** Try to deduce the type of file for zName based on its content. Return
** one of the SHELL_OPEN_* constants.
**
** If the file does not exist or is empty but its name looks like a ZIP
** archive and the dfltZip flag is true, then assume it is a ZIP archive.
** Otherwise, assume an ordinary database regardless of the filename if
** the type cannot be determined from content.
*/
static int deduceDatabaseType(const char *zName){
static int deduceDatabaseType(const char *zName, int dfltZip){
FILE *f = fopen(zName, "rb");
size_t n;
int rc = SHELL_OPEN_UNSPEC;
char zBuf[100];
if( f==0 ) return SHELL_OPEN_NORMAL;
if( f==0 ){
if( dfltZip && sqlite3_strlike("%.zip",zName,0)==0 ) return SHELL_OPEN_ZIPFILE;
return SHELL_OPEN_NORMAL;
}
fseek(f, -25, SEEK_END);
n = fread(zBuf, 25, 1, f);
if( n==1 && memcmp(zBuf, "Start-Of-SQLite3-", 17)==0 ){
@@ -3418,6 +3460,8 @@ static int deduceDatabaseType(const char *zName){
if( n==1 && zBuf[0]==0x50 && zBuf[1]==0x4b && zBuf[2]==0x05
&& zBuf[3]==0x06 ){
rc = SHELL_OPEN_ZIPFILE;
}else if( n==0 && dfltZip && sqlite3_strlike("%.zip",zName,0)==0 ){
return SHELL_OPEN_ZIPFILE;
}
}
fclose(f);
@@ -3432,7 +3476,7 @@ static void open_db(ShellState *p, int keepAlive){
if( p->db==0 ){
sqlite3_initialize();
if( p->openMode==SHELL_OPEN_UNSPEC && access(p->zDbFilename,0)==0 ){
p->openMode = deduceDatabaseType(p->zDbFilename);
p->openMode = (u8)deduceDatabaseType(p->zDbFilename, 0);
}
switch( p->openMode ){
case SHELL_OPEN_APPENDVFS: {
@@ -3444,6 +3488,10 @@ static void open_db(ShellState *p, int keepAlive){
sqlite3_open(":memory:", &p->db);
break;
}
case SHELL_OPEN_READONLY: {
sqlite3_open_v2(p->zDbFilename, &p->db, SQLITE_OPEN_READONLY, 0);
break;
}
case SHELL_OPEN_UNSPEC:
case SHELL_OPEN_NORMAL: {
sqlite3_open(p->zDbFilename, &p->db);
@@ -3473,10 +3521,12 @@ static void open_db(ShellState *p, int keepAlive){
shellModuleSchema, 0, 0);
sqlite3_create_function(p->db, "shell_putsnl", 1, SQLITE_UTF8, p,
shellPutsFunc, 0, 0);
#ifndef SQLITE_NOHAVE_SYSTEM
sqlite3_create_function(p->db, "edit", 1, SQLITE_UTF8, 0,
editFunc, 0, 0);
sqlite3_create_function(p->db, "edit", 2, SQLITE_UTF8, 0,
editFunc, 0, 0);
#endif
if( p->openMode==SHELL_OPEN_ZIPFILE ){
char *zSql = sqlite3_mprintf(
"CREATE VIRTUAL TABLE zip USING zipfile(%Q);", p->zDbFilename);
@@ -4091,6 +4141,7 @@ static void output_reset(ShellState *p){
#endif
}else{
output_file_close(p->out);
#ifndef SQLITE_NOHAVE_SYSTEM
if( p->doXdgOpen ){
const char *zXdgOpenCmd =
#if defined(_WIN32)
@@ -4109,6 +4160,7 @@ static void output_reset(ShellState *p){
outputModePop(p);
p->doXdgOpen = 0;
}
#endif /* !defined(SQLITE_NOHAVE_SYSTEM) */
}
p->outfile[0] = 0;
p->out = stdout;
@@ -5219,8 +5271,8 @@ static int arCreateOrUpdateCommand(
" data BLOB -- compressed content\n"
")";
const char *zDrop = "DROP TABLE IF EXISTS sqlar";
const char *zInsertFmt =
"REPLACE INTO sqlar(name,mode,mtime,sz,data)\n"
const char *zInsertFmt[2] = {
"REPLACE INTO %s(name,mode,mtime,sz,data)\n"
" SELECT\n"
" %s,\n"
" mode,\n"
@@ -5229,30 +5281,70 @@ static int arCreateOrUpdateCommand(
" WHEN '-' THEN length(data)\n"
" WHEN 'd' THEN 0\n"
" ELSE -1 END,\n"
" CASE WHEN lsmode(mode) LIKE 'd%%' THEN NULL else data END\n"
" sqlar_compress(data)\n"
" FROM fsdir(%Q,%Q)\n"
" WHERE lsmode(mode) NOT LIKE '?%%';";
" WHERE lsmode(mode) NOT LIKE '?%%';",
"REPLACE INTO %s(name,mode,mtime,data)\n"
" SELECT\n"
" %s,\n"
" mode,\n"
" mtime,\n"
" data\n"
" FROM fsdir(%Q,%Q)\n"
" WHERE lsmode(mode) NOT LIKE '?%%';"
};
int i; /* For iterating through azFile[] */
int rc; /* Return code */
const char *zTab = 0; /* SQL table into which to insert */
char *zSql;
char zTemp[50];
arExecSql(pAr, "PRAGMA page_size=512");
rc = arExecSql(pAr, "SAVEPOINT ar;");
if( rc!=SQLITE_OK ) return rc;
if( bUpdate==0 ){
rc = arExecSql(pAr, zDrop);
if( rc!=SQLITE_OK ) return rc;
zTemp[0] = 0;
if( pAr->bZip ){
/* Initialize the zipfile virtual table, if necessary */
if( pAr->zFile ){
sqlite3_uint64 r;
sqlite3_randomness(sizeof(r),&r);
sqlite3_snprintf(sizeof(zTemp),zTemp,"zip%016llx",r);
zTab = zTemp;
zSql = sqlite3_mprintf(
"CREATE VIRTUAL TABLE temp.%s USING zipfile(%Q)",
zTab, pAr->zFile
);
rc = arExecSql(pAr, zSql);
sqlite3_free(zSql);
}else{
zTab = "zip";
}
}else{
/* Initialize the table for an SQLAR */
zTab = "sqlar";
if( bUpdate==0 ){
rc = arExecSql(pAr, zDrop);
if( rc!=SQLITE_OK ) goto end_ar_transaction;
}
rc = arExecSql(pAr, zCreate);
}
rc = arExecSql(pAr, zCreate);
for(i=0; i<pAr->nArg && rc==SQLITE_OK; i++){
char *zSql = sqlite3_mprintf(zInsertFmt,
char *zSql = sqlite3_mprintf(zInsertFmt[pAr->bZip], zTab,
pAr->bVerbose ? "shell_putsnl(name)" : "name",
pAr->azArg[i], pAr->zDir);
rc = arExecSql(pAr, zSql);
sqlite3_free(zSql);
}
end_ar_transaction:
if( rc!=SQLITE_OK ){
arExecSql(pAr, "ROLLBACK TO ar; RELEASE ar;");
}else{
rc = arExecSql(pAr, "RELEASE ar;");
if( pAr->bZip && pAr->zFile ){
zSql = sqlite3_mprintf("DROP TABLE %s", zTemp);
arExecSql(pAr, zSql);
sqlite3_free(zSql);
}
}
return rc;
}
@@ -5274,20 +5366,17 @@ static int arDotCommand(
cmd.p = pState;
cmd.db = pState->db;
if( cmd.zFile ){
eDbType = deduceDatabaseType(cmd.zFile);
eDbType = deduceDatabaseType(cmd.zFile, 1);
}else{
eDbType = pState->openMode;
}
if( eDbType==SHELL_OPEN_ZIPFILE ){
if( cmd.zFile==0 ){
cmd.zSrcTable = sqlite3_mprintf("zip");
}else{
cmd.zSrcTable = sqlite3_mprintf("zipfile(%Q)", cmd.zFile);
}
if( cmd.eCmd==AR_CMD_CREATE || cmd.eCmd==AR_CMD_UPDATE ){
utf8_printf(stderr, "zip archives are read-only\n");
rc = SQLITE_ERROR;
goto end_ar_command;
if( cmd.eCmd==AR_CMD_EXTRACT || cmd.eCmd==AR_CMD_LIST ){
if( cmd.zFile==0 ){
cmd.zSrcTable = sqlite3_mprintf("zip");
}else{
cmd.zSrcTable = sqlite3_mprintf("zipfile(%Q)", cmd.zFile);
}
}
cmd.bZip = 1;
}else if( cmd.zFile ){
@@ -5312,14 +5401,12 @@ static int arDotCommand(
goto end_ar_command;
}
sqlite3_fileio_init(cmd.db, 0, 0);
#ifdef SQLITE_HAVE_ZLIB
sqlite3_sqlar_init(cmd.db, 0, 0);
#endif
sqlite3_create_function(cmd.db, "shell_putsnl", 1, SQLITE_UTF8, cmd.p,
shellPutsFunc, 0, 0);
}
if( cmd.zSrcTable==0 ){
if( cmd.zSrcTable==0 && cmd.bZip==0 ){
if( cmd.eCmd!=AR_CMD_CREATE
&& sqlite3_table_column_metadata(cmd.db,0,"sqlar","name",0,0,0,0,0)
){
@@ -5712,7 +5799,7 @@ static int do_meta_command(char *zLine, ShellState *p){
}else if( strcmp(azArg[1],"trigger")==0 ){
p->autoEQP = AUTOEQP_trigger;
}else{
p->autoEQP = booleanValue(azArg[1]);
p->autoEQP = (u8)booleanValue(azArg[1]);
}
}else{
raw_printf(stderr, "Usage: .eqp off|on|trigger|full\n");
@@ -5799,14 +5886,11 @@ static int do_meta_command(char *zLine, ShellState *p){
callback, &data, &zErrMsg);
data.cMode = data.mode = MODE_Insert;
data.zDestTable = "sqlite_stat1";
shell_exec(p->db, "SELECT * FROM sqlite_stat1",
shell_callback, &data,&zErrMsg);
shell_exec(p, "SELECT * FROM sqlite_stat1", &zErrMsg);
data.zDestTable = "sqlite_stat3";
shell_exec(p->db, "SELECT * FROM sqlite_stat3",
shell_callback, &data,&zErrMsg);
shell_exec(p, "SELECT * FROM sqlite_stat3", &zErrMsg);
data.zDestTable = "sqlite_stat4";
shell_exec(p->db, "SELECT * FROM sqlite_stat4",
shell_callback, &data, &zErrMsg);
shell_exec(p, "SELECT * FROM sqlite_stat4", &zErrMsg);
raw_printf(p->out, "ANALYZE sqlite_master;\n");
}
}else
@@ -6287,12 +6371,14 @@ static int do_meta_command(char *zLine, ShellState *p){
const char *z = azArg[iName];
if( optionMatch(z,"new") ){
newFlag = 1;
#ifdef SQLITE_HAVE_ZIP
#ifdef SQLITE_HAVE_ZLIB
}else if( optionMatch(z, "zip") ){
p->openMode = SHELL_OPEN_ZIPFILE;
#endif
}else if( optionMatch(z, "append") ){
p->openMode = SHELL_OPEN_APPENDVFS;
}else if( optionMatch(z, "readonly") ){
p->openMode = SHELL_OPEN_READONLY;
}else if( z[0]=='-' ){
utf8_printf(stderr, "unknown option: %s\n", z);
rc = 1;
@@ -6349,6 +6435,7 @@ static int do_meta_command(char *zLine, ShellState *p){
}
output_reset(p);
if( zFile[0]=='-' && zFile[1]=='-' ) zFile++;
#ifndef SQLITE_NOHAVE_SYSTEM
if( strcmp(zFile, "-e")==0 || strcmp(zFile, "-x")==0 ){
p->doXdgOpen = 1;
outputModePush(p);
@@ -6363,6 +6450,7 @@ static int do_meta_command(char *zLine, ShellState *p){
}
zFile = p->zTempFile;
}
#endif /* SQLITE_NOHAVE_SYSTEM */
if( zFile[0]=='|' ){
#ifdef SQLITE_OMIT_POPEN
raw_printf(stderr, "Error: pipes are not supported in this OS\n");
@@ -6482,10 +6570,9 @@ static int do_meta_command(char *zLine, ShellState *p){
sqlite3_close(pSrc);
}else
if( c=='s' && strncmp(azArg[0], "scanstats", n)==0 ){
if( nArg==2 ){
p->scanstatsOn = booleanValue(azArg[1]);
p->scanstatsOn = (u8)booleanValue(azArg[1]);
#ifndef SQLITE_ENABLE_STMT_SCANSTATUS
raw_printf(stderr, "Warning: .scanstats not available in this build.\n");
#endif
@@ -7073,11 +7160,12 @@ static int do_meta_command(char *zLine, ShellState *p){
if( bDebug ){
utf8_printf(p->out, "%s\n", zSql);
}else{
shell_exec(p->db, zSql, shell_callback, p, 0);
shell_exec(p, zSql, 0);
}
sqlite3_free(zSql);
}else
#ifndef SQLITE_NOHAVE_SYSTEM
if( c=='s'
&& (strncmp(azArg[0], "shell", n)==0 || strncmp(azArg[0],"system",n)==0)
){
@@ -7097,6 +7185,7 @@ static int do_meta_command(char *zLine, ShellState *p){
sqlite3_free(zCmd);
if( x ) raw_printf(stderr, "System command returns %d\n", x);
}else
#endif /* !defined(SQLITE_NOHAVE_SYSTEM) */
if( c=='s' && strncmp(azArg[0], "show", n)==0 ){
static const char *azBool[] = { "off", "on", "trigger", "full"};
@@ -7136,7 +7225,7 @@ static int do_meta_command(char *zLine, ShellState *p){
if( c=='s' && strncmp(azArg[0], "stats", n)==0 ){
if( nArg==2 ){
p->statsOn = booleanValue(azArg[1]);
p->statsOn = (u8)booleanValue(azArg[1]);
}else if( nArg==1 ){
display_stats(p->db, p, 0);
}else{
@@ -7537,6 +7626,20 @@ static int do_meta_command(char *zLine, ShellState *p){
if( c=='v' && strncmp(azArg[0], "version", n)==0 ){
utf8_printf(p->out, "SQLite %s %s\n" /*extra-version-info*/,
sqlite3_libversion(), sqlite3_sourceid());
#if SQLITE_HAVE_ZLIB
utf8_printf(p->out, "zlib version %s\n", zlibVersion());
#endif
#define CTIMEOPT_VAL_(opt) #opt
#define CTIMEOPT_VAL(opt) CTIMEOPT_VAL_(opt)
#if defined(__clang__) && defined(__clang_major__)
utf8_printf(p->out, "clang-" CTIMEOPT_VAL(__clang_major__) "."
CTIMEOPT_VAL(__clang_minor__) "."
CTIMEOPT_VAL(__clang_patchlevel__) "\n");
#elif defined(_MSC_VER)
utf8_printf(p->out, "msvc-" CTIMEOPT_VAL(_MSC_VER) "\n");
#elif defined(__GNUC__) && defined(__VERSION__)
utf8_printf(p->out, "gcc-" __VERSION__ "\n");
#endif
}else
if( c=='v' && strncmp(azArg[0], "vfsinfo", n)==0 ){
@@ -7662,6 +7765,16 @@ static int line_is_command_terminator(const char *zLine){
return 0;
}
/*
** We need a default sqlite3_complete() implementation to use in case
** the shell is compiled with SQLITE_OMIT_COMPLETE. The default assumes
** any arbitrary text is a complete SQL statement. This is not very
** user-friendly, but it does seem to work.
*/
#ifdef SQLITE_OMIT_COMPLETE
int sqlite3_complete(const char *zSql){ return 1; }
#endif
/*
** Return true if zSql is a complete SQL statement. Return false if it
** ends in the middle of a string literal or C-style comment.
@@ -7686,7 +7799,7 @@ static int runOneSqlLine(ShellState *p, char *zSql, FILE *in, int startline){
open_db(p, 0);
if( ShellHasFlag(p,SHFLG_Backslash) ) resolve_backslashes(zSql);
BEGIN_TIMER;
rc = shell_exec(p->db, zSql, shell_callback, p, &zErrMsg);
rc = shell_exec(p, zSql, &zErrMsg);
END_TIMER;
if( rc || zErrMsg ){
char zPrefix[100];
@@ -7918,6 +8031,10 @@ static void process_sqliterc(
** Show available command line options
*/
static const char zOptions[] =
#if defined(SQLITE_HAVE_ZLIB) && !defined(SQLITE_OMIT_VIRTUALTABLE)
" -A ARGS... run \".archive ARGS\" and exit\n"
#endif
" -append append the database to the end of the file\n"
" -ascii set output mode to 'ascii'\n"
" -bail stop after hitting an error\n"
" -batch force batch I/O\n"
@@ -7944,6 +8061,7 @@ static const char zOptions[] =
" -nullvalue TEXT set text string for NULL values. Default ''\n"
" -pagecache SIZE N use N slots of SZ bytes each for page cache memory\n"
" -quote set output mode to 'quote'\n"
" -readonly open the database read-only\n"
" -separator SEP set output column separator. Default: '|'\n"
" -stats print memory stats before each finalize\n"
" -version show SQLite version\n"
@@ -7951,6 +8069,9 @@ static const char zOptions[] =
#ifdef SQLITE_ENABLE_VFSTRACE
" -vfstrace enable tracing of all VFS calls\n"
#endif
#ifdef SQLITE_HAVE_ZLIB
" -zip open the file as a ZIP Archive\n"
#endif
;
static void usage(int showDetail){
utf8_printf(stderr,
@@ -8053,21 +8174,39 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
}
#endif
main_init(&data);
/* On Windows, we must translate command-line arguments into UTF-8.
** The SQLite memory allocator subsystem has to be enabled in order to
** do this. But we want to run an sqlite3_shutdown() afterwards so that
** subsequent sqlite3_config() calls will work. So copy all results into
** memory that does not come from the SQLite memory allocator.
*/
#if !SQLITE_SHELL_IS_UTF8
sqlite3_initialize();
argv = sqlite3_malloc64(sizeof(argv[0])*argc);
argv = malloc(sizeof(argv[0])*argc);
if( argv==0 ){
raw_printf(stderr, "out of memory\n");
exit(1);
}
for(i=0; i<argc; i++){
argv[i] = sqlite3_win32_unicode_to_utf8(wargv[i]);
char *z = sqlite3_win32_unicode_to_utf8(wargv[i]);
int n;
if( z==0 ){
raw_printf(stderr, "out of memory\n");
exit(1);
}
n = (int)strlen(z);
argv[i] = malloc( n+1 );
if( argv[i]==0 ){
raw_printf(stderr, "out of memory\n");
exit(1);
}
memcpy(argv[i], z, n+1);
sqlite3_free(z);
}
sqlite3_shutdown();
#endif
assert( argc>=1 && argv && argv[0] );
Argv0 = argv[0];
@@ -8187,12 +8326,20 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
utf8_printf(stderr, "no such VFS: \"%s\"\n", argv[i]);
exit(1);
}
#ifdef SQLITE_HAVE_ZIP
#ifdef SQLITE_HAVE_ZLIB
}else if( strcmp(z,"-zip")==0 ){
data.openMode = SHELL_OPEN_ZIPFILE;
#endif
}else if( strcmp(z,"-append")==0 ){
data.openMode = SHELL_OPEN_APPENDVFS;
}else if( strcmp(z,"-readonly")==0 ){
data.openMode = SHELL_OPEN_READONLY;
#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_HAVE_ZLIB)
}else if( strncmp(z, "-A",2)==0 ){
/* All remaining command-line arguments are passed to the ".archive"
** command, so ignore them */
break;
#endif
}
}
if( data.zDbFilename==0 ){
@@ -8246,7 +8393,7 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
}else if( strcmp(z,"-csv")==0 ){
data.mode = MODE_Csv;
memcpy(data.colSeparator,",",2);
#ifdef SQLITE_HAVE_ZIP
#ifdef SQLITE_HAVE_ZLIB
}else if( strcmp(z,"-zip")==0 ){
data.openMode = SHELL_OPEN_ZIPFILE;
#endif
@@ -8329,7 +8476,7 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
if( rc && bail_on_error ) return rc==2 ? 0 : rc;
}else{
open_db(&data, 0);
rc = shell_exec(data.db, z, shell_callback, &data, &zErrMsg);
rc = shell_exec(&data, z, &zErrMsg);
if( zErrMsg!=0 ){
utf8_printf(stderr,"Error: %s\n", zErrMsg);
if( bail_on_error ) return rc!=0 ? rc : 1;
@@ -8338,6 +8485,23 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
if( bail_on_error ) return rc;
}
}
#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_HAVE_ZLIB)
}else if( strncmp(z, "-A", 2)==0 ){
if( nCmd>0 ){
utf8_printf(stderr, "Error: cannot mix regular SQL or dot-commands"
" with \"%s\"\n", z);
return 1;
}
open_db(&data, 0);
if( z[2] ){
argv[i] = &z[2];
arDotCommand(&data, argv+(i-1), argc-(i-1));
}else{
arDotCommand(&data, argv+i, argc-i);
}
readStdin = 0;
break;
#endif
}else{
utf8_printf(stderr,"%s: Error: unknown option: %s\n", Argv0, z);
raw_printf(stderr,"Use -help for a list of options.\n");
@@ -8357,7 +8521,7 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
if( rc ) return rc==2 ? 0 : rc;
}else{
open_db(&data, 0);
rc = shell_exec(data.db, azCmd[i], shell_callback, &data, &zErrMsg);
rc = shell_exec(&data, azCmd[i], &zErrMsg);
if( zErrMsg!=0 ){
utf8_printf(stderr,"Error: %s\n", zErrMsg);
return rc!=0 ? rc : 1;
@@ -8420,8 +8584,8 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
data.doXdgOpen = 0;
clearTempFile(&data);
#if !SQLITE_SHELL_IS_UTF8
for(i=0; i<argc; i++) sqlite3_free(argv[i]);
sqlite3_free(argv);
for(i=0; i<argc; i++) free(argv[i]);
free(argv);
#endif
return rc;
}
+167 -76
View File
@@ -510,7 +510,6 @@ int sqlite3_exec(
#define SQLITE_CANTOPEN_ISDIR (SQLITE_CANTOPEN | (2<<8))
#define SQLITE_CANTOPEN_FULLPATH (SQLITE_CANTOPEN | (3<<8))
#define SQLITE_CANTOPEN_CONVPATH (SQLITE_CANTOPEN | (4<<8))
#define SQLITE_CANTOPEN_DIRTYWAL (SQLITE_CANTOPEN | (5<<8))
#define SQLITE_CORRUPT_VTAB (SQLITE_CORRUPT | (1<<8))
#define SQLITE_READONLY_RECOVERY (SQLITE_READONLY | (1<<8))
#define SQLITE_READONLY_CANTLOCK (SQLITE_READONLY | (2<<8))
@@ -2497,16 +2496,16 @@ void sqlite3_free_table(char **result);
**
** These routines are work-alikes of the "printf()" family of functions
** from the standard C library.
** These routines understand most of the common K&R formatting options,
** plus some additional non-standard formats, detailed below.
** Note that some of the more obscure formatting options from recent
** C-library standards are omitted from this implementation.
** These routines understand most of the common formatting options from
** the standard library printf()
** plus some additional non-standard formats ([%q], [%Q], [%w], and [%z]).
** See the [built-in printf()] documentation for details.
**
** ^The sqlite3_mprintf() and sqlite3_vmprintf() routines write their
** results into memory obtained from [sqlite3_malloc()].
** results into memory obtained from [sqlite3_malloc64()].
** The strings returned by these two routines should be
** released by [sqlite3_free()]. ^Both routines return a
** NULL pointer if [sqlite3_malloc()] is unable to allocate enough
** NULL pointer if [sqlite3_malloc64()] is unable to allocate enough
** memory to hold the resulting string.
**
** ^(The sqlite3_snprintf() routine is similar to "snprintf()" from
@@ -2530,71 +2529,7 @@ void sqlite3_free_table(char **result);
**
** ^The sqlite3_vsnprintf() routine is a varargs version of sqlite3_snprintf().
**
** These routines all implement some additional formatting
** options that are useful for constructing SQL statements.
** All of the usual printf() formatting options apply. In addition, there
** is are "%q", "%Q", "%w" and "%z" options.
**
** ^(The %q option works like %s in that it substitutes a nul-terminated
** string from the argument list. But %q also doubles every '\'' character.
** %q is designed for use inside a string literal.)^ By doubling each '\''
** character it escapes that character and allows it to be inserted into
** the string.
**
** For example, assume the string variable zText contains text as follows:
**
** <blockquote><pre>
** char *zText = "It's a happy day!";
** </pre></blockquote>
**
** One can use this text in an SQL statement as follows:
**
** <blockquote><pre>
** char *zSQL = sqlite3_mprintf("INSERT INTO table VALUES('%q')", zText);
** sqlite3_exec(db, zSQL, 0, 0, 0);
** sqlite3_free(zSQL);
** </pre></blockquote>
**
** Because the %q format string is used, the '\'' character in zText
** is escaped and the SQL generated is as follows:
**
** <blockquote><pre>
** INSERT INTO table1 VALUES('It''s a happy day!')
** </pre></blockquote>
**
** This is correct. Had we used %s instead of %q, the generated SQL
** would have looked like this:
**
** <blockquote><pre>
** INSERT INTO table1 VALUES('It's a happy day!');
** </pre></blockquote>
**
** This second example is an SQL syntax error. As a general rule you should
** always use %q instead of %s when inserting text into a string literal.
**
** ^(The %Q option works like %q except it also adds single quotes around
** the outside of the total string. Additionally, if the parameter in the
** argument list is a NULL pointer, %Q substitutes the text "NULL" (without
** single quotes).)^ So, for example, one could say:
**
** <blockquote><pre>
** char *zSQL = sqlite3_mprintf("INSERT INTO table VALUES(%Q)", zText);
** sqlite3_exec(db, zSQL, 0, 0, 0);
** sqlite3_free(zSQL);
** </pre></blockquote>
**
** The code above will render a correct SQL statement in the zSQL
** variable even if the zText variable is a NULL pointer.
**
** ^(The "%w" formatting option is like "%q" except that it expects to
** be contained within double-quotes instead of single quotes, and it
** escapes the double-quote character instead of the single-quote
** character.)^ The "%w" formatting option is intended for safely inserting
** table and column names into a constructed SQL statement.
**
** ^(The "%z" formatting option works like "%s" but with the
** addition that after the string has been read and copied into
** the result, [sqlite3_free()] is called on the input string.)^
** See also: [built-in printf()], [printf() SQL function]
*/
char *sqlite3_mprintf(const char*,...);
char *sqlite3_vmprintf(const char*, va_list);
@@ -2952,8 +2887,8 @@ SQLITE_DEPRECATED void *sqlite3_profile(sqlite3*,
** KEYWORDS: SQLITE_TRACE
**
** These constants identify classes of events that can be monitored
** using the [sqlite3_trace_v2()] tracing logic. The third argument
** to [sqlite3_trace_v2()] is an OR-ed combination of one or more of
** using the [sqlite3_trace_v2()] tracing logic. The M argument
** to [sqlite3_trace_v2(D,M,X,P)] is an OR-ed combination of one or more of
** the following constants. ^The first argument to the trace callback
** is one of the following constants.
**
@@ -3660,13 +3595,13 @@ int sqlite3_limit(sqlite3*, int id, int newVal);
** or [GLOB] operator or if the parameter is compared to an indexed column
** and the [SQLITE_ENABLE_STAT3] compile-time option is enabled.
** </li>
** </ol>
**
** <p>^sqlite3_prepare_v3() differs from sqlite3_prepare_v2() only in having
** the extra prepFlags parameter, which is a bit array consisting of zero or
** more of the [SQLITE_PREPARE_PERSISTENT|SQLITE_PREPARE_*] flags. ^The
** sqlite3_prepare_v2() interface works exactly the same as
** sqlite3_prepare_v3() with a zero prepFlags parameter.
** </ol>
*/
int sqlite3_prepare(
sqlite3 *db, /* Database handle */
@@ -4799,6 +4734,9 @@ SQLITE_DEPRECATED int sqlite3_memory_alarm(void(*)(void*,sqlite3_int64,int),
** datatype of the value
** <tr><td><b>sqlite3_value_numeric_type&nbsp;&nbsp;</b>
** <td>&rarr;&nbsp;&nbsp;<td>Best numeric datatype of the value
** <tr><td><b>sqlite3_value_nochange&nbsp;&nbsp;</b>
** <td>&rarr;&nbsp;&nbsp;<td>True if the column is unchanged in an UPDATE
** against a virtual table.
** </table></blockquote>
**
** <b>Details:</b>
@@ -4847,6 +4785,19 @@ SQLITE_DEPRECATED int sqlite3_memory_alarm(void(*)(void*,sqlite3_int64,int),
** then the conversion is performed. Otherwise no conversion occurs.
** The [SQLITE_INTEGER | datatype] after conversion is returned.)^
**
** ^Within the [xUpdate] method of a [virtual table], the
** sqlite3_value_nochange(X) interface returns true if and only if
** the column corresponding to X is unchanged by the UPDATE operation
** that the xUpdate method call was invoked to implement and if
** and the prior [xColumn] method call that was invoked to extracted
** the value for that column returned without setting a result (probably
** because it queried [sqlite3_vtab_nochange()] and found that the column
** was unchanging). ^Within an [xUpdate] method, any value for which
** sqlite3_value_nochange(X) is true will in all other respects appear
** to be a NULL value. If sqlite3_value_nochange(X) is invoked anywhere other
** than within an [xUpdate] method call for an UPDATE statement, then
** the return value is arbitrary and meaningless.
**
** Please pay particular attention to the fact that the pointer returned
** from [sqlite3_value_blob()], [sqlite3_value_text()], or
** [sqlite3_value_text16()] can be invalidated by a subsequent call to
@@ -4869,6 +4820,7 @@ int sqlite3_value_bytes(sqlite3_value*);
int sqlite3_value_bytes16(sqlite3_value*);
int sqlite3_value_type(sqlite3_value*);
int sqlite3_value_numeric_type(sqlite3_value*);
int sqlite3_value_nochange(sqlite3_value*);
/*
** CAPI3REF: Finding The Subtype Of SQL Values
@@ -7278,6 +7230,15 @@ int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int resetFlg);
** highwater mark associated with SQLITE_DBSTATUS_CACHE_WRITE is always 0.
** </dd>
**
** [[SQLITE_DBSTATUS_CACHE_SPILL]] ^(<dt>SQLITE_DBSTATUS_CACHE_SPILL</dt>
** <dd>This parameter returns the number of dirty cache entries that have
** been written to disk in the middle of a transaction due to the page
** cache overflowing. Transactions are more efficient if they are written
** to disk all at once. When pages spill mid-transaction, that introduces
** additional overhead. This parameter can be used help identify
** inefficiencies that can be resolve by increasing the cache size.
** </dd>
**
** [[SQLITE_DBSTATUS_DEFERRED_FKS]] ^(<dt>SQLITE_DBSTATUS_DEFERRED_FKS</dt>
** <dd>This parameter returns zero for the current value if and only if
** all foreign key constraints (deferred or immediate) have been
@@ -7297,7 +7258,8 @@ int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int resetFlg);
#define SQLITE_DBSTATUS_CACHE_WRITE 9
#define SQLITE_DBSTATUS_DEFERRED_FKS 10
#define SQLITE_DBSTATUS_CACHE_USED_SHARED 11
#define SQLITE_DBSTATUS_MAX 11 /* Largest defined DBSTATUS */
#define SQLITE_DBSTATUS_CACHE_SPILL 12
#define SQLITE_DBSTATUS_MAX 12 /* Largest defined DBSTATUS */
/*
@@ -8306,6 +8268,13 @@ int sqlite3_vtab_on_conflict(sqlite3 *);
** column value will not change. Applications might use this to substitute
** a lighter-weight value to return that the corresponding [xUpdate] method
** understands as a "no-change" value.
**
** If the [xColumn] method calls sqlite3_vtab_nochange() and finds that
** the column is not changed by the UPDATE statement, they the xColumn
** method can optionally return without setting a result, without calling
** any of the [sqlite3_result_int|sqlite3_result_xxxxx() interfaces].
** In that case, [sqlite3_value_nochange(X)] will return true for the
** same column in the [xUpdate] method.
*/
int sqlite3_vtab_nochange(sqlite3_context*);
@@ -8770,6 +8739,128 @@ SQLITE_EXPERIMENTAL int sqlite3_snapshot_cmp(
*/
SQLITE_EXPERIMENTAL int sqlite3_snapshot_recover(sqlite3 *db, const char *zDb);
/*
** CAPI3REF: Serialize a database
**
** The sqlite3_serialize(D,S,P,F) interface returns a pointer to memory
** that is a serialization of the S database on [database connection] D.
** If P is not a NULL pointer, then the size of the database in bytes
** is written into *P.
**
** For an ordinary on-disk database file, the serialization is just a
** copy of the disk file. For an in-memory database or a "TEMP" database,
** the serialization is the same sequence of bytes which would be written
** to disk if that database where backed up to disk.
**
** The usual case is that sqlite3_serialize() copies the serialization of
** the database into memory obtained from [sqlite3_malloc64()] and returns
** a pointer to that memory. The caller is responsible for freeing the
** returned value to avoid a memory leak. However, if the F argument
** contains the SQLITE_SERIALIZE_NOCOPY bit, then no memory allocations
** are made, and the sqlite3_serialize() function will return a pointer
** to the contiguous memory representation of the database that SQLite
** is currently using for that database, or NULL if the no such contiguous
** memory representation of the database exists. A contiguous memory
** representation of the database will usually only exist if there has
** been a prior call to [sqlite3_deserialize(D,S,...)] with the same
** values of D and S.
** The size of the database is written into *P even if the
** SQLITE_SERIALIZE_NOCOPY bit is set but no contigious copy
** of the database exists.
**
** A call to sqlite3_serialize(D,S,P,F) might return NULL even if the
** SQLITE_SERIALIZE_NOCOPY bit is omitted from argument F if a memory
** allocation error occurs.
**
** This interface is only available if SQLite is compiled with the
** [SQLITE_ENABLE_DESERIALIZE] option.
*/
unsigned char *sqlite3_serialize(
sqlite3 *db, /* The database connection */
const char *zSchema, /* Which DB to serialize. ex: "main", "temp", ... */
sqlite3_int64 *piSize, /* Write size of the DB here, if not NULL */
unsigned int mFlags /* Zero or more SQLITE_SERIALIZE_* flags */
);
/*
** CAPI3REF: Flags for sqlite3_serialize
**
** Zero or more of the following constants can be OR-ed together for
** the F argument to [sqlite3_serialize(D,S,P,F)].
**
** SQLITE_SERIALIZE_NOCOPY means that [sqlite3_serialize()] will return
** a pointer to contiguous in-memory database that it is currently using,
** without making a copy of the database. If SQLite is not currently using
** a contiguous in-memory database, then this option causes
** [sqlite3_serialize()] to return a NULL pointer. SQLite will only be
** using a contiguous in-memory database if it has been initialized by a
** prior call to [sqlite3_deserialize()].
*/
#define SQLITE_SERIALIZE_NOCOPY 0x001 /* Do no memory allocations */
/*
** CAPI3REF: Deserialize a database
**
** The sqlite3_deserialize(D,S,P,N,M,F) interface causes the
** [database connection] D to disconnection from database S and then
** reopen S as an in-memory database based on the serialization contained
** in P. The serialized database P is N bytes in size. M is the size of
** the buffer P, which might be larger than N. If M is larger than N, and
** the SQLITE_DESERIALIZE_READONLY bit is not set in F, then SQLite is
** permitted to add content to the in-memory database as long as the total
** size does not exceed M bytes.
**
** If the SQLITE_DESERIALIZE_FREEONCLOSE bit is set in F, then SQLite will
** invoke sqlite3_free() on the serialization buffer when the database
** connection closes. If the SQLITE_DESERIALIZE_RESIZEABLE bit is set, then
** SQLite will try to increase the buffer size using sqlite3_realloc64()
** if writes on the database cause it to grow larger than M bytes.
**
** The sqlite3_deserialize() interface will fail with SQLITE_BUSY if the
** database is currently in a read transaction or is involved in a backup
** operation.
**
** If sqlite3_deserialize(D,S,P,N,M,F) fails for any reason and if the
** SQLITE_DESERIALIZE_FREEONCLOSE bit is set in argument F, then
** [sqlite3_free()] is invoked on argument P prior to returning.
**
** This interface is only available if SQLite is compiled with the
** [SQLITE_ENABLE_DESERIALIZE] option.
*/
int sqlite3_deserialize(
sqlite3 *db, /* The database connection */
const char *zSchema, /* Which DB to reopen with the deserialization */
unsigned char *pData, /* The serialized database content */
sqlite3_int64 szDb, /* Number bytes in the deserialization */
sqlite3_int64 szBuf, /* Total size of buffer pData[] */
unsigned mFlags /* Zero or more SQLITE_DESERIALIZE_* flags */
);
/*
** CAPI3REF: Flags for sqlite3_deserialize()
**
** The following are allowed values for 6th argument (the F argument) to
** the [sqlite3_deserialize(D,S,P,N,M,F)] interface.
**
** The SQLITE_DESERIALIZE_FREEONCLOSE means that the database serialization
** in the P argument is held in memory obtained from [sqlite3_malloc64()]
** and that SQLite should take ownership of this memory and automatically
** free it when it has finished using it. Without this flag, the caller
** is resposible for freeing any dynamically allocated memory.
**
** The SQLITE_DESERIALIZE_RESIZEABLE flag means that SQLite is allowed to
** grow the size of the database using calls to [sqlite3_realloc64()]. This
** flag should only be used if SQLITE_DESERIALIZE_FREEONCLOSE is also used.
** Without this flag, the deserialized database cannot increase in size beyond
** the number of bytes specified by the M parameter.
**
** The SQLITE_DESERIALIZE_READONLY flag means that the deserialized database
** should be treated as read-only.
*/
#define SQLITE_DESERIALIZE_FREEONCLOSE 1 /* Call sqlite3_free() on close */
#define SQLITE_DESERIALIZE_RESIZEABLE 2 /* Resize using sqlite3_realloc64() */
#define SQLITE_DESERIALIZE_READONLY 4 /* Database is read-only */
/*
** Undo the hack that converts floating point types to integer for
** builds on processors without floating point support.
+7
View File
@@ -292,6 +292,9 @@ struct sqlite3_api_routines {
int (*bind_pointer)(sqlite3_stmt*,int,void*,const char*,void(*)(void*));
void (*result_pointer)(sqlite3_context*,void*,const char*,void(*)(void*));
void *(*value_pointer)(sqlite3_value*,const char*);
int (*vtab_nochange)(sqlite3_context*);
int (*value_nochange)(sqlite3_value*);
const char *(*vtab_collation)(sqlite3_index_info*,int);
};
/*
@@ -558,6 +561,10 @@ typedef int (*sqlite3_loadext_entry)(
#define sqlite3_bind_pointer sqlite3_api->bind_pointer
#define sqlite3_result_pointer sqlite3_api->result_pointer
#define sqlite3_value_pointer sqlite3_api->value_pointer
/* Version 3.22.0 and later */
#define sqlite3_vtab_nochange sqlite3_api->vtab_nochange
#define sqlite3_value_nochange sqlite3_api->value_nochange
#define sqlite3_vtab_collation sqlite3_api->vtab_collation
#endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */
#if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
+14 -2
View File
@@ -1365,8 +1365,9 @@ struct sqlite3 {
int newTnum; /* Rootpage of table being initialized */
u8 iDb; /* Which db file is being initialized */
u8 busy; /* TRUE if currently initializing */
u8 orphanTrigger; /* Last statement is orphaned TEMP trigger */
u8 imposterTable; /* Building an imposter table */
unsigned orphanTrigger : 1; /* Last statement is orphaned TEMP trigger */
unsigned imposterTable : 1; /* Building an imposter table */
unsigned reopenMemdb : 1; /* ATTACH is really a reopen using MemDB */
} init;
int nVdbeActive; /* Number of VDBEs currently running */
int nVdbeRead; /* Number of active VDBEs that read or write */
@@ -1754,6 +1755,7 @@ struct Column {
#define COLFLAG_PRIMKEY 0x0001 /* Column is part of the primary key */
#define COLFLAG_HIDDEN 0x0002 /* A hidden column in a virtual table */
#define COLFLAG_HASTYPE 0x0004 /* Type name follows column name */
#define COLFLAG_UNIQUE 0x0008 /* Column def contains "UNIQUE" or "PK" */
/*
** A "Collating Sequence" is defined by an instance of the following
@@ -3117,6 +3119,7 @@ struct AuthContext {
#define OPFLAG_PERMUTE 0x01 /* OP_Compare: use the permutation */
#define OPFLAG_SAVEPOSITION 0x02 /* OP_Delete/Insert: save cursor pos */
#define OPFLAG_AUXDELETE 0x04 /* OP_Delete: index in a DELETE op */
#define OPFLAG_NOCHNG_MAGIC 0x6d /* OP_MakeRecord: serialtype 10 is ok */
/*
* Each trigger present in the database schema is stored as an instance of
@@ -3837,6 +3840,8 @@ void sqlite3EndTransaction(Parse*,int);
void sqlite3Savepoint(Parse*, int, Token*);
void sqlite3CloseSavepoints(sqlite3 *);
void sqlite3LeaveMutexAndCloseZombie(sqlite3*);
int sqlite3ExprIdToTrueFalse(Expr*);
int sqlite3ExprTruthValue(const Expr*);
int sqlite3ExprIsConstant(Expr*);
int sqlite3ExprIsConstantNotJoin(Expr*);
int sqlite3ExprIsConstantOrFunction(Expr*, u8);
@@ -4019,6 +4024,10 @@ int sqlite3TwoPartName(Parse *, Token *, Token *, Token **);
const char *sqlite3ErrName(int);
#endif
#ifdef SQLITE_ENABLE_DESERIALIZE
int sqlite3MemdbInit(void);
#endif
const char *sqlite3ErrStr(int);
int sqlite3ReadSchema(Parse *pParse);
CollSeq *sqlite3FindCollSeq(sqlite3*,u8 enc, const char*,int);
@@ -4067,6 +4076,9 @@ extern FuncDefHash sqlite3BuiltinFunctions;
extern int sqlite3PendingByte;
#endif
#endif
#ifdef VDBE_PROFILE
extern sqlite3_uint64 sqlite3NProfileCnt;
#endif
void sqlite3RootPageMoved(sqlite3*, int, int, int);
void sqlite3Reindex(Parse*, Token*, Token*);
void sqlite3AlterFunctions(void);
+3
View File
@@ -337,6 +337,9 @@ int sqlite3_db_status(
** pagers the database handle is connected to. *pHighwater is always set
** to zero.
*/
case SQLITE_DBSTATUS_CACHE_SPILL:
op = SQLITE_DBSTATUS_CACHE_WRITE+1;
/* Fall through into the next case */
case SQLITE_DBSTATUS_CACHE_HIT:
case SQLITE_DBSTATUS_CACHE_MISS:
case SQLITE_DBSTATUS_CACHE_WRITE:{
+148 -50
View File
@@ -64,7 +64,9 @@
# define GETPID getpid
#elif !defined(_WIN32_WCE)
# ifndef SQLITE_AMALGAMATION
# define WIN32_LEAN_AND_MEAN
# ifndef WIN32_LEAN_AND_MEAN
# define WIN32_LEAN_AND_MEAN
# endif
# include <windows.h>
# endif
# define GETPID (int)GetCurrentProcessId
@@ -646,7 +648,7 @@ static int DbTraceV2Handler(
}
case SQLITE_TRACE_PROFILE: {
sqlite3_stmt *pStmt = (sqlite3_stmt *)pd;
sqlite3_int64 ns = (sqlite3_int64)xd;
sqlite3_int64 ns = *(sqlite3_int64*)xd;
pCmd = Tcl_NewStringObj(pDb->zTraceV2, -1);
Tcl_IncrRefCount(pCmd);
@@ -1846,35 +1848,35 @@ static int SQLITE_TCLAPI DbObjCmd(
int choice;
int rc = TCL_OK;
static const char *DB_strs[] = {
"authorizer", "backup", "busy",
"cache", "changes", "close",
"collate", "collation_needed", "commit_hook",
"complete", "copy", "enable_load_extension",
"errorcode", "eval", "exists",
"function", "incrblob", "interrupt",
"last_insert_rowid", "nullvalue", "onecolumn",
"preupdate", "profile", "progress",
"rekey", "restore", "rollback_hook",
"status", "timeout", "total_changes",
"trace", "trace_v2", "transaction",
"unlock_notify", "update_hook", "version",
"wal_hook",
0
"authorizer", "backup", "busy",
"cache", "changes", "close",
"collate", "collation_needed", "commit_hook",
"complete", "copy", "deserialize",
"enable_load_extension", "errorcode", "eval",
"exists", "function", "incrblob",
"interrupt", "last_insert_rowid", "nullvalue",
"onecolumn", "preupdate", "profile",
"progress", "rekey", "restore",
"rollback_hook", "serialize", "status",
"timeout", "total_changes", "trace",
"trace_v2", "transaction", "unlock_notify",
"update_hook", "version", "wal_hook",
0
};
enum DB_enum {
DB_AUTHORIZER, DB_BACKUP, DB_BUSY,
DB_CACHE, DB_CHANGES, DB_CLOSE,
DB_COLLATE, DB_COLLATION_NEEDED, DB_COMMIT_HOOK,
DB_COMPLETE, DB_COPY, DB_ENABLE_LOAD_EXTENSION,
DB_ERRORCODE, DB_EVAL, DB_EXISTS,
DB_FUNCTION, DB_INCRBLOB, DB_INTERRUPT,
DB_LAST_INSERT_ROWID, DB_NULLVALUE, DB_ONECOLUMN,
DB_PREUPDATE, DB_PROFILE, DB_PROGRESS,
DB_REKEY, DB_RESTORE, DB_ROLLBACK_HOOK,
DB_STATUS, DB_TIMEOUT, DB_TOTAL_CHANGES,
DB_TRACE, DB_TRACE_V2, DB_TRANSACTION,
DB_UNLOCK_NOTIFY, DB_UPDATE_HOOK, DB_VERSION,
DB_WAL_HOOK,
DB_AUTHORIZER, DB_BACKUP, DB_BUSY,
DB_CACHE, DB_CHANGES, DB_CLOSE,
DB_COLLATE, DB_COLLATION_NEEDED, DB_COMMIT_HOOK,
DB_COMPLETE, DB_COPY, DB_DESERIALIZE,
DB_ENABLE_LOAD_EXTENSION, DB_ERRORCODE, DB_EVAL,
DB_EXISTS, DB_FUNCTION, DB_INCRBLOB,
DB_INTERRUPT, DB_LAST_INSERT_ROWID, DB_NULLVALUE,
DB_ONECOLUMN, DB_PREUPDATE, DB_PROFILE,
DB_PROGRESS, DB_REKEY, DB_RESTORE,
DB_ROLLBACK_HOOK, DB_SERIALIZE, DB_STATUS,
DB_TIMEOUT, DB_TOTAL_CHANGES, DB_TRACE,
DB_TRACE_V2, DB_TRANSACTION, DB_UNLOCK_NOTIFY,
DB_UPDATE_HOOK, DB_VERSION, DB_WAL_HOOK
};
/* don't leave trailing commas on DB_enum, it confuses the AIX xlc compiler */
@@ -2412,6 +2414,53 @@ static int SQLITE_TCLAPI DbObjCmd(
break;
}
/*
** $db deserialize ?DATABASE? VALUE
**
** Reopen DATABASE (default "main") using the content in $VALUE
*/
case DB_DESERIALIZE: {
#ifndef SQLITE_ENABLE_DESERIALIZE
Tcl_AppendResult(interp, "MEMDB not available in this build",
(char*)0);
rc = TCL_ERROR;
#else
const char *zSchema;
Tcl_Obj *pValue;
unsigned char *pBA;
unsigned char *pData;
int len, xrc;
if( objc==3 ){
zSchema = 0;
pValue = objv[2];
}else if( objc==4 ){
zSchema = Tcl_GetString(objv[2]);
pValue = objv[3];
}else{
Tcl_WrongNumArgs(interp, 2, objv, "?DATABASE? VALUE");
rc = TCL_ERROR;
break;
}
pBA = Tcl_GetByteArrayFromObj(pValue, &len);
pData = sqlite3_malloc64( len );
if( pData==0 && len>0 ){
Tcl_AppendResult(interp, "out of memory", (char*)0);
rc = TCL_ERROR;
}else{
if( len>0 ) memcpy(pData, pBA, len);
xrc = sqlite3_deserialize(pDb->db, zSchema, pData, len, len,
SQLITE_DESERIALIZE_FREEONCLOSE |
SQLITE_DESERIALIZE_RESIZEABLE);
if( xrc ){
Tcl_AppendResult(interp, "unable to set MEMDB content", (char*)0);
rc = TCL_ERROR;
}
}
#endif
break;
}
/*
** $db enable_load_extension BOOLEAN
**
@@ -2887,6 +2936,39 @@ static int SQLITE_TCLAPI DbObjCmd(
break;
}
/*
** $db serialize ?DATABASE?
**
** Return a serialization of a database.
*/
case DB_SERIALIZE: {
#ifndef SQLITE_ENABLE_DESERIALIZE
Tcl_AppendResult(interp, "MEMDB not available in this build",
(char*)0);
rc = TCL_ERROR;
#else
const char *zSchema = objc>=3 ? Tcl_GetString(objv[2]) : "main";
sqlite3_int64 sz = 0;
unsigned char *pData;
if( objc!=2 && objc!=3 ){
Tcl_WrongNumArgs(interp, 2, objv, "?DATABASE?");
rc = TCL_ERROR;
}else{
int needFree;
pData = sqlite3_serialize(pDb->db, zSchema, &sz, SQLITE_SERIALIZE_NOCOPY);
if( pData ){
needFree = 0;
}else{
pData = sqlite3_serialize(pDb->db, zSchema, &sz, 0);
needFree = 1;
}
Tcl_SetObjResult(interp, Tcl_NewByteArrayObj(pData,sz));
if( needFree ) sqlite3_free(pData);
}
#endif
break;
}
/*
** $db status (step|sort|autoindex|vmstep)
**
@@ -3347,6 +3429,24 @@ static int SQLITE_TCLAPI DbObjCmdAdaptor(
}
#endif /* SQLITE_TCL_NRE */
/*
** Issue the usage message when the "sqlite3" command arguments are
** incorrect.
*/
static int sqliteCmdUsage(
Tcl_Interp *interp,
Tcl_Obj *const*objv
){
Tcl_WrongNumArgs(interp, 1, objv,
"HANDLE ?FILENAME? ?-vfs VFSNAME? ?-readonly BOOLEAN? ?-create BOOLEAN?"
" ?-nomutex BOOLEAN? ?-fullmutex BOOLEAN? ?-uri BOOLEAN?"
#if defined(SQLITE_HAS_CODEC) && !defined(SQLITE_OMIT_CODEC_FROM_TCL)
" ?-key CODECKEY?"
#endif
);
return TCL_ERROR;
}
/*
** sqlite3 DBNAME FILENAME ?-vfs VFSNAME? ?-key KEY? ?-readonly BOOLEAN?
** ?-create BOOLEAN? ?-nomutex BOOLEAN?
@@ -3372,7 +3472,7 @@ static int SQLITE_TCLAPI DbMain(
const char *zArg;
char *zErrMsg;
int i;
const char *zFile;
const char *zFile = 0;
const char *zVfs = 0;
int flags;
Tcl_DString translatedFilename;
@@ -3383,7 +3483,7 @@ static int SQLITE_TCLAPI DbMain(
int rc;
/* In normal use, each TCL interpreter runs in a single thread. So
** by default, we can turn of mutexing on SQLite database connections.
** by default, we can turn off mutexing on SQLite database connections.
** However, for testing purposes it is useful to have mutexes turned
** on. So, by default, mutexes default off. But if compiled with
** SQLITE_TCL_DEFAULT_FULLMUTEX then mutexes default on.
@@ -3412,18 +3512,26 @@ static int SQLITE_TCLAPI DbMain(
#endif
return TCL_OK;
}
if( zArg[0]=='-' ) return sqliteCmdUsage(interp, objv);
}
for(i=3; i+1<objc; i+=2){
for(i=2; i<objc; i++){
zArg = Tcl_GetString(objv[i]);
if( zArg[0]!='-' ){
if( zFile!=0 ) return sqliteCmdUsage(interp, objv);
zFile = zArg;
continue;
}
if( i==objc-1 ) return sqliteCmdUsage(interp, objv);
i++;
if( strcmp(zArg,"-key")==0 ){
#if defined(SQLITE_HAS_CODEC) && !defined(SQLITE_OMIT_CODEC_FROM_TCL)
pKey = Tcl_GetByteArrayFromObj(objv[i+1], &nKey);
pKey = Tcl_GetByteArrayFromObj(objv[i], &nKey);
#endif
}else if( strcmp(zArg, "-vfs")==0 ){
zVfs = Tcl_GetString(objv[i+1]);
zVfs = Tcl_GetString(objv[i]);
}else if( strcmp(zArg, "-readonly")==0 ){
int b;
if( Tcl_GetBooleanFromObj(interp, objv[i+1], &b) ) return TCL_ERROR;
if( Tcl_GetBooleanFromObj(interp, objv[i], &b) ) return TCL_ERROR;
if( b ){
flags &= ~(SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE);
flags |= SQLITE_OPEN_READONLY;
@@ -3433,7 +3541,7 @@ static int SQLITE_TCLAPI DbMain(
}
}else if( strcmp(zArg, "-create")==0 ){
int b;
if( Tcl_GetBooleanFromObj(interp, objv[i+1], &b) ) return TCL_ERROR;
if( Tcl_GetBooleanFromObj(interp, objv[i], &b) ) return TCL_ERROR;
if( b && (flags & SQLITE_OPEN_READONLY)==0 ){
flags |= SQLITE_OPEN_CREATE;
}else{
@@ -3441,7 +3549,7 @@ static int SQLITE_TCLAPI DbMain(
}
}else if( strcmp(zArg, "-nomutex")==0 ){
int b;
if( Tcl_GetBooleanFromObj(interp, objv[i+1], &b) ) return TCL_ERROR;
if( Tcl_GetBooleanFromObj(interp, objv[i], &b) ) return TCL_ERROR;
if( b ){
flags |= SQLITE_OPEN_NOMUTEX;
flags &= ~SQLITE_OPEN_FULLMUTEX;
@@ -3450,7 +3558,7 @@ static int SQLITE_TCLAPI DbMain(
}
}else if( strcmp(zArg, "-fullmutex")==0 ){
int b;
if( Tcl_GetBooleanFromObj(interp, objv[i+1], &b) ) return TCL_ERROR;
if( Tcl_GetBooleanFromObj(interp, objv[i], &b) ) return TCL_ERROR;
if( b ){
flags |= SQLITE_OPEN_FULLMUTEX;
flags &= ~SQLITE_OPEN_NOMUTEX;
@@ -3459,7 +3567,7 @@ static int SQLITE_TCLAPI DbMain(
}
}else if( strcmp(zArg, "-uri")==0 ){
int b;
if( Tcl_GetBooleanFromObj(interp, objv[i+1], &b) ) return TCL_ERROR;
if( Tcl_GetBooleanFromObj(interp, objv[i], &b) ) return TCL_ERROR;
if( b ){
flags |= SQLITE_OPEN_URI;
}else{
@@ -3470,20 +3578,10 @@ static int SQLITE_TCLAPI DbMain(
return TCL_ERROR;
}
}
if( objc<3 || (objc&1)!=1 ){
Tcl_WrongNumArgs(interp, 1, objv,
"HANDLE FILENAME ?-vfs VFSNAME? ?-readonly BOOLEAN? ?-create BOOLEAN?"
" ?-nomutex BOOLEAN? ?-fullmutex BOOLEAN? ?-uri BOOLEAN?"
#if defined(SQLITE_HAS_CODEC) && !defined(SQLITE_OMIT_CODEC_FROM_TCL)
" ?-key CODECKEY?"
#endif
);
return TCL_ERROR;
}
zErrMsg = 0;
p = (SqliteDb*)Tcl_Alloc( sizeof(*p) );
memset(p, 0, sizeof(*p));
zFile = Tcl_GetStringFromObj(objv[2], 0);
if( zFile==0 ) zFile = "";
zFile = Tcl_TranslateFileName(interp, zFile, &translatedFilename);
rc = sqlite3_open_v2(zFile, &p->db, flags, zVfs);
Tcl_DStringFree(&translatedFilename);
+30
View File
@@ -4559,6 +4559,35 @@ static int SQLITE_TCLAPI test_complete16(
return TCL_OK;
}
/*
** Usage: sqlite3_normalize SQL
**
** Return the normalized value for an SQL statement.
*/
static int SQLITE_TCLAPI test_normalize(
void * clientData,
Tcl_Interp *interp,
int objc,
Tcl_Obj *CONST objv[]
){
char *zSql;
char *zNorm;
extern char *sqlite3_normalize(const char*);
if( objc!=2 ){
Tcl_WrongNumArgs(interp, 1, objv, "SQL");
return TCL_ERROR;
}
zSql = (char*)Tcl_GetString(objv[1]);
zNorm = sqlite3_normalize(zSql);
if( zNorm ){
Tcl_SetObjResult(interp, Tcl_NewStringObj(zNorm, -1));
sqlite3_free(zNorm);
}
return TCL_OK;
}
/*
** Usage: sqlite3_step STMT
**
@@ -7547,6 +7576,7 @@ int Sqlitetest1_Init(Tcl_Interp *interp){
{ "sqlite3_open16", test_open16 ,0 },
{ "sqlite3_open_v2", test_open_v2 ,0 },
{ "sqlite3_complete16", test_complete16 ,0 },
{ "sqlite3_normalize", test_normalize ,0 },
{ "sqlite3_prepare", test_prepare ,0 },
{ "sqlite3_prepare16", test_prepare16 ,0 },
+12
View File
@@ -148,6 +148,12 @@ static void set_options(Tcl_Interp *interp){
Tcl_SetVar2(interp, "sqlite_options", "hiddencolumns", "0", TCL_GLOBAL_ONLY);
#endif
#ifdef SQLITE_ENABLE_DESERIALIZE
Tcl_SetVar2(interp, "sqlite_options", "deserialize", "1", TCL_GLOBAL_ONLY);
#else
Tcl_SetVar2(interp, "sqlite_options", "deserialize", "0", TCL_GLOBAL_ONLY);
#endif
#ifdef SQLITE_ENABLE_MEMSYS3
Tcl_SetVar2(interp, "sqlite_options", "mem3", "1", TCL_GLOBAL_ONLY);
#else
@@ -501,6 +507,12 @@ Tcl_SetVar2(interp, "sqlite_options", "long_double",
Tcl_SetVar2(interp, "sqlite_options", "mergesort", "1", TCL_GLOBAL_ONLY);
#ifdef SQLITE_ENABLE_NULL_TRIM
Tcl_SetVar2(interp, "sqlite_options", "null_trim", "1", TCL_GLOBAL_ONLY);
#else
Tcl_SetVar2(interp, "sqlite_options", "null_trim", "0", TCL_GLOBAL_ONLY);
#endif
#ifdef SQLITE_OMIT_OR_OPTIMIZATION
Tcl_SetVar2(interp, "sqlite_options", "or_opt", "0", TCL_GLOBAL_ONLY);
#else
+1
View File
@@ -1383,6 +1383,7 @@ static int SQLITE_TCLAPI test_db_status(
{ "CACHE_WRITE", SQLITE_DBSTATUS_CACHE_WRITE },
{ "DEFERRED_FKS", SQLITE_DBSTATUS_DEFERRED_FKS },
{ "CACHE_USED_SHARED", SQLITE_DBSTATUS_CACHE_USED_SHARED },
{ "CACHE_SPILL", SQLITE_DBSTATUS_CACHE_SPILL },
};
Tcl_Obj *pResult;
if( objc!=4 ){
+3
View File
@@ -20,7 +20,10 @@
** We need several data types from the Windows SDK header.
*/
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#include "windows.h"
/*
+18
View File
@@ -292,6 +292,11 @@ void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 moreToFollow){
sqlite3TreeViewLine(pView,"NULL");
break;
}
case TK_TRUEFALSE: {
sqlite3TreeViewLine(pView,
sqlite3ExprTruthValue(pExpr) ? "TRUE" : "FALSE");
break;
}
#ifndef SQLITE_OMIT_BLOB_LITERAL
case TK_BLOB: {
sqlite3TreeViewLine(pView,"%s", pExpr->u.zToken);
@@ -348,6 +353,19 @@ void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 moreToFollow){
case TK_ISNULL: zUniOp = "ISNULL"; break;
case TK_NOTNULL: zUniOp = "NOTNULL"; break;
case TK_TRUTH: {
int x;
const char *azOp[] = {
"IS-FALSE", "IS-TRUE", "IS-NOT-FALSE", "IS-NOT-TRUE"
};
assert( pExpr->op2==TK_IS || pExpr->op2==TK_ISNOT );
assert( pExpr->pRight );
assert( pExpr->pRight->op==TK_TRUEFALSE );
x = (pExpr->op2==TK_ISNOT)*2 + sqlite3ExprTruthValue(pExpr->pRight);
zUniOp = azOp[x];
break;
}
case TK_SPAN: {
sqlite3TreeViewLine(pView, "SPAN %Q", pExpr->u.zToken);
sqlite3TreeViewExpr(pView, pExpr->pLeft, 0);
+7 -1
View File
@@ -827,7 +827,8 @@ static void updateVirtualTable(
if( aXRef[i]>=0 ){
sqlite3ExprCode(pParse, pChanges->a[aXRef[i]].pExpr, regArg+2+i);
}else{
sqlite3VdbeAddOp4Int(v, OP_VColumn, iCsr, i, regArg+2+i, 1);
sqlite3VdbeAddOp3(v, OP_VColumn, iCsr, i, regArg+2+i);
sqlite3VdbeChangeP5(v, 1); /* Enable sqlite3_vtab_nochange() */
}
}
if( HasRowid(pTab) ){
@@ -862,6 +863,11 @@ static void updateVirtualTable(
/* Create a record from the argument register contents and insert it into
** the ephemeral table. */
sqlite3VdbeAddOp3(v, OP_MakeRecord, regArg, nArg, regRec);
#ifdef SQLITE_DEBUG
/* Signal an assert() within OP_MakeRecord that it is allowed to
** accept no-change records with serial_type 10 */
sqlite3VdbeChangeP5(v, OPFLAG_NOCHNG_MAGIC);
#endif
sqlite3VdbeAddOp2(v, OP_NewRowid, ephemTab, regRowid);
sqlite3VdbeAddOp3(v, OP_Insert, ephemTab, regRec, regRowid);
}
+52 -21
View File
@@ -327,6 +327,26 @@ int sqlite3_strnicmp(const char *zLeft, const char *zRight, int N){
** This routine only works for values of E between 1 and 341.
*/
static LONGDOUBLE_TYPE sqlite3Pow10(int E){
#if defined(_MSC_VER)
static const LONGDOUBLE_TYPE x[] = {
1.0e+001,
1.0e+002,
1.0e+004,
1.0e+008,
1.0e+016,
1.0e+032,
1.0e+064,
1.0e+128,
1.0e+256
};
LONGDOUBLE_TYPE r = 1.0;
int i;
assert( E>=0 && E<=307 );
for(i=0; E!=0; i++, E >>=1){
if( E & 1 ) r *= x[i];
}
return r;
#else
LONGDOUBLE_TYPE x = 10.0;
LONGDOUBLE_TYPE r = 1.0;
while(1){
@@ -336,6 +356,7 @@ static LONGDOUBLE_TYPE sqlite3Pow10(int E){
x *= x;
}
return r;
#endif
}
/*
@@ -574,7 +595,7 @@ static int compare2pow63(const char *zNum, int incr){
** Returns:
**
** 0 Successful transformation. Fits in a 64-bit signed integer.
** 1 Excess text after the integer value
** 1 Excess non-space text after the integer value
** 2 Integer too large for a 64-bit signed integer or is malformed
** 3 Special case of 9223372036854775808
**
@@ -617,47 +638,57 @@ int sqlite3Atoi64(const char *zNum, i64 *pNum, int length, u8 enc){
for(i=0; &zNum[i]<zEnd && (c=zNum[i])>='0' && c<='9'; i+=incr){
u = u*10 + c - '0';
}
testcase( i==18*incr );
testcase( i==19*incr );
testcase( i==20*incr );
if( u>LARGEST_INT64 ){
/* This test and assignment is needed only to suppress UB warnings
** from clang and -fsanitize=undefined. This test and assignment make
** the code a little larger and slower, and no harm comes from omitting
** them, but we must appaise the undefined-behavior pharisees. */
*pNum = neg ? SMALLEST_INT64 : LARGEST_INT64;
}else if( neg ){
*pNum = -(i64)u;
}else{
*pNum = (i64)u;
}
testcase( i==18 );
testcase( i==19 );
testcase( i==20 );
if( &zNum[i]<zEnd /* Extra bytes at the end */
|| (i==0 && zStart==zNum) /* No digits */
rc = 0;
if( (i==0 && zStart==zNum) /* No digits */
|| nonNum /* UTF16 with high-order bytes non-zero */
){
rc = 1;
}else{
rc = 0;
}else if( &zNum[i]<zEnd ){ /* Extra bytes at the end */
int jj = i;
do{
if( !sqlite3Isspace(zNum[jj]) ){
rc = 1; /* Extra non-space text after the integer */
break;
}
jj += incr;
}while( &zNum[jj]<zEnd );
}
if( i>19*incr ){ /* Too many digits */
/* zNum is empty or contains non-numeric text or is longer
** than 19 digits (thus guaranteeing that it is too large) */
return 2;
}else if( i<19*incr ){
if( i<19*incr ){
/* Less than 19 digits, so we know that it fits in 64 bits */
assert( u<=LARGEST_INT64 );
return rc;
}else{
/* zNum is a 19-digit numbers. Compare it against 9223372036854775808. */
c = compare2pow63(zNum, incr);
c = i>19*incr ? 1 : compare2pow63(zNum, incr);
if( c<0 ){
/* zNum is less than 9223372036854775808 so it fits */
assert( u<=LARGEST_INT64 );
return rc;
}else if( c>0 ){
/* zNum is greater than 9223372036854775808 so it overflows */
return 2;
}else{
/* zNum is exactly 9223372036854775808. Fits if negative. The
** special case 2 overflow if positive */
assert( u-1==LARGEST_INT64 );
return neg ? rc : 3;
*pNum = neg ? SMALLEST_INT64 : LARGEST_INT64;
if( c>0 ){
/* zNum is greater than 9223372036854775808 so it overflows */
return 2;
}else{
/* zNum is exactly 9223372036854775808. Fits if negative. The
** special case 2 overflow if positive */
assert( u-1==LARGEST_INT64 );
return neg ? rc : 3;
}
}
}
}
+2 -2
View File
@@ -39,8 +39,8 @@ static int execSql(sqlite3 *db, char **pzErrMsg, const char *zSql){
while( SQLITE_ROW==(rc = sqlite3_step(pStmt)) ){
const char *zSubSql = (const char*)sqlite3_column_text(pStmt,0);
assert( sqlite3_strnicmp(zSql,"SELECT",6)==0 );
if( zSubSql ){
assert( zSubSql[0]!='S' );
assert( sqlite3_strnicmp(zSubSql,"SELECT",6)!=0 || CORRUPT_DB );
if( zSubSql && zSubSql[0]!='S' ){
rc = execSql(db, pzErrMsg, zSubSql);
if( rc!=SQLITE_OK ) break;
}
+123 -74
View File
@@ -264,6 +264,11 @@ static void applyNumericAffinity(Mem *pRec, int bTryForInt){
pRec->flags |= MEM_Real;
if( bTryForInt ) sqlite3VdbeIntegerAffinity(pRec);
}
/* TEXT->NUMERIC is many->one. Hence, it is important to invalidate the
** string representation after computing a numeric equivalent, because the
** string representation might not be the canonical representation for the
** numeric value. Ticket [343634942dd54ab57b7024] 2018-01-31. */
pRec->flags &= ~MEM_Str;
}
/*
@@ -464,7 +469,7 @@ static void memTracePrint(Mem *p){
if( p->flags & MEM_Undefined ){
printf(" undefined");
}else if( p->flags & MEM_Null ){
printf(" NULL");
printf(p->flags & MEM_Zero ? " NULL-nochng" : " NULL");
}else if( (p->flags & (MEM_Int|MEM_Str))==(MEM_Int|MEM_Str) ){
printf(" si:%lld", p->u.i);
}else if( p->flags & MEM_Int ){
@@ -643,7 +648,7 @@ int sqlite3VdbeExec(
assert( pOp>=aOp && pOp<&aOp[p->nOp]);
#ifdef VDBE_PROFILE
start = sqlite3Hwtime();
start = sqlite3NProfileCnt ? sqlite3NProfileCnt : sqlite3Hwtime();
#endif
nVmStep++;
#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
@@ -2167,18 +2172,8 @@ case OP_Or: { /* same as TK_OR, in1, in2, out3 */
int v1; /* Left operand: 0==FALSE, 1==TRUE, 2==UNKNOWN or NULL */
int v2; /* Right operand: 0==FALSE, 1==TRUE, 2==UNKNOWN or NULL */
pIn1 = &aMem[pOp->p1];
if( pIn1->flags & MEM_Null ){
v1 = 2;
}else{
v1 = sqlite3VdbeIntValue(pIn1)!=0;
}
pIn2 = &aMem[pOp->p2];
if( pIn2->flags & MEM_Null ){
v2 = 2;
}else{
v2 = sqlite3VdbeIntValue(pIn2)!=0;
}
v1 = sqlite3VdbeBooleanValue(&aMem[pOp->p1], 2);
v2 = sqlite3VdbeBooleanValue(&aMem[pOp->p2], 2);
if( pOp->opcode==OP_And ){
static const unsigned char and_logic[] = { 0, 0, 0, 0, 1, 2, 0, 2, 2 };
v1 = and_logic[v1*3+v2];
@@ -2196,6 +2191,35 @@ case OP_Or: { /* same as TK_OR, in1, in2, out3 */
break;
}
/* Opcode: IsTrue P1 P2 P3 P4 *
** Synopsis: r[P2] = coalesce(r[P1]==TRUE,P3) ^ P4
**
** This opcode implements the IS TRUE, IS FALSE, IS NOT TRUE, and
** IS NOT FALSE operators.
**
** Interpret the value in register P1 as a boolean value. Store that
** boolean (a 0 or 1) in register P2. Or if the value in register P1 is
** NULL, then the P3 is stored in register P2. Invert the answer if P4
** is 1.
**
** The logic is summarized like this:
**
** <ul>
** <li> If P3==0 and P4==0 then r[P2] := r[P1] IS TRUE
** <li> If P3==1 and P4==1 then r[P2] := r[P1] IS FALSE
** <li> If P3==0 and P4==1 then r[P2] := r[P1] IS NOT TRUE
** <li> If P3==1 and P4==0 then r[P2] := r[P1] IS NOT FALSE
** </ul>
*/
case OP_IsTrue: { /* in1, out2 */
assert( pOp->p4type==P4_INT32 );
assert( pOp->p4.i==0 || pOp->p4.i==1 );
assert( pOp->p3==0 || pOp->p3==1 );
sqlite3VdbeMemSetInt64(&aMem[pOp->p2],
sqlite3VdbeBooleanValue(&aMem[pOp->p1], pOp->p3) ^ pOp->p4.i);
break;
}
/* Opcode: Not P1 P2 * * *
** Synopsis: r[P2]= !r[P1]
**
@@ -2206,10 +2230,10 @@ case OP_Or: { /* same as TK_OR, in1, in2, out3 */
case OP_Not: { /* same as TK_NOT, in1, out2 */
pIn1 = &aMem[pOp->p1];
pOut = &aMem[pOp->p2];
sqlite3VdbeMemSetNull(pOut);
if( (pIn1->flags & MEM_Null)==0 ){
pOut->flags = MEM_Int;
pOut->u.i = !sqlite3VdbeIntValue(pIn1);
sqlite3VdbeMemSetInt64(pOut, !sqlite3VdbeBooleanValue(pIn1,0));
}else{
sqlite3VdbeMemSetNull(pOut);
}
break;
}
@@ -2276,30 +2300,25 @@ case OP_Once: { /* jump */
** is considered true if it is numeric and non-zero. If the value
** in P1 is NULL then take the jump if and only if P3 is non-zero.
*/
case OP_If: { /* jump, in1 */
int c;
c = sqlite3VdbeBooleanValue(&aMem[pOp->p1], pOp->p3);
VdbeBranchTaken(c!=0, 2);
if( c ) goto jump_to_p2;
break;
}
/* Opcode: IfNot P1 P2 P3 * *
**
** Jump to P2 if the value in register P1 is False. The value
** is considered false if it has a numeric value of zero. If the value
** in P1 is NULL then take the jump if and only if P3 is non-zero.
*/
case OP_If: /* jump, in1 */
case OP_IfNot: { /* jump, in1 */
int c;
pIn1 = &aMem[pOp->p1];
if( pIn1->flags & MEM_Null ){
c = pOp->p3;
}else{
#ifdef SQLITE_OMIT_FLOATING_POINT
c = sqlite3VdbeIntValue(pIn1)!=0;
#else
c = sqlite3VdbeRealValue(pIn1)!=0.0;
#endif
if( pOp->opcode==OP_IfNot ) c = !c;
}
c = !sqlite3VdbeBooleanValue(&aMem[pOp->p1], !pOp->p3);
VdbeBranchTaken(c!=0, 2);
if( c ){
goto jump_to_p2;
}
if( c ) goto jump_to_p2;
break;
}
@@ -2360,7 +2379,7 @@ case OP_IfNullRow: { /* jump */
** P2 is the column number for the argument to the sqlite_offset() function.
** This opcode does not use P2 itself, but the P2 value is used by the
** code generator. The P1, P2, and P3 operands to this opcode are the
** as as for OP_Column.
** same as for OP_Column.
**
** This opcode is only available if SQLite is compiled with the
** -DSQLITE_ENABLE_OFFSET_SQL_FUNC option.
@@ -2792,9 +2811,18 @@ case OP_MakeRecord: {
pRec = pLast;
do{
assert( memIsValid(pRec) );
pRec->uTemp = serial_type = sqlite3VdbeSerialType(pRec, file_format, &len);
serial_type = sqlite3VdbeSerialType(pRec, file_format, &len);
if( pRec->flags & MEM_Zero ){
if( nData ){
if( serial_type==0 ){
/* Values with MEM_Null and MEM_Zero are created by xColumn virtual
** table methods that never invoke sqlite3_result_xxxxx() while
** computing an unchanging column value in an UPDATE statement.
** Give such values a special internal-use-only serial-type of 10
** so that they can be passed through to xUpdate and have
** a true sqlite3_value_nochange(). */
assert( pOp->p5==OPFLAG_NOCHNG_MAGIC || CORRUPT_DB );
serial_type = 10;
}else if( nData ){
if( sqlite3VdbeMemExpandBlob(pRec) ) goto no_mem;
}else{
nZero += pRec->u.nZero;
@@ -2805,6 +2833,7 @@ case OP_MakeRecord: {
testcase( serial_type==127 );
testcase( serial_type==128 );
nHdr += serial_type<=127 ? 1 : sqlite3VarintLen(serial_type);
pRec->uTemp = serial_type;
if( pRec==pData0 ) break;
pRec--;
}while(1);
@@ -4415,10 +4444,8 @@ case OP_InsertInt: {
int seekResult; /* Result of prior seek or 0 if no USESEEKRESULT flag */
const char *zDb; /* database name - used by the update hook */
Table *pTab; /* Table structure - used by update and pre-update hooks */
int op; /* Opcode for update hook: SQLITE_UPDATE or SQLITE_INSERT */
BtreePayload x; /* Payload to be inserted */
op = 0;
pData = &aMem[pOp->p2];
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
assert( memIsValid(pData) );
@@ -4446,19 +4473,21 @@ case OP_InsertInt: {
zDb = db->aDb[pC->iDb].zDbSName;
pTab = pOp->p4.pTab;
assert( (pOp->p5 & OPFLAG_ISNOOP) || HasRowid(pTab) );
op = ((pOp->p5 & OPFLAG_ISUPDATE) ? SQLITE_UPDATE : SQLITE_INSERT);
}else{
pTab = 0; /* Not needed. Silence a compiler warning. */
pTab = 0;
zDb = 0; /* Not needed. Silence a compiler warning. */
}
#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
/* Invoke the pre-update hook, if any */
if( db->xPreUpdateCallback
&& pOp->p4type==P4_TABLE
&& !(pOp->p5 & OPFLAG_ISUPDATE)
){
sqlite3VdbePreUpdateHook(p, pC, SQLITE_INSERT, zDb, pTab, x.nKey, pOp->p2);
if( pTab ){
if( db->xPreUpdateCallback && !(pOp->p5 & OPFLAG_ISUPDATE) ){
sqlite3VdbePreUpdateHook(p, pC, SQLITE_INSERT, zDb, pTab, x.nKey,pOp->p2);
}
if( db->xUpdateCallback==0 || pTab->aCol==0 ){
/* Prevent post-update hook from running in cases when it should not */
pTab = 0;
}
}
if( pOp->p5 & OPFLAG_ISNOOP ) break;
#endif
@@ -4483,8 +4512,12 @@ case OP_InsertInt: {
/* Invoke the update-hook if required. */
if( rc ) goto abort_due_to_error;
if( db->xUpdateCallback && op ){
db->xUpdateCallback(db->pUpdateArg, op, zDb, pTab->zName, x.nKey);
if( pTab ){
assert( db->xUpdateCallback!=0 );
assert( pTab->aCol!=0 );
db->xUpdateCallback(db->pUpdateArg,
(pOp->p5 & OPFLAG_ISUPDATE) ? SQLITE_UPDATE : SQLITE_INSERT,
zDb, pTab->zName, x.nKey);
}
break;
}
@@ -6190,12 +6223,17 @@ case OP_AggStep0: {
assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) );
assert( n==0 || (pOp->p2>0 && pOp->p2+n<=(p->nMem+1 - p->nCursor)+1) );
assert( pOp->p3<pOp->p2 || pOp->p3>=pOp->p2+n );
pCtx = sqlite3DbMallocRawNN(db, sizeof(*pCtx) + (n-1)*sizeof(sqlite3_value*));
pCtx = sqlite3DbMallocRawNN(db, n*sizeof(sqlite3_value*) +
(sizeof(pCtx[0]) + sizeof(Mem) - sizeof(sqlite3_value*)));
if( pCtx==0 ) goto no_mem;
pCtx->pMem = 0;
pCtx->pOut = (Mem*)&(pCtx->argv[n]);
sqlite3VdbeMemInit(pCtx->pOut, db, MEM_Null);
pCtx->pFunc = pOp->p4.pFunc;
pCtx->iOp = (int)(pOp - aOp);
pCtx->pVdbe = p;
pCtx->skipFlag = 0;
pCtx->isError = 0;
pCtx->argc = n;
pOp->p4type = P4_FUNCCTX;
pOp->p4.pCtx = pCtx;
@@ -6206,7 +6244,6 @@ case OP_AggStep: {
int i;
sqlite3_context *pCtx;
Mem *pMem;
Mem t;
assert( pOp->p4type==P4_FUNCCTX );
pCtx = pOp->p4.pCtx;
@@ -6229,26 +6266,28 @@ case OP_AggStep: {
#endif
pMem->n++;
sqlite3VdbeMemInit(&t, db, MEM_Null);
pCtx->pOut = &t;
pCtx->fErrorOrAux = 0;
pCtx->skipFlag = 0;
assert( pCtx->pOut->flags==MEM_Null );
assert( pCtx->isError==0 );
assert( pCtx->skipFlag==0 );
(pCtx->pFunc->xSFunc)(pCtx,pCtx->argc,pCtx->argv); /* IMP: R-24505-23230 */
if( pCtx->fErrorOrAux ){
if( pCtx->isError ){
sqlite3VdbeError(p, "%s", sqlite3_value_text(&t));
if( pCtx->isError ){
if( pCtx->isError>0 ){
sqlite3VdbeError(p, "%s", sqlite3_value_text(pCtx->pOut));
rc = pCtx->isError;
}
sqlite3VdbeMemRelease(&t);
if( pCtx->skipFlag ){
assert( pOp[-1].opcode==OP_CollSeq );
i = pOp[-1].p1;
if( i ) sqlite3VdbeMemSetInt64(&aMem[i], 1);
pCtx->skipFlag = 0;
}
sqlite3VdbeMemRelease(pCtx->pOut);
pCtx->pOut->flags = MEM_Null;
pCtx->isError = 0;
if( rc ) goto abort_due_to_error;
}else{
assert( t.flags==MEM_Null );
}
if( pCtx->skipFlag ){
assert( pOp[-1].opcode==OP_CollSeq );
i = pOp[-1].p1;
if( i ) sqlite3VdbeMemSetInt64(&aMem[i], 1);
}
assert( pCtx->pOut->flags==MEM_Null );
assert( pCtx->skipFlag==0 );
break;
}
@@ -6693,15 +6732,15 @@ case OP_VFilter: { /* jump */
#endif /* SQLITE_OMIT_VIRTUALTABLE */
#ifndef SQLITE_OMIT_VIRTUALTABLE
/* Opcode: VColumn P1 P2 P3 P4 *
/* Opcode: VColumn P1 P2 P3 * P5
** Synopsis: r[P3]=vcolumn(P2)
**
** Store in register P3 the value of the P2-th column of
** the current row of the virtual-table of cursor P1.
**
** If the VColumn opcode is being used to fetch the value of
** an unchanging column during an UPDATE operation, then the P4
** value is 1. Otherwise, P4 is 0. The P4 value is returned
** an unchanging column during an UPDATE operation, then the P5
** value is 1. Otherwise, P5 is 0. The P5 value is returned
** by sqlite3_vtab_nochange() routine can can be used
** by virtual table implementations to return special "no-change"
** marks which can be more efficient, depending on the virtual table.
@@ -6726,11 +6765,17 @@ case OP_VColumn: {
assert( pModule->xColumn );
memset(&sContext, 0, sizeof(sContext));
sContext.pOut = pDest;
sContext.bVtabNoChng = pOp->p4.i!=0;
MemSetTypeFlag(pDest, MEM_Null);
if( pOp->p5 ){
sqlite3VdbeMemSetNull(pDest);
pDest->flags = MEM_Null|MEM_Zero;
pDest->u.nZero = 0;
}else{
MemSetTypeFlag(pDest, MEM_Null);
}
rc = pModule->xColumn(pCur->uc.pVCur, &sContext, pOp->p2);
sqlite3VtabImportErrmsg(p, pVtab);
if( sContext.isError ){
if( sContext.isError>0 ){
sqlite3VdbeError(p, "%s", sqlite3_value_text(pDest));
rc = sContext.isError;
}
sqlite3VdbeChangeEncoding(pDest, encoding);
@@ -6995,6 +7040,7 @@ case OP_Function0: {
pCtx->pFunc = pOp->p4.pFunc;
pCtx->iOp = (int)(pOp - aOp);
pCtx->pVdbe = p;
pCtx->isError = 0;
pCtx->argc = n;
pOp->p4type = P4_FUNCCTX;
pOp->p4.pCtx = pCtx;
@@ -7029,16 +7075,17 @@ case OP_Function: {
}
#endif
MemSetTypeFlag(pOut, MEM_Null);
pCtx->fErrorOrAux = 0;
assert( pCtx->isError==0 );
(*pCtx->pFunc->xSFunc)(pCtx, pCtx->argc, pCtx->argv);/* IMP: R-24505-23230 */
/* If the function returned an error, throw an exception */
if( pCtx->fErrorOrAux ){
if( pCtx->isError ){
if( pCtx->isError ){
if( pCtx->isError>0 ){
sqlite3VdbeError(p, "%s", sqlite3_value_text(pOut));
rc = pCtx->isError;
}
sqlite3VdbeDeleteAuxData(db, &p->pAuxData, pCtx->iOp, pOp->p1);
pCtx->isError = 0;
if( rc ) goto abort_due_to_error;
}
@@ -7080,8 +7127,10 @@ case OP_Function: {
*/
case OP_Trace:
case OP_Init: { /* jump */
char *zTrace;
int i;
#ifndef SQLITE_OMIT_TRACE
char *zTrace;
#endif
/* If the P4 argument is not NULL, then it must be an SQL comment string.
** The "--" string is broken up to prevent false-positives with srcck1.c.
@@ -7198,7 +7247,7 @@ default: { /* This is really OP_Noop and OP_Explain */
#ifdef VDBE_PROFILE
{
u64 endTime = sqlite3Hwtime();
u64 endTime = sqlite3NProfileCnt ? sqlite3NProfileCnt : sqlite3Hwtime();
if( endTime>start ) pOrigOp->cycles += endTime - start;
pOrigOp->cnt++;
}
+1
View File
@@ -127,6 +127,7 @@ typedef struct VdbeOpList VdbeOpList;
#define P4_INT64 (-14) /* P4 is a 64-bit signed integer */
#define P4_INTARRAY (-15) /* P4 is a vector of 32-bit integers */
#define P4_FUNCCTX (-16) /* P4 is a pointer to an sqlite3_context object */
#define P4_DYNBLOB (-17) /* Pointer to memory from sqliteMalloc() */
/* Error message codes for OP_Halt */
#define P5_ConstraintNotNull 1
+1 -2
View File
@@ -317,8 +317,6 @@ struct sqlite3_context {
int iOp; /* Instruction number of OP_Function */
int isError; /* Error code returned by the function. */
u8 skipFlag; /* Skip accumulator loading if true */
u8 fErrorOrAux; /* isError!=0 or pVdbe->pAuxData modified */
u8 bVtabNoChng; /* Fetching an unchanging column in a vtab UPDATE */
u8 argc; /* Number of arguments */
sqlite3_value *argv[1]; /* Argument set */
};
@@ -488,6 +486,7 @@ int sqlite3VdbeMemStringify(Mem*, u8, u8);
i64 sqlite3VdbeIntValue(Mem*);
int sqlite3VdbeMemIntegerify(Mem*);
double sqlite3VdbeRealValue(Mem*);
int sqlite3VdbeBooleanValue(Mem*, int ifNull);
void sqlite3VdbeIntegerAffinity(Mem*);
int sqlite3VdbeMemRealify(Mem*);
int sqlite3VdbeMemNumerify(Mem*);
+11 -12
View File
@@ -268,6 +268,11 @@ int sqlite3_value_type(sqlite3_value* pVal){
return aType[pVal->flags&MEM_AffMask];
}
/* Return true if a parameter to xUpdate represents an unchanged column */
int sqlite3_value_nochange(sqlite3_value *pVal){
return (pVal->flags&(MEM_Null|MEM_Zero))==(MEM_Null|MEM_Zero);
}
/* Make a copy of an sqlite3_value object
*/
sqlite3_value *sqlite3_value_dup(const sqlite3_value *pOrig){
@@ -367,14 +372,12 @@ void sqlite3_result_double(sqlite3_context *pCtx, double rVal){
void sqlite3_result_error(sqlite3_context *pCtx, const char *z, int n){
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
pCtx->isError = SQLITE_ERROR;
pCtx->fErrorOrAux = 1;
sqlite3VdbeMemSetStr(pCtx->pOut, z, n, SQLITE_UTF8, SQLITE_TRANSIENT);
}
#ifndef SQLITE_OMIT_UTF16
void sqlite3_result_error16(sqlite3_context *pCtx, const void *z, int n){
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
pCtx->isError = SQLITE_ERROR;
pCtx->fErrorOrAux = 1;
sqlite3VdbeMemSetStr(pCtx->pOut, z, n, SQLITE_UTF16NATIVE, SQLITE_TRANSIENT);
}
#endif
@@ -480,8 +483,7 @@ int sqlite3_result_zeroblob64(sqlite3_context *pCtx, u64 n){
return SQLITE_OK;
}
void sqlite3_result_error_code(sqlite3_context *pCtx, int errCode){
pCtx->isError = errCode;
pCtx->fErrorOrAux = 1;
pCtx->isError = errCode ? errCode : -1;
#ifdef SQLITE_DEBUG
if( pCtx->pVdbe ) pCtx->pVdbe->rcApp = errCode;
#endif
@@ -495,7 +497,6 @@ void sqlite3_result_error_code(sqlite3_context *pCtx, int errCode){
void sqlite3_result_error_toobig(sqlite3_context *pCtx){
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
pCtx->isError = SQLITE_TOOBIG;
pCtx->fErrorOrAux = 1;
sqlite3VdbeMemSetStr(pCtx->pOut, "string or blob too big", -1,
SQLITE_UTF8, SQLITE_STATIC);
}
@@ -505,7 +506,6 @@ void sqlite3_result_error_nomem(sqlite3_context *pCtx){
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
sqlite3VdbeMemSetNull(pCtx->pOut);
pCtx->isError = SQLITE_NOMEM_BKPT;
pCtx->fErrorOrAux = 1;
sqlite3OomFault(pCtx->pOut->db);
}
@@ -761,7 +761,7 @@ sqlite3 *sqlite3_context_db_handle(sqlite3_context *p){
*/
int sqlite3_vtab_nochange(sqlite3_context *p){
assert( p );
return p->bVtabNoChng;
return sqlite3_value_nochange(p->pOut);
}
/*
@@ -912,10 +912,7 @@ void sqlite3_set_auxdata(
pAuxData->iAuxArg = iArg;
pAuxData->pNextAux = pVdbe->pAuxData;
pVdbe->pAuxData = pAuxData;
if( pCtx->fErrorOrAux==0 ){
pCtx->isError = 0;
pCtx->fErrorOrAux = 1;
}
if( pCtx->isError==0 ) pCtx->isError = -1;
}else if( pAuxData->xDeleteAux ){
pAuxData->xDeleteAux(pAuxData->pAux);
}
@@ -1671,7 +1668,9 @@ int sqlite3_stmt_status(sqlite3_stmt *pStmt, int op, int resetFlag){
Vdbe *pVdbe = (Vdbe*)pStmt;
u32 v;
#ifdef SQLITE_ENABLE_API_ARMOR
if( !pStmt ){
if( !pStmt
|| (op!=SQLITE_STMTSTATUS_MEMUSED && (op<0||op>=ArraySize(pVdbe->aCounter)))
){
(void)SQLITE_MISUSE_BKPT;
return 0;
}
+9 -1
View File
@@ -866,6 +866,7 @@ static void freeP4(sqlite3 *db, int p4type, void *p4){
case P4_REAL:
case P4_INT64:
case P4_DYNAMIC:
case P4_DYNBLOB:
case P4_INTARRAY: {
sqlite3DbFree(db, p4);
break;
@@ -1407,6 +1408,7 @@ static char *displayP4(Op *pOp, char *zTemp, int nTemp){
sqlite3XPrintf(&x, "program");
break;
}
case P4_DYNBLOB:
case P4_ADVANCE: {
zTemp[0] = 0;
break;
@@ -3452,7 +3454,13 @@ u32 sqlite3VdbeSerialGet(
Mem *pMem /* Memory cell to write value into */
){
switch( serial_type ){
case 10: /* Reserved for future use */
case 10: { /* Internal use only: NULL with virtual table
** UPDATE no-change flag set */
pMem->flags = MEM_Null|MEM_Zero;
pMem->n = 0;
pMem->u.nZero = 0;
break;
}
case 11: /* Reserved for future use */
case 0: { /* Null */
/* EVIDENCE-OF: R-24078-09375 Value is a NULL. */
+71 -2
View File
@@ -43,7 +43,7 @@ int sqlite3VdbeCheckMemInvariants(Mem *p){
if( p->flags & MEM_Null ){
/* Cannot be both MEM_Null and some other type */
assert( (p->flags & (MEM_Int|MEM_Real|MEM_Str|MEM_Blob
|MEM_RowSet|MEM_Frame|MEM_Agg|MEM_Zero))==0 );
|MEM_RowSet|MEM_Frame|MEM_Agg))==0 );
/* If MEM_Null is set, then either the value is a pure NULL (the usual
** case) or it is a pointer set using sqlite3_bind_pointer() or
@@ -93,6 +93,51 @@ int sqlite3VdbeCheckMemInvariants(Mem *p){
}
#endif
#ifdef SQLITE_DEBUG
/*
** Check that string value of pMem agrees with its integer or real value.
**
** A single int or real value always converts to the same strings. But
** many different strings can be converted into the same int or real.
** If a table contains a numeric value and an index is based on the
** corresponding string value, then it is important that the string be
** derived from the numeric value, not the other way around, to ensure
** that the index and table are consistent. See ticket
** https://www.sqlite.org/src/info/343634942dd54ab (2018-01-31) for
** an example.
**
** This routine looks at pMem to verify that if it has both a numeric
** representation and a string representation then the string rep has
** been derived from the numeric and not the other way around. It returns
** true if everything is ok and false if there is a problem.
**
** This routine is for use inside of assert() statements only.
*/
int sqlite3VdbeMemConsistentDualRep(Mem *p){
char zBuf[100];
char *z;
int i, j, incr;
if( (p->flags & MEM_Str)==0 ) return 1;
if( (p->flags & (MEM_Int|MEM_Real))==0 ) return 1;
if( p->flags & MEM_Int ){
sqlite3_snprintf(sizeof(zBuf),zBuf,"%lld",p->u.i);
}else{
sqlite3_snprintf(sizeof(zBuf),zBuf,"%!.15g",p->u.r);
}
z = p->z;
i = j = 0;
incr = 1;
if( p->enc!=SQLITE_UTF8 ){
incr = 2;
if( p->enc==SQLITE_UTF16BE ) z++;
}
while( zBuf[j] ){
if( zBuf[j++]!=z[i] ) return 0;
i += incr;
}
return 1;
}
#endif /* SQLITE_DEBUG */
/*
** If pMem is an object with a valid string representation, this routine
@@ -527,6 +572,16 @@ double sqlite3VdbeRealValue(Mem *pMem){
}
}
/*
** Return 1 if pMem represents true, and return 0 if pMem represents false.
** Return the value ifNull if pMem is NULL.
*/
int sqlite3VdbeBooleanValue(Mem *pMem, int ifNull){
if( pMem->flags & MEM_Int ) return pMem->u.i!=0;
if( pMem->flags & MEM_Null ) return ifNull;
return sqlite3VdbeRealValue(pMem)!=0.0;
}
/*
** The MEM structure is already a MEM_Real. Try to also make it a
** MEM_Int if we can.
@@ -582,6 +637,18 @@ int sqlite3VdbeMemRealify(Mem *pMem){
return SQLITE_OK;
}
/* Compare a floating point value to an integer. Return true if the two
** values are the same within the precision of the floating point value.
**
** For some versions of GCC on 32-bit machines, if you do the more obvious
** comparison of "r1==(double)i" you sometimes get an answer of false even
** though the r1 and (double)i values are bit-for-bit the same.
*/
static int sqlite3RealSameAsInt(double r1, sqlite3_int64 i){
double r2 = (double)i;
return memcmp(&r1, &r2, sizeof(r1))==0;
}
/*
** Convert pMem so that it has types MEM_Real or MEM_Int or both.
** Invalidate any prior representations.
@@ -601,7 +668,7 @@ int sqlite3VdbeMemNumerify(Mem *pMem){
}else{
i64 i = pMem->u.i;
sqlite3AtoF(pMem->z, &pMem->u.r, pMem->n, pMem->enc);
if( rc==1 && pMem->u.r==(double)i ){
if( rc==1 && sqlite3RealSameAsInt(pMem->u.r, i) ){
pMem->u.i = i;
MemSetTypeFlag(pMem, MEM_Int);
}else{
@@ -1084,6 +1151,7 @@ static SQLITE_NOINLINE const void *valueToText(sqlite3_value* pVal, u8 enc){
assert(pVal->enc==(enc & ~SQLITE_UTF16_ALIGNED) || pVal->db==0
|| pVal->db->mallocFailed );
if( pVal->enc==(enc & ~SQLITE_UTF16_ALIGNED) ){
assert( sqlite3VdbeMemConsistentDualRep(pVal) );
return pVal->z;
}else{
return 0;
@@ -1106,6 +1174,7 @@ const void *sqlite3ValueText(sqlite3_value* pVal, u8 enc){
assert( (enc&3)==(enc&~SQLITE_UTF16_ALIGNED) );
assert( (pVal->flags & MEM_RowSet)==0 );
if( (pVal->flags&(MEM_Str|MEM_Term))==(MEM_Str|MEM_Term) && pVal->enc==enc ){
assert( sqlite3VdbeMemConsistentDualRep(pVal) );
return pVal->z;
}
if( pVal->flags&MEM_Null ){
+44 -29
View File
@@ -554,7 +554,11 @@ struct WalIterator {
** page and SQLITE_OK is returned. If an error (an OOM or VFS error) occurs,
** then an SQLite error code is returned and *ppPage is set to 0.
*/
static int walIndexPage(Wal *pWal, int iPage, volatile u32 **ppPage){
static SQLITE_NOINLINE int walIndexPageRealloc(
Wal *pWal, /* The WAL context */
int iPage, /* The page we seek */
volatile u32 **ppPage /* Write the page pointer here */
){
int rc = SQLITE_OK;
/* Enlarge the pWal->apWiData[] array if required */
@@ -573,21 +577,20 @@ static int walIndexPage(Wal *pWal, int iPage, volatile u32 **ppPage){
}
/* Request a pointer to the required page from the VFS */
if( pWal->apWiData[iPage]==0 ){
if( pWal->exclusiveMode==WAL_HEAPMEMORY_MODE ){
pWal->apWiData[iPage] = (u32 volatile *)sqlite3MallocZero(WALINDEX_PGSZ);
if( !pWal->apWiData[iPage] ) rc = SQLITE_NOMEM_BKPT;
}else{
rc = sqlite3OsShmMap(pWal->pDbFd, iPage, WALINDEX_PGSZ,
pWal->writeLock, (void volatile **)&pWal->apWiData[iPage]
);
assert( pWal->apWiData[iPage]!=0 || rc!=SQLITE_OK || pWal->writeLock==0 );
testcase( pWal->apWiData[iPage]==0 && rc==SQLITE_OK );
if( (rc&0xff)==SQLITE_READONLY ){
pWal->readOnly |= WAL_SHM_RDONLY;
if( rc==SQLITE_READONLY ){
rc = SQLITE_OK;
}
assert( pWal->apWiData[iPage]==0 );
if( pWal->exclusiveMode==WAL_HEAPMEMORY_MODE ){
pWal->apWiData[iPage] = (u32 volatile *)sqlite3MallocZero(WALINDEX_PGSZ);
if( !pWal->apWiData[iPage] ) rc = SQLITE_NOMEM_BKPT;
}else{
rc = sqlite3OsShmMap(pWal->pDbFd, iPage, WALINDEX_PGSZ,
pWal->writeLock, (void volatile **)&pWal->apWiData[iPage]
);
assert( pWal->apWiData[iPage]!=0 || rc!=SQLITE_OK || pWal->writeLock==0 );
testcase( pWal->apWiData[iPage]==0 && rc==SQLITE_OK );
if( (rc&0xff)==SQLITE_READONLY ){
pWal->readOnly |= WAL_SHM_RDONLY;
if( rc==SQLITE_READONLY ){
rc = SQLITE_OK;
}
}
}
@@ -596,6 +599,16 @@ static int walIndexPage(Wal *pWal, int iPage, volatile u32 **ppPage){
assert( iPage==0 || *ppPage || rc!=SQLITE_OK );
return rc;
}
static int walIndexPage(
Wal *pWal, /* The WAL context */
int iPage, /* The page we seek */
volatile u32 **ppPage /* Write the page pointer here */
){
if( pWal->nWiData<=iPage || (*ppPage = pWal->apWiData[iPage])==0 ){
return walIndexPageRealloc(pWal, iPage, ppPage);
}
return SQLITE_OK;
}
/*
** Return a pointer to the WalCkptInfo structure in the wal-index.
@@ -1572,8 +1585,9 @@ static void walIteratorFree(WalIterator *p){
/*
** Construct a WalInterator object that can be used to loop over all
** pages in the WAL in ascending order. The caller must hold the checkpoint
** lock.
** pages in the WAL following frame nBackfill in ascending order. Frames
** nBackfill or earlier may be included - excluding them is an optimization
** only. The caller must hold the checkpoint lock.
**
** On success, make *pp point to the newly allocated WalInterator object
** return SQLITE_OK. Otherwise, return an error code. If this routine
@@ -1582,7 +1596,7 @@ static void walIteratorFree(WalIterator *p){
** The calling routine should invoke walIteratorFree() to destroy the
** WalIterator object when it has finished with it.
*/
static int walIteratorInit(Wal *pWal, WalIterator **pp){
static int walIteratorInit(Wal *pWal, u32 nBackfill, WalIterator **pp){
WalIterator *p; /* Return value */
int nSegment; /* Number of segments to merge */
u32 iLast; /* Last frame in log */
@@ -1619,7 +1633,7 @@ static int walIteratorInit(Wal *pWal, WalIterator **pp){
rc = SQLITE_NOMEM_BKPT;
}
for(i=0; rc==SQLITE_OK && i<nSegment; i++){
for(i=walFramePage(nBackfill+1); rc==SQLITE_OK && i<nSegment; i++){
volatile ht_slot *aHash;
u32 iZero;
volatile u32 *aPgno;
@@ -1653,6 +1667,7 @@ static int walIteratorInit(Wal *pWal, WalIterator **pp){
if( rc!=SQLITE_OK ){
walIteratorFree(p);
p = 0;
}
*pp = p;
return rc;
@@ -1775,13 +1790,6 @@ static int walCheckpoint(
pInfo = walCkptInfo(pWal);
if( pInfo->nBackfill<pWal->hdr.mxFrame ){
/* Allocate the iterator */
rc = walIteratorInit(pWal, &pIter);
if( rc!=SQLITE_OK ){
return rc;
}
assert( pIter );
/* EVIDENCE-OF: R-62920-47450 The busy-handler callback is never invoked
** in the SQLITE_CHECKPOINT_PASSIVE mode. */
assert( eMode!=SQLITE_CHECKPOINT_PASSIVE || xBusy==0 );
@@ -1818,7 +1826,13 @@ static int walCheckpoint(
}
}
if( pInfo->nBackfill<mxSafeFrame
/* Allocate the iterator */
if( pInfo->nBackfill<mxSafeFrame ){
rc = walIteratorInit(pWal, pInfo->nBackfill, &pIter);
assert( rc==SQLITE_OK || pIter==0 );
}
if( pIter
&& (rc = walBusyLock(pWal, xBusy, pBusyArg, WAL_READ_LOCK(0),1))==SQLITE_OK
){
i64 nSize; /* Current size of database file */
@@ -2868,7 +2882,7 @@ int sqlite3WalFindFrame(
** table after the current read-transaction had started.
*/
iMinHash = walFramePage(pWal->minFrame);
for(iHash=walFramePage(iLast); iHash>=iMinHash && iRead==0; iHash--){
for(iHash=walFramePage(iLast); iHash>=iMinHash; iHash--){
volatile ht_slot *aHash; /* Pointer to hash table */
volatile u32 *aPgno; /* Pointer to array of page numbers */
u32 iZero; /* Frame number corresponding to aPgno[0] */
@@ -2891,6 +2905,7 @@ int sqlite3WalFindFrame(
return SQLITE_CORRUPT_BKPT;
}
}
if( iRead ) break;
}
#ifdef SQLITE_ENABLE_EXPENSIVE_ASSERT
+27 -7
View File
@@ -2481,10 +2481,12 @@ static int whereLoopAddBtreeIndex(
if( iCol==XN_ROWID
|| (iCol>=0 && nInMul==0 && saved_nEq==pProbe->nKeyCol-1)
){
if( iCol>=0 && pProbe->uniqNotNull==0 ){
pNew->wsFlags |= WHERE_UNQ_WANTED;
}else{
if( iCol==XN_ROWID || pProbe->uniqNotNull
|| (pProbe->nKeyCol==1 && pProbe->onError && eOp==WO_EQ)
){
pNew->wsFlags |= WHERE_ONEROW;
}else{
pNew->wsFlags |= WHERE_UNQ_WANTED;
}
}
}else if( eOp & WO_ISNULL ){
@@ -4631,6 +4633,7 @@ WhereInfo *sqlite3WhereBegin(
*/
for(ii=0; ii<sWLB.pWC->nTerm; ii++){
WhereTerm *pT = &sWLB.pWC->a[ii];
if( pT->wtFlags & TERM_VIRTUAL ) continue;
if( pT->prereqAll==0 && (nTabList==0 || exprIsDeterministic(pT->pExpr)) ){
sqlite3ExprIfFalse(pParse, pT->pExpr, pWInfo->iBreak, SQLITE_JUMPIFNULL);
pT->wtFlags |= TERM_CODED;
@@ -4801,15 +4804,32 @@ WhereInfo *sqlite3WhereBegin(
/* If the caller is an UPDATE or DELETE statement that is requesting
** to use a one-pass algorithm, determine if this is appropriate.
**
** A one-pass approach can be used if the caller has requested one
** and either (a) the scan visits at most one row or (b) each
** of the following are true:
**
** * the caller has indicated that a one-pass approach can be used
** with multiple rows (by setting WHERE_ONEPASS_MULTIROW), and
** * the table is not a virtual table, and
** * either the scan does not use the OR optimization or the caller
** is a DELETE operation (WHERE_DUPLICATES_OK is only specified
** for DELETE).
**
** The last qualification is because an UPDATE statement uses
** WhereInfo.aiCurOnePass[1] to determine whether or not it really can
** use a one-pass approach, and this is not set accurately for scans
** that use the OR optimization.
*/
assert( (wctrlFlags & WHERE_ONEPASS_DESIRED)==0 || pWInfo->nLevel==1 );
if( (wctrlFlags & WHERE_ONEPASS_DESIRED)!=0 ){
int wsFlags = pWInfo->a[0].pWLoop->wsFlags;
int bOnerow = (wsFlags & WHERE_ONEROW)!=0;
if( bOnerow
|| ((wctrlFlags & WHERE_ONEPASS_MULTIROW)!=0
&& 0==(wsFlags & WHERE_VIRTUALTABLE))
){
if( bOnerow || (
0!=(wctrlFlags & WHERE_ONEPASS_MULTIROW)
&& 0==(wsFlags & WHERE_VIRTUALTABLE)
&& (0==(wsFlags & WHERE_MULTI_OR) || (wctrlFlags & WHERE_DUPLICATES_OK))
)){
pWInfo->eOnePass = bOnerow ? ONEPASS_SINGLE : ONEPASS_MULTI;
if( HasRowid(pTabList->a[0].pTab) && (wsFlags & WHERE_IDX_ONLY) ){
if( wctrlFlags & WHERE_ONEPASS_MULTIROW ){
+15 -1
View File
@@ -1395,7 +1395,15 @@ Bitmask sqlite3WhereCodeOneLoopStart(
if( sqlite3ExprIsVector(pX->pRight) ){
r1 = rTemp = sqlite3GetTempReg(pParse);
codeExprOrVector(pParse, pX->pRight, r1, 1);
op = aMoveOp[(pX->op - TK_GT) | 0x0001];
testcase( pX->op==TK_GT );
testcase( pX->op==TK_GE );
testcase( pX->op==TK_LT );
testcase( pX->op==TK_LE );
op = aMoveOp[((pX->op - TK_GT - 1) & 0x3) | 0x1];
assert( pX->op!=TK_GT || op==OP_SeekGE );
assert( pX->op!=TK_GE || op==OP_SeekGE );
assert( pX->op!=TK_LT || op==OP_SeekLE );
assert( pX->op!=TK_LE || op==OP_SeekLE );
}else{
r1 = sqlite3ExprCodeTemp(pParse, pX->pRight, &rTemp);
disableTerm(pLevel, pStart);
@@ -2170,6 +2178,12 @@ Bitmask sqlite3WhereCodeOneLoopStart(
WO_EQ|WO_IN|WO_IS, 0);
if( pAlt==0 ) continue;
if( pAlt->wtFlags & (TERM_CODED) ) continue;
if( (pAlt->eOperator & WO_IN)
&& (pAlt->pExpr->flags & EP_xIsSelect)
&& (pAlt->pExpr->x.pSelect->pEList->nExpr>1)
){
continue;
}
testcase( pAlt->eOperator & WO_EQ );
testcase( pAlt->eOperator & WO_IS );
testcase( pAlt->eOperator & WO_IN );
+4 -1
View File
@@ -876,6 +876,9 @@ static Bitmask exprSelectUsage(WhereMaskSet *pMaskSet, Select *pS){
for(i=0; i<pSrc->nSrc; i++){
mask |= exprSelectUsage(pMaskSet, pSrc->a[i].pSelect);
mask |= sqlite3WhereExprUsage(pMaskSet, pSrc->a[i].pOn);
if( pSrc->a[i].fg.isTabFunc ){
mask |= sqlite3WhereExprListUsage(pMaskSet, pSrc->a[i].u1.pFuncArg);
}
}
}
pS = pS->pPrior;
@@ -1288,7 +1291,7 @@ static void exprAnalyze(
exprAnalyze(pSrc, pWC, idxNew);
}
pTerm = &pWC->a[idxTerm];
pTerm->wtFlags = TERM_CODED|TERM_VIRTUAL; /* Disable the original */
pTerm->wtFlags |= TERM_CODED|TERM_VIRTUAL; /* Disable the original */
pTerm->eOperator = 0;
}
+45
View File
@@ -343,4 +343,49 @@ do_test cast-4.4 {
}
} {0 abc 0.0 abc}
# Added 2018-01-26
#
# EVIDENCE-OF: R-48741-32454 If the prefix integer is greater than
# +9223372036854775807 then the result of the cast is exactly
# +9223372036854775807.
do_execsql_test cast-5.1 {
SELECT CAST('9223372036854775808' AS integer);
SELECT CAST(' +000009223372036854775808' AS integer);
SELECT CAST('12345678901234567890123' AS INTEGER);
} {9223372036854775807 9223372036854775807 9223372036854775807}
# EVIDENCE-OF: R-06028-16857 Similarly, if the prefix integer is less
# than -9223372036854775808 then the result of the cast is exactly
# -9223372036854775808.
do_execsql_test cast-5.2 {
SELECT CAST('-9223372036854775808' AS integer);
SELECT CAST('-9223372036854775809' AS integer);
SELECT CAST('-12345678901234567890123' AS INTEGER);
} {-9223372036854775808 -9223372036854775808 -9223372036854775808}
# EVIDENCE-OF: R-33990-33527 When casting to INTEGER, if the text looks
# like a floating point value with an exponent, the exponent will be
# ignored because it is no part of the integer prefix.
# EVIDENCE-OF: R-24225-46995 For example, "(CAST '123e+5' AS INTEGER)"
# results in 123, not in 12300000.
do_execsql_test case-5.3 {
SELECT CAST('123e+5' AS INTEGER);
SELECT CAST('123e+5' AS NUMERIC);
} {123 12300000.0}
# The following does not have anything to do with the CAST operator,
# but it does deal with affinity transformations.
#
do_execsql_test case-6.1 {
DROP TABLE IF EXISTS t1;
CREATE TABLE t1(a NUMERIC);
INSERT INTO t1 VALUES
('9000000000000000001'),
('9000000000000000001 '),
(' 9000000000000000001'),
(' 9000000000000000001 ');
SELECT * FROM t1;
} {9000000000000000001 9000000000000000001 9000000000000000001 9000000000000000001}
finish_test
+13 -3
View File
@@ -142,6 +142,7 @@ proc write_file {zFile zData} {
# b) Less than 512, or
# c) Greater than SQLITE_MAX_PAGE_SIZE
#
if {[atomic_batch_write test.db]==0} {
do_test crash8-3.1 {
list [file exists test.db-joural] [file exists test.db]
} {0 1}
@@ -228,6 +229,7 @@ do_test crash8-3.11 {
PRAGMA integrity_check
}
} {6 ok}
}
# If a connection running in persistent-journal mode is part of a
@@ -266,8 +268,12 @@ ifcapable pragma {
UPDATE aux.ab SET b = randstr(1000,1000) WHERE a>=1;
UPDATE ab SET b = randstr(1000,1000) WHERE a>=1;
}
list [file exists test.db-journal] [file exists test2.db-journal]
} {1 1}
} {persist persist}
if {[atomic_batch_write test.db]==0} {
do_test crash8.4.1.1 {
list [file exists test.db-journal] [file exists test2.db-journal]
} {1 1}
}
do_test crash8-4.2 {
execsql {
@@ -346,7 +352,11 @@ ifcapable pragma {
# Since the following tests (crash8-5.*) rely upon being able
# to copy a file while open, they will not work on Windows.
#
if {$::tcl_platform(platform)=="unix"} {
# They also depend on being able to copy the journal file, which
# is not created on F2FS file-systems that support atomic
# write. So do not run these tests in that case either.
#
if {$::tcl_platform(platform)=="unix" && [atomic_batch_write test.db]==0 } {
for {set i 1} {$i < 10} {incr i} {
catch { db close }
forcedelete test.db test.db-journal
+39
View File
@@ -415,4 +415,43 @@ ifcapable shared_cache {
}
}
#-------------------------------------------------------------------------
# Test that passing an out-of-range value to sqlite3_stmt_status does
# not cause a crash.
reset_db
do_execsql_test 5.0 {
CREATE TABLE t1(x, y);
INSERT INTO t1 VALUES(1, 2);
INSERT INTO t1 VALUES(3, 4);
}
do_test 5.1 {
set ::stmt [sqlite3_prepare db "SELECT * FROM t1" -1 dummy]
sqlite3_step $::stmt
sqlite3_step $::stmt
sqlite3_step $::stmt
sqlite3_reset $::stmt
} {SQLITE_OK}
ifcapable api_armor {
do_test 5.2 { sqlite3_stmt_status $::stmt -1 0 } 0
}
do_test 5.3 { sqlite3_stmt_status $::stmt 0 0 } 0
do_test 5.4 {
expr [sqlite3_stmt_status $::stmt 99 0]>0
} 1
foreach {tn id res} {
1 SQLITE_STMTSTATUS_MEMUSED 1
2 SQLITE_STMTSTATUS_FULLSCAN_STEP 1
3 SQLITE_STMTSTATUS_SORT 0
4 SQLITE_STMTSTATUS_AUTOINDEX 0
5 SQLITE_STMTSTATUS_VM_STEP 1
6 SQLITE_STMTSTATUS_REPREPARE 0
7 SQLITE_STMTSTATUS_RUN 1
} {
if {$tn==2} breakpoint
do_test 5.5.$tn { expr [sqlite3_stmt_status $::stmt $id 0]>0 } $res
}
sqlite3_finalize $::stmt
finish_test
+13
View File
@@ -37,6 +37,10 @@ proc db_write {db {reset 0}} {
sqlite3_db_status $db CACHE_WRITE $reset
}
proc db_spill {db {reset 0}} {
sqlite3_db_status $db CACHE_SPILL $reset
}
do_test 1.1 {
db close
sqlite3 db test.db
@@ -98,5 +102,14 @@ do_test 2.7 {
} {0 4 0}
do_test 2.8 { db_write db 1 } {0 4 0}
do_test 2.9 { db_write db 0 } {0 0 0}
do_test 3.0 { db_spill db 1 } {0 0 0}
do_test 3.1 { db_spill db 0 } {0 0 0}
do_execsql_test 3.2 {
PRAGMA journal_mode=DELETE;
PRAGMA cache_size=3;
UPDATE t1 SET b=randomblob(1000);
} {delete}
do_test 3.3 { db_spill db 0 } {0 8 0}
finish_test
+5
View File
@@ -17,6 +17,11 @@ set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix delete_db
if {[atomic_batch_write test.db]} {
finish_test
return
}
proc delete_all {} {
foreach f [glob -nocomplain test2*] { file delete $f }
foreach f [glob -nocomplain test3*] { file delete $f }
+6 -1
View File
@@ -252,7 +252,9 @@ db2 close
# opens the journal file for exclusive access, preventing its contents
# from being inspected externally.
#
if {$tcl_platform(platform) != "windows"} {
if {$tcl_platform(platform) != "windows"
&& [atomic_batch_write test.db]==0
} {
# Return a list of two booleans (either 0 or 1). The first is true
# if the named file exists. The second is true only if the file
@@ -391,6 +393,7 @@ do_test exclusive-4.5 {
# Tests exclusive-5.X - test that statement journals are truncated
# instead of deleted when in exclusive access mode.
#
if {[atomic_batch_write test.db]==0} {
# Close and reopen the database so that the temp database is no
# longer active.
@@ -508,4 +511,6 @@ do_execsql_test exclusive-6.5 {
SELECT * FROM sqlite_master;
} {exclusive}
} ;# atomic_batch_write==0
finish_test

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