Compare commits

...

182 Commits

Author SHA1 Message Date
drh 09e8f4adf7 Merge version 3.39.4 changes into the reuse-schema-3.39 branch.
FossilOrigin-Name: 8102592836dcf6f08749a516e126f3990a20f40866ed4a6e85d134ab49907ece
2022-09-30 12:27:46 +00:00
drh 48fa01e4a8 Version 3.39.4
FossilOrigin-Name: a29f9949895322123f7c38fbe94c649a9d6e6c9cd0c3b41c96d694552f26b309
2022-09-29 15:55:41 +00:00
drh e18246199a Fix misuse of the sqlite3_set_auxdata() interface in the ICU extension.
FossilOrigin-Name: 6607dd010359d0f2e07e49ce69d4bfd1e57c3505df5d667cf7735facf34112d7
2022-09-28 19:19:11 +00:00
drh 76167f96b0 Remove a NEVER macro in defragmentPage() that dbsqlfuzz discovered can be
true.  crash-32d9312f145cdce41613573f6431d9a3e439e3d7

FossilOrigin-Name: a4342fc020a41bc5eed2d8f02ec4a759a78c5b0cbc1ae5e8dc167dcc69aa698d
2022-09-28 13:38:49 +00:00
drh 3ec786ab9c Enhance defensive mode so that it disallows CREATE TRIGGER statements if
the statements within the trigger attempt to write on a shadow table.  Also
make the legacy FTS3 code more robust against integer overflow during
memory allocation.

FossilOrigin-Name: c41f25e6f3591e575452c4c68f8072a0163cc00d80af31f90d407c7deca79622
2022-09-27 02:04:52 +00:00
dan 8cf7bedb81 Enhance the b-tree page sorting code to ensure that sqlite3PagerRekey() never
overloads a page number and uses only the PENDING_BYTE page for temporary
storage.

FossilOrigin-Name: aa6a5b729782dee75f14ae4e780302c4446074c20d1eb300346fbe874eb64706
2022-09-10 13:50:33 +00:00
drh 77aa809a37 Enhance an assert() to impose for tighter constraints on the operation of pcache.
FossilOrigin-Name: 461511cc99e5b1f936d0acbfcfe117c4ceb721a28eed50bb6db7a2244aedb599
2022-09-07 20:14:38 +00:00
drh 1b7e5d2b0b Fix the windows build so that it works with -DSQLITE_OMIT_AUTOINIT.
FossilOrigin-Name: 1662eb07d8fa01457b3e3f37894234aae27c25a67059da968ab8cb599d3bd8f6
2022-09-07 19:58:48 +00:00
drh 3943571dda Ensure that the Rekey() operation does not overwrite an existing page number.
FossilOrigin-Name: cd1e40064ccd9fe2189feb4fd3b77be265990baba8be3d53256b85716650f5bc
2022-09-07 19:50:06 +00:00
drh 3ec39b0cf2 Increase the version number to 3.39.4
FossilOrigin-Name: e98bed127db003c4ea34d8ca331b29a0256d9073c27a3e914f02030c1b0af77c
2022-09-07 19:35:23 +00:00
drh 810f9218f4 Merge patches for version 3.39.3 into the reuse-schema-3.39 branch.
FossilOrigin-Name: efd54164b02f35b5d39ab4d18e349c18f3ec8afb728da39d20373e26742da177
2022-09-05 13:36:32 +00:00
drh 230ad4565e Version 3.39.3
FossilOrigin-Name: 4635f4a69c8c2a8df242b384a992aea71224e39a2ccab42d8c0b0602f1e826e8
2022-09-05 11:02:23 +00:00
dan 98e57757dc Ensure the Pager.journalOff variable is zeroed if an error occurs while writing the initial header to the journal file.
FossilOrigin-Name: fe547035ce9204a8e573540115fa8514fbf875e3cae493d88ff3eceb61a67384
2022-09-02 21:21:58 +00:00
drh e8b45c33cd Remove a NEVER() that is sometimes true.
FossilOrigin-Name: 85a8a117402737352d0c36e9f24a9bdb3842b34f1c520db2d37a2fc91b026486
2022-09-02 19:18:49 +00:00
drh 47405642f2 Fix an assert() associated with the dbsqlfuzz error at [8372468bb5d8922c].
FossilOrigin-Name: f448480e1b93d94ee852b252df6e2fd8649a08f78ab294b07f77307ac0821beb
2022-09-02 17:26:22 +00:00
drh 16938fc374 When an OOM occurs and sets the Parse.nErr value, also set the Parse.nErr
value for all outer Parse objects.
dbsqlfuzz d33f60aaa67733aa700cd69dacf8e0e23a327a29

FossilOrigin-Name: 073621afa2fd833a3ee976d7508a11eca67520e1bc6d5351654fa220c9397976
2022-09-02 16:45:21 +00:00
drh cdce08b05a Mutex protect access to the sqlite3_test_directory and sqlite3_data_directory
global variables.  See
[forum:/forumpost/719a11e1314d1c70|forum thread 719a11e1314d1c70].

FossilOrigin-Name: 34c6ec3989fd605f020efa077a0ffacf426456bab1b0290aaa517ccf04fe7de5
2022-09-02 12:12:46 +00:00
drh 254c5ad58d Defer deleting a transient SELECT statement associated with a flattening
of one arm of a compound SELECT until after the parse has completed.

FossilOrigin-Name: 8403c0d5d626eaf6c4830e6d706af3ea2d84a9a12b8eecc6f549fa2ca24352b7
2022-09-01 14:33:28 +00:00
drh 87cef5ed35 Do not attempt the OP_Count optimization on queries with HAVING clauses.
This fixes a problem exposed by [2cf373b10c9bc4cb].

FossilOrigin-Name: 5f93239a8c0fc724837b208fb3d48fd709c5b60c15e90dbb82fd046c0b735b04
2022-08-31 14:40:46 +00:00
drh 9eb67ef5f9 Any function call can abort. Take this into account when deciding if a DML
statement needs a statement journal.  See
[forum:/forumpost/9b9e4716c0d7bbd1|forum thread 9b9e4716c0d7bbd1] for more
information.

FossilOrigin-Name: 5bf4c5fd0a6ac02392249d3a2057a6fca5b3fcf7c8ad376bbd009d11a9ecd765
2022-08-30 14:13:15 +00:00
drh 7ef2cf86d3 Avoid having fts3 read uninitialized values when processing deferred tokens.
FossilOrigin-Name: 8e2bfe58030cab8230001c73b60c3ecd421dde5c473b39429ddad610e1d2b1be
2022-08-05 19:37:05 +00:00
drh 0b316cb36d Fix a problem with the query optimizer for LIMIT/OFFSET queries when
underlying query is a UNION ALL and both arms of the UNION ALL are
subqueries with an ORDER BY clause.  This bug was reported at
[forum:/forumpost/6b5e9188f0657616|forum post 6b5e9188f0657616].  The
problem was introduced in 2015 (SQLite version 3.9.0) by check-in
[4b631364354068af].  See also ticket [b65cb2c8d91f6685].

FossilOrigin-Name: 5e1db87cfa262deb85447c1e0bc0412bcebec2ee5503b01f309c61c548a7f32c
2022-08-04 17:17:41 +00:00
drh 71dc5f83f4 Improvement on the previous check-in.
FossilOrigin-Name: 0d0c31117a530356495fa24e020bb9536a1c4b68c35a1e96cbd70ea5a7cc4e75
2022-08-03 17:27:52 +00:00
drh 7dde866d3b For an IN operator used with a RIGHT JOIN, use the number of terms in the
vector, not the number of equality terms, to size the column map.
dbsqlfuzz 14cfdad6ca45e607163f54049ddf5065183dc657.

FossilOrigin-Name: 003e4eee6b53a4dee3b8593dc052661d56bd426c8fc184b8a6b5e760a7f9e003
2022-08-03 16:04:12 +00:00
drh 65f517d619 Bump the version number up to 3.39.3.
FossilOrigin-Name: d0f7f22a8f4e74d344d9ac7b5bd5a3905179ab1954c8351b0aac912c410a6767
2022-08-01 13:17:41 +00:00
drh 96e3015e4d In the xUpdate method of the GeoPoly virtual table, make sure that the
number of updated columns does not exceed the underlying implementation, even
if the virtual table object records an excess number of column in the nAux
field due to table constraints in the table definition.
Fix for the problem reported by
[forum:/forumpost/a096ab7d96bb057a|forum post a096ab7d96bb057a].

FossilOrigin-Name: a8ae721617e75742966cbc77bf56a264e36b7278cb718eb155d72b579c95d5cd
2022-08-01 13:15:29 +00:00
drh 17a318c7de Merge the fixes from branch-3.39 into the reuse-schema branch.
FossilOrigin-Name: 578538baf2923f1a2a078d173dfdfb830acf5ce8640de901e9d560c6f4df8a55
2022-07-21 16:07:24 +00:00
drh 202b2a7b54 Version 3.39.2
FossilOrigin-Name: 698edb77537b67c41adc68f9b892db56bcf9a55e00371a61420f3ddd668e6603
2022-07-21 15:24:47 +00:00
drh b0ddbf7922 In the query planner, restore the former aggressiveness in reordering of
FROM clause terms that existed prior to version 3.39.0 for queries that
contain no RIGHT or FULL JOINs.

FossilOrigin-Name: 9141e873c575b049ce7aeaf313d05966f1966087caf33a6c80d2416a28571a21
2022-07-21 12:26:01 +00:00
drh fd34e75b0a Simplify the logic that converts the "1" expression in "ORDER BY 1" into a
copy of the expression that defines the first output column.

FossilOrigin-Name: 449935914c3f64e37bbfb9842e868927222fa3d5315c123a32818e67fcfbbf60
2022-07-20 17:01:18 +00:00
drh 6eb7354fab Increase the size of loop variables in the printf() implementation to avoid
harmless compiler warnings.

FossilOrigin-Name: 26db4fc22fe6665809d321b8a88b60efbbfecd5723ff3e370b857661b981c32c
2022-07-18 15:27:29 +00:00
mistachkin afb21dc9ca Fix harmless compiler warnings seen with MSVC.
FossilOrigin-Name: 2be8fa158e035faf0ec46830a9ec270fb292cd79a882a8fe8dadd19d6ee057a0
2022-07-15 15:24:10 +00:00
dan b1c445732e Fix a memory leak in fts3 that could occur when processing a corrupt database.
FossilOrigin-Name: 48f323b9561969bc7d7157ee361c18b047a876be5907c34d2a73254256934098
2022-07-15 15:11:41 +00:00
drh effc07ec9c Fix the whereKeyStats() routine (part of STAT4 processing only) so that it
is able to cope with row-value comparisons against the primary key index
of a WITHOUT ROWID table.
[forum:/forumpost/3607259d3c|Forum post 3607259d3c].

FossilOrigin-Name: 2a6f761864a462de5c2d5bc666b82fb0b7e124a03443cd1482620dde344b34bb
2022-07-15 12:34:31 +00:00
dan 8d65601931 Update some faulty assert() statements in fts3.
FossilOrigin-Name: 958d104bcfb63b53b1f7ed745fafed8f392b71ed8b694675502473da735fc6a0
2022-07-15 12:07:25 +00:00
drh c892515c7a Bump the version number up to 3.39.2.
FossilOrigin-Name: c4dbcb282d28bcc9b8001f387d0fc605be928453b3f61d2f5150f529647027b2
2022-07-14 01:54:17 +00:00
drh 9dde91f613 When applying the omit-ORDER-BY optimization, defer deleting the AST of
the deleted ORDER BY clause until after code generation ends.

FossilOrigin-Name: b88d6c4b814ec4166ec50f32a2f10d7857df05414c0048c1234ab290a273e50c
2022-07-14 01:49:17 +00:00
drh 11dbd0be3c Version 3.39.1
FossilOrigin-Name: 7c16541a0efb3985578181171c9f2bb3fdc4bad6a2ec85c6e31ab96f3eff201f
2022-07-13 19:41:41 +00:00
drh b3f7a5d8f6 The query flattener should not run if the subquery is a compound that contains
a RIGHT JOIN in any arm and the subquery is not the first element of the
outer query.  Otherwise, prior elements of the outer query will not have
the JT_LTORJ flag set.  Fix for the problem reported in
[forum:/forumpost/174afeae5734d42d|forum post 174afeae5734d42d].

FossilOrigin-Name: cf9ed7f2e1a7be230a8ff689a759289a6bf59c1c84169f2ed510f74c02e0c2e0
2022-07-13 16:06:35 +00:00
drh 14030cca04 Fix test case error messages so that they work with after the removal of
the unnecessary zErrMsg clearing from [44d77a7f807f5dc3].

FossilOrigin-Name: 7b167b87d63f6a7399886c84a40bf53b504aa9f6bd18dd06aad2a02aa0a88b2f
2022-07-13 11:27:20 +00:00
dan 9d905ce1c5 Update makefiles to fix building the non-amalgamation testfixture with SQLITE_DEBUG.
FossilOrigin-Name: 1ca705641708cc39d984c8f688df1418f9abd7cc39ac8cb6f0cd689f0bc2b568
2022-07-12 15:12:19 +00:00
drh 9dfd155f68 Use 64-bit memory allocation APIs in the sqlite_stmt virtual table, to avoid
harmless compiler warnings.

FossilOrigin-Name: 4c40b38cbe04ddd8c1ef442bf14e1625f5494d64c78ae830b9e01fe4c7243394
2022-07-11 19:48:48 +00:00
drh 31114a38cc Fix harmless compiler warnings.
FossilOrigin-Name: 9931bb202e2a4e0a980ebc6164e8f1da6c724e07242f448058e1c4cc3694b2b3
2022-07-11 19:29:48 +00:00
drh 4292973810 Increase the version number to 3.39.1.
FossilOrigin-Name: 88b1b0327f6d2843a4c84b4f5249162cf81a86bfd43f9412ebe6142d7c2df2fb
2022-07-11 14:44:28 +00:00
drh 8d7ffd2904 Ensure that the Parse.nErr flag is set following an SQLITE_TOOBIG error on
a nested parse.  Fix for the problem identified by
[forum/forumpost/d5a82ba9eedee30c | forum post d5a82ba9eedee30c].
Also, remove unnecessary clearing of the Parse.zErrMsg field
following a nested parse.

FossilOrigin-Name: eaef7b71900ef7701c11f07ec8b0ca3fec7e055ce8fd9c769f36669b482de134
2022-07-11 14:43:33 +00:00
drh 64477226e2 Fix a problem in fts3 to do with deferred tokens and OR expressions.
FossilOrigin-Name: bbe999e345d43b2f90493d11b95bb5da39d356bfddfc79234cfa70ac1eb273e8
2022-07-11 14:39:55 +00:00
dan d120a50ef7 Fix for builds with both SQLITE_DEBUG and SQLITE_OMIT_WINDOWFUNC defined.
FossilOrigin-Name: dfe46de2d4149fea5031c670f2bcec20851b0941ed9b7adf6cb31a01040362c5
2022-07-05 19:56:10 +00:00
drh f14c4c91e1 Fix the initial-prefix optimization for the REGEXP extension such that it
works even if the prefix contains characters that require a 3-byte UTF8
encoding.  This should fix the problem reported by
[forum:/forumpost/96692f8ba5|forum post 96692f8ba5].

FossilOrigin-Name: 7a32ccccef7712a40aba86c2204457f6772403befabe0aab19407399df46f096
2022-07-03 14:32:18 +00:00
drh 98c336c2b2 Fix documentation and test-script typos and a dependency problem on a Makefile. Fix the sqlite_stmt extension virtual table so that it shows the state of all
prepared statements for a single instant in time.

FossilOrigin-Name: 0a9e08be6d06e571ef9dc688317271de8054179a0458e196d3bc2dc6262efecc
2022-06-30 14:19:38 +00:00
drh 7983d0f0b7 Merge version 3.39.0 into the reuse-schema branch.
FossilOrigin-Name: bee9903df5c89823e4e285fa1a56f20c8b0408d55bd74dbf71ea61e993da6dc9
2022-06-25 17:20:36 +00:00
drh 660e3fad0b Merge the 3.39.0 release candidate 1 changes into the reuse-schema branch.
FossilOrigin-Name: 506a3e6f242f42d3106f80ad4385a5ef458461fbd056258e65c82dd4e0a80e8c
2022-06-24 16:15:20 +00:00
drh af313837d5 Merge the latest trunk enhancements into the reuse-schema branch.
FossilOrigin-Name: 7f405fe209d141435562b69ff161a545c63c5804f7de37871d24d7b6ee80ecec
2022-06-16 13:57:58 +00:00
drh 39ade05f33 Merge the latest trunk enhancements into the reuse-schema branch.
FossilOrigin-Name: 4d46296ef6c2e7d63d2d2dc59af1e7d62c951b3c40784688811a6b4f230fc869
2022-05-28 15:01:35 +00:00
drh 1d373b4de6 Merge the latest trunk enhancements into the reuse-schema branch.
FossilOrigin-Name: 495f0353db126bd4ab4cd654842f253b4938a8e8bf285a186ec69f95fb221923
2022-05-17 15:33:05 +00:00
drh b928283248 Merge all recent trunk changes into the reuse-schema branch.
FossilOrigin-Name: 9f6d6e6135f9b8120fc20adfd595d5aba2004659859ef5cb6cc67981f850ccdc
2022-05-10 13:06:56 +00:00
drh d4ff324e8a Merge the latest trunk changes into the reuse-schema branch.
FossilOrigin-Name: f3fa81963ec40de02e0ba7226c7a509a27bf2a7ecfed933fa811e94721e36285
2022-03-12 15:21:23 +00:00
drh fa98d0ea0d Don't reload the schema on PRAGMA database_list.
FossilOrigin-Name: 630fe446da880b5320ff014a9f7dde683664eb5cb9fd47be5b9b32ed3c590f71
2022-02-22 20:38:45 +00:00
drh 4484700648 Merge version 3.38.0 into the reuse-schema branch.
FossilOrigin-Name: 8fe85dcdb1107a240379ea3e128c51e4be80232e632f4ec74de9b3a98e0c2061
2022-02-22 20:04:24 +00:00
drh d046825cce Merge the latest trunk changes into the reuse-schema branch.
FossilOrigin-Name: b3c26f4a34ab1557beddffccb818218a583c4daf078d338450eb79369fc2adf4
2022-02-21 16:49:49 +00:00
drh cee8c84dc9 Merge the latest trunk enhancements into the reuse-schema branch.
FossilOrigin-Name: b9ba43fcb3b727fc344ab754a0132a62ff640daff8cc2ca17fd41e57fba2168d
2022-02-15 20:56:16 +00:00
drh 41a871f0d2 Merge trunk enhancements into the reuse-schema branch.
FossilOrigin-Name: 5744e1020b63f9eb89c12d6ea3ba33e17a6fea1478625c22240dcae50b50203e
2022-02-04 18:12:18 +00:00
drh da60a1b0be Merge the latest trunk enhancements into the reuse-schema branch.
FossilOrigin-Name: 6e4154d414afe2562b488149b10c175d1f15bd1d5060ee479d5ae9386a2e277e
2022-01-25 16:28:57 +00:00
drh 1546d749e3 Merge the latest trunk changes into the reuse-schema branch.
FossilOrigin-Name: 769ff85765746d3c94211ade114c6762baa76bb0db2dbe634334ca1beb4eed7f
2022-01-17 20:01:45 +00:00
drh bba8f23721 Merge version 3.37.0 into the reuse-schema branch.
FossilOrigin-Name: f83d50d5076339682c011329d7ab431ccaf134b37984706f199d878c3a88b553
2021-11-27 15:12:21 +00:00
drh 2ba1bb5b6f Merge recent trunk enhancements into the reuse-schema branch.
FossilOrigin-Name: d08832cb938a50891963446276d4ada3e73412ba6c316520f7cb8b180ae4f0f5
2021-11-22 16:05:44 +00:00
drh b2ded7c318 Merge recent trunk enhancements into the reuse-schema branch.
FossilOrigin-Name: 748bce4c0172c60737c910c6f5b642259dcd4369b1fb473eb7fc48834fa0fcea
2021-11-09 14:00:57 +00:00
dan 9d04907363 Avoid accessing the sqlite3_module.xShadowName field if (sqlite3_module.iVersion<3).
FossilOrigin-Name: b1fc3de81e46e13f9bf592e8910a576e7573a700e8eac5be0bc839e7e2be53b6
2021-11-06 07:08:39 +00:00
drh bd564771f6 Merge the latest trunk enhancements into the reuse-schema branch.
FossilOrigin-Name: ca09148e13d33a74ff75cf9c1d9e776ae0bf10ce8505656d8b5ca31398761b38
2021-11-05 23:32:17 +00:00
drh b7416ed80f Merge the latest trunk enhancements into the reuse-schema branch.
FossilOrigin-Name: 7623132efe9aaaf3a02d6c1ff82e199a075d2cadbe8030d2381c50509f862626
2021-10-29 14:04:22 +00:00
drh b963701038 Merge recent trunk enhancements into the reuse-schema branch
FossilOrigin-Name: cd15fc3c08373dad63ba7eafb117d0d09913b8fc339882fd909da5ec485a7138
2021-10-21 14:10:04 +00:00
drh 63f94dfe9f Merge recent trunk enhancements into the reuse-schema branch.
FossilOrigin-Name: 64234c5c9a5709e7c7c1b18bf32f4374692129b353c4698010abfc98bd00bcc4
2021-10-04 11:49:35 +00:00
drh fd89e834b8 Merge recent trunk enhancements into the reuse-schema branch.
FossilOrigin-Name: c8d1f17fde280acd3e98772d947a5b1e698b08d25b23bcd0731ae2d18cfbddcf
2021-08-09 18:17:26 +00:00
drh 339fbb64be Merge recent trunk enhancements into the reuse-schema branch.
FossilOrigin-Name: d71adc3fd85cfc5902b7146101d030ab2fbe932ed05848a407a7422ddeeb4c43
2021-08-03 16:11:59 +00:00
dan 3fc9378b03 Merge latest trunk changes into this branch.
FossilOrigin-Name: 0e968f9de3b706fedb675d058ed713a9e639c46d1482dec98c3449567242501e
2021-07-09 13:29:19 +00:00
drh bfab6fb822 Merge version 3.36.0
FossilOrigin-Name: 792215204d887ecb8b1a0d65773d272b84606c9867b52d94701039de5c8bb12c
2021-06-18 19:01:15 +00:00
drh 371cc2491f Merge recent trunk enhancements into reuse-schema branch.
FossilOrigin-Name: 92d8f967c9a7e4005c63703af8075b3d2ae5aa43c6b5bc6e599735dc4479bef6
2021-06-17 17:26:53 +00:00
dan babfb2e536 Update this branch with latest changes from trunk.
FossilOrigin-Name: f21a53fb4141eaeca2fb33b25bbadfad4e461b0ed1a3526f54a42316f3dd5d9b
2021-06-14 14:35:33 +00:00
drh 1b0b429f23 The SQLITE_ENABLE_SHARED_SCHEMA compile-time option is on by default in the
configure-generated makefile, permitting a complete test of this branch
using "./configure && make test".

FossilOrigin-Name: e867d226226dafd850a5cdd1f8d5688b106ee2deee52602b2718bb59dd184742
2021-05-27 15:24:59 +00:00
dan ea8f049012 Merge latest trunk changes into this branch.
FossilOrigin-Name: dbc65a695877306e2add75aba2a279efbb30bfadb5339883cf74aa417f11de86
2021-05-22 15:05:02 +00:00
dan 356f24f0d3 Merge version 3.35.4 with this branch.
FossilOrigin-Name: e69f29892e5226957578b06e9f7966a8e820fc72c0a8b0a83773fb168caa500f
2021-04-07 15:13:47 +00:00
drh 6857efa5a8 Merge in changes for 3.35.3
FossilOrigin-Name: 76f19f4bcfc0228df669c89e0676845e98bbfe161d77b4573d6db513b751a8ca
2021-03-26 13:16:06 +00:00
drh 4d55331f24 Update to version 3.35.2
FossilOrigin-Name: 18bec0d263bd79ca94b5c9e196434e587fbce246178d329d4243ced0ad25ba10
2021-03-17 19:52:33 +00:00
drh 082f003903 Merge version 3.35.1 into the reuse-schema branch.
FossilOrigin-Name: 0fe60a63ae50acce53d576af98cf2fdd9a49f992168fe5be066abce13d1c9fa9
2021-03-15 19:34:44 +00:00
drh 017616e441 Merge the 3.35.0 release into the reuse-schema branch.
FossilOrigin-Name: c8237a024d14fc7827fec89d768cb533b78a77a2ed3b9b6df43f262d257d98a6
2021-03-12 17:26:59 +00:00
dan 89f4e8c325 Update this branch with latest fixes from trunk.
FossilOrigin-Name: 12363f8e176690d237b06e2fa6e9e3710574bdf841b8f6cef0cce34646367aa1
2021-03-11 21:00:42 +00:00
dan 8af662c8d6 Merge latest trunk changes into this branch.
FossilOrigin-Name: ef8c6e06cb094c5a6f5862f0f3f2a67c3db40dc39e520cc421311bcb55e0f762
2021-03-11 10:55:08 +00:00
drh ce3cc96805 Merge recent trunk enhancements into the reuse-schema branch.
FossilOrigin-Name: 73bf458e1dbe21e19b7b283d5d7534dd8bcb01475570958fc2291e805c1cc56d
2021-03-03 19:54:08 +00:00
dan 7dd6817e58 Merge latest trunk changes into this branch.
FossilOrigin-Name: d29c41bd2670ccd205ca6190aa071c0ac7e9748bd9425fbfec0aa7acc8ae0aeb
2021-02-10 20:20:35 +00:00
dan 2f35820fdc Merge latest trunk changes into this branch.
FossilOrigin-Name: 9f41f604055553f0c62d4c0d5a00c6a43d1a938f36901238c52c065702b9c536
2020-12-17 11:30:12 +00:00
dan 85aaf75855 Update this branch with latest trunk changes.
FossilOrigin-Name: 846e8444f761a4f3e3e0fb89e87b329799a6e8dd32ac7580dc20eb6ff9ed0d36
2020-12-04 18:47:28 +00:00
drh 36b4ffef75 Merge the 3.34.0 release into the reuse-schema branch.
FossilOrigin-Name: 73b5f614cd6603d6cf9605ac4ccb510a2560fca70a8a3f3f930cf2a4e853c301
2020-12-01 16:36:04 +00:00
dan bd89471096 Merge trunk changes into this branch.
FossilOrigin-Name: f4b7c10057a50c5b1f38d4e35ec684ad9d6e21278675fec98961e1fa408ded52
2020-11-25 20:29:45 +00:00
dan 5422f18381 Merge trunk changes into this branch.
FossilOrigin-Name: 6004de525d90e5a32742349db9a7c818e1ae2d3bf3f57aff9058a3cb8f6f0fff
2020-11-18 21:15:42 +00:00
dan 934eb637c2 Merge latest trunk changes into this branch.
FossilOrigin-Name: ae1a778dbbab2beb171678c55b82a0dc095b1515ae16059e199af510bcf89c03
2020-09-07 11:23:22 +00:00
dan 8280fcc66f Merge tsan error fix from trunk into this branch.
FossilOrigin-Name: 93cc60b34278ec45e382edbd99aa22268eb32bfe6c917bad7d1e9f158cedf57b
2020-09-04 19:12:16 +00:00
dan 5a5f8b366b Update this branch with latest changes from trunk.
FossilOrigin-Name: ca8deb44c70c3d8a1cdde5bb92a3db812e4e38bfce9a97feb658594c8267609f
2020-09-04 17:40:22 +00:00
drh 73d2d7938e Merge the 3.33.0 release into the reuse-schema branch.
FossilOrigin-Name: e456d437083c550570063b874d685f110162a0551f51d5f190f90c1354e6e996
2020-08-14 13:55:40 +00:00
drh e805679133 Merge all changes since the 3.32.0 release into the reuse-schema branch.
FossilOrigin-Name: b1a77b7eade14d58b3ccd50b98c2ffb6362d093f2cde2bd178ea62cef2cb8d9f
2020-08-11 14:55:17 +00:00
drh bb85a9053e Update the reuse-schema branch to version 3.32.1
FossilOrigin-Name: ecf8dece0362b79d248bae1847d2224d18af395c336a604bbcf2b29ffab645d5
2020-05-25 16:34:57 +00:00
drh 19b2d07824 Merge version 3.32.0 into the reuse-schema branch.
FossilOrigin-Name: 31706878c3ab3ad8f84035553f0c4de25af1e371577e7caccba191fe172905ee
2020-05-22 18:41:15 +00:00
drh 02d30805c8 Bring the reuse-schema branch up to date with the latest trunk changes.
FossilOrigin-Name: d8ea0cb69d9b47c2d3e1048671623cada18cc997612edf8f617ea48882e2b052
2020-05-18 19:11:35 +00:00
drh 6d78967393 Merge trunk enhancements in the reuse-schema branch.
(Actual date of this check-in is 2020-05-18.)

FossilOrigin-Name: 5af4abe98c747ff5c6a84b6cc1f7b69d9b492a807a8fd5234163f3bd9c96c574
2020-05-16 18:59:59 +00:00
dan 006f49bc9b Merge trunk change [895bd20b29] into this branch.
FossilOrigin-Name: 507f972e91ffdc8d80a6ce594139ea4c7afad38791a08032637340fbf49842bc
2020-03-05 18:59:59 +00:00
drh 0a6e45f4d9 Merge trunk enhancements into the reuse-schema branch.
FossilOrigin-Name: 9d068e1ef04e84c025d2f696919dd5d1fe385abacbbd3ea31da58c74ae2812bf
2020-03-05 16:30:00 +00:00
dan 8e8c7ccc9b Merge latest trunk changes into this branch.
FossilOrigin-Name: 3f5650aae69498fce8c3f2b9c9e67e52f676776ea6d8a2f0f153fdeb8857231c
2020-02-27 15:20:37 +00:00
drh c3c71c1451 Merge in version 3.31.0
FossilOrigin-Name: f418afa1bfde909bb90a60990e16be6beace9788319a5e1871e94b442fcd688c
2020-01-22 20:02:11 +00:00
drh 5e87610fdf Merge recent fixes from trunk.
FossilOrigin-Name: 9c920bbad3d0a79279e8ff89a01d0f197c77d0a530ac51c57e57fe6db316c905
2020-01-20 15:32:47 +00:00
dan d3698b7fe8 Fix a couple of test case issues on this branch.
FossilOrigin-Name: 9830a44bc65e1176ca11ae84d7a291e6986662d2bbac5e352ae6e2423358c60b
2020-01-18 19:58:06 +00:00
dan 72d2de6eef Have this branch call sqlite3LockAndPrepare() instead of sqlite3Prepare() when parsing SQL for new schema objects in order to ensure that schemas are released as soon as possible.
FossilOrigin-Name: 7a4ec57985fc5d980048bb7f1677452fb8cc4825cff8956760a1747b81b648bb
2020-01-18 18:59:15 +00:00
drh 0df48684bd Fix the assert_schema_state_ok() routine so that it correctly ignores
ATTACH-ed database that failed to open due to an error.

FossilOrigin-Name: 1194a42add4119715347bb592feef352e4958d0c669c946d976a42049a712b68
2020-01-15 17:18:34 +00:00
drh 106ab91fc8 Merge all recent enhancements and fixes from trunk.
FossilOrigin-Name: f783917800a5ce7c4bb31725b26d266cd4f133a0cc8414c6bf4789a8cd1e45c8
2020-01-15 14:26:58 +00:00
drh 806e04ab8f Bring the reuse-schema branch up-to-date with version 3.30.0.
FossilOrigin-Name: 6e09afecd6086211253b5f8eab718dde097f92a88100e54604a3f063c1a1fc98
2019-10-04 15:31:42 +00:00
drh eb888e2497 Merge in the 3.30.0 beta 1 changes.
FossilOrigin-Name: 067961241293b99b7f716e6f05e302b8354c9e7216296148b6f4ab59f8d3f4b0
2019-09-30 16:57:25 +00:00
drh d973196e30 Merge all recent trunk enhancements into the reuse-schema branch.
FossilOrigin-Name: 27eb223690989a294c5aad7a8ab1927904b1041e36ce7a0c04800bce49ec9142
2019-09-16 12:35:48 +00:00
dan f6b6f46538 Merge latest trunk changes with this branch.
FossilOrigin-Name: 5b4689d89cd27b238586ddee638b856145a9731ff70ffcb1659613528b792167
2019-08-13 15:22:10 +00:00
dan f8f62070f8 In shared-schema mode, handle the case where a connection has created a virtual-table object, but is later assigned a different shared-schema object for which the virtual-table schema has not yet been initialized.
FossilOrigin-Name: e30c7414fe483fcb68aeedd364dc5a3da62b01a80808a917016a9f148f1f3130
2019-08-09 14:54:44 +00:00
dan 73debcccd1 Fix spurious "no such table: x1" errors in shared-schema mode that could occur
when a query that is a join across two or more databases needs to call the xConnect() methods of a virtual table.

FossilOrigin-Name: edf45cd7c6c1122db961ae66c21c7e974115e6048f1f5014015a5f693f1844bf
2019-08-08 15:47:32 +00:00
dan 1430806e39 Fix a bug causing "no such table" and other similar sqlite3_prepare*() errors to return SQLITE_SCHEMA instead of SQLITE_ERROR in shared-schema mode when there is an attached database for which the schema has never been loaded.
FossilOrigin-Name: 111e2c73cf430ae61e3f4cc34a1bee8ac7025b8a960fc3f3b7f493009b759ad7
2019-08-08 11:44:57 +00:00
dan 49c7657ac9 Add a multi-threaded test to threadtest3.c for the feature on this branch.
FossilOrigin-Name: 62557fab0d21d47893e69d504ae2b4405c1837ccd6300a5a6743cb756eb28ad3
2019-08-06 15:02:49 +00:00
dan e046ccb5f0 Add an assert() to the code on this branch.
FossilOrigin-Name: fdd44bbb501c7252097e79685e916e760846e183bc9f022f9cf32f1d32f0089d
2019-08-06 11:45:33 +00:00
dan 0b5d397cb4 Merge latest changes from trunk into this branch.
FossilOrigin-Name: 7f1e4e4b99644f986aa68bd40afddc4886145972eae1106347185eeff52150d6
2019-07-26 20:54:05 +00:00
drh 2833522a9a Add a ctime.c entry for SQLITE_ENABLE_SHARED_SCHEMA.
FossilOrigin-Name: 892ac94511a41dc4043ceb76aae267b1252d08fee41c475fb848c15519477adb
2019-07-18 19:50:54 +00:00
dan 06526fef2e Modify the bits used for special flags on this branch to account for the fact that some of them are now used for other purposes.
FossilOrigin-Name: 5a8d0f50f3c4dedfd7f97daba4cb1a8cfbe3bc44e0834199d4dd93a0d062ef81
2019-07-18 13:33:00 +00:00
drh 7e0410951f Merge the version 3.29.0 release enhancements into the reuse-schema branch.
FossilOrigin-Name: 9819ead089ef5ed92f529d9addbd89760ca5be7eacb3d209c99f639ec5761004
2019-07-10 18:45:50 +00:00
drh abbad7ef3c Merge recent trunk enhancements into the reuse-schema branch.
FossilOrigin-Name: fae92fee54685cf0d44937e246e79652ee4679baa3bfb2774ff3ecf739a1e1e7
2019-07-08 21:32:00 +00:00
drh cdfb4a29f4 Updates to the shared_schema.md notes document.
FossilOrigin-Name: 51af2ade8eddae16a7290ab9676bcb4a677f0be72959640d0b664966398d8319
2019-06-03 14:02:58 +00:00
drh ce86700aa7 In the CLI, add ".help" text for the .shared-schema command.
FossilOrigin-Name: 3ba6f790e029f8c66b9ba16c657463606e6d45e095a498407154477c1358fbb2
2019-06-03 13:46:50 +00:00
drh 5593a4c26d The ".shared-schema" command in the CLI requires the sqlite_dbpage table,
so disable it if the build does not include that extension.

FossilOrigin-Name: 0913ff4dc38290677357885ca40fe19ce45dafea6168a4e7403f0af083a48c65
2019-05-24 13:15:52 +00:00
drh 88e7099875 Merge recent enhancements from trunk.
FossilOrigin-Name: ff9f3e09510b4418cb166fa2557598a279e7baedc315a5d1c3ae63beb92c238d
2019-05-24 13:04:55 +00:00
drh 28c156d6d6 Merge all the latest trunk enhancements into the reuse-schema branch.
FossilOrigin-Name: 018f3199b9ba043fbbf88ec46b4fa16728f6507e000f4813ed346aaf6665add6
2019-05-14 22:25:26 +00:00
drh e2e8e9b16f Merge recent changes from trunk into reuse-schema
FossilOrigin-Name: 5c6c9e7f6f83d565b317e3442e8bc664478adb407fe416d068fe0dcd17ffa5b5
2019-04-15 15:35:43 +00:00
dan ff0e1d8d04 Remove a "puts" statement accidentally left in a test script.
FossilOrigin-Name: 9f591ac07871958d173ae4cf9065c8000a9efb80676d158935d2700fff61a361
2019-03-26 19:14:50 +00:00
dan 98c5bff6c8 Add a few extra tests for SQLITE_STATUS_SCHEMA_USED with shared-schema databases.
FossilOrigin-Name: e399fede7b27a70f90e363d987f23004d7015844f38d00d6d216433d70e4b901
2019-03-26 18:40:38 +00:00
drh 3eadd64c0e Merge recent trunk enhancements.
FossilOrigin-Name: db4e2cc36acca2708e9bd2e0febb4e1b3d6a6a3fa60d9bd6f2a49f4a8d1bc523
2019-03-26 11:57:50 +00:00
dan d32261e7a9 Merge latest trunk changes with this branch.
FossilOrigin-Name: 3196f5f480f221dc71bb92e6718a5c356782774be25df4df79dda0ac1101255a
2019-03-21 17:22:05 +00:00
dan 6847647dc4 Disable the feature on this branch in non-SQLITE_ENABLE_SHARED_SCHEMA builds.
FossilOrigin-Name: b8e536089b0e6dec500a28556f826c99b78d979615ba3bc01ed31ead1b2112df
2019-03-21 17:13:55 +00:00
dan ae070eff74 Use the IsReuseSchema() macro more consistently. Also, rename it to IsSharedSchema().
FossilOrigin-Name: c1be211c0286a6ff3ef8ab6839136175efb000118ff8704d3cc01b2a23b841ab
2019-03-20 20:02:03 +00:00
dan f4c01da150 Fix an error message.
FossilOrigin-Name: a70fdaa3903835dca338d68e750716fd3ab9dedbdfb2be6d6e058fd5fcb415fa
2019-03-20 19:17:45 +00:00
dan 0d46c528dd Merge latest trunk changes into this branch.
FossilOrigin-Name: 4cd20ca6776ef1c2f041fe6d30f84a3cf5f8a634eb34db2dce3217ee781d5848
2019-03-20 16:03:02 +00:00
dan 209f79234b Merge latest trunk changes into this branch.
FossilOrigin-Name: 97a9604d85cf5044e8109e533d4682b25bfe6a110f403ebd0fdef03880059f37
2019-03-04 07:25:38 +00:00
dan 22b16ac3d0 Update doc/shared_schema.md to describe the shell tool ".shared-schema" dot-command.
FossilOrigin-Name: 0ce2092a5968d75d014fdc238391c362a9600c28bf18cdc631e98259a5278712
2019-02-26 16:36:21 +00:00
dan 88a96c49f2 Add new test file reuse5.test. For testing the shell tool ".shared-schema" command.
FossilOrigin-Name: fa6008d547c6b24108a26e022f3f427fa19ffae006c88fee9de97d2244521de0
2019-02-26 16:13:43 +00:00
dan 85a76ddc12 Add the ".shared-schema check|fix DB1 DB2..." command to the shell tool. For checking if a database is eligible to share an in-memory with the main database, and for fixing small problems that prevent it from being so.
FossilOrigin-Name: 7d8e8a957235479fba568e1d3ff2cdfe4695184ee1a7ac64bce905a993725164
2019-02-26 15:43:45 +00:00
dan 20a434abd3 Fix a comment in build.c.
FossilOrigin-Name: d6a9bff6f5cc52957deffe47fdba1197db111cac110760dec7680f91499a99f1
2019-02-25 19:23:01 +00:00
dan 9c2b284dbd Merge latest trunk changes into this branch.
FossilOrigin-Name: 5c1cf30859ed734eb2d6bc52adb057ca62a6b5a7eef66d8da1fa833e84468dee
2019-02-25 18:07:09 +00:00
dan 74e020a164 Where possible, avoid loading all schemas into memory for PRAGMA statements.
FossilOrigin-Name: 64f97530ad387655767b5205fb9a9c723210cd4975176ab6fb71bca0cb585a74
2019-02-25 17:54:23 +00:00
dan 94dba01337 Merge latest trunk changes into this branch.
FossilOrigin-Name: 001771afd0567c04736a778fc78fd7144492ae7c830e7f55de61869ce988f0ed
2019-02-22 17:44:58 +00:00
dan 239f69e204 Further test cases and fixes for SQLITE_OPEN_SHARED_SCHEMA.
FossilOrigin-Name: ba0ab042f401a9d3b81dc546573214bbe2ad712c932aafcf0c045f189bbf09ca
2019-02-20 18:44:28 +00:00
dan 05a094d4c5 Add test and fixes for SQLITE_OPEN_SHARED_SCHEMA mode.
FossilOrigin-Name: 9a78d89c8427ae737d4798cc146e41ada7cb83f4e39dcf3ac9469c510ed37673
2019-02-20 17:36:10 +00:00
dan aec53fa5ba Improve error messages caused by corrupt database schemas in OPEN_SHARED_SCHEMA mode.
FossilOrigin-Name: 8ac75b8a880447ea67cf7646fc5af1379ce35861f396634119d7381e1dde404a
2019-02-19 18:00:28 +00:00
dan a011145aae Ensure that creating temp schema items does not cause an OPEN_SHARABLE_SCHEMA connection to load all schemas into memory.
FossilOrigin-Name: 88cbf54eee7845f9e40e6879fc38eb98a80e81c987b7edeb39f3058590003347
2019-02-18 18:16:05 +00:00
dan 13af9ba7af Enhance the virtual table in test_schemapool.c so that it can be used to check that SHARED_SCHEMA connections are not allocating and freeing schemas when they should not be.
FossilOrigin-Name: cb236cb98564b870317ba3e481a3c7d7f9769b0294a01246bcb724f04e1e7b10
2019-02-15 19:36:47 +00:00
dan 6170a98cfa Fix a problem with eponymous virtual tables and SHARED_SCHEMA databases. Also, after preparing statements that require all database schemas (REINDEX, ANALYZE, CREATE, DROP and some PRAGMA statements), do not allow the database connection to return more than one schema to each schema-pool.
FossilOrigin-Name: ecf6251ec0bb745a4ef9bad9f9ecd3babb687a3806fd96554b265313625270c5
2019-02-15 19:00:41 +00:00
dan d0932d5358 Revert the rearrangement of VDBE code in [219b39e14] so that vdbe.c matches trunk. Since the new call to sqlite3Init() in OP_ParseSchema was removed, the rearrangement no longer provides any performance advantage.
FossilOrigin-Name: 03c4f00317233a34f29e1218786166d17837d47206532a29d2713093f01adea5
2019-02-15 11:54:57 +00:00
dan 61155cb70b Fix SQLITE_DBSTATUS_SCHEMA_USED so that it works with SQLITE_OPEN_SHARED_SCHEMA connections.
FossilOrigin-Name: d43b3c056cb13930865c504c9498b2c83e4bebce9bff01ee21293e7dc7a6711e
2019-02-14 21:04:27 +00:00
dan d746d250f0 Change the name of the SQLITE_OPEN_REUSE_SCHEMA flag to SQLITE_OPEN_SHARED_SCHEMA.
FossilOrigin-Name: 7257fcc8c990b46a4f6a9e506f4a4a40195e6b2c626efd380cfa01f0ce8eb0fb
2019-02-14 18:38:44 +00:00
dan 155a112b81 Fix a typo in shared_schema.md.
FossilOrigin-Name: e47a5aea76560e86e5417fea9e2219ec6c30e47ef383e499cfe927f64d584dac
2019-02-14 17:59:36 +00:00
dan a5150d4f05 Add documentation file doc/shared_schema.md to describe the change on this branch.
FossilOrigin-Name: a5f8067dde1e8974f779ab838a02416a7dd9d20d253af860d08d635cfede6fee
2019-02-14 17:51:38 +00:00
dan 64104062a7 Merge latest trunk into this branch.
FossilOrigin-Name: 577d1638362666a8220401d0d0d8bfb3c028ab09e7def1e4bf195db37269c22f
2019-02-14 15:56:59 +00:00
dan 1395c92f1f Add missing comments and fix other code issues in the new functions in callback.c.
FossilOrigin-Name: 441cabb62fe14bbef8b19066941426eeb2de128564ec2bfb762228fdae794447
2019-02-14 15:47:18 +00:00
dan 33a37f5ef0 Fix for sqlite3_table_column_metadata() on REUSE_SCHEMA databases.
FossilOrigin-Name: 53220ad7809954eb4118d9127849efa82787f43898af00c9127cd4998a12c619
2019-02-13 19:17:30 +00:00
dan 9d65677e57 Avoid crashing after parsing a corrupt schema with a REUSE_SCHEMA connection.
FossilOrigin-Name: b102148e71c0102eedbf28d9bc8ea8d9bd742eac45ee7f1b08ece60bcdab5036
2019-02-13 18:29:49 +00:00
dan 6758315c8e Fix a problem with the incrblob API and reusable schemas.
FossilOrigin-Name: 34f0f96f47040df1e305ac9fd4664c5ed4246580e22a00573c73d6528a5725b5
2019-02-13 15:51:07 +00:00
drh 5944230305 Rearrange the code in the VDBE to help out the C-compiler optimizer.
And fix a harmless compiler warning.

FossilOrigin-Name: 219b39e149a0334b577e094e066e1ca2fe686b408468e9f196611490f3a82810
2019-02-13 14:06:56 +00:00
drh a72a438cd7 Performance optimization in the VDBE, and a fix for a harmless compiler
warning.

FossilOrigin-Name: e002666ac79c3452a772323c6ecc696104341cd842e77541553ec028f188096b
2019-02-13 13:48:48 +00:00
dan d62150108a Fix a problem with OPEN_REUSE_SCHEMA connections reloading the temp schema.
FossilOrigin-Name: 7c2ec2d4cfcda9c0aa6d57bd9a12ff98b78e648533d49da27f91d5a37bf1e001
2019-02-13 08:40:34 +00:00
dan 2ce6757bd4 Add tests for creating temp schema objects with SQLITE_OPEN_REUSE_SCHEMA connections.
FossilOrigin-Name: 8c07b609fccc43795498b942c733896defd8887e4ddd9e0ef48c124dfcf9fd7f
2019-02-12 20:58:34 +00:00
dan 33d1394e1a Share schemas between databases attached to the same database handle.
FossilOrigin-Name: ea611d7cba604dc901c8088ccfa13367a5ee75f9499ea8d8b62a590daac2eae0
2019-02-12 19:20:33 +00:00
dan 81fb4ef019 Merge latest trunk changes into this branch.
FossilOrigin-Name: dbedd81bf2e29ae9ed88526c1cc97e5c4d0a256ad7d960304bbb5e15c44f51f0
2019-02-11 20:13:13 +00:00
dan d4e11dd78f Add eponymous virtual table "schemapool". For inspecting the current contents of the schema-pool.
FossilOrigin-Name: 2ebeb747832bd53284ab23b4c2558f0fa550c0ea2b4a6c1640eeb83f8132c556
2019-02-11 19:34:38 +00:00
dan 5add6f25e2 Fix virtual table support for SQLITE_OPEN_REUSABLE_SCHEMA connections.
FossilOrigin-Name: 3ca8856a7b1c36885cea007b8fb05b59f1fdc9d4b54436819193f498519a23c7
2019-02-09 17:47:14 +00:00
dan 30fdc47579 Add test cases and fix problems on this branch.
FossilOrigin-Name: 2b2e9f81cdc7a3ac1eacc087fbd0414ead732878aae296bab6b54b4a7cd0a06e
2019-02-08 19:30:09 +00:00
dan 73e6f3adbd Merge latest trunk into this branch.
FossilOrigin-Name: c089cc4fbe2e5e53d76154146870d14fc3b8d342a49580e41a5616817099715c
2019-02-05 19:51:15 +00:00
dan 73b8e1f2d6 Fix memory leaks on this branch.
FossilOrigin-Name: e9c5e1891ff4f7e57131031f068efea87027ddab0cd7846e0514a105853be47d
2019-02-05 19:15:36 +00:00
dan 01d6eab9a5 Fix a problem with reloading the schema on this branch.
FossilOrigin-Name: 5dfbef8349e47f9d9fcdbb648ecd18b5bc7eebdb1a3ddaf91789d036b7de8a90
2019-02-04 21:02:00 +00:00
dan e54087db7b Try new approach ensuring that each Schema object is only used by one connection/database at any one time.
FossilOrigin-Name: 9e8e5f52cf90579c3071f04a3c6857bb76b4ca1b1900a7f865de789ed0bb8678
2019-02-02 21:02:22 +00:00
dan d000f2286d Merge latest trunk changes with this branch.
FossilOrigin-Name: ae88f8e1ffc33748e45308c21ba83499228ae05344df81e41dd61e14a1270588
2018-11-09 18:44:45 +00:00
drh 8874678ecd Add the ability to open a database connection in -reuseschema mode in the CLI.
Adjust memory allocation accounting so that a shared schema is allocated
across each database sharing it.

FossilOrigin-Name: 3869b2106b9a639b5e739dc9f9acd2f7a9223d3ce562297b877c5d4d2bf76468
2018-10-08 23:29:05 +00:00
dan 8612853f70 Fix a problem with using virtual tables via reuse-schema connections.
FossilOrigin-Name: e5897dafda2b003c34eeecb44e091e2ac0d8589c9db728a0b02fb56966cfc9b7
2018-10-08 20:57:35 +00:00
drh 62012c0b34 Merge fixes from trunk.
FossilOrigin-Name: 9c8255a199d6544b02302bfe3ecd253098821170646a509d2e3dc6cf4e43289b
2018-10-08 20:37:21 +00:00
dan 7d3159668c Merge latest trunk changes into this branch.
FossilOrigin-Name: 2ac72114a1f5344b42472b941c60f460c28c981a22ea40909b30f7bf4eb4b11b
2018-10-08 18:58:51 +00:00
dan d6af93a92c Add experimental sqlite3_open_v2() flag SQLITE_OPEN_REUSE_SCHEMA. For sharing
identical in-memory schema objects between connections.

FossilOrigin-Name: a625698048c05375f12ea8875892fdbf3518291f10917fe68dd2294280cd3b42
2017-08-09 20:35:10 +00:00
86 changed files with 4309 additions and 489 deletions
+5 -1
View File
@@ -140,6 +140,7 @@ GCOV_LDFLAGS1 = -lgcov
USE_GCOV = @USE_GCOV@
LTCOMPILE_EXTRAS += $(GCOV_CFLAGS$(USE_GCOV))
LTLINK_EXTRAS += $(GCOV_LDFLAGS$(USE_GCOV))
LTCOMPILE_EXTRAS += -DSQLITE_ENABLE_SHARED_SCHEMA
# The directory into which to store package information for
@@ -419,6 +420,7 @@ TESTSRC = \
$(TOP)/src/test_quota.c \
$(TOP)/src/test_rtree.c \
$(TOP)/src/test_schema.c \
$(TOP)/src/test_schemapool.c \
$(TOP)/src/test_server.c \
$(TOP)/src/test_superlock.c \
$(TOP)/src/test_syscall.c \
@@ -480,6 +482,7 @@ TESTSRC2 = \
$(TOP)/src/bitvec.c \
$(TOP)/src/btree.c \
$(TOP)/src/build.c \
$(TOP)/src/callback.c \
$(TOP)/src/ctime.c \
$(TOP)/src/date.c \
$(TOP)/src/dbpage.c \
@@ -503,6 +506,7 @@ TESTSRC2 = \
$(TOP)/src/pcache1.c \
$(TOP)/src/select.c \
$(TOP)/src/tokenize.c \
$(TOP)/src/treeview.c \
$(TOP)/src/utf.c \
$(TOP)/src/util.c \
$(TOP)/src/vdbeapi.c \
@@ -874,7 +878,7 @@ hash.lo: $(TOP)/src/hash.c $(HDR)
insert.lo: $(TOP)/src/insert.c $(HDR)
$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/insert.c
json.lo: $(TOP)/src/json.c
json.lo: $(TOP)/src/json.c $(HDR)
$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/json.c
legacy.lo: $(TOP)/src/legacy.c $(HDR)
+1
View File
@@ -1537,6 +1537,7 @@ TESTSRC = \
$(TOP)\src\test_quota.c \
$(TOP)\src\test_rtree.c \
$(TOP)\src\test_schema.c \
$(TOP)\src\test_schemapool.c \
$(TOP)\src\test_server.c \
$(TOP)\src\test_superlock.c \
$(TOP)\src\test_syscall.c \
+1 -1
View File
@@ -1 +1 @@
3.39.0
3.39.4
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.39.0.
# Generated by GNU Autoconf 2.69 for sqlite 3.39.4.
#
#
# 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.39.0'
PACKAGE_STRING='sqlite 3.39.0'
PACKAGE_VERSION='3.39.4'
PACKAGE_STRING='sqlite 3.39.4'
PACKAGE_BUGREPORT=''
PACKAGE_URL=''
@@ -1468,7 +1468,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.39.0 to adapt to many kinds of systems.
\`configure' configures sqlite 3.39.4 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1533,7 +1533,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
short | recursive ) echo "Configuration of sqlite 3.39.0:";;
short | recursive ) echo "Configuration of sqlite 3.39.4:";;
esac
cat <<\_ACEOF
@@ -1661,7 +1661,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
sqlite configure 3.39.0
sqlite configure 3.39.4
generated by GNU Autoconf 2.69
Copyright (C) 2012 Free Software Foundation, Inc.
@@ -2080,7 +2080,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.39.0, which was
It was created by sqlite $as_me 3.39.4, which was
generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@
@@ -12390,7 +12390,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.39.0, which was
This file was extended by sqlite $as_me 3.39.4, which was
generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -12456,7 +12456,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.39.0
sqlite config.status 3.39.4
configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\"
+142
View File
@@ -0,0 +1,142 @@
Shared-Schema Mode Notes
========================
The [reuse-schema](/timeline?r=reuse-schema) branch contains changes
to allow SQLite connections to share schemas
between database connections within the same process in order to save memory.
Schemas may be shared between multiple databases attached to the same or
distinct connection handles.
Compile with -DSQLITE\_ENABLE\_SHARED\_SCHEMA in order to enable the
shared-schema enhancement. Enabling the shared-schema enhancement causes
approximately a 0.1% increase in CPU cycles consumed and about a 3000-byte
increase in the size of the library, even if shared-schema is never used.
Assuming the compile-time requirements are satisfied, the shared-schema
feature is engaged by opening the database connection using the
sqlite3&#95;open&#95;v2() API with the SQLITE&#95;OPEN&#95;SHARED&#95;SCHEMA
flag specified. The main database and any attached databases will then share
an in-memory Schema object with any other database opened within the process
for which:
* the contents of the sqlite&#95;master table, including all object names,
SQL statements and root pages are identical, and
* have the same values for the schema-cookie.
Temp databases (those populated with "CREATE TEMP TABLE" and similar
statements) never share schemas.
Connections opened with the SQLITE&#95;OPEN&#95;SHARED&#95;SCHEMA flag
specified may not modify any database schema except that belonging to the
temp database in anyway. This includes creating or dropping database
objects, vacuuming the database, or running ANALYZE when the
sqlite&#95;stat\[14\] tables do not exist.
For SQLITE&#95;OPEN&#95;SHARED&#95;SCHEMA connections, the
SQLITE&#95;DBSTATUS&#95;SCHEMA&#95;USED sqlite3&#95;db&#95;status() verb
distributes the memory used for a shared schema object evenly between all
database connections that share it.
## The ".shared-schema" Command
The shell tool on this branch contains a special dot-command to help with
managing databases. The ".shared-schema" dot-command can be used to test
whether or not two databases are similar enough to share in-memory schemas,
and to fix minor problems that prevent them from doing so. To test if
two or more database are compatible, one database is opened directly using
the shell tool and the following command issued:
.shared-schema check <database-1> [<database-2>]...
where &lt;database-1&gt; etc. are replaced with the names of database files
on disk. For each database specified on the command line, a single line of
output is produced. If the database can share an in-memory schema with the
main database opened by the shell tool, the output is of the form:
<database> is compatible
Otherwise, if the database cannot share a schema with the main db, the output
is of the form:
<database> is NOT compatible (<reason>)
where &lt;reason&gt; indicates the cause of the incompatibility. &lt;reason&gt;
is always one of the following.
<ul>
<li> <b>objects</b> - the databases contain a different set schema objects
(tables, indexes, views and triggers).
<li> <b>SQL</b> - the databases contain the same set of objects, but the SQL
statements used to create them were not the same.
<li> <b>root pages</b> - the databases contain the same set of objects created
by the same SQL statements, but the root pages are not the same.
<li> <b>order of sqlite&#95;master rows</b> - the databases contain the same
set of objects created by the same SQL statements with the same root pages,
but the order of the rows in the sqlite&#95;master tables are different.
<li> <b>schema cookie</b> - the database schemas are compatible, but the
schema cookie values ("PRAGMA schema&#95;version") are different.
</ul>
The final three problems in the list above can be fixed using the
.shared-schema command. To modify such a database so that it can share a
schema with the main database, the following shell command is used:
.shared-schema fix <database-1> [<database-2>]...
If a database can be modified so that it may share a schema with the main
database opened by the shell tool, output is as follows:
Fixing <database>... <database> is compatible
If a database does not require modification, or cannot be modified such that
it can share a schema with the main database, the output of "fix" is identical
to that of the "check" command.
## Implementation Notes
A single Schema object is never used by more than one database simultaneously,
regardless of whether or not those databases are attached to the same or
different database handles. Instead, a pool of schema objects is maintained
for each unique sqlite&#95;master-contents/schema-cookie combination
opened within the process. Each time database schemas are required by a
connection, for example as part of an sqlite3&#95;prepare\*(),
sqlite3&#95;blob&#95;open() or sqlite3&#95;blob&#95;open() call, it obtains
the minimum number of schemas required from the various schema-pools, returning
them at the end of the call. This means that a single schema-pool only ever
contains more than one copy of the schema if:
* Two threads require schemas from the same pool at the same time, or
* A single sqlite3&#95;prepare\*() call requires schemas for two or more
attached databases that use the same schema-pool.
The size of a schema-pool never shrinks. Each schema pool always maintains
a number of schema objects equal to the highwater mark of schema objects
simultaneously required by clients.
This approach is preferred to allowing multiple databases to use the same
Schema object simultaneously for three reasons:
* The Schema object is not completely read-only. For example, the
Index.zIdxAff string is allocated lazily.
* Throughout the statement compiler, SQLite uses variables like
Table.pSchema and Index.pSchema with the sqlite3SchemaToIndex() routine
in order to determine which attached database a Table or Index object
resides in. This mechanism does not work if the same Schema may be
used by two or more attached databases.
* It may be easier to modify this approach in order to allow
SQLITE&#95;OPEN&#95;SHARED&#95;SCHEMA connections to modify database
schemas, should that be required.
SQLITE&#95;OPEN&#95;SHARED&#95;SCHEMA connections do not store their
virtual-table handles in the Table.pVTable list of each table. This would not
work, as (a) there is no guarantee that a connection will be assigned the same
Schema object each time it requests one from a schema-pool and (b) a single
Schema (and therefore Table) object may correspond to tables in two or more
databases attached to a single connection. Instead, all virtual-table handles
associated with a single database are stored in a linked-list headed at
Db.pVTable.
+11 -9
View File
@@ -2888,7 +2888,7 @@ static int fts3TermSelectMerge(
**
** Similar padding is added in the fts3DoclistOrMerge() function.
*/
pTS->aaOutput[0] = sqlite3_malloc(nDoclist + FTS3_VARINT_MAX + 1);
pTS->aaOutput[0] = sqlite3_malloc64((i64)nDoclist + FTS3_VARINT_MAX + 1);
pTS->anOutput[0] = nDoclist;
if( pTS->aaOutput[0] ){
memcpy(pTS->aaOutput[0], aDoclist, nDoclist);
@@ -4308,8 +4308,7 @@ static int fts3EvalDeferredPhrase(Fts3Cursor *pCsr, Fts3Phrase *pPhrase){
char *aPoslist = 0; /* Position list for deferred tokens */
int nPoslist = 0; /* Number of bytes in aPoslist */
int iPrev = -1; /* Token number of previous deferred token */
assert( pPhrase->doclist.bFreeList==0 );
char *aFree = (pPhrase->doclist.bFreeList ? pPhrase->doclist.pList : 0);
for(iToken=0; iToken<pPhrase->nToken; iToken++){
Fts3PhraseToken *pToken = &pPhrase->aToken[iToken];
@@ -4323,6 +4322,7 @@ static int fts3EvalDeferredPhrase(Fts3Cursor *pCsr, Fts3Phrase *pPhrase){
if( pList==0 ){
sqlite3_free(aPoslist);
sqlite3_free(aFree);
pPhrase->doclist.pList = 0;
pPhrase->doclist.nList = 0;
return SQLITE_OK;
@@ -4343,6 +4343,7 @@ static int fts3EvalDeferredPhrase(Fts3Cursor *pCsr, Fts3Phrase *pPhrase){
nPoslist = (int)(aOut - aPoslist);
if( nPoslist==0 ){
sqlite3_free(aPoslist);
sqlite3_free(aFree);
pPhrase->doclist.pList = 0;
pPhrase->doclist.nList = 0;
return SQLITE_OK;
@@ -4375,13 +4376,14 @@ static int fts3EvalDeferredPhrase(Fts3Cursor *pCsr, Fts3Phrase *pPhrase){
nDistance = iPrev - nMaxUndeferred;
}
aOut = (char *)sqlite3_malloc(nPoslist+8);
aOut = (char *)sqlite3Fts3MallocZero(nPoslist+FTS3_BUFFER_PADDING);
if( !aOut ){
sqlite3_free(aPoslist);
return SQLITE_NOMEM;
}
pPhrase->doclist.pList = aOut;
assert( p1 && p2 );
if( fts3PoslistPhraseMerge(&aOut, nDistance, 0, 1, &p1, &p2) ){
pPhrase->doclist.bFreeList = 1;
pPhrase->doclist.nList = (int)(aOut - pPhrase->doclist.pList);
@@ -4394,6 +4396,7 @@ static int fts3EvalDeferredPhrase(Fts3Cursor *pCsr, Fts3Phrase *pPhrase){
}
}
if( pPhrase->doclist.pList!=aFree ) sqlite3_free(aFree);
return SQLITE_OK;
}
#endif /* SQLITE_DISABLE_FTS4_DEFERRED */
@@ -4742,7 +4745,7 @@ static int fts3EvalIncrPhraseNext(
if( bEof==0 ){
int nList = 0;
int nByte = a[p->nToken-1].nList;
char *aDoclist = sqlite3_malloc(nByte+FTS3_BUFFER_PADDING);
char *aDoclist = sqlite3_malloc64((i64)nByte+FTS3_BUFFER_PADDING);
if( !aDoclist ) return SQLITE_NOMEM;
memcpy(aDoclist, a[p->nToken-1].pList, nByte+1);
memset(&aDoclist[nByte], 0, FTS3_BUFFER_PADDING);
@@ -5568,11 +5571,10 @@ static int fts3EvalTestExpr(
default: {
#ifndef SQLITE_DISABLE_FTS4_DEFERRED
if( pCsr->pDeferred
&& (pExpr->iDocid==pCsr->iPrevId || pExpr->bDeferred)
){
if( pCsr->pDeferred && (pExpr->bDeferred || (
pExpr->iDocid==pCsr->iPrevId && pExpr->pPhrase->doclist.pList
))){
Fts3Phrase *pPhrase = pExpr->pPhrase;
assert( pExpr->bDeferred || pPhrase->doclist.bFreeList==0 );
if( pExpr->bDeferred ){
fts3EvalInvalidatePoslist(pPhrase);
}
+1 -1
View File
@@ -558,7 +558,7 @@ struct Fts3MultiSegReader {
int nAdvance; /* How many seg-readers to advance */
Fts3SegFilter *pFilter; /* Pointer to filter object */
char *aBuffer; /* Buffer to merge doclists in */
int nBuffer; /* Allocated size of aBuffer[] in bytes */
i64 nBuffer; /* Allocated size of aBuffer[] in bytes */
int iColFilter; /* If >=0, filter for this column */
int bRestart;
+1 -1
View File
@@ -621,7 +621,7 @@ static int porterNext(
if( n>c->nAllocated ){
char *pNew;
c->nAllocated = n+20;
pNew = sqlite3_realloc(c->zToken, c->nAllocated);
pNew = sqlite3_realloc64(c->zToken, c->nAllocated);
if( !pNew ) return SQLITE_NOMEM;
c->zToken = pNew;
}
+1 -1
View File
@@ -185,7 +185,7 @@ static int simpleNext(
if( n>c->nTokenAllocated ){
char *pNew;
c->nTokenAllocated = n+20;
pNew = sqlite3_realloc(c->pToken, c->nTokenAllocated);
pNew = sqlite3_realloc64(c->pToken, c->nTokenAllocated);
if( !pNew ) return SQLITE_NOMEM;
c->pToken = pNew;
}
+32 -30
View File
@@ -649,7 +649,7 @@ static int fts3PendingListAppendVarint(
/* Allocate or grow the PendingList as required. */
if( !p ){
p = sqlite3_malloc(sizeof(*p) + 100);
p = sqlite3_malloc64(sizeof(*p) + 100);
if( !p ){
return SQLITE_NOMEM;
}
@@ -658,14 +658,14 @@ static int fts3PendingListAppendVarint(
p->nData = 0;
}
else if( p->nData+FTS3_VARINT_MAX+1>p->nSpace ){
int nNew = p->nSpace * 2;
p = sqlite3_realloc(p, sizeof(*p) + nNew);
i64 nNew = p->nSpace * 2;
p = sqlite3_realloc64(p, sizeof(*p) + nNew);
if( !p ){
sqlite3_free(*pp);
*pp = 0;
return SQLITE_NOMEM;
}
p->nSpace = nNew;
p->nSpace = (int)nNew;
p->aData = (char *)&p[1];
}
@@ -1222,7 +1222,7 @@ int sqlite3Fts3ReadBlock(
int nByte = sqlite3_blob_bytes(p->pSegments);
*pnBlob = nByte;
if( paBlob ){
char *aByte = sqlite3_malloc(nByte + FTS3_NODE_PADDING);
char *aByte = sqlite3_malloc64((i64)nByte + FTS3_NODE_PADDING);
if( !aByte ){
rc = SQLITE_NOMEM;
}else{
@@ -1339,7 +1339,7 @@ static int fts3SegReaderNext(
int nTerm = fts3HashKeysize(pElem);
if( (nTerm+1)>pReader->nTermAlloc ){
sqlite3_free(pReader->zTerm);
pReader->zTerm = (char*)sqlite3_malloc((nTerm+1)*2);
pReader->zTerm = (char*)sqlite3_malloc64(((i64)nTerm+1)*2);
if( !pReader->zTerm ) return SQLITE_NOMEM;
pReader->nTermAlloc = (nTerm+1)*2;
}
@@ -1347,7 +1347,7 @@ static int fts3SegReaderNext(
pReader->zTerm[nTerm] = '\0';
pReader->nTerm = nTerm;
aCopy = (char*)sqlite3_malloc(nCopy);
aCopy = (char*)sqlite3_malloc64(nCopy);
if( !aCopy ) return SQLITE_NOMEM;
memcpy(aCopy, pList->aData, nCopy);
pReader->nNode = pReader->nDoclist = nCopy;
@@ -1634,7 +1634,7 @@ int sqlite3Fts3SegReaderNew(
nExtra = nRoot + FTS3_NODE_PADDING;
}
pReader = (Fts3SegReader *)sqlite3_malloc(sizeof(Fts3SegReader) + nExtra);
pReader = (Fts3SegReader *)sqlite3_malloc64(sizeof(Fts3SegReader) + nExtra);
if( !pReader ){
return SQLITE_NOMEM;
}
@@ -1726,7 +1726,7 @@ int sqlite3Fts3SegReaderPending(
if( nElem==nAlloc ){
Fts3HashElem **aElem2;
nAlloc += 16;
aElem2 = (Fts3HashElem **)sqlite3_realloc(
aElem2 = (Fts3HashElem **)sqlite3_realloc64(
aElem, nAlloc*sizeof(Fts3HashElem *)
);
if( !aElem2 ){
@@ -2060,7 +2060,7 @@ static int fts3NodeAddTerm(
** this is not expected to be a serious problem.
*/
assert( pTree->aData==(char *)&pTree[1] );
pTree->aData = (char *)sqlite3_malloc(nReq);
pTree->aData = (char *)sqlite3_malloc64(nReq);
if( !pTree->aData ){
return SQLITE_NOMEM;
}
@@ -2078,7 +2078,7 @@ static int fts3NodeAddTerm(
if( isCopyTerm ){
if( pTree->nMalloc<nTerm ){
char *zNew = sqlite3_realloc(pTree->zMalloc, nTerm*2);
char *zNew = sqlite3_realloc64(pTree->zMalloc, (i64)nTerm*2);
if( !zNew ){
return SQLITE_NOMEM;
}
@@ -2104,7 +2104,7 @@ static int fts3NodeAddTerm(
** now. Instead, the term is inserted into the parent of pTree. If pTree
** has no parent, one is created here.
*/
pNew = (SegmentNode *)sqlite3_malloc(sizeof(SegmentNode) + p->nNodeSize);
pNew = (SegmentNode *)sqlite3_malloc64(sizeof(SegmentNode) + p->nNodeSize);
if( !pNew ){
return SQLITE_NOMEM;
}
@@ -2242,7 +2242,7 @@ static int fts3SegWriterAdd(
){
int nPrefix; /* Size of term prefix in bytes */
int nSuffix; /* Size of term suffix in bytes */
int nReq; /* Number of bytes required on leaf page */
i64 nReq; /* Number of bytes required on leaf page */
int nData;
SegmentWriter *pWriter = *ppWriter;
@@ -2251,13 +2251,13 @@ static int fts3SegWriterAdd(
sqlite3_stmt *pStmt;
/* Allocate the SegmentWriter structure */
pWriter = (SegmentWriter *)sqlite3_malloc(sizeof(SegmentWriter));
pWriter = (SegmentWriter *)sqlite3_malloc64(sizeof(SegmentWriter));
if( !pWriter ) return SQLITE_NOMEM;
memset(pWriter, 0, sizeof(SegmentWriter));
*ppWriter = pWriter;
/* Allocate a buffer in which to accumulate data */
pWriter->aData = (char *)sqlite3_malloc(p->nNodeSize);
pWriter->aData = (char *)sqlite3_malloc64(p->nNodeSize);
if( !pWriter->aData ) return SQLITE_NOMEM;
pWriter->nSize = p->nNodeSize;
@@ -2332,7 +2332,7 @@ static int fts3SegWriterAdd(
** the buffer to make it large enough.
*/
if( nReq>pWriter->nSize ){
char *aNew = sqlite3_realloc(pWriter->aData, nReq);
char *aNew = sqlite3_realloc64(pWriter->aData, nReq);
if( !aNew ) return SQLITE_NOMEM;
pWriter->aData = aNew;
pWriter->nSize = nReq;
@@ -2357,7 +2357,7 @@ static int fts3SegWriterAdd(
*/
if( isCopyTerm ){
if( nTerm>pWriter->nMalloc ){
char *zNew = sqlite3_realloc(pWriter->zMalloc, nTerm*2);
char *zNew = sqlite3_realloc64(pWriter->zMalloc, (i64)nTerm*2);
if( !zNew ){
return SQLITE_NOMEM;
}
@@ -2665,12 +2665,12 @@ static void fts3ColumnFilter(
static int fts3MsrBufferData(
Fts3MultiSegReader *pMsr, /* Multi-segment-reader handle */
char *pList,
int nList
i64 nList
){
if( nList>pMsr->nBuffer ){
char *pNew;
pMsr->nBuffer = nList*2;
pNew = (char *)sqlite3_realloc(pMsr->aBuffer, pMsr->nBuffer);
pNew = (char *)sqlite3_realloc64(pMsr->aBuffer, pMsr->nBuffer);
if( !pNew ) return SQLITE_NOMEM;
pMsr->aBuffer = pNew;
}
@@ -2726,7 +2726,7 @@ int sqlite3Fts3MsrIncrNext(
fts3SegReaderSort(pMsr->apSegment, nMerge, j, xCmp);
if( nList>0 && fts3SegReaderIsPending(apSegment[0]) ){
rc = fts3MsrBufferData(pMsr, pList, nList+1);
rc = fts3MsrBufferData(pMsr, pList, (i64)nList+1);
if( rc!=SQLITE_OK ) return rc;
assert( (pMsr->aBuffer[nList] & 0xFE)==0x00 );
pList = pMsr->aBuffer;
@@ -2863,11 +2863,11 @@ int sqlite3Fts3MsrIncrRestart(Fts3MultiSegReader *pCsr){
return SQLITE_OK;
}
static int fts3GrowSegReaderBuffer(Fts3MultiSegReader *pCsr, int nReq){
static int fts3GrowSegReaderBuffer(Fts3MultiSegReader *pCsr, i64 nReq){
if( nReq>pCsr->nBuffer ){
char *aNew;
pCsr->nBuffer = nReq*2;
aNew = sqlite3_realloc(pCsr->aBuffer, pCsr->nBuffer);
aNew = sqlite3_realloc64(pCsr->aBuffer, pCsr->nBuffer);
if( !aNew ){
return SQLITE_NOMEM;
}
@@ -2958,7 +2958,8 @@ int sqlite3Fts3SegReaderStep(
){
pCsr->nDoclist = apSegment[0]->nDoclist;
if( fts3SegReaderIsPending(apSegment[0]) ){
rc = fts3MsrBufferData(pCsr, apSegment[0]->aDoclist, pCsr->nDoclist);
rc = fts3MsrBufferData(pCsr, apSegment[0]->aDoclist,
(i64)pCsr->nDoclist);
pCsr->aDoclist = pCsr->aBuffer;
}else{
pCsr->aDoclist = apSegment[0]->aDoclist;
@@ -3011,7 +3012,8 @@ int sqlite3Fts3SegReaderStep(
nByte = sqlite3Fts3VarintLen(iDelta) + (isRequirePos?nList+1:0);
rc = fts3GrowSegReaderBuffer(pCsr, nByte+nDoclist+FTS3_NODE_PADDING);
rc = fts3GrowSegReaderBuffer(pCsr,
(i64)nByte+nDoclist+FTS3_NODE_PADDING);
if( rc ) return rc;
if( isFirst ){
@@ -3037,7 +3039,7 @@ int sqlite3Fts3SegReaderStep(
fts3SegReaderSort(apSegment, nMerge, j, xCmp);
}
if( nDoclist>0 ){
rc = fts3GrowSegReaderBuffer(pCsr, nDoclist+FTS3_NODE_PADDING);
rc = fts3GrowSegReaderBuffer(pCsr, (i64)nDoclist+FTS3_NODE_PADDING);
if( rc ) return rc;
memset(&pCsr->aBuffer[nDoclist], 0, FTS3_NODE_PADDING);
pCsr->aDoclist = pCsr->aBuffer;
@@ -3750,7 +3752,7 @@ struct NodeReader {
static void blobGrowBuffer(Blob *pBlob, int nMin, int *pRc){
if( *pRc==SQLITE_OK && nMin>pBlob->nAlloc ){
int nAlloc = nMin;
char *a = (char *)sqlite3_realloc(pBlob->a, nAlloc);
char *a = (char *)sqlite3_realloc64(pBlob->a, nAlloc);
if( a ){
pBlob->nAlloc = nAlloc;
pBlob->a = a;
@@ -4547,7 +4549,7 @@ static int fts3RepackSegdirLevel(
if( nIdx>=nAlloc ){
int *aNew;
nAlloc += 16;
aNew = sqlite3_realloc(aIdx, nAlloc*sizeof(int));
aNew = sqlite3_realloc64(aIdx, nAlloc*sizeof(int));
if( !aNew ){
rc = SQLITE_NOMEM;
break;
@@ -4921,7 +4923,7 @@ int sqlite3Fts3Incrmerge(Fts3Table *p, int nMerge, int nMin){
/* Allocate space for the cursor, filter and writer objects */
const int nAlloc = sizeof(*pCsr) + sizeof(*pFilter) + sizeof(*pWriter);
pWriter = (IncrmergeWriter *)sqlite3_malloc(nAlloc);
pWriter = (IncrmergeWriter *)sqlite3_malloc64(nAlloc);
if( !pWriter ) return SQLITE_NOMEM;
pFilter = (Fts3SegFilter *)&pWriter[1];
pCsr = (Fts3MultiSegReader *)&pFilter[1];
@@ -5557,7 +5559,7 @@ int sqlite3Fts3DeferredTokenList(
return SQLITE_OK;
}
pRet = (char *)sqlite3_malloc(p->pList->nData);
pRet = (char *)sqlite3_malloc64(p->pList->nData);
if( !pRet ) return SQLITE_NOMEM;
nSkip = sqlite3Fts3GetVarint(p->pList->aData, &dummy);
@@ -5577,7 +5579,7 @@ int sqlite3Fts3DeferToken(
int iCol /* Column that token must appear in (or -1) */
){
Fts3DeferredToken *pDeferred;
pDeferred = sqlite3_malloc(sizeof(*pDeferred));
pDeferred = sqlite3_malloc64(sizeof(*pDeferred));
if( !pDeferred ){
return SQLITE_NOMEM;
}
+6 -2
View File
@@ -16,12 +16,16 @@ source [file join [file dirname [info script]] fts5_common.tcl]
source $testdir/malloc_common.tcl
set testprefix fts5fault4
# If SQLITE_ENABLE_FTS3 is defined, omit this file.
# If SQLITE_ENABLE_FTS5 is not defined, omit this file.
ifcapable !fts5 {
finish_test
return
}
set ::TMPDBERROR [list 1 \
{unable to open a temporary database file for storing temporary tables}
]
#-------------------------------------------------------------------------
# An OOM while dropping an fts5 table.
#
@@ -391,7 +395,7 @@ do_faultsim_test 14.1 -faults oom-t* -prep {
} -body {
db eval { ALTER TABLE "tbl one" RENAME TO "tbl two" }
} -test {
faultsim_test_result {0 {}}
faultsim_test_result {0 {}} $::TMPDBERROR
}
finish_test
+3 -2
View File
@@ -299,8 +299,9 @@ static void icuRegexpFunc(sqlite3_context *p, int nArg, sqlite3_value **apArg){
if( U_SUCCESS(status) ){
sqlite3_set_auxdata(p, 0, pExpr, icuRegexpDelete);
}else{
assert(!pExpr);
pExpr = sqlite3_get_auxdata(p, 0);
}
if( !pExpr ){
icuFunctionError(p, "uregex_open", status);
return;
}
+1 -1
View File
@@ -685,7 +685,7 @@ static const char *re_compile(ReCompiled **ppRe, const char *zIn, int noCase){
pRe->zInit[j++] = (unsigned char)(0xc0 | (x>>6));
pRe->zInit[j++] = 0x80 | (x&0x3f);
}else if( x<=0xffff ){
pRe->zInit[j++] = (unsigned char)(0xd0 | (x>>12));
pRe->zInit[j++] = (unsigned char)(0xe0 | (x>>12));
pRe->zInit[j++] = 0x80 | ((x>>6)&0x3f);
pRe->zInit[j++] = 0x80 | (x&0x3f);
}else{
+81 -44
View File
@@ -30,6 +30,16 @@ SQLITE_EXTENSION_INIT1
#ifndef SQLITE_OMIT_VIRTUALTABLE
#define STMT_NUM_INTEGER_COLUMN 10
typedef struct StmtRow StmtRow;
struct StmtRow {
sqlite3_int64 iRowid; /* Rowid value */
char *zSql; /* column "sql" */
int aCol[STMT_NUM_INTEGER_COLUMN+1]; /* all other column values */
StmtRow *pNext; /* Next row to return */
};
/* stmt_vtab is a subclass of sqlite3_vtab which will
** serve as the underlying representation of a stmt virtual table
*/
@@ -47,8 +57,7 @@ typedef struct stmt_cursor stmt_cursor;
struct stmt_cursor {
sqlite3_vtab_cursor base; /* Base class - must be first */
sqlite3 *db; /* Database connection for this cursor */
sqlite3_stmt *pStmt; /* Statement cursor is currently pointing at */
sqlite3_int64 iRowid; /* The rowid */
StmtRow *pRow; /* Current row */
};
/*
@@ -92,7 +101,7 @@ static int stmtConnect(
"CREATE TABLE x(sql,ncol,ro,busy,nscan,nsort,naidx,nstep,"
"reprep,run,mem)");
if( rc==SQLITE_OK ){
pNew = sqlite3_malloc( sizeof(*pNew) );
pNew = sqlite3_malloc64( sizeof(*pNew) );
*ppVtab = (sqlite3_vtab*)pNew;
if( pNew==0 ) return SQLITE_NOMEM;
memset(pNew, 0, sizeof(*pNew));
@@ -114,7 +123,7 @@ static int stmtDisconnect(sqlite3_vtab *pVtab){
*/
static int stmtOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
stmt_cursor *pCur;
pCur = sqlite3_malloc( sizeof(*pCur) );
pCur = sqlite3_malloc64( sizeof(*pCur) );
if( pCur==0 ) return SQLITE_NOMEM;
memset(pCur, 0, sizeof(*pCur));
pCur->db = ((stmt_vtab*)p)->db;
@@ -122,10 +131,21 @@ static int stmtOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
return SQLITE_OK;
}
static void stmtCsrReset(stmt_cursor *pCur){
StmtRow *pRow = 0;
StmtRow *pNext = 0;
for(pRow=pCur->pRow; pRow; pRow=pNext){
pNext = pRow->pNext;
sqlite3_free(pRow);
}
pCur->pRow = 0;
}
/*
** Destructor for a stmt_cursor.
*/
static int stmtClose(sqlite3_vtab_cursor *cur){
stmtCsrReset((stmt_cursor*)cur);
sqlite3_free(cur);
return SQLITE_OK;
}
@@ -136,8 +156,9 @@ static int stmtClose(sqlite3_vtab_cursor *cur){
*/
static int stmtNext(sqlite3_vtab_cursor *cur){
stmt_cursor *pCur = (stmt_cursor*)cur;
pCur->iRowid++;
pCur->pStmt = sqlite3_next_stmt(pCur->db, pCur->pStmt);
StmtRow *pNext = pCur->pRow->pNext;
sqlite3_free(pCur->pRow);
pCur->pRow = pNext;
return SQLITE_OK;
}
@@ -151,39 +172,11 @@ static int stmtColumn(
int i /* Which column to return */
){
stmt_cursor *pCur = (stmt_cursor*)cur;
switch( i ){
case STMT_COLUMN_SQL: {
sqlite3_result_text(ctx, sqlite3_sql(pCur->pStmt), -1, SQLITE_TRANSIENT);
break;
}
case STMT_COLUMN_NCOL: {
sqlite3_result_int(ctx, sqlite3_column_count(pCur->pStmt));
break;
}
case STMT_COLUMN_RO: {
sqlite3_result_int(ctx, sqlite3_stmt_readonly(pCur->pStmt));
break;
}
case STMT_COLUMN_BUSY: {
sqlite3_result_int(ctx, sqlite3_stmt_busy(pCur->pStmt));
break;
}
default: {
assert( i==STMT_COLUMN_MEM );
i = SQLITE_STMTSTATUS_MEMUSED +
STMT_COLUMN_NSCAN - SQLITE_STMTSTATUS_FULLSCAN_STEP;
/* Fall thru */
}
case STMT_COLUMN_NSCAN:
case STMT_COLUMN_NSORT:
case STMT_COLUMN_NAIDX:
case STMT_COLUMN_NSTEP:
case STMT_COLUMN_REPREP:
case STMT_COLUMN_RUN: {
sqlite3_result_int(ctx, sqlite3_stmt_status(pCur->pStmt,
i-STMT_COLUMN_NSCAN+SQLITE_STMTSTATUS_FULLSCAN_STEP, 0));
break;
}
StmtRow *pRow = pCur->pRow;
if( i==STMT_COLUMN_SQL ){
sqlite3_result_text(ctx, pRow->zSql, -1, SQLITE_TRANSIENT);
}else{
sqlite3_result_int(ctx, pRow->aCol[i]);
}
return SQLITE_OK;
}
@@ -194,7 +187,7 @@ static int stmtColumn(
*/
static int stmtRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
stmt_cursor *pCur = (stmt_cursor*)cur;
*pRowid = pCur->iRowid;
*pRowid = pCur->pRow->iRowid;
return SQLITE_OK;
}
@@ -204,7 +197,7 @@ static int stmtRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
*/
static int stmtEof(sqlite3_vtab_cursor *cur){
stmt_cursor *pCur = (stmt_cursor*)cur;
return pCur->pStmt==0;
return pCur->pRow==0;
}
/*
@@ -219,9 +212,53 @@ static int stmtFilter(
int argc, sqlite3_value **argv
){
stmt_cursor *pCur = (stmt_cursor *)pVtabCursor;
pCur->pStmt = 0;
pCur->iRowid = 0;
return stmtNext(pVtabCursor);
sqlite3_stmt *p = 0;
sqlite3_int64 iRowid = 1;
StmtRow **ppRow = 0;
stmtCsrReset(pCur);
ppRow = &pCur->pRow;
for(p=sqlite3_next_stmt(pCur->db, 0); p; p=sqlite3_next_stmt(pCur->db, p)){
const char *zSql = sqlite3_sql(p);
sqlite3_int64 nSql = zSql ? strlen(zSql)+1 : 0;
StmtRow *pNew = (StmtRow*)sqlite3_malloc64(sizeof(StmtRow) + nSql);
if( pNew==0 ) return SQLITE_NOMEM;
memset(pNew, 0, sizeof(StmtRow));
if( zSql ){
pNew->zSql = (char*)&pNew[1];
memcpy(pNew->zSql, zSql, nSql);
}
pNew->aCol[STMT_COLUMN_NCOL] = sqlite3_column_count(p);
pNew->aCol[STMT_COLUMN_RO] = sqlite3_stmt_readonly(p);
pNew->aCol[STMT_COLUMN_BUSY] = sqlite3_stmt_busy(p);
pNew->aCol[STMT_COLUMN_NSCAN] = sqlite3_stmt_status(
p, SQLITE_STMTSTATUS_FULLSCAN_STEP, 0
);
pNew->aCol[STMT_COLUMN_NSORT] = sqlite3_stmt_status(
p, SQLITE_STMTSTATUS_SORT, 0
);
pNew->aCol[STMT_COLUMN_NAIDX] = sqlite3_stmt_status(
p, SQLITE_STMTSTATUS_AUTOINDEX, 0
);
pNew->aCol[STMT_COLUMN_NSTEP] = sqlite3_stmt_status(
p, SQLITE_STMTSTATUS_VM_STEP, 0
);
pNew->aCol[STMT_COLUMN_REPREP] = sqlite3_stmt_status(
p, SQLITE_STMTSTATUS_REPREPARE, 0
);
pNew->aCol[STMT_COLUMN_RUN] = sqlite3_stmt_status(
p, SQLITE_STMTSTATUS_RUN, 0
);
pNew->aCol[STMT_COLUMN_MEM] = sqlite3_stmt_status(
p, SQLITE_STMTSTATUS_MEMUSED, 0
);
pNew->iRowid = iRowid++;
*ppRow = pNew;
ppRow = &pNew->pNext;
}
return SQLITE_OK;
}
/*
+1 -1
View File
@@ -1695,7 +1695,7 @@ static int geopolyUpdate(
sqlite3_free(p);
nChange = 1;
}
for(jj=1; jj<pRtree->nAux; jj++){
for(jj=1; jj<nData-2; jj++){
nChange++;
sqlite3_bind_value(pUp, jj+2, aData[jj+2]);
}
+6 -2
View File
@@ -23,6 +23,10 @@ ifcapable !rtree {
return
}
set ::TMPDBERROR [list 1 \
{unable to open a temporary database file for storing temporary tables}
]
# Test summary:
#
# rtree3-1: Test OOM in simple CREATE TABLE, INSERT, DELETE and SELECT
@@ -196,9 +200,9 @@ do_test rtree3-7.prep {
do_faultsim_test rtree3-7 -faults oom-* -prep {
faultsim_restore_and_reopen
} -body {
execsql { ALTER TABLE rt RENAME TO rt2 }
execsql { ALTER TABLE rt RENAME TO rt2 }
} -test {
faultsim_test_result {0 {}}
faultsim_test_result {0 {}} $::TMPDBERROR
}
do_faultsim_test rtree3-8 -faults oom-* -prep {
+3
View File
@@ -344,6 +344,7 @@ TESTSRC = \
$(TOP)/src/test_quota.c \
$(TOP)/src/test_rtree.c \
$(TOP)/src/test_schema.c \
$(TOP)/src/test_schemapool.c \
$(TOP)/src/test_server.c \
$(TOP)/src/test_sqllog.c \
$(TOP)/src/test_superlock.c \
@@ -400,6 +401,7 @@ TESTSRC2 = \
$(TOP)/src/backup.c \
$(TOP)/src/btree.c \
$(TOP)/src/build.c \
$(TOP)/src/callback.c \
$(TOP)/src/date.c \
$(TOP)/src/dbpage.c \
$(TOP)/src/dbstat.c \
@@ -423,6 +425,7 @@ TESTSRC2 = \
$(TOP)/src/select.c \
$(TOP)/src/threads.c \
$(TOP)/src/tokenize.c \
$(TOP)/src/treeview.c \
$(TOP)/src/utf.c \
$(TOP)/src/util.c \
$(TOP)/src/vdbeapi.c \
+89 -82
View File
@@ -1,13 +1,13 @@
C Version\s3.39.0
D 2022-06-25T14:57:57.276
C Merge\sversion\s3.39.4\schanges\sinto\sthe\sreuse-schema-3.39\sbranch.
D 2022-09-30T12:27:46.631
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
F Makefile.in bccb0ed3f05fc41aee15da77c844c48b5da419cbb9af35b8a147536c9ad1c822
F Makefile.in 9c3b2a19a0695008e177b61f903a67ad6109da2ace2a906b50f8f517a46802d1
F Makefile.linux-gcc f609543700659711fbd230eced1f01353117621dccae7b9fb70daa64236c5241
F Makefile.msc de7cb3e095ce2fdc33513ccd76ebdaeda1483d0ddab0410fe65cbdeadd4c0ee1
F Makefile.msc 73a85e1c9858209075fe6d4efadb2201ac147ee995733752c3e2432d747b2977
F README.md 8b8df9ca852aeac4864eb1e400002633ee6db84065bd01b78c33817f97d31f5e
F VERSION fa8e7d2d1cc962f9e14c6d410387cf75860ee139462763fda887c1be4261f824
F VERSION ad74f073c8910c112b5db75d9a7be486305a91d8a352d53f2a4c7dda9e9e5efa
F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50
F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2
F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90
@@ -34,13 +34,14 @@ F autoconf/tea/win/rules.vc c511f222b80064096b705dbeb97060ee1d6b6d63
F config.guess 883205ddf25b46f10c181818bf42c09da9888884af96f79e1719264345053bd6
F config.h.in 6376abec766e9a0785178b1823b5a587e9f1ccbc
F config.sub c2d0260f17f3e4bc0b6808fccf1b291cb5e9126c14fc5890efc77b9fd0175559
F configure 00378d14cca0ce02fa9eca28fd494789c2eda7d10d86003a5f9a42f34b0af418 x
F configure 01ce1a8ad8aa8450bc4e7bef937588a116ed724aa49802537ec9399ee18a8488 x
F configure.ac 3ef6eeff4387585bfcab76b0c3f6e15a0618587bb90245dd5d44e4378141bb35
F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad
F doc/F2FS.txt c1d4a0ae9711cfe0e1d8b019d154f1c29e0d3abfe820787ba1e9ed7691160fcd
F doc/json-enhancements.md e356fc834781f1f1aa22ee300027a270b2c960122468499bf347bb123ce1ea4f
F doc/lemon.html efc0cd2345d66905505d98f862e1c571512def0ceb5b016cb658fd4918eb76a3
F doc/pager-invariants.txt 27fed9a70ddad2088750c4a2b493b63853da2710
F doc/shared_schema.md 759fc374709fccf4e5d2d0cbd05f8fedd38fb022bdd8a6c5b5f492684c7023b9
F doc/trusted-schema.md 33625008620e879c7bcfbbfa079587612c434fa094d338b08242288d358c3e8a
F doc/vdbesort-memory.md 4da2639c14cd24a31e0af694b1a8dd37eaf277aff3867e9a8cc14046bc49df56
F doc/vfs-shm.txt e101f27ea02a8387ce46a05be2b1a902a021d37a
@@ -102,25 +103,25 @@ F ext/fts3/README.content b9078d0843a094d86af0d48dffbff13c906702b4c3558012e67b9c
F ext/fts3/README.syntax a19711dc5458c20734b8e485e75fb1981ec2427a
F ext/fts3/README.tokenizers b92bdeb8b46503f0dd301d364efc5ef59ef9fa8e2758b8e742f39fa93a2e422d
F ext/fts3/README.txt 8c18f41574404623b76917b9da66fcb0ab38328d
F ext/fts3/fts3.c 6634a3854e70afa8710ee5e3a7253cd0f0c89d4cce207fcbfe2ead3bad1db7d5
F ext/fts3/fts3.c 46c116ee0868fc09520d61a1b747c62343c71c399ba67a3d0395b0be29b1a19f
F ext/fts3/fts3.h 3a10a0af180d502cecc50df77b1b22df142817fe
F ext/fts3/fts3Int.h dafdc371f9fbab175744b06cfe019d5f040cdfdbd11fea752f5dc28d45b04c05
F ext/fts3/fts3Int.h ae2a44b04cddb5fb35cac4ea5f7f819b2894fd258186465777a19f7acfdf84ed
F ext/fts3/fts3_aux.c f0dc9bd98582615b7750218899bd0c729879b6bbf94d1be57ca1833ff49afc6f
F ext/fts3/fts3_expr.c 903bfb9433109fffb10e910d7066c49cbf8eeae316adc93f0499c4da7dfc932a
F ext/fts3/fts3_hash.c 8b6e31bfb0844c27dc6092c2620bdb1fca17ed613072db057d96952c6bdb48b7
F ext/fts3/fts3_hash.h 39cf6874dc239d6b4e30479b1975fe5b22a3caaf
F ext/fts3/fts3_icu.c 305ce7fb6036484085b5556a9c8e62acdc7763f0f4cdf5fd538212a9f3720116
F ext/fts3/fts3_porter.c 3565faf04b626cddf85f03825e86056a4562c009
F ext/fts3/fts3_porter.c e19807ce0ae31c1c6e9898e89ecc93183d7ec224ea101af039722a4f49e5f2b8
F ext/fts3/fts3_snippet.c f9a8149173553113f3c495a503843e30028b5dc3723d0ca798c5ad6142e130e6
F ext/fts3/fts3_term.c f45a1e7c6ef464abb1231245d123dae12266b69e05cc56e14045b76591ae92d1
F ext/fts3/fts3_test.c d8d7b2734f894e8a489987447658e374cdd3a3bc8575c401decf1911cb7c6454
F ext/fts3/fts3_tokenize_vtab.c a95feda3590f3c3e17672fe35b67ea6112471aeea4c07ef7744a6606b66549aa
F ext/fts3/fts3_tokenizer.c 6d8fc150c48238955d5182bf661498db0dd473c8a2a80e00c16994a646fa96e7
F ext/fts3/fts3_tokenizer.h 64c6ef6c5272c51ebe60fc607a896e84288fcbc3
F ext/fts3/fts3_tokenizer1.c 5c98225a53705e5ee34824087478cf477bdb7004
F ext/fts3/fts3_tokenizer1.c c1de4ae28356ad98ccb8b2e3388a7fdcce7607b5523738c9afb6275dab765154
F ext/fts3/fts3_unicode.c de426ff05c1c2e7bce161cf6b706638419c3a1d9c2667de9cb9dc0458c18e226
F ext/fts3/fts3_unicode2.c 416eb7e1e81142703520d284b768ca2751d40e31fa912cae24ba74860532bf0f
F ext/fts3/fts3_write.c 85279b980f99253c296006503a13f92957ec49b716123083f021acc74545ecfc
F ext/fts3/fts3_write.c 4fb644df0ff840267e47a724286c7a1fa5540273a7ce15756dd5913a101ec302
F ext/fts3/fts3speed.tcl b54caf6a18d38174f1a6e84219950d85e98bb1e9
F ext/fts3/tool/fts3cov.sh c331d006359456cf6f8f953e37f2b9c7d568f3863f00bb5f7eb87fea4ac01b73
F ext/fts3/tool/fts3view.c 413c346399159df81f86c4928b7c4a455caab73bfbc8cd68f950f632e5751674
@@ -191,7 +192,7 @@ F ext/fts5/test/fts5eb.test a973baadac524dbbb4ad9b0e99030e12cabde2c6b28e0ac43729
F ext/fts5/test/fts5fault1.test d28a65caee75db6897c3cf1358c5230d3bb2a3bf7fb31062c19c7e5382b3d2bd
F ext/fts5/test/fts5fault2.test 69c8fdbef830cd0d450908d4504d5bb86609e255af99c421c20a0756251fe344
F ext/fts5/test/fts5fault3.test da2f9e3e56ff5740d68ebdd6877c97089e7ed28ddff28a0da87a6afea27e5522
F ext/fts5/test/fts5fault4.test 1c1db5fcfe59401e7833146100f1d8de284a0a686fac31ddac9fb56c459f725b
F ext/fts5/test/fts5fault4.test 87a10d0caee57da587c7588b0c8d25d2930197399b4812ad1e4d574c75324cee
F ext/fts5/test/fts5fault5.test a336e4e11847de24c9497f80cce18e00bb3fab7fb11f97d04eb9af898900a762
F ext/fts5/test/fts5fault6.test a0fc0a8f99e4b16500c31dfc7e38e1defe0f1693ac47650517ac7b723b1956f8
F ext/fts5/test/fts5fault7.test 0acbec416edb24b8881f154e99c31e9ccf73f539cfcd164090be139e9e97ed4c
@@ -255,7 +256,7 @@ F ext/fts5/tool/loadfts5.tcl 95b03429ee6b138645703c6ca192c3ac96eaf093
F ext/fts5/tool/mkfts5c.tcl 3eba8e9bee4221ed165f3304b51b2a74a705f4ec5df3d044573a2be539534af8
F ext/fts5/tool/showfts5.tcl d54da0e067306663e2d5d523965ca487698e722c
F ext/icu/README.txt 7ab7ced8ae78e3a645b57e78570ff589d4c672b71370f5aa9e1cd7024f400fc9
F ext/icu/icu.c 91c021c7e3e8bbba286960810fa303295c622e323567b2e6def4ce58e4466e60
F ext/icu/icu.c c074519b46baa484bb5396c7e01e051034da8884bad1a1cb7f09bbe6be3f0282
F ext/icu/sqliteicu.h fa373836ed5a1ee7478bdf8a1650689294e41d0c89c1daab26e9ae78a32075a8
F ext/lsm1/Makefile a553b728bba6c11201b795188c5708915cc4290f02b7df6ba7e8c4c943fd5cd9
F ext/lsm1/Makefile.msc f8c878b467232226de288da320e1ac71c131f5ec91e08b21f502303347260013
@@ -334,7 +335,7 @@ F ext/misc/normalize.c bd84355c118e297522aba74de34a4fd286fc775524e0499b14473918d
F ext/misc/percentile.c b9086e223d583bdaf8cb73c98a6539d501a2fc4282654adbfea576453d82e691
F ext/misc/prefixes.c 0f4f8cff5aebc00a7e3ac4021fd59cfe1a8e17c800ceaf592859ecb9cbc38196
F ext/misc/qpvtab.c 09738419e25f603a35c0ac8bd0a04daab794f48d08a9bc07a6085b9057b99009
F ext/misc/regexp.c b267fd05ff8d38b22f4c2809d7b7a2c61d522e9faf2feb928dbb9662e4a3a386
F ext/misc/regexp.c 03e483711534c437b2e29648d2a4b7730f5cb781a434ac8150907376bc4489f6
F ext/misc/remember.c add730f0f7e7436cd15ea3fd6a90fd83c3f706ab44169f7f048438b7d6baa69c
F ext/misc/rot13.c 51ac5f51e9d5fd811db58a9c23c628ad5f333c173f1fc53c8491a3603d38556c
F ext/misc/scrub.c 2a44b0d44c69584c0580ad2553f6290a307a49df4668941d2812135bfb96a946
@@ -344,7 +345,7 @@ F ext/misc/shathree.c 7b17615869a495659f1569ada1d8d3d21b4a24614f2746d93cc87ef7c0
F ext/misc/showauth.c 732578f0fe4ce42d577e1c86dc89dd14a006ab52
F ext/misc/spellfix.c 94df9bbfa514a563c1484f684a2df3d128a2f7209a84ca3ca100c68a0163e29f
F ext/misc/sqlar.c 0ace5d3c10fe736dc584bf1159a36b8e2e60fab309d310cd8a0eecd9036621b6
F ext/misc/stmt.c 35063044a388ead95557e4b84b89c1b93accc2f1c6ddea3f9710e8486a7af94a
F ext/misc/stmt.c ed05ad78013edccd43f4fc33d8244001f6f886eb2dfd2106ba33616ac514c6fb
F ext/misc/templatevtab.c 8a16a91a5ceaccfcbd6aaaa56d46828806e460dd194965b3f77bf38f14b942c4
F ext/misc/totype.c fa4aedeb07f66169005dffa8de3b0a2b621779fd44f85c103228a42afa71853b
F ext/misc/uint.c 053fed3bce2e89583afcd4bf804d75d659879bbcedac74d0fa9ed548839a030b
@@ -413,12 +414,12 @@ F ext/repair/test/checkfreelist01.test 3e8aa6aeb4007680c94a8d07b41c339aa635cc782
F ext/repair/test/checkindex01.test b530f141413b587c9eb78ff734de6bb79bc3515c335096108c12c01bddbadcec
F ext/repair/test/test.tcl 686d76d888dffd021f64260abf29a55c57b2cedfa7fc69150b42b1d6119aac3c
F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761
F ext/rtree/geopoly.c cc3f89c11abcf114fa60d74709ae8b5bc1eae5a261b30bc1bb7085089c03bfab
F ext/rtree/geopoly.c bb0dcd013dbb3fe0335b6bbae0d9c29fcfffda93d5ef6c31daa47e802132e435
F ext/rtree/rtree.c d7b4b8b81d8d54376a7f81de5be85ec58b37c11604bcf42984a8418b34158d93
F ext/rtree/rtree.h 4a690463901cb5e6127cf05eb8e642f127012fd5003830dbc974eca5802d9412
F ext/rtree/rtree1.test d47f58832145fcfed9067bc457ca8664962196c4566c17a1ebd679367db55d11
F ext/rtree/rtree2.test 9d9deddbb16fd0c30c36e6b4fdc3ee3132d765567f0f9432ee71e1303d32603d
F ext/rtree/rtree3.test 4ee5d7df86040efe3d8d84f141f2962a7745452200a7cba1db06f86d97050499
F ext/rtree/rtree3.test 272594f88c344e973864008bbe4c71fd3a41a264c097d568593ee7886d83d409
F ext/rtree/rtree4.test 304de65d484540111b896827e4261815e5dca4ce28eeecd58be648cd73452c4b
F ext/rtree/rtree5.test 49c9041d713d54560b315c2c7ef7207ee287eba1b20f8266968a06f2e55d3142
F ext/rtree/rtree6.test 9ce3691c1aac43070a9f194f0ebf54372db346c5a82241fd11b525ed53ce9f3f
@@ -491,7 +492,7 @@ F ext/userauth/userauth.c 7f00cded7dcaa5d47f54539b290a43d2e59f4b1eb5f447545fa865
F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x
F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8
F magic.txt 8273bf49ba3b0c8559cb2774495390c31fd61c60
F main.mk a5412510e5ec952915a7fda34e02079bb4e6ff8f97903f2a3d9ad2dee3e18044
F main.mk 556c8cb7074f4f24ecd5d9fcd9e718f54e2a9c40ffe22a7d265424a28e336b59
F mkso.sh fd21c06b063bb16a5d25deea1752c2da6ac3ed83
F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271
F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504
@@ -503,20 +504,20 @@ F spec.template 86a4a43b99ebb3e75e6b9a735d5fd293a24e90ca
F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b
F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786
F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a
F src/alter.c 0390ca1d69ec3626cfa9f153114b7ab233e6b2bada6a9eb91361ed385fe90deb
F src/analyze.c aabdf3769c7fd9954a8ec508eb7041ae174b66f88d12c47199fabbea9a646467
F src/attach.c 4431f82f0247bf3aaf91589acafdff77d1882235c95407b36da1585c765fbbc8
F src/alter.c 23f95fd33885c27edb5ece2bec9c184d3c7e575a3de60a97c036aa9d225e06f4
F src/analyze.c ac1decb7db9f8fc12ad930d35b44f06d4097643b52dc9264ae18f8eca5c25f0d
F src/attach.c e1eb237a21422b2d637fd854e1b72609b1b589e24b4b3a5cac0e13c9ef20ee8d
F src/auth.c f4fa91b6a90bbc8e0d0f738aa284551739c9543a367071f55574681e0f24f8cf
F src/backup.c a2891172438e385fdbe97c11c9745676bec54f518d4447090af97189fd8e52d7
F src/bitvec.c 7c849aac407230278445cb069bebc5f89bf2ddd87c5ed9459b070a9175707b3d
F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6
F src/btree.c b5a74c39d3123dadd190019c0afadd7f62b43dfe0712a39e9d0ff2fe26be5d93
F src/btree.c 98e30d582239e1c940390f6487aa0d231691989a142fa863a689c021517ede08
F src/btree.h 74d64b8f28cfa4a894d14d4ed64fa432cd697b98b61708d4351482ae15913e22
F src/btreeInt.h 8ce1332edd89dfd2461d561ac10a0ab5601c8e06200cb5230596c3caaf54482e
F src/build.c 23f874642825d7eaaeeb7a3281b2b1a75e1d4c4dd9ae4dceddcd908266634214
F src/callback.c 4c19af69835787bfe790ac560f3071a824eb629f34e41f97b52ce5235c77de1c
F src/build.c e54898c7e04c50f67699829f3d7674cf81ed8166bcf163612db01ff6b31759aa
F src/callback.c f733593c95ed7ab24e0a0f57db6755b9bd433862d187766ec9f161ef7c79efeb
F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e
F src/ctime.c 026dbdcdbd8c3cde98a88483ee88310ff43150ab164ad768f12cc700a11495ad
F src/ctime.c 53d64b59d7cfa1a1f01ae81d7f7115014d7d89f3c544079d08f6b159af2fb848
F src/date.c 15082566229d4b1e5f24fdb490bf9bcc68824b911d70e3573ef075a1b9e2d26f
F src/dbpage.c 90661a87e1db8bfbc8d2ebbdcd3749651ddb287c555c07a28fb17c7c591ffb68
F src/dbstat.c 861e08690fcb0f2ee1165eff0060ea8d4f3e2ea10f80dab7d32ad70443a6ff2d
@@ -534,8 +535,8 @@ F src/insert.c 173845e5a6bac96ae937409e4f876b631f26b31dabb9df8fd0eb3b130b2bb3a7
F src/json.c 7749b98c62f691697c7ee536b570c744c0583cab4a89200fdd0fc2aa8cc8cbd6
F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa
F src/loadext.c 853385cc7a604157e137585097949252d5d0c731768e16b044608e5c95c3614b
F src/main.c e946f1d9e30bf49cf399ddf860cfd2319e3a97bbaabfb8e87d6ab985a20d54ad
F src/malloc.c a9127efdcef92d6934c6339ea9813075b90edc0ce2e5c723556381a3828fb720
F src/main.c 0033f65efa7d3431546170a1a6c8f7878861194222877e57b7518021c1c27e58
F src/malloc.c 4a3785323104678a8b4b0a482fe0c2a80900e7468ddf76ab0f2ea1c79a8ca8cd
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
F src/mem1.c c12a42539b1ba105e3707d0e628ad70e611040d8f5e38cf942cee30c867083de
F src/mem2.c c8bfc9446fd0798bddd495eb5d9dbafa7d4b7287d8c22d50a83ac9daa26d8a75
@@ -554,32 +555,32 @@ F src/os.c b1c4f2d485961e9a5b6b648c36687d25047c252222e9660b7cc25a6e1ea436ab
F src/os.h 1ff5ae51d339d0e30d8a9d814f4b8f8e448169304d83a7ed9db66a65732f3e63
F src/os_common.h b2f4707a603e36811d9b1a13278bffd757857b85
F src/os_setup.h 0dbaea40a7d36bf311613d31342e0b99e2536586
F src/os_unix.c 2df2b33db88f00af13805d4573ee126bc5973f9e3b91d03c575fa7ba64e7dc41
F src/os_win.c a8ea80037e81127ca01959daa87387cc135f325c88dc745376c4f760de852a10
F src/os_unix.c e020676e334a0a78c3affb7dd1789a240071ed6af98309f1bef76948cb8382bd
F src/os_win.c e9454cb141908e8eef2102180bad353a36480612d5b736e4c2bd5777d9b25a34
F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a
F src/pager.c 74596fc3d5d8a50de32c37225fc300cccd5ea27ea303c5f4b845d6572f999c5f
F src/pager.c 8c3853cad320c24904a2f970777bbdda2deb9572f53e6a1d73b28b85a7fd30cc
F src/pager.h f82e9844166e1585f5786837ddc7709966138ced17f568c16af7ccf946c2baa3
F src/parse.y 8e67d820030d2655b9942ffe61c1e7e6b96cea2f2f72183533299393907d0564
F src/pcache.c 084e638432c610f95aea72b8509f0845d2791293f39d1b82f0c0a7e089c3bb6b
F src/pcache.c 5df59c993907b742dfac6aa9038d2515856bede56040a7640d39d06e1c93b494
F src/pcache.h 4f87acd914cef5016fae3030343540d75f5b85a1877eed1a2a19b9f284248586
F src/pcache1.c 54881292a9a5db202b2c0ac541c5e3ef9a5e8c4f1c1383adb2601d5499a60e65
F src/pragma.c d1aead03e8418ff586c7cfca344c50a914b8eb06abd841e8e91a982d823671da
F src/pragma.h e690a356c18e98414d2e870ea791c1be1545a714ba623719deb63f7f226d8bb7
F src/prepare.c c62820c15dcb63013519c8e41d9f928d7478672cc902cfd0581c733c271dbf45
F src/printf.c 6166a30417b05c5b2f82e1f183f75faa2926ad60531c0b688a57dbc951441a20
F src/pcache1.c 3e6267b17bae4cbaf02dfa08c4507794452991206862e3fc5c94d28313d32c18
F src/pragma.c 395a1d0912218e6bd67d0cc58b9317540f74da8b7f1e370150a495f0fdbe05ef
F src/pragma.h 50f6d3b408ed56bde4f4e4aead8c0b2022030b692e8de237c1b7a0b5ce87a0c8
F src/prepare.c d91f59db086b7b738ada7f06c1c09e151a40ca219565d1937da3968b299166e6
F src/printf.c e99ee9741e79ae3873458146f59644276657340385ade4e76a5f5d1c25793764
F src/random.c 097dc8b31b8fba5a9aca1697aeb9fd82078ec91be734c16bffda620ced7ab83c
F src/resolve.c 1655e44c77c51ebbe82924287528a78bd4a4aaaf34189dbae28d19ccf2ca615c
F src/resolve.c f0d663c9b1ceeb3e7d262ede872dd3b24b323a7cc11d84c05a39d962e7d64b07
F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92
F src/select.c 2db8bbf13f57cc9872f9b927546e98f5ea583e9e364182426492a434a994421b
F src/shell.c.in 08e59f1cb9d9b1180aba52861aaada0c95f6ddd210488719684e160a0724c806
F src/sqlite.h.in 172528c287399a34f188154017b7268bf82c6d5b780902e361958d2318c4e37c
F src/select.c fea5ae26259dc995b2144a28bbb5b013196dbcc86527cd992ed109b00af7f9e8
F src/shell.c.in d92bc2b81afab457b82297c7405a9388a5ae1d792b5e90ebdf589d05987d0be2
F src/sqlite.h.in fab3ab25167b24762a27dbef9e49cbe469963f80dec6e22398c33f2c7ec73aca
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
F src/sqlite3ext.h a988810c9b21c0dc36dc7a62735012339dc76fc7ab448fb0792721d30eacb69d
F src/sqliteInt.h 8353e96646372efdb0795a13cd9949831b4992c928de8f5c43b2524e8a4c6e7b
F src/sqliteInt.h e938d47c077c8ef50caa3aa212ec32680451b7d31cc9623612e61d3f0d176fed
F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657
F src/status.c 4a3da6d77eeb3531cb0dbdf7047772a2a1b99f98c69e90ce009c75fe6328b2c0
F src/status.c 99fd56b274f5d4b79b5af65a92ae37286755cd212ed2c6b13ad34183970b2165
F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1
F src/tclsqlite.c 4e64ba300a5a26e0f1170e09032429faeb65e45e8f3d1a7833e8edb69fc2979e
F src/tclsqlite.c c5b9f6540d6de1adc6554589ce4011e07bb02250440a3e777ff86b40f1c1dd2c
F src/test1.c 1356984e97bff07e4a8cc3863e892f05b3348678a74783bb6f350b76316736f1
F src/test2.c 3efb99ab7f1fc8d154933e02ae1378bac9637da5
F src/test3.c 61798bb0d38b915067a8c8e03f5a534b431181f802659a6616f9b4ff7d872644
@@ -595,7 +596,7 @@ F src/test_backup.c bf5da90c9926df0a4b941f2d92825a01bbe090a0
F src/test_bestindex.c 8294d8223b7f18a3ddb7f9a0e30815dcca4e61681f78b538c870f7d934f88b81
F src/test_blob.c ae4a0620b478548afb67963095a7417cd06a4ec0a56adb453542203bfdcb31ce
F src/test_btree.c 8b2dc8b8848cf3a4db93f11578f075e82252a274
F src/test_config.c 8264637b06a3c1f0727c88d1ea32dcf7986b9e7e358a970cae87cdac8a5b2708
F src/test_config.c 73ebdc35580900d12c20b984db9ec1abe860dc75f66ae703f2b6fc9d95e09dc1
F src/test_delete.c e2fe07646dff6300b48d49b2fee2fe192ed389e834dd635e3b3bac0ce0bf9f8f
F src/test_demovfs.c 86142ba864d4297d54c5b2e972e74f3141ae4b30f05b3a95824184ed2d3d7f91
F src/test_devsym.c aff2255ea290d7718da08af30cdf18e470ff7325a5eff63e0057b1496ed66593
@@ -619,11 +620,12 @@ F src/test_quota.c 6cb9297115b551f433a9ad1741817a9831abed99
F src/test_quota.h 2a8ad1952d1d2ca9af0ce0465e56e6c023b5e15d
F src/test_rtree.c 671f3fae50ff116ef2e32a3bf1fe21b5615b4b7b
F src/test_schema.c f5d6067dfc2f2845c4dd56df63e66ee826fb23877855c785f75cc2ca83fd0c1b
F src/test_schemapool.c ae21a79f9bc7e9099ae78dbd46d5c28ee75330e62e3256a9fde25564ff9df492
F src/test_server.c a2615049954cbb9cfb4a62e18e2f0616e4dc38fe
F src/test_sqllog.c 540feaea7280cd5f926168aee9deb1065ae136d0bbbe7361e2ef3541783e187a
F src/test_superlock.c 4839644b9201da822f181c5bc406c0b2385f672e
F src/test_syscall.c 1073306ba2e9bfc886771871a13d3de281ed3939
F src/test_tclsh.c c4065ced25126e25c40122c5ff62dc89902ea617d72cdd27765151cdd7fcc477
F src/test_tclsh.c ec192bceacfe67d427e97d4985a298b0aaadb266dfbc77c54425537c5e263b65
F src/test_tclvar.c 33ff42149494a39c5fbb0df3d25d6fafb2f668888e41c0688d07273dcb268dfc
F src/test_thread.c 269ea9e1fa5828dba550eb26f619aa18aedbc29fd92f8a5f6b93521fbb74a61c
F src/test_vdbecov.c f60c6f135ec42c0de013a1d5136777aa328a776d33277f92abac648930453d43
@@ -634,32 +636,32 @@ F src/test_windirent.h 90dfbe95442c9762357fe128dc7ae3dc199d006de93eb33ba3972e0a9
F src/test_window.c cdae419fdcea5bad6dcd9368c685abdad6deb59e9fc8b84b153de513d394ba3f
F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9
F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c
F src/tokenize.c a38f52058b517929e264094abd0b5fd1e8e145a1aa43bc6f6a72ae5218f96c98
F src/treeview.c 0bd550f5974565eba541db339906be7a3f9e91beafb879cb40705382887f08e1
F src/trigger.c 61bea163b1fa3039bc572ed8312461b978e5c527e5301f302b078f4c1ccdec6a
F src/tokenize.c 36eb0799e487759bbe73e5742b82ee676f06cea2515ff578d03c59a74ccf2d6c
F src/treeview.c 07787f67cd297a6d09d04b8d70c06769c60c9c1d9080378f93929c16f8fd3298
F src/trigger.c 53fbf255f234d23aa7b877a18e0024436eec88373b7c0ebe1ba3f69341dfa72c
F src/update.c c52a7991bece0453d22c77c08469512ee2f1391c12503fd347d1c939220c5877
F src/upsert.c 8789047a8f0a601ea42fa0256d1ba3190c13746b6ba940fe2d25643a7e991937
F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0
F src/util.c 602fe229f32a96ceccae4f40824129669582096f7c355f53dbac156c9fecef23
F src/vacuum.c bb346170b0b54c6683bba4a5983aea40485597fdf605c87ec8bc2e199fe88cd8
F src/vdbe.c 3df15f0f2cd9d8faeeea18398a62f16c07fda2bfd8d726186f07508ad69b40e2
F src/vdbe.h 07641758ca8b4f4c6d81ea667ea167c541e6ece21f5574da11e3d21ec37e2662
F src/util.c 0be191521ff6d2805995f4910f0b6231b42843678b2efdc1abecaf39929a673f
F src/vacuum.c 50f980eee45f25faf1faedc5be27a561c0df086e27bef12618485f10b3bae40b
F src/vdbe.c e8793796792a70d9aab3560f8fb1c25f51d60d64bcb7c3f03be35823d81d156a
F src/vdbe.h f521a8218438c6c41e84276ac668c1c3a5bf530e37d20d1021e8c8af533ea69e
F src/vdbeInt.h 2cad0aeeb106371ed0e0946bab89f60627087068847afc2451c05056961c18da
F src/vdbeapi.c 602610f1252d59cd69742f78a1e2f6fbae40a4b407f5506a6a7b869b0df08ff2
F src/vdbeaux.c 328b866880e67526300aa2361c5e50beb3d97dd8746db37dd4aa0135aea60e4d
F src/vdbeblob.c 5e61ce31aca17db8fb60395407457a8c1c7fb471dde405e0cd675974611dcfcd
F src/vdbeaux.c 910f617aab8a24e1591fc2d2a41e31d94866ce51c2ee04c62620e0f91926a5e9
F src/vdbeblob.c aa23a326ff86bdde8f7ba74cf23c3e1795b13bee749314feaf26273be2f63e89
F src/vdbemem.c 5ebf05c0182addedb1607ade848e1c83cef40981df94d1abfab0c59288c6064f
F src/vdbesort.c 43756031ca7430f7aec3ef904824a7883c4ede783e51f280d99b9b65c0796e35
F src/vdbetrace.c fe0bc29ebd4e02c8bc5c1945f1d2e6be5927ec12c06d89b03ef2a4def34bf823
F src/vdbevtab.c f99b275366c5fc5e2d99f734729880994ab9500bdafde7fae3b02d562b9d323c
F src/vtab.c 3d72c780d1ea08906a198e4f033921a658a54590e3ed72c544995d84f3f9464a
F src/vtab.c 7064064da041cf67212c60229cb81d4f78337b4bece2aa2ecc3d50fb09b8fefc
F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9
F src/wal.c b9df133a705093da8977da5eb202eaadb844839f1c7297c08d33471f5491843d
F src/wal.h c3aa7825bfa2fe0d85bef2db94655f99870a285778baa36307c0a16da32b226a
F src/walker.c f890a3298418d7cba3b69b8803594fdc484ea241206a8dfa99db6dd36f8cbb3b
F src/where.c 9a44063e60d8f42dd9dc8147b8e8dcfc315bbd13e25c395211292c36d828c869
F src/where.c e7b7c9d37f4f8d14d4d05b20e57ae43712a51ffed7d45f547a23f9c42ee483dd
F src/whereInt.h b48ca529ffe293c18cbfa8326af18a09e39910de66fb3e96ef788c7cbf8ef3a7
F src/wherecode.c 0b09abfcb88c61c6a6984a3e065786631ff35495e9bdf865e6b74ab0a1299c5b
F src/wherecode.c f8acceb057286ed95b66689d1981985228fd925001fdc49dbd3b112f4d739174
F src/whereexpr.c 55a39f42aaf982574fbf52906371a84cceed98a994422198dfd03db4fce4cc46
F src/window.c fff1b51757438c664e471d5184634e48dcdf8ea34b640f3b1b0810b1e06de18c
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
@@ -1007,7 +1009,7 @@ F test/fts3conf.test c84bbaec81281c1788aa545ac6e78a6bd6cde2bdbbce2da261690e3659f
F test/fts3corrupt.test 6732477c5ace050c5758a40a8b5706c8c0cccd416b9c558e0e15224805a40e57
F test/fts3corrupt2.test e318f0676e5e78d5a4b702637e2bb25265954c08a1b1e4aaf93c7880bb0c67d0
F test/fts3corrupt3.test 0d5b69a0998b4adf868cc301fc78f3d0707745f1d984ce044c205cdb764b491f
F test/fts3corrupt4.test 799ff994b964fed7201be6b6b62c7ff2ef7bb3da6c02b9eaf0d96a5a4d9b6ca3
F test/fts3corrupt4.test 589e043d1114ea02c83530e459ef5c2d6adce63094e72826ed3bceb02e795116
F test/fts3corrupt5.test 0549f85ec4bd22e992f645f13c59b99d652f2f5e643dac75568bfd23a6db7ed5
F test/fts3corrupt6.test f417c910254f32c0bc9ead7affa991a1d5aec35b3b32a183ffb05eea78289525
F test/fts3cov.test 7eacdbefd756cfa4dc2241974e3db2834e9b372ca215880e00032222f32194cf
@@ -1024,8 +1026,8 @@ F test/fts3expr3.test c4d4a7d6327418428c96e0a3a1137c251b8dfbf8
F test/fts3expr4.test f5b2832549f01b1f7f73389fa21d4b875499bc95bf7c8b36271844888c6a0938
F test/fts3expr5.test a5b9a053becbdb8e973fbf4d6d3abaabeb42d511d1848bd57931f3e0a1cf983e
F test/fts3f.test 8c438d5e1cab526b0021988fb1dc70cf3597b006a33ffd6c955ee89929077fe3
F test/fts3fault.test 798e45af84be7978ca33d5bdc94246eb44724db24174b5d8e9b1ac46c57fb08d
F test/fts3fault2.test 6a17a11d8034b1c4eca9f3091649273d56c49ff049e2173df8060f94341e9da0
F test/fts3fault.test f4e1342acfe6d216a001490e8cd52afac1f9ffe4a11bbcdcb296129a45c5df45
F test/fts3fault2.test 7b2741e5095367238380b0fcdb837f36c24484c7a5f353659b387df63cf039ec
F test/fts3first.test dbdedd20914c8d539aa3206c9b34a23775644641
F test/fts3fuzz001.test e3c7b0ce9b04cc02281dcc96812a277f02df03cd7dc082055d87e11eb18aaf56
F test/fts3join.test ee25def5e763ea8879c19e74f862d5191410ccc7259338887a3685e97f512662
@@ -1168,7 +1170,7 @@ F test/join4.test 1a352e4e267114444c29266ce79e941af5885916
F test/join5.test d22b6cba8fb59ab3f1c82701434c360705eb12d4ce200c449f37b018fc47681a
F test/join6.test f809c025fa253f9e150c0e9afd4cef8813257bceeb6f46e04041228c9403cc2c
F test/join7.test 2268dcbb54b724391dda3748ea95c60d960607ffeed67885675998e7117697f6
F test/join8.test d0e75bf880a1b1ee8fda57d8187170c5b2ff0c0cd0e1d6d474faa99fe1283d8d
F test/join8.test ef5fb09a7ce6b59addb8bd16e11607db6c44a0afcac5774a5dc03193fd0a1df5
F test/join9.test 9056ddd3b0c0f4f9d658f4521038d9a37dc23ead8ca9a505d0b0db2b6a471e05
F test/joinA.test 7eab225dc1c1ab258a5e62513a4ed7cabbd3db971d59d5d92f4fb6fa14c12f6a
F test/joinB.test 1b2ba3fc8568b49411787fccbf540570c148e9b6a53a30f80691cb6268098ded
@@ -1183,7 +1185,7 @@ F test/journal3.test 7c3cf23ffc77db06601c1fcfc9743de8441cb77db9d1aa931863d94f5ff
F test/jrnlmode.test 9b5bc01dac22223cb60ec2d5f97acf568d73820794386de5634dcadbea9e1946
F test/jrnlmode2.test 8759a1d4657c064637f8b079592651530db738419e1d649c6df7048cd724363d
F test/jrnlmode3.test 556b447a05be0e0963f4311e95ab1632b11c9eaa
F test/json101.test 9d46b8e254c4e23306da175dd226d5c4f164db6b294bcea98e5dcd891ba48c91
F test/json101.test 9f6337e7423d2c1774d1d485c919fc4e11c8f7e423a2f8831f73471983432108
F test/json102.test 327e77275f338c028faefa2da5164daf6b142a165e3015ff2a6e4251ddc6a0ac
F test/json103.test 53df87f83a4e5fa0c0a56eb29ff6c94055c6eb919f33316d62161a8880112dbe
F test/json104.test a502dc01853aada95d721b3b275afbe2dc18fffdac1fea6e96fb20c13586bbb5
@@ -1233,7 +1235,7 @@ F test/mallocJ.test b5d1839da331d96223e5f458856f8ffe1366f62e
F test/mallocK.test 25897506da0098cea09b302ff432b0fb6d8002773c1e0fc9732aa8b444bfd455
F test/mallocL.test fb311ff80afddf3b1a75e52289081f4754d901dc
F test/mallocM.test 78bbe9d3da84a5c679123cdb40d7b2010b18fc46e13897e4f253c6ba6fbff134
F test/malloc_common.tcl aac62499b76be719fac31e7a3e54a7fd53272e7f
F test/malloc_common.tcl 806c50379cf4fa65008cd4d5af18273e5dac8ab62d1d4316c76aa2ecd2e54018
F test/malloctraceviewer.tcl b7a54595270c1d201abf1c3f3d461f27eaf24cdef623ad08a0fe5e411264c8a9
F test/manydb.test 28385ae2087967aa05c38624cec7d96ec74feb3e
F test/mem5.test c6460fba403c5703141348cd90de1c294188c68f
@@ -1244,7 +1246,7 @@ F test/memjournal2.test 89a4e0d1084170a281efa4d54c2677599f986f44227f98f7dfae2828
F test/memleak.test 10b9c6c57e19fc68c32941495e9ba1c50123f6e2
F test/memsubsys1.test 9e7555a22173b8f1c96c281ce289b338fcba2abe8b157f8798ca195bbf1d347e
F test/memsubsys2.test 3e4a8d0c05fd3e5fa92017c64666730a520c7e08
F test/merge1.test 0ade470d77b689c4a64dc7f736527fcd893140bcafa70af8f7b98523cfb83f16
F test/merge1.test 2de6d6ef8d25402764b1aab49d8f9d7f89208c89a6674e437f76de4c812157b8
F test/minmax.test fe638b55d77d2375531a8f549b338eafcd9adfbd2f72df37ed77d9b26ca0a71a
F test/minmax2.test cf9311babb6f0518d04e42fd6a42c619531c4309a9dd790a2c4e9b3bc595e0de
F test/minmax3.test cc1e8b010136db0d01a6f2a29ba5a9f321034354
@@ -1285,7 +1287,7 @@ F test/null.test b7ff206a1c60fe01aa2abd33ef9ea83c93727d993ca8a613de86e925c9f2bc6
F test/nulls1.test 7a5e4346ee4285034100b4cd20e6784f16a9d6c927e44ecdf10034086bbee9c9
F test/numcast.test 5d126f7f581432e86a90d1e35cac625164aec4a1
F test/numindex1.test 20a5450d4b056e48cd5db30e659f13347a099823
F test/offset1.test f06b83657bcf26f9ce805e67450e189e282143b2
F test/offset1.test 72cca52482cbd5bc687cfa67aa2566c859081b5a353fd2f9da9bbd3914dea1ef
F test/openv2.test 0d3040974bf402e19b7df4b783e447289d7ab394
F test/optfuzz-db01.c 9f2fa80b8f84ebbf1f2e8b13421a4e0477fe300f6686fbd76cac1d2db66e0fdc
F test/optfuzz-db01.txt 21f6bdeadc701cf11528276e2a55c70bfcb846ba42df327f979bd9e7b6ce7041
@@ -1342,7 +1344,7 @@ F test/randexpr1.test eda062a97e60f9c38ae8d806b03b0ddf23d796df
F test/rbu.test 168573d353cd0fd10196b87b0caa322c144ef736
F test/rdonly.test 64e2696c322e3538df0b1ed624e21f9a23ed9ff8
F test/recover.test ccb8c2623902a92ebb76770edd075cb4f75a4760bb7afde38026572c6e79070d
F test/regexp1.test 0c3ff80f66b0eff80e623eb5db7a3dad512095c573d78ac23009785f6d8f51ce
F test/regexp1.test 4a44e014664a109bbb1c37d29d9b61ca5aa5a7f49cc564c95208a80f818e3377
F test/regexp2.test 55ed41da802b0e284ac7e2fe944be3948f93ff25abbca0361a609acfed1368b5
F test/reindex.test cd9d6021729910ece82267b4f5e1b5ac2911a7566c43b43c176a6a4732e2118d
F test/releasetest_data.tcl 11ba48a21ed1c808147b0e77c6e93d204577f4327ffe6d7c3b34cd3c01eac3a2
@@ -1350,6 +1352,13 @@ F test/resetdb.test 8062cf10a09d8c048f8de7711e94571c38b38168db0e5877ba7561789e5e
F test/resolver01.test f4022acafda7f4d40eca94dbf16bc5fc4ac30ceb
F test/returning1.test c43b8370a351f77aec6d71f4a2cde59b849369ed1933261a2c2c69e23e34ff5e
F test/returningfault.test ae4c4b5e8745813287a359d9ccdb9d5c883c2e68afb18fb0767937d5de5692a4
F test/reuse1.test faa2ce5ff566d936b8a10d9e22ba2ee66a54ce89fdcf8aef561df6b15b0ff3d3
F test/reuse2.test 5dd9c98579358f0d5a90d25e36dd6e678a03e23446b6c7f2630a8da22ae7ca94
F test/reuse3.test 876d15c42d61b1f6ab718cd8169912514ad314d7fe1cd9788080aa62168ba0d1
F test/reuse4.test adaad66253aea6cc748674328abe69b650c5c78b8676ed1162d3de09742519f9
F test/reuse5.test bbe6cf7384ef90f134392edd93d626385ef0bf6f40eefc3d993535cd0861d83b
F test/reuse6.test f4674f9967aee2a0b49c02832120b8b495291c0d87aae084c54e6c0cc18132fe
F test/reusefault.test ef646a0fb51d50ddfb4b7cd872f88e7d36eaba64bde7797b3418c3774e1c8d14
F test/rollback.test 06680159bc6746d0f26276e339e3ae2f951c64812468308838e0a3362d911eaa
F test/rollback2.test 3f3a4e20401825017df7e7671e9f31b6de5fae5620c2b9b49917f52f8c160a8f
F test/rollbackfault.test 0e646aeab8840c399cfbfa43daab46fd609cf04a
@@ -1357,7 +1366,7 @@ F test/round1.test 768018b04522ca420b1aba8a24bd76091d269f3bce3902af3ec6ebcee41ab
F test/rowallock.test 3f88ec6819489d0b2341c7a7528ae17c053ab7cc
F test/rowhash.test 0bc1d31415e4575d10cacf31e1a66b5cc0f8be81
F test/rowid.test e29025be95baf6b32f0d5edef59a7633028325896a98f1caa8019559ca910350
F test/rowvalue.test ff1ffa31cebe12feb6f989e09263f3b1e8c560db94b40fe006126a8435fd6832
F test/rowvalue.test baf4fa3ec1a8c1c920c3faa5fd25959cb454bbd99ac8960397c34549d9fc4abe
F test/rowvalue2.test 060d238b7e5639a7c5630cb5e63e311b44efef2b
F test/rowvalue3.test 1347e25ca11c547c5a6ff0cc5626f95aa9740e9275bfaec096029f57cb2130ce
F test/rowvalue4.test 441e7e366ac6d939a3a95a574031c56ec2a854077a91d66eee5ff1d86cb5be58
@@ -1390,7 +1399,7 @@ F test/securedel.test 2f70b2449186a1921bd01ec9da407fbfa98c3a7a5521854c300c194b2f
F test/securedel2.test 2d54c28e46eb1fd6902089958b20b1b056c6f1c5
F test/select1.test 692e84cfa29c405854c69e8a4027183d64c22952866a123fabbce741a379e889
F test/select2.test 352480e0e9c66eda9c3044e412abdf5be0215b56
F test/select3.test 399a0b23f8618bfe07ea24fb67f2952f620d6eba662bccabf6f4f71c2d89e6c9
F test/select3.test ce4f78bbc809b0513f960f1ee84cdbc5af50ba112c343d5266558a8b2468f656
F test/select4.test f0684d3da3bccacbe2a1ebadf6fb49d9df6f53acb4c6ebc228a88d0d6054cc7b
F test/select5.test 8afc5e5dcdebc2be54472e73ebd9cd1adef1225fd15d37a1c62f969159f390ae
F test/select6.test 9b2fb4ffedf52e1b5703cfcae1212e7a4a063f014c0458d78d29aca3db766d1f
@@ -1497,7 +1506,7 @@ F test/tabfunc01.test 241425ce3998687ab24adba09cb95e8012e17499b84a0ed47e128ab45e
F test/table.test eb3463b7add9f16a5bb836badf118cf391b809d09fdccd1f79684600d07ec132
F test/tableapi.test ecbcc29c4ab62c1912c3717c48ea5c5e59f7d64e4a91034e6148bd2b82f177f4
F test/tableopts.test dba698ba97251017b7c80d738c198d39ab747930
F test/tclsqlite.test ad0bbd92edabe64cc91d990a0748142fe5ab962d74ac71fa3bfa94d50d2f4c87
F test/tclsqlite.test 350536a4233914aa437b6735e3e8e683e921a71ced8fa9fb5396057a04dbea33
F test/tempdb.test 4cdaa23ddd8acb4d79cbb1b68ccdfd09b0537aaba909ca69a876157c2a2cbd08
F test/tempdb2.test 353864e96fd3ae2f70773d0ffbf8b1fe48589b02c2ec05013b540879410c3440
F test/tempfault.test 0c0d349c9a99bf5f374655742577f8712c647900
@@ -1516,7 +1525,7 @@ F test/thread2.test f35d2106452b77523b3a2b7d1dcde2e5ee8f9e46
F test/thread_common.tcl 334639cadcb9f912bf82aa73f49efd5282e6cadd
F test/threadtest1.c 6029d9c5567db28e6dc908a0c63099c3ba6c383b
F test/threadtest2.c a70a8e94bef23339d34226eb9521015ef99f4df8
F test/threadtest3.c 655bff6c0895ec03f014126aa65e808fac9aae8c5a7a7da58a510cbe8b43b781
F test/threadtest3.c 25cb92accb4fa6d53e708d6006ed2db7a7533ef7b838ef1306455c6fe57e978a
F test/threadtest4.c c1e67136ceb6c7ec8184e56ac61db28f96bd2925
F test/threadtest5.c 9b4d782c58d8915d7e955ff8051f3d03628bda0d33b82971ea8c0f2f2808c421
F test/time-wordcount.sh 8e0b0f8109367827ad5d58f5cc849705731e4b90
@@ -1690,12 +1699,13 @@ F test/triggerF.test 5d76f0a8c428ff87a4d5ed52da06f6096a2c787a1e21b846111dfac4123
F test/triggerG.test 2b816093c91ba73c733cfa8aedcc210ad819d72a98b1da30768a3c56505233e9
F test/triggerupfrom.test d1f9e56090408115c522bee626cc33a2f3370f627a5e341d832589d72e3aa271
F test/trustschema1.test 4e970aef0bfe0cee139703cc7209d0e0f07725d999b180ba50770f49edef1494
F test/tt3_checkpoint.c ac7ca661d739280c89d9c253897df64a59a49369bd1247207ac0f655b622579d
F test/tt3_index.c 39eec10a35f57672225be4d182862152896dee4a
F test/tt3_lookaside1.c 0377e202c3c2a50d688cb65ba203afeda6fafeb9
F test/tt3_checkpoint.c 69214e2ce81bbbd3c1b82c31e103607fd2e6790818aef4792957fc9cc88d067e
F test/tt3_index.c 95592839426dc85ce5a7a57b41be2cbf3c2ec3457b9cd841a06ed5877f712c7c
F test/tt3_lookaside1.c 2ddd99bfffeef288f0786827ef68f912f6f47ce3d3184e62f05808d8e13b920e
F test/tt3_reuseschema.c 4d52e141f89f009028d8ab0bd1f0697d0edffa94bafc1fff0f7ad4d9d9baa549
F test/tt3_shared.c b37d22defc944a2ac4c91c927fd06c1d48cd51e2ce9d004fe868625bd2399f93
F test/tt3_stress.c f9a769ca8b026ecc76ee93ca8c9700a5619f8e51c581107c4053ba6ac97f616f
F test/tt3_vacuum.c 71b254cde1fc49d6c8c44efd54f4668f3e57d7b3a8f4601ade069f75a999ba39
F test/tt3_stress.c 077e817ac1168443b075fedb44e92db84bb4dc5bd3b6fe1aba25c94ac280b231
F test/tt3_vacuum.c 727bfda1299b18435eeba80dee8e6ff43462146d7c1e2096cc809f01db568391
F test/types.test bf816ce73c7dfcfe26b700c19f97ef4050d194ff
F test/types2.test 1aeb81976841a91eef292723649b5c4fe3bc3cac
F test/types3.test 99e009491a54f4dc02c06bdbc0c5eea56ae3e25a
@@ -1911,7 +1921,7 @@ F tool/mkmsvcmin.tcl 6ecab9fe22c2c8de4d82d4c46797bda3d2deac8e763885f5a38d0c44a89
F tool/mkopcodec.tcl 33d20791e191df43209b77d37f0ff0904620b28465cca6990cf8d60da61a07ef
F tool/mkopcodeh.tcl 5dab48c49a25452257494e9601702ab63adaba6bd54a9b382615fa52661c8f8c
F tool/mkopts.tcl 680f785fdb09729fd9ac50632413da4eadbdf9071535e3f26d03795828ab07fa
F tool/mkpragmatab.tcl bd07bd59d45d0f3448e123d6937e9811195f9908a51e09d774609883055bfd3d
F tool/mkpragmatab.tcl 0e059aaab521b490c86ba3d4f945319b438558de7738e90f26c54f4ffcdd79bb
F tool/mkshellc.tcl df5d249617f9cc94d5c48eb0401673eb3f31f383ecbc54e8a13ca3dd97e89450
F tool/mksourceid.c 36aa8020014aed0836fd13c51d6dc9219b0df1761d6b5f58ff5b616211b079b9
F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97
@@ -1978,11 +1988,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
P cd6254fcd32798f7be4e6d827597ddaa2e46ac6e2f0149cd3a3be0416fa18835
R 4b3e64a86ee9acaa4f97f1ab6ad6f3ae
T +sym-major-release *
T +sym-release *
T +sym-version-3.39.0 *
P efd54164b02f35b5d39ab4d18e349c18f3ec8afb728da39d20373e26742da177 a29f9949895322123f7c38fbe94c649a9d6e6c9cd0c3b41c96d694552f26b309
R d0339000980575865473b9832db36209
U drh
Z f64bfe891f96e530fe80668f0f22f84a
Z 31dd8436fe348e8e93bab7ea8a531a47
# Remove this line to create a well-formed Fossil manifest.
+1 -1
View File
@@ -1 +1 @@
14e166f40dbfa6e055543f8301525f2ca2e96a02a57269818b9e69e162e98918
8102592836dcf6f08749a516e126f3990a20f40866ed4a6e85d134ab49907ece
+2 -2
View File
@@ -112,8 +112,8 @@ static void renameReloadSchema(Parse *pParse, int iDb, u16 p5){
Vdbe *v = pParse->pVdbe;
if( v ){
sqlite3ChangeCookie(pParse, iDb);
sqlite3VdbeAddParseSchemaOp(pParse->pVdbe, iDb, 0, p5);
if( iDb!=1 ) sqlite3VdbeAddParseSchemaOp(pParse->pVdbe, 1, 0, p5);
sqlite3VdbeAddParseSchemaOp(pParse, iDb, 0, p5);
if( iDb!=1 ) sqlite3VdbeAddParseSchemaOp(pParse, 1, 0, p5);
}
}
+1
View File
@@ -212,6 +212,7 @@ static void openStatTable(
** side-effect of the CREATE TABLE statement is to leave the rootpage
** of the new table in register pParse->regRoot. This is important
** because the OpenWrite opcode below will be needing it. */
sqlite3SchemaWritable(pParse, iDb);
sqlite3NestedParse(pParse,
"CREATE TABLE %Q.%s(%s)", pDb->zDbSName, zTab, aTable[i].zCols
);
+5 -4
View File
@@ -205,14 +205,14 @@ static void attachFunc(
** way we found it.
*/
if( rc==SQLITE_OK ){
sqlite3BtreeEnterAll(db);
db->init.iDb = 0;
db->mDbFlags &= ~(DBFLAG_SchemaKnownOk);
if( !REOPEN_AS_MEMDB(db) ){
if( !IsSharedSchema(db) && !REOPEN_AS_MEMDB(db) ){
sqlite3BtreeEnterAll(db);
rc = sqlite3Init(db, &zErrDyn);
sqlite3BtreeLeaveAll(db);
assert( zErrDyn==0 || rc!=SQLITE_OK );
}
sqlite3BtreeLeaveAll(db);
assert( zErrDyn==0 || rc!=SQLITE_OK );
}
#ifdef SQLITE_USER_AUTHENTICATION
if( rc==SQLITE_OK && !REOPEN_AS_MEMDB(db) ){
@@ -312,6 +312,7 @@ static void detachFunc(
pEntry = sqliteHashNext(pEntry);
}
(void)sqlite3SchemaDisconnect(db, i, 0);
sqlite3BtreeClose(pDb->pBt);
pDb->pBt = 0;
pDb->pSchema = 0;
+27 -32
View File
@@ -1548,7 +1548,7 @@ static int defragmentPage(MemPage *pPage, int nMaxFrag){
if( iFree2+sz2 > usableSize ) return SQLITE_CORRUPT_PAGE(pPage);
memmove(&data[iFree+sz+sz2], &data[iFree+sz], iFree2-(iFree+sz));
sz += sz2;
}else if( NEVER(iFree+sz>usableSize) ){
}else if( iFree+sz>usableSize ){
return SQLITE_CORRUPT_PAGE(pPage);
}
@@ -7904,8 +7904,6 @@ static int balance_nonroot(
Pgno pgno; /* Temp var to store a page number in */
u8 abDone[NB+2]; /* True after i'th new page is populated */
Pgno aPgno[NB+2]; /* Page numbers of new pages before shuffling */
Pgno aPgOrder[NB+2]; /* Copy of aPgno[] used for sorting pages */
u16 aPgFlags[NB+2]; /* flags field of new pages before shuffling */
CellArray b; /* Parsed information on cells being balanced */
memset(abDone, 0, sizeof(abDone));
@@ -8329,42 +8327,39 @@ static int balance_nonroot(
** of the table is closer to a linear scan through the file. That in turn
** helps the operating system to deliver pages from the disk more rapidly.
**
** An O(n^2) insertion sort algorithm is used, but since n is never more
** than (NB+2) (a small constant), that should not be a problem.
** An O(N*N) sort algorithm is used, but since N is never more than NB+2
** (5), that is not a performance concern.
**
** When NB==3, this one optimization makes the database about 25% faster
** for large insertions and deletions.
*/
for(i=0; i<nNew; i++){
aPgOrder[i] = aPgno[i] = apNew[i]->pgno;
aPgFlags[i] = apNew[i]->pDbPage->flags;
for(j=0; j<i; j++){
if( NEVER(aPgno[j]==aPgno[i]) ){
/* This branch is taken if the set of sibling pages somehow contains
** duplicate entries. This can happen if the database is corrupt.
** It would be simpler to detect this as part of the loop below, but
** we do the detection here in order to avoid populating the pager
** cache with two separate objects associated with the same
** page number. */
assert( CORRUPT_DB );
rc = SQLITE_CORRUPT_BKPT;
goto balance_cleanup;
}
}
aPgno[i] = apNew[i]->pgno;
assert( apNew[i]->pDbPage->flags & PGHDR_WRITEABLE );
assert( apNew[i]->pDbPage->flags & PGHDR_DIRTY );
}
for(i=0; i<nNew; i++){
int iBest = 0; /* aPgno[] index of page number to use */
for(j=1; j<nNew; j++){
if( aPgOrder[j]<aPgOrder[iBest] ) iBest = j;
for(i=0; i<nNew-1; i++){
int iB = i;
for(j=i+1; j<nNew; j++){
if( apNew[j]->pgno < apNew[iB]->pgno ) iB = j;
}
pgno = aPgOrder[iBest];
aPgOrder[iBest] = 0xffffffff;
if( iBest!=i ){
if( iBest>i ){
sqlite3PagerRekey(apNew[iBest]->pDbPage, pBt->nPage+iBest+1, 0);
}
sqlite3PagerRekey(apNew[i]->pDbPage, pgno, aPgFlags[iBest]);
apNew[i]->pgno = pgno;
/* If apNew[i] has a page number that is bigger than any of the
** subsequence apNew[i] entries, then swap apNew[i] with the subsequent
** entry that has the smallest page number (which we know to be
** entry apNew[iB]).
*/
if( iB!=i ){
Pgno pgnoA = apNew[i]->pgno;
Pgno pgnoB = apNew[iB]->pgno;
Pgno pgnoTemp = (PENDING_BYTE/pBt->pageSize)+1;
u16 fgA = apNew[i]->pDbPage->flags;
u16 fgB = apNew[iB]->pDbPage->flags;
sqlite3PagerRekey(apNew[i]->pDbPage, pgnoTemp, fgB);
sqlite3PagerRekey(apNew[iB]->pDbPage, pgnoA, fgA);
sqlite3PagerRekey(apNew[i]->pDbPage, pgnoB, fgB);
apNew[i]->pgno = pgnoB;
apNew[iB]->pgno = pgnoA;
}
}
+89 -63
View File
@@ -331,8 +331,6 @@ void sqlite3NestedParse(Parse *pParse, const char *zFormat, ...){
memset(PARSE_TAIL(pParse), 0, PARSE_TAIL_SZ);
db->mDbFlags |= DBFLAG_PreferBuiltin;
sqlite3RunParser(pParse, zSql);
sqlite3DbFree(db, pParse->zErrMsg);
pParse->zErrMsg = 0;
db->mDbFlags = savedDbFlags;
sqlite3DbFree(db, zSql);
memcpy(PARSE_TAIL(pParse), saveBuf, PARSE_TAIL_SZ);
@@ -349,6 +347,39 @@ int sqlite3UserAuthTable(const char *zTable){
}
#endif
#ifdef SQLITE_ENABLE_SHARED_SCHEMA
/*
** If this database connection was opened with the SQLITE_OPEN_SHARED_SCHEMA
** flag specified, then ensure that the database schema for database iDb
** is loaded. Either by obtaining a Schema object from the schema-pool, or
** by reading the contents of the sqlite_master table. Unless it is NULL,
** the location indicated by parameter pbUnload is set to 1 if a shared-schema
** is loaded.
**
** If the database handle was not opened with SQLITE_OPEN_SHARED_SCHEMA, or
** if the schema for database iDb is already loaded, this function is a no-op.
**
** SQLITE_OK is returned if successful, or an SQLite error code otherwise. If
** an error code is returned, (*pzErr) may be set to point to a buffer
** containing an error message. It is the responsibility of the caller to
** eventually free this buffer using sqlite3_free().
*/
int sqlite3SchemaLoad(sqlite3 *db, int iDb, int *pbUnload, char **pzErr){
int rc = SQLITE_OK;
if( IsSharedSchema(db)
&& DbHasProperty(db, iDb, DB_SchemaLoaded)==0
&& (db->init.busy==0 || (iDb!=1 && db->init.iDb==1))
){
struct sqlite3InitInfo sv = db->init;
memset(&db->init, 0, sizeof(struct sqlite3InitInfo));
rc = sqlite3InitOne(db, iDb, pzErr, 0);
db->init = sv;
if( pbUnload && rc==SQLITE_OK && iDb!=1 ) *pbUnload = 1;
}
return rc;
}
#endif
/*
** Locate the in-memory structure that describes a particular database
** table given the name of that table and (optionally) the name of the
@@ -374,59 +405,41 @@ Table *sqlite3FindTable(sqlite3 *db, const char *zName, const char *zDatabase){
return 0;
}
#endif
if( zDatabase ){
for(i=0; i<db->nDb; i++){
if( sqlite3StrICmp(zDatabase, db->aDb[i].zDbSName)==0 ) break;
}
if( i>=db->nDb ){
/* No match against the official names. But always match "main"
** to schema 0 as a legacy fallback. */
if( sqlite3StrICmp(zDatabase,"main")==0 ){
i = 0;
}else{
return 0;
}
}
p = sqlite3HashFind(&db->aDb[i].pSchema->tblHash, zName);
if( p==0 && sqlite3StrNICmp(zName, "sqlite_", 7)==0 ){
if( i==1 ){
if( sqlite3StrICmp(zName+7, &PREFERRED_TEMP_SCHEMA_TABLE[7])==0
|| sqlite3StrICmp(zName+7, &PREFERRED_SCHEMA_TABLE[7])==0
|| sqlite3StrICmp(zName+7, &LEGACY_SCHEMA_TABLE[7])==0
){
p = sqlite3HashFind(&db->aDb[1].pSchema->tblHash,
LEGACY_TEMP_SCHEMA_TABLE);
while(1){
for(i=OMIT_TEMPDB; i<db->nDb; i++){
int j = (i<2) ? i^1 : i; /* Search TEMP before MAIN */
if( zDatabase==0 || sqlite3DbIsNamed(db, j, zDatabase) ){
int bUnload = 0;
assert( sqlite3SchemaMutexHeld(db, j, 0) );
if( IsSharedSchema(db) ){
Parse *pParse = db->pParse;
if( pParse && pParse->nErr==0 ){
pParse->rc = sqlite3SchemaLoad(db, j, &bUnload, &pParse->zErrMsg);
if( pParse->rc ) pParse->nErr++;
}
}
}else{
if( sqlite3StrICmp(zName+7, &PREFERRED_SCHEMA_TABLE[7])==0 ){
p = sqlite3HashFind(&db->aDb[i].pSchema->tblHash,
LEGACY_SCHEMA_TABLE);
p = sqlite3HashFind(&db->aDb[j].pSchema->tblHash, zName);
if( p ) return p;
if( bUnload ){
sqlite3SchemaRelease(db, j);
}
}
}
}else{
/* Match against TEMP first */
p = sqlite3HashFind(&db->aDb[1].pSchema->tblHash, zName);
if( p ) return p;
/* The main database is second */
p = sqlite3HashFind(&db->aDb[0].pSchema->tblHash, zName);
if( p ) return p;
/* Attached databases are in order of attachment */
for(i=2; i<db->nDb; i++){
assert( sqlite3SchemaMutexHeld(db, i, 0) );
p = sqlite3HashFind(&db->aDb[i].pSchema->tblHash, zName);
if( p ) break;
/* Not found. If the name we were looking for was temp.sqlite_master
** then change the name to sqlite_temp_master and try again. */
if( sqlite3StrICmp(zName, PREFERRED_SCHEMA_TABLE)==0 ){
zName = LEGACY_SCHEMA_TABLE;
continue;
}
if( p==0 && sqlite3StrNICmp(zName, "sqlite_", 7)==0 ){
if( sqlite3StrICmp(zName+7, &PREFERRED_SCHEMA_TABLE[7])==0 ){
p = sqlite3HashFind(&db->aDb[0].pSchema->tblHash, LEGACY_SCHEMA_TABLE);
}else if( sqlite3StrICmp(zName+7, &PREFERRED_TEMP_SCHEMA_TABLE[7])==0 ){
p = sqlite3HashFind(&db->aDb[1].pSchema->tblHash,
LEGACY_TEMP_SCHEMA_TABLE);
}
if( sqlite3StrICmp(zName, PREFERRED_TEMP_SCHEMA_TABLE)==0 ){
zName = LEGACY_TEMP_SCHEMA_TABLE;
continue;
}
if( sqlite3StrICmp(zName, LEGACY_SCHEMA_TABLE)!=0 ) break;
if( sqlite3_stricmp(zDatabase, db->aDb[1].zDbSName)!=0 ) break;
zName = LEGACY_TEMP_SCHEMA_TABLE;
}
return p;
return 0;
}
/*
@@ -451,6 +464,7 @@ Table *sqlite3LocateTable(
/* Read the database schema. If an error occurs, leave an error message
** and code in pParse and return NULL. */
if( (db->mDbFlags & DBFLAG_SchemaKnownOk)==0
&& !IsSharedSchema(db)
&& SQLITE_OK!=sqlite3ReadSchema(pParse)
){
return 0;
@@ -467,9 +481,21 @@ Table *sqlite3LocateTable(
if( pMod==0 && sqlite3_strnicmp(zName, "pragma_", 7)==0 ){
pMod = sqlite3PragmaVtabRegister(db, zName);
}
if( pMod && sqlite3VtabEponymousTableInit(pParse, pMod) ){
testcase( pMod->pEpoTab==0 );
return pMod->pEpoTab;
if( pMod ){
if( IsSharedSchema(db) && pParse->nErr==0 ){
int bDummy = 0;
pParse->rc = sqlite3SchemaLoad(db, 0, &bDummy, &pParse->zErrMsg);
if( pParse->rc ) pParse->nErr++;
(void)bDummy;
}
if( sqlite3VtabEponymousTableInit(pParse, pMod) ){
Table *pEpoTab = pMod->pEpoTab;
if( pEpoTab ){
assert( IsSharedSchema(db)||pEpoTab->pSchema==db->aDb[0].pSchema );
pEpoTab->pSchema = db->aDb[0].pSchema; /* For SHARED_SCHEMA mode */
}
return pEpoTab;
}
}
}
#endif
@@ -479,15 +505,13 @@ Table *sqlite3LocateTable(
p = 0;
}
if( p==0 ){
if( p==0 && (!IsSharedSchema(db) || pParse->nErr==0) ){
const char *zMsg = flags & LOCATE_VIEW ? "no such view" : "no such table";
if( zDbase ){
sqlite3ErrorMsg(pParse, "%s: %s.%s", zMsg, zDbase, zName);
}else{
sqlite3ErrorMsg(pParse, "%s: %s", zMsg, zName);
}
}else{
assert( HasRowid(p) || p->iPKey<0 );
}
return p;
@@ -656,11 +680,10 @@ void sqlite3ResetOneSchema(sqlite3 *db, int iDb){
DbSetProperty(db, 1, DB_ResetWanted);
db->mDbFlags &= ~DBFLAG_SchemaKnownOk;
}
if( db->nSchemaLock==0 ){
for(i=0; i<db->nDb; i++){
if( DbHasProperty(db, i, DB_ResetWanted) ){
sqlite3SchemaClear(db->aDb[i].pSchema);
sqlite3SchemaClearOrDisconnect(db, i);
}
}
}
@@ -673,16 +696,17 @@ void sqlite3ResetOneSchema(sqlite3 *db, int iDb){
void sqlite3ResetAllSchemasOfConnection(sqlite3 *db){
int i;
sqlite3BtreeEnterAll(db);
for(i=0; i<db->nDb; i++){
for(i=0; i<db->nDb; i=(i?i+1:2)){
Db *pDb = &db->aDb[i];
if( pDb->pSchema ){
if( db->nSchemaLock==0 ){
sqlite3SchemaClear(pDb->pSchema);
sqlite3SchemaClearOrDisconnect(db, i);
}else{
DbSetProperty(db, i, DB_ResetWanted);
}
}
}
sqlite3SchemaClear(db->aDb[1].pSchema);
db->mDbFlags &= ~(DBFLAG_SchemaChange|DBFLAG_SchemaKnownOk);
sqlite3VtabUnlockList(db);
sqlite3BtreeLeaveAll(db);
@@ -1287,7 +1311,7 @@ void sqlite3StartTable(
*/
if( !IN_SPECIAL_PARSE ){
char *zDb = db->aDb[iDb].zDbSName;
if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){
if( !IsSharedSchema(db) && SQLITE_OK!=sqlite3ReadSchema(pParse) ){
goto begin_table_error;
}
pTable = sqlite3FindTable(db, zName, zDb);
@@ -2912,7 +2936,7 @@ void sqlite3EndTable(
#endif
/* Reparse everything to update our internal data structures */
sqlite3VdbeAddParseSchemaOp(v, iDb,
sqlite3VdbeAddParseSchemaOp(pParse, iDb,
sqlite3MPrintf(db, "tbl_name='%q' AND type!='trigger'", p->zName),0);
}
@@ -3465,7 +3489,7 @@ void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView, int noErr){
}
assert( pParse->nErr==0 );
assert( pName->nSrc==1 );
if( sqlite3ReadSchema(pParse) ) goto exit_drop_table;
if( !IsSharedSchema(db) && sqlite3ReadSchema(pParse) ) goto exit_drop_table;
if( noErr ) db->suppressErr++;
assert( isView==0 || isView==LOCATE_VIEW );
pTab = sqlite3LocateTableItem(pParse, isView, &pName->a[0]);
@@ -3480,6 +3504,7 @@ void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView, int noErr){
}
iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
assert( iDb>=0 && iDb<db->nDb );
sqlite3SchemaWritable(pParse, iDb);
/* If pTab is a virtual table, call ViewGetColumnNames() to ensure
** it is initialized.
@@ -3934,7 +3959,7 @@ void sqlite3CreateIndex(
if( IN_DECLARE_VTAB && idxType!=SQLITE_IDXTYPE_PRIMARYKEY ){
goto exit_create_index;
}
if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){
if( !IsSharedSchema(db) && SQLITE_OK!=sqlite3ReadSchema(pParse) ){
goto exit_create_index;
}
if( sqlite3HasExplicitNulls(pParse, pList) ){
@@ -4432,7 +4457,7 @@ void sqlite3CreateIndex(
if( pTblName ){
sqlite3RefillIndex(pParse, pIndex, iMem);
sqlite3ChangeCookie(pParse, iDb);
sqlite3VdbeAddParseSchemaOp(v, iDb,
sqlite3VdbeAddParseSchemaOp(pParse, iDb,
sqlite3MPrintf(db, "name='%q' AND type='index'", pIndex->zName), 0);
sqlite3VdbeAddOp2(v, OP_Expire, 0, 1);
}
@@ -4582,6 +4607,7 @@ void sqlite3DropIndex(Parse *pParse, SrcList *pName, int ifExists){
goto exit_drop_index;
}
iDb = sqlite3SchemaToIndex(db, pIndex->pSchema);
sqlite3SchemaWritable(pParse, iDb);
#ifndef SQLITE_OMIT_AUTHORIZATION
{
int code = SQLITE_DROP_INDEX;
+365 -6
View File
@@ -16,6 +16,63 @@
#include "sqliteInt.h"
/*
** Connections opened with the SQLITE_OPEN_SHARED_SCHEMA flag specified
** may use SchemaPool objects for any database that is not the temp db
** (iDb==1). For such databases (type "struct Db") there are three states
** the Schema/SchemaPool object may be in.
**
** 1) pSPool==0, pSchema points to an empty object allocated by
** sqlite3_malloc(). DB_SchemaLoaded flag is clear.
**
** 2) pSPool!=0, pSchema points to a populated object owned by the
** SchemaPool. DB_SchemaLoaded flag is set.
**
** 3) pSPool!=0, pSchema points to the SchemaPool's static object
** (SchemaPool.sSchema).
*/
struct SchemaPool {
int nRef; /* Number of pointers to this object */
int nDelete; /* Schema objects deleted by ReleaseAll() */
u64 cksum; /* Checksum for this Schema contents */
Schema *pSchema; /* Linked list of Schema objects */
Schema sSchema; /* The single dummy schema object */
SchemaPool *pNext; /* Next element in schemaPoolList */
};
#ifdef SQLITE_ENABLE_SHARED_SCHEMA
#ifdef SQLITE_DEBUG
static void assert_schema_state_ok(sqlite3 *db){
if( IsSharedSchema(db) && db->eOpenState!=SQLITE_STATE_ZOMBIE ){
int i;
for(i=0; i<db->nDb; i++){
if( i!=1 ){
Db *pDb = &db->aDb[i];
Btree *pBt = pDb->pBt;
if( pBt==0 ) continue;
assert( sqlite3BtreeSchema(pBt, 0, 0)==0 );
assert( pDb->pSchema );
if( pDb->pSPool ){
if( DbHasProperty(db, i, DB_SchemaLoaded)==0 ){
assert( pDb->pSchema->tblHash.count==0 );
assert( pDb->pSchema==&pDb->pSPool->sSchema );
}else{
assert( pDb->pSchema!=&pDb->pSPool->sSchema );
}
}else{
assert( DbHasProperty(db, i, DB_SchemaLoaded)==0 );
assert( pDb->pSchema->tblHash.count==0 );
assert( pDb->pSchema!=&pDb->pSPool->sSchema );
}
}
}
}
}
#else
# define assert_schema_state_ok(x)
#endif
#endif /* ifdef SQLITE_ENABLE_SHARED_SCHEMA */
/*
** Invoke the 'collation needed' callback to request a collation sequence
** in the encoding enc of name zName, length nName.
@@ -514,15 +571,317 @@ void sqlite3SchemaClear(void *p){
}
/*
** Find and return the schema associated with a BTree. Create
** a new one if necessary.
** If this database was opened with the SQLITE_OPEN_SHARED_SCHEMA flag
** and iDb!=1, then disconnect from the schema-pool associated with
** database iDb. Otherwise, clear the Schema object belonging to
** database iDb.
**
** If an OOM error occurs while disconnecting from a schema-pool,
** the db->mallocFailed flag is set.
*/
void sqlite3SchemaClearOrDisconnect(sqlite3 *db, int iDb){
Db *pDb = &db->aDb[iDb];
#ifdef SQLITE_ENABLE_SHARED_SCHEMA
if( IsSharedSchema(db) && iDb!=1 && pDb->pSPool ){
sqlite3SchemaDisconnect(db, iDb, 1);
}else
#endif
{
sqlite3SchemaClear(pDb->pSchema);
}
}
#ifdef SQLITE_ENABLE_SHARED_SCHEMA
/*
** Global linked list of SchemaPool objects. Read and write access must
** be protected by the SQLITE_MUTEX_STATIC_MASTER mutex.
*/
static SchemaPool *SQLITE_WSD schemaPoolList = 0;
#ifdef SQLITE_TEST
/*
** Return a pointer to the head of the linked list of SchemaPool objects.
** This is used by the virtual table in file test_schemapool.c.
*/
SchemaPool *sqlite3SchemaPoolList(void){ return schemaPoolList; }
#endif
/*
** Database handle db was opened with the SHARED_SCHEMA flag, and database
** iDb is currently connected to a schema-pool. When this function is called,
** (*pnByte) is set to nInit plus the amount of memory used to store a
** single instance of the Schema objects managed by the schema-pool.
** This function adjusts (*pnByte) sot hat it is set to nInit plus
** (nSchema/nRef) of the amount of memory used by a single Schema object,
** where nSchema is the number of Schema objects allocated by this pool,
** and nRef is the number of connections to the schema-pool.
*/
void sqlite3SchemaAdjustUsed(sqlite3 *db, int iDb, int nInit, int *pnByte){
SchemaPool *pSPool = db->aDb[iDb].pSPool;
int nSchema = 0;
Schema *p;
sqlite3_mutex_enter( sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER) );
for(p=pSPool->pSchema; p; p=p->pNext){
nSchema++;
}
*pnByte = nInit + ((*pnByte - nInit) * nSchema) / pSPool->nRef;
sqlite3_mutex_leave( sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER) );
}
/*
** Check that the schema of db iDb is writable (either because it is the
** temp db schema or because the db handle was opened without
** SQLITE_OPEN_SHARED_SCHEMA). If so, do nothing. Otherwise, leave an
** error in the Parse object.
*/
void sqlite3SchemaWritable(Parse *pParse, int iDb){
if( iDb!=1 && IsSharedSchema(pParse->db) && IN_DECLARE_VTAB==0 ){
sqlite3ErrorMsg(pParse, "attempt to modify read-only schema");
}
}
/*
** The schema object passed as the only argument was allocated using
** sqlite3_malloc() and then populated using the usual mechanism. This
** function frees both the Schema object and its contents.
*/
static void schemaDelete(Schema *pSchema){
sqlite3SchemaClear((void*)pSchema);
sqlite3_free(pSchema);
}
/*
** When this function is called, the database connection Db must be
** using a schema-pool (Db.pSPool!=0) and must currently have Db.pSchema
** set to point to a populated schema object checked out from the
** schema-pool. It is also assumed that the STATIC_MASTER mutex is held.
** This function returns the Schema object to the schema-pool and sets
** Db.pSchema to point to the schema-pool's static, empty, Schema object.
*/
static void schemaRelease(sqlite3 *db, Db *pDb){
Schema *pRelease = pDb->pSchema;
SchemaPool *pSPool = pDb->pSPool;
assert( pDb->pSchema->iGeneration==pSPool->sSchema.iGeneration );
pDb->pSchema = &pSPool->sSchema;
assert( pDb->pSPool && pRelease );
assert( pRelease->schemaFlags & DB_SchemaLoaded );
assert( (pDb->pSchema->schemaFlags & DB_SchemaLoaded)==0 );
assert( sqlite3_mutex_held(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER)) );
/* If the DBFLAG_FreeSchema flag is set and the database connection holds
** at least one other copy of the schema being released, delete it instead
** of returning it to the schema-pool. */
if( db->mDbFlags & DBFLAG_FreeSchema ){
int i;
for(i=0; i<db->nDb; i++){
Db *p = &db->aDb[i];
if( p!=pDb && p->pSchema!=&pSPool->sSchema && pDb->pSPool==p->pSPool ){
pSPool->nDelete++;
schemaDelete(pRelease);
return;
}
}
}
pRelease->pNext = pDb->pSPool->pSchema;
pDb->pSPool->pSchema = pRelease;
}
/*
** The schema for database iDb of database handle db, which was opened
** with SQLITE_OPEN_SHARED_SCHEMA, has just been parsed. This function either
** finds a matching SchemaPool object on the global list (schemaPoolList) or
** else allocates a new one and sets the Db.pSPool variable accordingly.
**
** SQLITE_OK is returned if no error occurs, or an SQLite error code
** (SQLITE_NOMEM) otherwise.
*/
int sqlite3SchemaConnect(sqlite3 *db, int iDb, u64 cksum){
Schema *pSchema = db->aDb[iDb].pSchema;
SchemaPool *p;
assert( pSchema && iDb!=1 && db->aDb[iDb].pSPool==0 );
sqlite3_mutex_enter( sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER) );
/* Search for a matching SchemaPool object */
for(p=schemaPoolList; p; p=p->pNext){
if( p->cksum==cksum && p->sSchema.schema_cookie==pSchema->schema_cookie ){
break;
}
}
if( !p ){
/* No SchemaPool object found. Allocate a new one. */
p = (SchemaPool*)sqlite3_malloc(sizeof(SchemaPool));
if( p ){
memset(p, 0, sizeof(SchemaPool));
p->cksum = cksum;
p->pNext = schemaPoolList;
schemaPoolList = p;
p->sSchema.schema_cookie = pSchema->schema_cookie;
p->sSchema.iGeneration = pSchema->iGeneration;
p->sSchema.file_format = pSchema->file_format;
p->sSchema.enc = pSchema->enc;
p->sSchema.cache_size = pSchema->cache_size;
}
}
if( p ) p->nRef++;
/* If the SchemaPool contains one or more free schemas at the moment,
** delete one of them. */
if( p && p->pSchema ){
Schema *pDel = p->pSchema;
p->pSchema = pDel->pNext;
schemaDelete(pDel);
}
sqlite3_mutex_leave( sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER) );
db->aDb[iDb].pSPool = p;
return (p ? SQLITE_OK : SQLITE_NOMEM);
}
/*
** If parameter iDb is 1 (the temp db), or if connection handle db was not
** opened with the SQLITE_OPEN_SHARED_SCHEMA flag, this function is a no-op.
** Otherwise, it disconnects from the schema-pool associated with database
** iDb, assuming it is connected.
**
** If parameter bNew is true, then Db.pSchema is set to point to a new, empty,
** Schema object obtained from sqlite3_malloc(). Or, if bNew is false, then
** Db.pSchema is set to NULL before returning.
**
** If the bNew parameter is true, then this function may allocate memory.
** If the allocation attempt fails, then SQLITE_NOMEM is returned and the
** schema-pool is not disconnected from. Or, if no OOM error occurs,
** SQLITE_OK is returned.
*/
int sqlite3SchemaDisconnect(sqlite3 *db, int iDb, int bNew){
int rc = SQLITE_OK;
if( IsSharedSchema(db) ){
Db *pDb = &db->aDb[iDb];
SchemaPool *pSPool = pDb->pSPool;
assert_schema_state_ok(db);
assert( pDb->pSchema );
if( pSPool==0 ){
assert( pDb->pVTable==0 );
assert( bNew==0 );
schemaDelete(pDb->pSchema);
pDb->pSchema = 0;
}else{
VTable *p;
VTable *pNext;
for(p=pDb->pVTable; p; p=pNext){
pNext = p->pNext;
sqlite3VtabUnlock(p);
}
pDb->pVTable = 0;
sqlite3_mutex_enter( sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER) );
if( DbHasProperty(db, iDb, DB_SchemaLoaded) ){
schemaRelease(db, pDb);
}
if( bNew ){
Schema *pNew = sqlite3SchemaGet(db, 0);
if( pNew==0 ){
rc = SQLITE_NOMEM;
}else{
pDb->pSchema = pNew;
}
}
if( rc==SQLITE_OK ){
assert( pSPool->nRef>=1 );
pDb->pSPool = 0;
pSPool->nRef--;
if( pSPool->nRef<=0 ){
SchemaPool **pp;
while( pSPool->pSchema ){
Schema *pNext = pSPool->pSchema->pNext;
schemaDelete(pSPool->pSchema);
pSPool->pSchema = pNext;
}
for(pp=&schemaPoolList; (*pp)!=pSPool; pp=&((*pp)->pNext));
*pp = pSPool->pNext;
sqlite3_free(pSPool);
}
}
sqlite3_mutex_leave( sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER) );
}
}
return rc;
}
/*
** Extract and return a pointer to a schema object from the SchemaPool passed
** as the only argument, if one is available. If one is not available, return
** NULL.
*/
Schema *sqlite3SchemaExtract(SchemaPool *pSPool){
Schema *pRet = 0;
sqlite3_mutex_enter( sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER) );
if( pSPool->pSchema ){
pRet = pSPool->pSchema;
pSPool->pSchema = pRet->pNext;
pRet->pNext = 0;
}
sqlite3_mutex_leave( sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER) );
return pRet;
}
/*
** Return all sharable schemas held by database handle db back to their
** respective schema-pools. Db.pSchema variables are left pointing to
** the static, empty, Schema object owned by each schema-pool.
*/
void sqlite3SchemaReleaseAll(sqlite3 *db){
int i;
assert_schema_state_ok(db);
sqlite3_mutex_enter( sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER) );
for(i=0; i<db->nDb; i++){
if( i!=1 ){
Db *pDb = &db->aDb[i];
if( pDb->pSPool && DbHasProperty(db,i,DB_SchemaLoaded) ){
schemaRelease(db, pDb);
}
}
}
db->mDbFlags &= ~DBFLAG_FreeSchema;
sqlite3_mutex_leave( sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER) );
}
/*
** Release any sharable schema held by connection iDb of database handle
** db. Db.pSchema is left pointing to the static, empty, Schema object
** owned by the schema-pool.
*/
void sqlite3SchemaRelease(sqlite3 *db, int iDb){
Db *pDb = &db->aDb[iDb];
assert( iDb!=1 );
assert_schema_state_ok(db);
sqlite3_mutex_enter( sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER) );
schemaRelease(db, pDb);
sqlite3_mutex_leave( sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER) );
}
#endif /* ifdef SQLITE_ENABLE_SHARED_SCHEMA */
/*
** In most cases, this function finds and returns the schema associated
** with BTree handle pBt, creating a new one if necessary. However, if
** the database handle was opened with the SQLITE_OPEN_SHARED_SCHEMA flag
** specified, a new, empty, Schema object in memory obtained by
** sqlite3_malloc() is always returned.
*/
Schema *sqlite3SchemaGet(sqlite3 *db, Btree *pBt){
Schema * p;
if( pBt ){
p = (Schema *)sqlite3BtreeSchema(pBt, sizeof(Schema), sqlite3SchemaClear);
Schema *p;
if( pBt && IsSharedSchema(db)==0 ){
p = (Schema*)sqlite3BtreeSchema(pBt, sizeof(Schema), sqlite3SchemaClear);
}else{
p = (Schema *)sqlite3DbMallocZero(0, sizeof(Schema));
p = (Schema*)sqlite3DbMallocZero(0, sizeof(Schema));
}
if( !p ){
sqlite3OomFault(db);
+3
View File
@@ -310,6 +310,9 @@ static const char * const sqlite3azCompileOpt[] = {
#ifdef SQLITE_ENABLE_SESSION
"ENABLE_SESSION",
#endif
#if SQLITE_ENABLE_SHARED_SCHEMA
"ENABLE_SHARED_SCHEMA",
#endif
#ifdef SQLITE_ENABLE_SNAPSHOT
"ENABLE_SNAPSHOT",
#endif
+37 -6
View File
@@ -1164,6 +1164,17 @@ static void disconnectAllVtab(sqlite3 *db){
if( IsVirtual(pTab) ) sqlite3VtabDisconnect(db, pTab);
}
}
#ifdef SQLITE_ENABLE_SHARED_SCHEMA
if( IsSharedSchema(db) && i!=1 ){
VTable *pVTable;
VTable *pNext;
for(pVTable=db->aDb[i].pVTable; pVTable; pVTable=pNext){
pNext = pVTable->pNext;
sqlite3VtabUnlock(pVTable);
}
db->aDb[i].pVTable = 0;
}
#endif /* ifdef SQLITE_ENABLE_SHARED_SCHEMA */
}
for(p=sqliteHashFirst(&db->aModule); p; p=sqliteHashNext(p)){
Module *pMod = (Module *)sqliteHashData(p);
@@ -1332,6 +1343,7 @@ void sqlite3LeaveMutexAndCloseZombie(sqlite3 *db){
sqlite3BtreeClose(pDb->pBt);
pDb->pBt = 0;
if( j!=1 ){
(void)sqlite3SchemaDisconnect(db, j, 0);
pDb->pSchema = 0;
}
}
@@ -3756,7 +3768,7 @@ int sqlite3_table_column_metadata(
int *pPrimaryKey, /* OUTPUT: True if column part of PK */
int *pAutoinc /* OUTPUT: True if column is auto-increment */
){
int rc;
int rc = SQLITE_OK;
char *zErrMsg = 0;
Table *pTab = 0;
Column *pCol = 0;
@@ -3766,7 +3778,7 @@ int sqlite3_table_column_metadata(
int notnull = 0;
int primarykey = 0;
int autoinc = 0;
int bUnlock;
#ifdef SQLITE_ENABLE_API_ARMOR
if( !sqlite3SafetyCheckOk(db) || zTableName==0 ){
@@ -3776,14 +3788,29 @@ int sqlite3_table_column_metadata(
/* Ensure the database schema has been loaded */
sqlite3_mutex_enter(db->mutex);
bUnlock = sqlite3LockReusableSchema(db);
sqlite3BtreeEnterAll(db);
rc = sqlite3Init(db, &zErrMsg);
if( SQLITE_OK!=rc ){
goto error_out;
if( IsSharedSchema(db)==0 ){
rc = sqlite3Init(db, &zErrMsg);
}
/* Locate the table in question */
pTab = sqlite3FindTable(db, zTableName, zDbName);
if( rc==SQLITE_OK ){
#ifdef SQLITE_ENABLE_SHARED_SCHEMA
Parse sParse; /* Fake Parse object for FindTable */
Parse *pSaved = db->pParse;
memset(&sParse, 0, sizeof(sParse));
db->pParse = &sParse;
#endif
pTab = sqlite3FindTable(db, zTableName, zDbName);
#ifdef SQLITE_ENABLE_SHARED_SCHEMA
sqlite3_free(sParse.zErrMsg);
rc = sParse.rc;
db->pParse = pSaved;
#endif
}
if( SQLITE_OK!=rc ) goto error_out;
if( !pTab || IsView(pTab) ){
pTab = 0;
goto error_out;
@@ -3856,6 +3883,7 @@ error_out:
sqlite3ErrorWithMsg(db, rc, (zErrMsg?"%s":0), zErrMsg);
sqlite3DbFree(db, zErrMsg);
rc = sqlite3ApiExit(db, rc);
sqlite3UnlockReusableSchema(db, bUnlock);
sqlite3_mutex_leave(db->mutex);
return rc;
}
@@ -4112,8 +4140,11 @@ int sqlite3_test_control(int op, ...){
sqlite3ShowTriggerStepList(0);
sqlite3ShowTrigger(0);
sqlite3ShowTriggerList(0);
#ifndef SQLITE_OMIT_WINDOWFUNC
sqlite3ShowWindow(0);
sqlite3ShowWinFunc(0);
#endif
sqlite3ShowSelect(0);
}
#endif
break;
+5
View File
@@ -776,8 +776,13 @@ void *sqlite3OomFault(sqlite3 *db){
}
DisableLookaside;
if( db->pParse ){
Parse *pParse;
sqlite3ErrorMsg(db->pParse, "out of memory");
db->pParse->rc = SQLITE_NOMEM_BKPT;
for(pParse=db->pParse->pOuterParse; pParse; pParse = pParse->pOuterParse){
pParse->nErr++;
pParse->rc = SQLITE_NOMEM;
}
}
}
return 0;
+20 -11
View File
@@ -5855,6 +5855,7 @@ static const char *unixTempFileDir(void){
static int unixGetTempname(int nBuf, char *zBuf){
const char *zDir;
int iLimit = 0;
int rc = SQLITE_OK;
/* It's odd to simulate an io-error here, but really this is just
** using the io-error infrastructure to test that SQLite handles this
@@ -5863,18 +5864,26 @@ static int unixGetTempname(int nBuf, char *zBuf){
zBuf[0] = 0;
SimulateIOError( return SQLITE_IOERR );
sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_TEMPDIR));
zDir = unixTempFileDir();
if( zDir==0 ) return SQLITE_IOERR_GETTEMPPATH;
do{
u64 r;
sqlite3_randomness(sizeof(r), &r);
assert( nBuf>2 );
zBuf[nBuf-2] = 0;
sqlite3_snprintf(nBuf, zBuf, "%s/"SQLITE_TEMP_FILE_PREFIX"%llx%c",
zDir, r, 0);
if( zBuf[nBuf-2]!=0 || (iLimit++)>10 ) return SQLITE_ERROR;
}while( osAccess(zBuf,0)==0 );
return SQLITE_OK;
if( zDir==0 ){
rc = SQLITE_IOERR_GETTEMPPATH;
}else{
do{
u64 r;
sqlite3_randomness(sizeof(r), &r);
assert( nBuf>2 );
zBuf[nBuf-2] = 0;
sqlite3_snprintf(nBuf, zBuf, "%s/"SQLITE_TEMP_FILE_PREFIX"%llx%c",
zDir, r, 0);
if( zBuf[nBuf-2]!=0 || (iLimit++)>10 ){
rc = SQLITE_ERROR;
break;
}
}while( osAccess(zBuf,0)==0 );
}
sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_TEMPDIR));
return rc;
}
#if SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__)
+41 -6
View File
@@ -1918,10 +1918,12 @@ int sqlite3_win32_set_directory8(
const char *zValue /* New value for directory being set or reset */
){
char **ppDirectory = 0;
int rc;
#ifndef SQLITE_OMIT_AUTOINIT
int rc = sqlite3_initialize();
rc = sqlite3_initialize();
if( rc ) return rc;
#endif
sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_TEMPDIR));
if( type==SQLITE_WIN32_DATA_DIRECTORY_TYPE ){
ppDirectory = &sqlite3_data_directory;
}else if( type==SQLITE_WIN32_TEMP_DIRECTORY_TYPE ){
@@ -1936,14 +1938,19 @@ int sqlite3_win32_set_directory8(
if( zValue && zValue[0] ){
zCopy = sqlite3_mprintf("%s", zValue);
if ( zCopy==0 ){
return SQLITE_NOMEM_BKPT;
rc = SQLITE_NOMEM_BKPT;
goto set_directory8_done;
}
}
sqlite3_free(*ppDirectory);
*ppDirectory = zCopy;
return SQLITE_OK;
rc = SQLITE_OK;
}else{
rc = SQLITE_ERROR;
}
return SQLITE_ERROR;
set_directory8_done:
sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_TEMPDIR));
return rc;
}
/*
@@ -4717,6 +4724,18 @@ static int winMakeEndInDirSep(int nBuf, char *zBuf){
return 0;
}
/*
** If sqlite3_temp_directory is not, take the mutex and return true.
**
** If sqlite3_temp_directory is NULL, omit the mutex and return false.
*/
static int winTempDirDefined(void){
sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_TEMPDIR));
if( sqlite3_temp_directory!=0 ) return 1;
sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_TEMPDIR));
return 0;
}
/*
** Create a temporary file name and store the resulting pointer into pzBuf.
** The pointer returned in pzBuf must be freed via sqlite3_free().
@@ -4753,20 +4772,23 @@ static int winGetTempname(sqlite3_vfs *pVfs, char **pzBuf){
*/
nDir = nMax - (nPre + 15);
assert( nDir>0 );
if( sqlite3_temp_directory ){
if( winTempDirDefined() ){
int nDirLen = sqlite3Strlen30(sqlite3_temp_directory);
if( nDirLen>0 ){
if( !winIsDirSep(sqlite3_temp_directory[nDirLen-1]) ){
nDirLen++;
}
if( nDirLen>nDir ){
sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_TEMPDIR));
sqlite3_free(zBuf);
OSTRACE(("TEMP-FILENAME rc=SQLITE_ERROR\n"));
return winLogError(SQLITE_ERROR, 0, "winGetTempname1", 0);
}
sqlite3_snprintf(nMax, zBuf, "%s", sqlite3_temp_directory);
}
sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_TEMPDIR));
}
#if defined(__CYGWIN__)
else{
static const char *azDirs[] = {
@@ -5555,7 +5577,7 @@ static BOOL winIsVerbatimPathname(
** pathname into zOut[]. zOut[] will be at least pVfs->mxPathname
** bytes in size.
*/
static int winFullPathname(
static int winFullPathnameNoMutex(
sqlite3_vfs *pVfs, /* Pointer to vfs object */
const char *zRelative, /* Possibly relative input path */
int nFull, /* Size of output buffer in bytes */
@@ -5734,6 +5756,19 @@ static int winFullPathname(
}
#endif
}
static int winFullPathname(
sqlite3_vfs *pVfs, /* Pointer to vfs object */
const char *zRelative, /* Possibly relative input path */
int nFull, /* Size of output buffer in bytes */
char *zFull /* Output buffer */
){
int rc;
sqlite3_mutex *pMutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_TEMPDIR);
sqlite3_mutex_enter(pMutex);
rc = winFullPathnameNoMutex(pVfs, zRelative, nFull, zFull);
sqlite3_mutex_leave(pMutex);
return rc;
}
#ifndef SQLITE_OMIT_LOAD_EXTENSION
/*
+2 -1
View File
@@ -5821,6 +5821,7 @@ static int pager_open_journal(Pager *pPager){
if( rc!=SQLITE_OK ){
sqlite3BitvecDestroy(pPager->pInJournal);
pPager->pInJournal = 0;
pPager->journalOff = 0;
}else{
assert( pPager->eState==PAGER_WRITER_LOCKED );
pPager->eState = PAGER_WRITER_CACHEMOD;
@@ -7376,7 +7377,7 @@ int sqlite3PagerGetJournalMode(Pager *pPager){
int sqlite3PagerOkToChangeJournalMode(Pager *pPager){
assert( assert_pager_state(pPager) );
if( pPager->eState>=PAGER_WRITER_CACHEMOD ) return 0;
if( NEVER(isOpen(pPager->jfd) && pPager->journalOff>0) ) return 0;
if( isOpen(pPager->jfd) && pPager->journalOff>0 ) return 0;
return 1;
}
+10
View File
@@ -622,14 +622,24 @@ void sqlite3PcacheClearSyncFlags(PCache *pCache){
*/
void sqlite3PcacheMove(PgHdr *p, Pgno newPgno){
PCache *pCache = p->pCache;
sqlite3_pcache_page *pOther;
assert( p->nRef>0 );
assert( newPgno>0 );
assert( sqlite3PcachePageSanity(p) );
pcacheTrace(("%p.MOVE %d -> %d\n",pCache,p->pgno,newPgno));
pOther = sqlite3GlobalConfig.pcache2.xFetch(pCache->pCache, newPgno, 0);
if( pOther ){
PgHdr *pXPage = (PgHdr*)pOther->pExtra;
assert( pXPage->nRef==0 );
pXPage->nRef++;
pCache->nRefSum++;
sqlite3PcacheDrop(pXPage);
}
sqlite3GlobalConfig.pcache2.xRekey(pCache->pCache, p->pPage, p->pgno,newPgno);
p->pgno = newPgno;
if( (p->flags&PGHDR_DIRTY) && (p->flags&PGHDR_NEED_SYNC) ){
pcacheManageDirtyList(p, PCACHE_DIRTYLIST_FRONT);
assert( sqlite3PcachePageSanity(p) );
}
}
+10 -7
View File
@@ -1123,23 +1123,26 @@ static void pcache1Rekey(
PCache1 *pCache = (PCache1 *)p;
PgHdr1 *pPage = (PgHdr1 *)pPg;
PgHdr1 **pp;
unsigned int h;
unsigned int hOld, hNew;
assert( pPage->iKey==iOld );
assert( pPage->pCache==pCache );
assert( iOld!=iNew ); /* The page number really is changing */
pcache1EnterMutex(pCache->pGroup);
h = iOld%pCache->nHash;
pp = &pCache->apHash[h];
assert( pcache1FetchNoMutex(p, iOld, 0)==pPage ); /* pPg really is iOld */
hOld = iOld%pCache->nHash;
pp = &pCache->apHash[hOld];
while( (*pp)!=pPage ){
pp = &(*pp)->pNext;
}
*pp = pPage->pNext;
h = iNew%pCache->nHash;
assert( pcache1FetchNoMutex(p, iNew, 0)==0 ); /* iNew not in cache */
hNew = iNew%pCache->nHash;
pPage->iKey = iNew;
pPage->pNext = pCache->apHash[h];
pCache->apHash[h] = pPage;
pPage->pNext = pCache->apHash[hNew];
pCache->apHash[hNew] = pPage;
if( iNew>pCache->iMaxKey ){
pCache->iMaxKey = iNew;
}
+16 -3
View File
@@ -476,7 +476,13 @@ void sqlite3Pragma(
/* Make sure the database schema is loaded if the pragma requires that */
if( (pPragma->mPragFlg & PragFlg_NeedSchema)!=0 ){
if( sqlite3ReadSchema(pParse) ) goto pragma_out;
if( IsSharedSchema(db) && (zDb || (pPragma->mPragFlg & PragFlg_OneSchema)) ){
assert( iDb>=0 && iDb<db->nDb );
pParse->rc = sqlite3SchemaLoad(db, iDb, 0, &pParse->zErrMsg);
if( pParse->rc ) goto pragma_out;
}else{
if( sqlite3ReadSchema(pParse) ) goto pragma_out;
}
}
/* Register the result column names for pragmas that return results */
@@ -965,6 +971,7 @@ void sqlite3Pragma(
**
*/
case PragTyp_TEMP_STORE_DIRECTORY: {
sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_TEMPDIR));
if( !zRight ){
returnSingleText(v, sqlite3_temp_directory);
}else{
@@ -974,6 +981,7 @@ void sqlite3Pragma(
rc = sqlite3OsAccess(db->pVfs, zRight, SQLITE_ACCESS_READWRITE, &res);
if( rc!=SQLITE_OK || res==0 ){
sqlite3ErrorMsg(pParse, "not a writable directory");
sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_TEMPDIR));
goto pragma_out;
}
}
@@ -991,6 +999,7 @@ void sqlite3Pragma(
}
#endif /* SQLITE_OMIT_WSD */
}
sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_TEMPDIR));
break;
}
@@ -1009,6 +1018,7 @@ void sqlite3Pragma(
**
*/
case PragTyp_DATA_STORE_DIRECTORY: {
sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_TEMPDIR));
if( !zRight ){
returnSingleText(v, sqlite3_data_directory);
}else{
@@ -1018,6 +1028,7 @@ void sqlite3Pragma(
rc = sqlite3OsAccess(db->pVfs, zRight, SQLITE_ACCESS_READWRITE, &res);
if( rc!=SQLITE_OK || res==0 ){
sqlite3ErrorMsg(pParse, "not a writable directory");
sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_TEMPDIR));
goto pragma_out;
}
}
@@ -1029,6 +1040,7 @@ void sqlite3Pragma(
}
#endif /* SQLITE_OMIT_WSD */
}
sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_TEMPDIR));
break;
}
#endif
@@ -2030,9 +2042,10 @@ void sqlite3Pragma(
** applications for any purpose.
*/
case PragTyp_HEADER_VALUE: {
int iCookie = pPragma->iArg; /* Which cookie to read or write */
int iCookie; /* Which cookie to read or write */
iCookie = pPragma->iArg & PRAGMA_HEADER_VALUE_MASK;
sqlite3VdbeUsesBtree(v, iDb);
if( zRight && (pPragma->mPragFlg & PragFlg_ReadOnly)==0 ){
if( zRight && (pPragma->iArg & PRAGMA_HEADER_VALUE_READONLY)==0 ){
/* Write the specified cookie value */
static const VdbeOpList setCookie[] = {
{ OP_Transaction, 0, 1, 0}, /* 0 */
+23 -16
View File
@@ -56,12 +56,19 @@
#define PragFlg_NeedSchema 0x01 /* Force schema load before running */
#define PragFlg_NoColumns 0x02 /* OP_ResultRow called with zero columns */
#define PragFlg_NoColumns1 0x04 /* zero columns if RHS argument is present */
#define PragFlg_ReadOnly 0x08 /* Read-only HEADER_VALUE */
#define PragFlg_OneSchema 0x08 /* Only a single schema required */
#define PragFlg_Result0 0x10 /* Acts as query when no argument */
#define PragFlg_Result1 0x20 /* Acts as query when has one argument */
#define PragFlg_SchemaOpt 0x40 /* Schema restricts name search if present */
#define PragFlg_SchemaReq 0x80 /* Schema required - "main" is default */
/* For PragTyp_HEADER_VALUE pragmas the Pragma.iArg value is set
** to the index of the header field to access (always 10 or less).
** Ored with HEADER_VALUE_READONLY if the field is read only. */
#define PRAGMA_HEADER_VALUE_READONLY 0x0100
#define PRAGMA_HEADER_VALUE_MASK 0x00FF
/* Names of columns for pragmas that return multi-column result
** or that return single-column results where the name of the
** result column is different from the name of the pragma
@@ -162,7 +169,7 @@ static const PragmaName aPragmaName[] = {
#if !defined(SQLITE_OMIT_AUTOVACUUM)
{/* zName: */ "auto_vacuum",
/* ePragTyp: */ PragTyp_AUTO_VACUUM,
/* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq|PragFlg_NoColumns1,
/* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq|PragFlg_NoColumns1|PragFlg_OneSchema,
/* ColNames: */ 0, 0,
/* iArg: */ 0 },
#endif
@@ -183,7 +190,7 @@ static const PragmaName aPragmaName[] = {
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
{/* zName: */ "cache_size",
/* ePragTyp: */ PragTyp_CACHE_SIZE,
/* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq|PragFlg_NoColumns1,
/* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq|PragFlg_NoColumns1|PragFlg_OneSchema,
/* ColNames: */ 0, 0,
/* iArg: */ 0 },
#endif
@@ -244,9 +251,9 @@ static const PragmaName aPragmaName[] = {
#if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS)
{/* zName: */ "data_version",
/* ePragTyp: */ PragTyp_HEADER_VALUE,
/* ePragFlg: */ PragFlg_ReadOnly|PragFlg_Result0,
/* ePragFlg: */ PragFlg_Result0,
/* ColNames: */ 0, 0,
/* iArg: */ BTREE_DATA_VERSION },
/* iArg: */ BTREE_DATA_VERSION|PRAGMA_HEADER_VALUE_READONLY },
#endif
#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
{/* zName: */ "database_list",
@@ -258,7 +265,7 @@ static const PragmaName aPragmaName[] = {
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && !defined(SQLITE_OMIT_DEPRECATED)
{/* zName: */ "default_cache_size",
/* ePragTyp: */ PragTyp_DEFAULT_CACHE_SIZE,
/* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq|PragFlg_NoColumns1,
/* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq|PragFlg_NoColumns1|PragFlg_OneSchema,
/* ColNames: */ 55, 1,
/* iArg: */ 0 },
#endif
@@ -295,7 +302,7 @@ static const PragmaName aPragmaName[] = {
#if !defined(SQLITE_OMIT_FOREIGN_KEY)
{/* zName: */ "foreign_key_list",
/* ePragTyp: */ PragTyp_FOREIGN_KEY_LIST,
/* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt,
/* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt|PragFlg_OneSchema,
/* ColNames: */ 0, 8,
/* iArg: */ 0 },
#endif
@@ -311,9 +318,9 @@ static const PragmaName aPragmaName[] = {
#if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS)
{/* zName: */ "freelist_count",
/* ePragTyp: */ PragTyp_HEADER_VALUE,
/* ePragFlg: */ PragFlg_ReadOnly|PragFlg_Result0,
/* ePragFlg: */ PragFlg_Result0,
/* ColNames: */ 0, 0,
/* iArg: */ BTREE_FREE_PAGE_COUNT },
/* iArg: */ BTREE_FREE_PAGE_COUNT|PRAGMA_HEADER_VALUE_READONLY },
#endif
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
{/* zName: */ "full_column_names",
@@ -353,7 +360,7 @@ static const PragmaName aPragmaName[] = {
#if !defined(SQLITE_OMIT_AUTOVACUUM)
{/* zName: */ "incremental_vacuum",
/* ePragTyp: */ PragTyp_INCREMENTAL_VACUUM,
/* ePragFlg: */ PragFlg_NeedSchema|PragFlg_NoColumns,
/* ePragFlg: */ PragFlg_NeedSchema|PragFlg_NoColumns|PragFlg_OneSchema,
/* ColNames: */ 0, 0,
/* iArg: */ 0 },
#endif
@@ -384,7 +391,7 @@ static const PragmaName aPragmaName[] = {
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
{/* zName: */ "journal_mode",
/* ePragTyp: */ PragTyp_JOURNAL_MODE,
/* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq,
/* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq|PragFlg_OneSchema,
/* ColNames: */ 0, 0,
/* iArg: */ 0 },
{/* zName: */ "journal_size_limit",
@@ -422,7 +429,7 @@ static const PragmaName aPragmaName[] = {
/* iArg: */ 0 },
{/* zName: */ "max_page_count",
/* ePragTyp: */ PragTyp_PAGE_COUNT,
/* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq,
/* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq|PragFlg_OneSchema,
/* ColNames: */ 0, 0,
/* iArg: */ 0 },
{/* zName: */ "mmap_size",
@@ -450,7 +457,7 @@ static const PragmaName aPragmaName[] = {
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
{/* zName: */ "page_count",
/* ePragTyp: */ PragTyp_PAGE_COUNT,
/* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq,
/* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq|PragFlg_OneSchema,
/* ColNames: */ 0, 0,
/* iArg: */ 0 },
{/* zName: */ "page_size",
@@ -549,14 +556,14 @@ static const PragmaName aPragmaName[] = {
#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) && defined(SQLITE_DEBUG)
{/* zName: */ "stats",
/* ePragTyp: */ PragTyp_STATS,
/* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq,
/* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq|PragFlg_OneSchema,
/* ColNames: */ 33, 5,
/* iArg: */ 0 },
#endif
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
{/* zName: */ "synchronous",
/* ePragTyp: */ PragTyp_SYNCHRONOUS,
/* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq|PragFlg_NoColumns1,
/* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq|PragFlg_NoColumns1|PragFlg_OneSchema,
/* ColNames: */ 0, 0,
/* iArg: */ 0 },
#endif
@@ -645,7 +652,7 @@ static const PragmaName aPragmaName[] = {
/* iArg: */ 0 },
{/* zName: */ "wal_checkpoint",
/* ePragTyp: */ PragTyp_WAL_CHECKPOINT,
/* ePragFlg: */ PragFlg_NeedSchema,
/* ePragFlg: */ PragFlg_NeedSchema|PragFlg_OneSchema,
/* ColNames: */ 50, 3,
/* iArg: */ 0 },
#endif
+126 -10
View File
@@ -43,6 +43,11 @@ static void corruptSchema(
pData->rc = SQLITE_ERROR;
}else if( db->flags & SQLITE_WriteSchema ){
pData->rc = SQLITE_CORRUPT_BKPT;
}else if( IsSharedSchema(db)
&& 0==sqlite3StrNICmp(zExtra, "malformed database schema", 17)
){
pData->rc = SQLITE_CORRUPT_BKPT;
*pData->pzErrMsg = sqlite3DbStrDup(db, zExtra);
}else{
char *z;
const char *zObj = azObj[1] ? azObj[1] : "?";
@@ -53,6 +58,28 @@ static void corruptSchema(
}
}
#ifdef SQLITE_ENABLE_SHARED_SCHEMA
/*
** Update the Schema.cksum checksum to account for the database object
** specified by the three arguments following the first.
*/
static void schemaUpdateChecksum(
InitData *pData, /* Schema parse context */
const char *zName, /* Name of new database object */
const char *zRoot, /* Root page of new database object */
const char *zSql /* SQL used to create new database object */
){
int i;
u64 cksum = pData->cksum;
if( zName ){
for(i=0; zName[i]; i++) cksum += (cksum<<3) + zName[i];
}
if( zRoot ) for(i=0; zRoot[i]; i++) cksum += (cksum<<3) + zRoot[i];
if( zSql ) for(i=0; zSql[i]; i++) cksum += (cksum<<3) + zSql[i];
pData->cksum = cksum;
}
#endif /* ifdef SQLITE_ENABLE_SHARED_SCHEMA */
/*
** Check to see if any sibling index (another index on the same table)
** of pIndex has the same root page number, and if it does, return true.
@@ -76,6 +103,15 @@ static int sqlite3Prepare(
sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */
const char **pzTail /* OUT: End of parsed string */
);
static int sqlite3LockAndPrepare(
sqlite3 *db, /* Database handle. */
const char *zSql, /* UTF-8 encoded SQL statement. */
int nBytes, /* Length of zSql in bytes. */
u32 prepFlags, /* Zero or more SQLITE_PREPARE_* flags */
Vdbe *pReprepare, /* VM being reprepared */
sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */
const char **pzTail /* OUT: End of parsed string */
);
/*
@@ -141,7 +177,11 @@ int sqlite3InitCallback(void *pInit, int argc, char **argv, char **NotUsed){
db->init.orphanTrigger = 0;
db->init.azInit = (const char**)argv;
pStmt = 0;
#ifdef SQLITE_ENABLE_SHARED_SCHEMA
TESTONLY(rcp = ) sqlite3LockAndPrepare(db, argv[4], -1, 0, 0, &pStmt, 0);
#else
TESTONLY(rcp = ) sqlite3Prepare(db, argv[4], -1, 0, 0, &pStmt, 0);
#endif
rc = db->errCode;
assert( (rc&0xFF)==(rcp&0xFF) );
db->init.iDb = saved_iDb;
@@ -153,7 +193,12 @@ int sqlite3InitCallback(void *pInit, int argc, char **argv, char **NotUsed){
if( rc > pData->rc ) pData->rc = rc;
if( rc==SQLITE_NOMEM ){
sqlite3OomFault(db);
}else if( rc!=SQLITE_INTERRUPT && (rc&0xFF)!=SQLITE_LOCKED ){
}else if( rc!=SQLITE_INTERRUPT
#ifdef SQLITE_ENABLE_SHARED_SCHEMA
&& (rc&0xFF)!=SQLITE_LOCKED
&& (rc&0xFF)!=SQLITE_IOERR
#endif
){
corruptSchema(pData, argv, sqlite3_errmsg(db));
}
}
@@ -184,6 +229,12 @@ int sqlite3InitCallback(void *pInit, int argc, char **argv, char **NotUsed){
}
}
}
#ifdef SQLITE_ENABLE_SHARED_SCHEMA
if( IsSharedSchema(db) && iDb!=1 ){
schemaUpdateChecksum(pData, argv[0], argv[1], argv[2]);
}
#endif
return 0;
}
@@ -211,10 +262,28 @@ int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg, u32 mFlags){
assert( (db->mDbFlags & DBFLAG_SchemaKnownOk)==0 );
assert( iDb>=0 && iDb<db->nDb );
assert( db->aDb[iDb].pSchema );
assert( db->aDb[iDb].pSchema || (IsSharedSchema(db) && iDb!=1) );
assert( sqlite3_mutex_held(db->mutex) );
assert( iDb==1 || sqlite3BtreeHoldsMutex(db->aDb[iDb].pBt) );
pDb = &db->aDb[iDb];
#ifdef SQLITE_ENABLE_SHARED_SCHEMA
assert( pDb->pSPool==0 || IsSharedSchema(db) );
if( pDb->pSPool ){
/* See if there is a free schema object in the schema-pool. If not,
** disconnect from said schema pool and continue. This function will
** connect to a (possibly different) schema-pool before returning. */
Schema *pNew = sqlite3SchemaExtract(pDb->pSPool);
if( pNew ){
pDb->pSchema = pNew;
return SQLITE_OK;
}
rc = sqlite3SchemaDisconnect(db, iDb, 1);
if( rc!=SQLITE_OK ) goto error_out;
assert( pDb->pSchema && pDb->pSPool==0 );
}
#endif
db->init.busy = 1;
/* Construct the in-memory representation schema tables (sqlite_schema or
@@ -235,6 +304,7 @@ int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg, u32 mFlags){
initData.pzErrMsg = pzErrMsg;
initData.mInitFlags = mFlags;
initData.nInitRow = 0;
initData.cksum = 0;
initData.mxPage = 0;
sqlite3InitCallback(&initData, 5, (char **)azArg, 0);
db->mDbFlags &= mask;
@@ -245,7 +315,6 @@ int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg, u32 mFlags){
/* Create a cursor to hold the database open
*/
pDb = &db->aDb[iDb];
if( pDb->pBt==0 ){
assert( iDb==1 );
DbSetProperty(db, 1, DB_SchemaLoaded);
@@ -404,6 +473,10 @@ int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg, u32 mFlags){
rc = SQLITE_OK;
}
if( rc==SQLITE_OK && iDb!=1 && IsSharedSchema(db) ){
rc = sqlite3SchemaConnect(db, iDb, initData.cksum);
}
/* Jump here for an error that occurs after successfully allocating
** curMain and calling sqlite3BtreeEnter(). For an error that occurs
** before that point, jump to error_out.
@@ -425,6 +498,35 @@ error_out:
return rc;
}
#ifdef SQLITE_ENABLE_SHARED_SCHEMA
/*
** If this is a SHARED_SCHEMA connection and the DBFLAG_SchemaInUse flag
** is not currently set, set it and return non-zero. Otherwise, return 0.
*/
int sqlite3LockReusableSchema(sqlite3 *db){
if( IsSharedSchema(db) && (db->mDbFlags & DBFLAG_SchemaInuse)==0 ){
db->mDbFlags |= DBFLAG_SchemaInuse;
return 1;
}
return 0;
}
#endif /* ifdef SQLITE_ENABLE_SHARED_SCHEMA */
#ifdef SQLITE_ENABLE_SHARED_SCHEMA
/*
** This function is a no-op for non-SHARED_SCHEMA connections, or if bRelease
** is zero. Otherwise, clear the DBFLAG_SchemaInuse flag and release all
** schema references currently held.
*/
void sqlite3UnlockReusableSchema(sqlite3 *db, int bRelease){
if( bRelease ){
db->mDbFlags &= ~DBFLAG_SchemaInuse;
sqlite3SchemaReleaseAll(db);
}
}
#endif /* ifdef SQLITE_ENABLE_SHARED_SCHEMA */
/*
** Initialize all database files - the main database file, the file
** used to store temporary tables, and any additional database files
@@ -435,8 +537,12 @@ error_out:
** bit is set in the flags field of the Db structure.
*/
int sqlite3Init(sqlite3 *db, char **pzErrMsg){
int i, rc;
int rc = SQLITE_OK;
int bReleaseSchema;
int i;
int commit_internal = !(db->mDbFlags&DBFLAG_SchemaChange);
bReleaseSchema = sqlite3LockReusableSchema(db);
assert( sqlite3_mutex_held(db->mutex) );
assert( sqlite3BtreeHoldsMutex(db->aDb[0].pBt) );
@@ -446,20 +552,19 @@ int sqlite3Init(sqlite3 *db, char **pzErrMsg){
/* Do the main schema first */
if( !DbHasProperty(db, 0, DB_SchemaLoaded) ){
rc = sqlite3InitOne(db, 0, pzErrMsg, 0);
if( rc ) return rc;
}
/* All other schemas after the main schema. The "temp" schema must be last */
for(i=db->nDb-1; i>0; i--){
for(i=db->nDb-1; rc==SQLITE_OK && i>0; i--){
assert( i==1 || sqlite3BtreeHoldsMutex(db->aDb[i].pBt) );
if( !DbHasProperty(db, i, DB_SchemaLoaded) ){
rc = sqlite3InitOne(db, i, pzErrMsg, 0);
if( rc ) return rc;
}
}
if( commit_internal ){
if( rc==SQLITE_OK && commit_internal ){
sqlite3CommitInternalChanges(db);
}
return SQLITE_OK;
sqlite3UnlockReusableSchema(db, bReleaseSchema);
return rc;
}
/*
@@ -471,11 +576,12 @@ int sqlite3ReadSchema(Parse *pParse){
sqlite3 *db = pParse->db;
assert( sqlite3_mutex_held(db->mutex) );
if( !db->init.busy ){
db->mDbFlags |= DBFLAG_FreeSchema; /* For sharable-schema mode */
rc = sqlite3Init(db, &pParse->zErrMsg);
if( rc!=SQLITE_OK ){
pParse->rc = rc;
pParse->nErr++;
}else if( db->noSharedCache ){
}else if( db->noSharedCache && !IsSharedSchema(db) ){
db->mDbFlags |= DBFLAG_SchemaKnownOk;
}
}
@@ -501,6 +607,10 @@ static void schemaIsValid(Parse *pParse){
Btree *pBt = db->aDb[iDb].pBt; /* Btree database to read cookie from */
if( pBt==0 ) continue;
#ifdef SQLITE_ENABLE_SHARED_SCHEMA
if( IsSharedSchema(db) && iDb!=1 && db->aDb[iDb].pSPool==0 ) continue;
#endif
/* If there is not already a read-only (or read-write) transaction opened
** on the b-tree database, open one now. If a transaction is opened, it
** will be closed immediately after reading the meta-value. */
@@ -828,6 +938,7 @@ static int sqlite3LockAndPrepare(
){
int rc;
int cnt = 0;
int bReleaseSchema = 0;
#ifdef SQLITE_ENABLE_API_ARMOR
if( ppStmt==0 ) return SQLITE_MISUSE_BKPT;
@@ -837,6 +948,7 @@ static int sqlite3LockAndPrepare(
return SQLITE_MISUSE_BKPT;
}
sqlite3_mutex_enter(db->mutex);
bReleaseSchema = sqlite3LockReusableSchema(db);
sqlite3BtreeEnterAll(db);
do{
/* Make multiple attempts to compile the SQL, until it either succeeds
@@ -847,7 +959,11 @@ static int sqlite3LockAndPrepare(
if( rc==SQLITE_OK || db->mallocFailed ) break;
}while( (rc==SQLITE_ERROR_RETRY && (cnt++)<SQLITE_MAX_PREPARE_RETRY)
|| (rc==SQLITE_SCHEMA && (sqlite3ResetOneSchema(db,-1), cnt++)==0) );
sqlite3BtreeLeaveAll(db);
sqlite3UnlockReusableSchema(db, bReleaseSchema);
rc = sqlite3ApiExit(db, rc);
assert( (rc&db->errMask)==rc );
db->busyHandler.nBusy = 0;
+2 -2
View File
@@ -803,8 +803,8 @@ void sqlite3_str_vappendf(
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;
i64 i, j, k, n;
int needQuote, isnull;
char ch;
char q = ((xtype==etSQLESCAPE3)?'"':'\''); /* Quote character */
char *escarg;
+8 -18
View File
@@ -85,33 +85,23 @@ static void resolveAlias(
sqlite3ExprDelete(db, pDup);
pDup = 0;
}else{
Expr temp;
incrAggFunctionDepth(pDup, nSubquery);
if( pExpr->op==TK_COLLATE ){
assert( !ExprHasProperty(pExpr, EP_IntValue) );
pDup = sqlite3ExprAddCollateString(pParse, pDup, pExpr->u.zToken);
}
/* Before calling sqlite3ExprDelete(), set the EP_Static flag. This
** prevents ExprDelete() from deleting the Expr structure itself,
** allowing it to be repopulated by the memcpy() on the following line.
** The pExpr->u.zToken might point into memory that will be freed by the
** sqlite3DbFree(db, pDup) on the last line of this block, so be sure to
** make a copy of the token before doing the sqlite3DbFree().
*/
ExprSetProperty(pExpr, EP_Static);
sqlite3ExprDelete(db, pExpr);
memcpy(pExpr, pDup, sizeof(*pExpr));
if( !ExprHasProperty(pExpr, EP_IntValue) && pExpr->u.zToken!=0 ){
assert( (pExpr->flags & (EP_Reduced|EP_TokenOnly))==0 );
pExpr->u.zToken = sqlite3DbStrDup(db, pExpr->u.zToken);
pExpr->flags |= EP_MemToken;
}
memcpy(&temp, pDup, sizeof(Expr));
memcpy(pDup, pExpr, sizeof(Expr));
memcpy(pExpr, &temp, sizeof(Expr));
if( ExprHasProperty(pExpr, EP_WinFunc) ){
if( ALWAYS(pExpr->y.pWin!=0) ){
pExpr->y.pWin->pOwner = pExpr;
}
}
sqlite3DbFree(db, pDup);
sqlite3ParserAddCleanup(pParse,
(void(*)(sqlite3*,void*))sqlite3ExprDelete,
pDup);
}
}
@@ -314,7 +304,7 @@ static int lookupName(
pTab = pItem->pTab;
assert( pTab!=0 && pTab->zName!=0 );
assert( pTab->nCol>0 || pParse->nErr );
assert( pItem->fg.isNestedFrom == IsNestedFrom(pItem->pSelect) );
assert( (int)pItem->fg.isNestedFrom == IsNestedFrom(pItem->pSelect) );
if( pItem->fg.isNestedFrom ){
/* In this case, pItem is a subquery that has been formed from a
** parenthesized subset of the FROM clause terms. Example:
+29 -9
View File
@@ -324,7 +324,7 @@ int sqlite3ColumnIndex(Table *pTab, const char *zCol){
*/
void sqlite3SrcItemColumnUsed(SrcItem *pItem, int iCol){
assert( pItem!=0 );
assert( pItem->fg.isNestedFrom == IsNestedFrom(pItem->pSelect) );
assert( (int)pItem->fg.isNestedFrom == IsNestedFrom(pItem->pSelect) );
if( pItem->fg.isNestedFrom ){
ExprList *pResults;
assert( pItem->pSelect!=0 );
@@ -1688,7 +1688,7 @@ static void generateSortTail(
if( addrOnce ) sqlite3VdbeJumpHere(v, addrOnce);
addr = 1 + sqlite3VdbeAddOp2(v, OP_SorterSort, iTab, addrBreak);
VdbeCoverage(v);
codeOffset(v, p->iOffset, addrContinue);
assert( p->iLimit==0 && p->iOffset==0 );
sqlite3VdbeAddOp3(v, OP_SorterData, iTab, regSortOut, iSortTab);
bSeq = 0;
}else{
@@ -1696,6 +1696,9 @@ static void generateSortTail(
codeOffset(v, p->iOffset, addrContinue);
iSortTab = iTab;
bSeq = 1;
if( p->iOffset>0 ){
sqlite3VdbeAddOp2(v, OP_AddImm, p->iLimit, -1);
}
}
for(i=0, iCol=nKey+bSeq-1; i<nColumn; i++){
#ifdef SQLITE_ENABLE_SORTER_REFERENCES
@@ -3688,10 +3691,11 @@ static int multiSelectOrderBy(
*/
sqlite3VdbeResolveLabel(v, labelEnd);
/* Reassembly the compound query so that it will be freed correctly
/* Reassemble the compound query so that it will be freed correctly
** by the calling function */
if( pSplit->pPrior ){
sqlite3SelectDelete(db, pSplit->pPrior);
sqlite3ParserAddCleanup(pParse,
(void(*)(sqlite3*,void*))sqlite3SelectDelete, pSplit->pPrior);
}
pSplit->pPrior = pPrior;
pPrior->pNext = pSplit;
@@ -4122,6 +4126,9 @@ static void renumberCursors(
** (17d2) DISTINCT
** (17e) the subquery may not contain window functions, and
** (17f) the subquery must not be the RHS of a LEFT JOIN.
** (17g) either the subquery is the first element of the outer
** query or there are no RIGHT or FULL JOINs in any arm
** of the subquery. (This is a duplicate of condition (27b).)
**
** The parent and sub-query may contain WHERE clauses. Subject to
** rules (11), (13) and (14), they may also contain ORDER BY,
@@ -4173,7 +4180,11 @@ static void renumberCursors(
** See also (3) for restrictions on LEFT JOIN.
**
** (27) The subquery may not contain a FULL or RIGHT JOIN unless it
** is the first element of the parent query.
** is the first element of the parent query. This must be the
** the case if:
** (27a) the subquery is not compound query, and
** (27b) the subquery is a compound query and the RIGHT JOIN occurs
** in any arm of the compound query. (See also (17g).)
**
** (28) The subquery is not a MATERIALIZED CTE.
**
@@ -4303,7 +4314,7 @@ static int flattenSubquery(
assert( pSubSrc->nSrc>0 ); /* True by restriction (7) */
if( iFrom>0 && (pSubSrc->a[0].fg.jointype & JT_LTORJ)!=0 ){
return 0; /* Restriction (27) */
return 0; /* Restriction (27a) */
}
if( pSubitem->fg.isCte && pSubitem->u2.pCteUse->eM10d==M10d_Yes ){
return 0; /* (28) */
@@ -4323,7 +4334,7 @@ static int flattenSubquery(
** NATURAL join or a join that as an ON or USING clause.
**
** These conditions are sufficient to keep an EP_OuterON from being
** flattened into an EP_InnerON. Restrictions (3a) and (27) prevent
** flattened into an EP_InnerON. Restrictions (3a) and (27a) prevent
** an EP_InnerON from being flattened into an EP_OuterON.
*/
if( pSubSrc->nSrc>=2
@@ -4365,6 +4376,12 @@ static int flattenSubquery(
){
return 0;
}
if( iFrom>0 && (pSub1->pSrc->a[0].fg.jointype & JT_LTORJ)!=0 ){
/* Without this restriction, the JT_LTORJ flag would end up being
** omitted on left-hand tables of the right join that is being
** flattened. */
return 0; /* Restrictions (17g), (27b) */
}
testcase( pSub1->pSrc->nSrc>1 );
}
@@ -5197,6 +5214,7 @@ static Table *isSimpleCount(Select *p, AggInfo *pAggInfo){
|| p->pSrc->nSrc!=1
|| p->pSrc->a[0].pSelect
|| pAggInfo->nFunc!=1
|| p->pHaving
){
return 0;
}
@@ -5898,7 +5916,7 @@ static int selectExpander(Walker *pWalker, Select *p){
zTabName = pTab->zName;
}
if( db->mallocFailed ) break;
assert( pFrom->fg.isNestedFrom == IsNestedFrom(pFrom->pSelect) );
assert( (int)pFrom->fg.isNestedFrom == IsNestedFrom(pFrom->pSelect) );
if( pFrom->fg.isNestedFrom ){
assert( pFrom->pSelect!=0 );
pNestedFrom = pFrom->pSelect->pEList;
@@ -6827,7 +6845,9 @@ int sqlite3Select(
){
SELECTTRACE(0x100,pParse,p,
("omit superfluous ORDER BY on %r FROM-clause subquery\n",i+1));
sqlite3ExprListDelete(db, pSub->pOrderBy);
sqlite3ParserAddCleanup(pParse,
(void(*)(sqlite3*,void*))sqlite3ExprListDelete,
pSub->pOrderBy);
pSub->pOrderBy = 0;
}
+262 -8
View File
@@ -1184,13 +1184,14 @@ static ShellState shellState;
/* Allowed values for ShellState.openMode
*/
#define SHELL_OPEN_UNSPEC 0 /* No open-mode specified */
#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 */
#define SHELL_OPEN_DESERIALIZE 5 /* Open using sqlite3_deserialize() */
#define SHELL_OPEN_HEXDB 6 /* Use "dbtotxt" output as data source */
#define SHELL_OPEN_UNSPEC 0 /* No open-mode specified */
#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 */
#define SHELL_OPEN_DESERIALIZE 5 /* Open using sqlite3_deserialize() */
#define SHELL_OPEN_HEXDB 6 /* Use "dbtotxt" output as data source */
#define SHELL_OPEN_SHAREDSCHEMA 7 /* Open for schema reuse */
/* Allowed values for ShellState.eTraceType
*/
@@ -4490,6 +4491,12 @@ static const char *(azHelp[]) = {
" --sha3-384 Use the sha3-384 algorithm",
" --sha3-512 Use the sha3-512 algorithm",
" Any other argument is a LIKE pattern for tables to hash",
#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB)
".shared-schema CMD DB1 DB2 ...",
" Commands:",
" check Determine if DB1, DB2, etc have identical schemas",
" fix Attempt to make DB1, DB2, etc compatible",
#endif
#if !defined(SQLITE_NOHAVE_SYSTEM) && !defined(SQLITE_SHELL_WASM_MODE)
".shell CMD ARGS... Run CMD ARGS... in a system shell",
#endif
@@ -5030,6 +5037,11 @@ static void open_db(ShellState *p, int openFlags){
SQLITE_OPEN_READONLY|p->openFlags, 0);
break;
}
case SHELL_OPEN_SHAREDSCHEMA: {
sqlite3_open_v2(p->pAuxDb->zDbFilename, &p->db,
SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|SQLITE_OPEN_SHARED_SCHEMA,0);
break;
}
case SHELL_OPEN_UNSPEC:
case SHELL_OPEN_NORMAL: {
sqlite3_open_v2(zDbFilename, &p->db,
@@ -7300,6 +7312,237 @@ static char *shellMPrintf(int *pRc, const char *zFmt, ...){
}
return z;
}
static int sharedSchemaFix(ShellState *pState, const char *zDb, int eFix){
int rc = SQLITE_OK;
i64 iLast = 0;
int iCookie = 0;
int iAutoVacuum = 0;
sqlite3_stmt *pStmt = 0;
shellExecPrintf(pState->db, &rc, "ATTACH '%q' AS _shared_schema_tmp", zDb);
shellExecPrintf(pState->db, &rc, "PRAGMA writable_schema = 1");
shellExecPrintf(pState->db, &rc, "BEGIN");
shellPreparePrintf(pState->db, &rc, &pStmt,
"SELECT max(rowid) FROM _shared_schema_tmp.sqlite_master"
);
sqlite3_step(pStmt);
iLast = sqlite3_column_int64(pStmt, 0);
shellFinalize(&rc, pStmt);
shellPreparePrintf(pState->db, &rc, &pStmt,
"INSERT INTO _shared_schema_tmp.sqlite_master SELECT "
" type, name, tbl_name, ("
" SELECT rootpage FROM _shared_schema_tmp.sqlite_master WHERE "
" type IS o.type AND name IS o.name AND rowid<=?"
" ), sql FROM main.sqlite_master AS o"
);
sqlite3_bind_int64(pStmt, 1, iLast);
sqlite3_step(pStmt);
shellFinalize(&rc, pStmt);
shellExecPrintf(pState->db, &rc,
"DELETE FROM _shared_schema_tmp.sqlite_master WHERE rowid<=%lld",
iLast
);
shellExecPrintf(pState->db, &rc, "COMMIT");
sqlite3_exec(pState->db, "PRAGMA writable_schema = 0", 0, 0, 0);
/* Copy the auto-vacuum setting from main to the target db */
shellPreparePrintf(pState->db, &rc, &pStmt, "PRAGMA main.auto_vacuum");
sqlite3_step(pStmt);
iAutoVacuum = sqlite3_column_int(pStmt, 0);
shellFinalize(&rc, pStmt);
shellExecPrintf(pState->db, &rc,
"PRAGMA _shared_schema_tmp.auto_vacuum = %d", iAutoVacuum
);
/* Vacuum the db in order to standardize the rootpage numbers. */
shellExecPrintf(pState->db, &rc, "VACUUM _shared_schema_tmp");
/* Set the schema-cookie value to the same as database "main" */
shellPreparePrintf(pState->db, &rc, &pStmt, "PRAGMA main.schema_version");
sqlite3_step(pStmt);
iCookie = sqlite3_column_int(pStmt, 0);
shellFinalize(&rc, pStmt);
shellExecPrintf(pState->db, &rc,
"PRAGMA _shared_schema_tmp.schema_version = %d", iCookie
);
sqlite3_exec(pState->db, "DETACH _shared_schema_tmp", 0, 0, 0);
return rc;
}
static int sharedSchemaCheck(ShellState *pState, const char *zDb, int *peFix){
int rc = SQLITE_OK;
int bFailed = 0;
sqlite3_stmt *pStmt = 0;
if( peFix ) *peFix = 0;
shellExecPrintf(pState->db, &rc, "ATTACH '%q' AS _shared_schema_tmp", zDb);
/* Check if this database has the same set of objects as the current db */
shellPreparePrintf(pState->db, &rc, &pStmt,
"SELECT type, name FROM _shared_schema_tmp.sqlite_master AS o "
"WHERE NOT EXISTS ("
" SELECT 1 FROM main.sqlite_master "
" WHERE name IS o.name AND type IS o.type"
")"
" UNION ALL "
"SELECT type, name FROM main.sqlite_master AS o "
"WHERE NOT EXISTS ("
" SELECT 1 FROM _shared_schema_tmp.sqlite_master "
" WHERE name IS o.name AND type IS o.type"
")"
);
if( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){
utf8_printf(pState->out, "%s is NOT compatible (objects)\n", zDb);
bFailed = 1;
}
shellFinalize(&rc, pStmt);
/* Check if this database has the same set of SQL statements as the
** current db. */
if( bFailed==0 ){
shellPreparePrintf(pState->db, &rc, &pStmt,
"SELECT 1 FROM _shared_schema_tmp.sqlite_master AS o "
"WHERE sql IS NOT ("
" SELECT sql FROM main.sqlite_master "
" WHERE name IS o.name AND type IS o.type"
")"
);
if( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){
utf8_printf(pState->out, "%s is NOT compatible (SQL)\n", zDb);
bFailed = 1;
}
shellFinalize(&rc, pStmt);
}
/* Check if this database has the same set of root pages as the current
** db. */
if( bFailed==0 ){
shellPreparePrintf(pState->db, &rc, &pStmt,
"SELECT 1 FROM _shared_schema_tmp.sqlite_master AS o "
"WHERE rootpage IS NOT ("
" SELECT rootpage FROM main.sqlite_master "
" WHERE name IS o.name AND type IS o.type"
")"
);
if( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){
if( peFix==0 ){
utf8_printf(pState->out, "%s is NOT compatible (root pages)\n", zDb);
}
bFailed = 1;
if( peFix ) *peFix = 1;
}
shellFinalize(&rc, pStmt);
}
if( bFailed==0 ){
shellPreparePrintf(pState->db, &rc, &pStmt,
"SELECT 1 WHERE ("
" SELECT group_concat(rootpage || '.' || name || '.' || sql, '.') "
" FROM _shared_schema_tmp.sqlite_master"
") IS NOT ("
" SELECT group_concat(rootpage || '.' || name || '.' || sql, '.') "
" FROM main.sqlite_master"
")"
);
if( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){
if( peFix==0 ){
utf8_printf(pState->out,
"%s is NOT compatible (order of sqlite_master rows)\n", zDb
);
}
bFailed = 1;
if( peFix ) *peFix = 2;
}
shellFinalize(&rc, pStmt);
}
if( bFailed==0 ){
int iMain = -1;
int iNew = +1;
shellPreparePrintf(pState->db, &rc, &pStmt,
"PRAGMA main.schema_version"
);
if( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){
iMain = sqlite3_column_int(pStmt, 0);
}
shellFinalize(&rc, pStmt);
shellPreparePrintf(pState->db, &rc, &pStmt,
"PRAGMA _shared_schema_tmp.schema_version"
);
if( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){
iNew = sqlite3_column_int(pStmt, 0);
}
shellFinalize(&rc, pStmt);
if( rc==SQLITE_OK && iMain!=iNew ){
if( peFix==0 ){
utf8_printf(pState->out,
"%s is NOT compatible (schema cookie)\n", zDb
);
}
bFailed = 1;
if( peFix ) *peFix = 3;
}
}
if( rc==SQLITE_OK && bFailed==0 ){
utf8_printf(pState->out, "%s is compatible\n", zDb);
}
sqlite3_exec(pState->db, "DETACH _shared_schema_tmp", 0, 0, 0);
return rc;
}
/*
** .shared-schema check|fix DB1 DB2...
*/
static int sharedSchemaDotCommand(
ShellState *pState, /* Current shell tool state */
char **azArg, /* Array of arguments passed to dot command */
int nArg /* Number of entries in azArg[] */
){
int rc = SQLITE_OK;
int bFix = 0; /* Fix databases if possible */
int n1;
int i;
if( nArg<3 ){
goto shared_schema_usage;
}
n1 = (int)strlen(azArg[1]);
if( n1>0 && n1<=3 && memcmp("fix", azArg[1], n1)==0 ){
bFix = 1;
}else if( n1==0 || n1>5 || memcmp("check", azArg[1], n1) ){
goto shared_schema_usage;
}
for(i=2; rc==SQLITE_OK && i<nArg; i++){
int eFix = 0;
rc = sharedSchemaCheck(pState, azArg[i], bFix ? &eFix : 0);
if( rc==SQLITE_OK && bFix && eFix ){
utf8_printf(pState->out, "Fixing %s... ", azArg[i]);
fflush(pState->out);
rc = sharedSchemaFix(pState, azArg[i], eFix);
if( rc==SQLITE_OK ){
rc = sharedSchemaCheck(pState, azArg[i], &eFix);
if( rc==SQLITE_OK && eFix ){
utf8_printf(pState->out, "VACUUMing main... ");
fflush(pState->out);
rc = sqlite3_exec(pState->db, "VACUUM main", 0, 0, 0);
if( rc==SQLITE_OK ){
rc = sharedSchemaCheck(pState, azArg[i], 0);
}
}
}
}
}
return rc;
shared_schema_usage:
raw_printf(stderr, "usage: .shared-schema check|fix DB1 DB2...\n");
return SQLITE_ERROR;
}
/*
@@ -10678,6 +10921,13 @@ static int do_meta_command(char *zLine, ShellState *p){
sqlite3_free(zSql);
}else
#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB)
if( c=='s' && strncmp(azArg[0], "shared-schema", n)==0 ){
open_db(p, 0);
sharedSchemaDotCommand(p, azArg, nArg);
}else
#endif
#if !defined(SQLITE_NOHAVE_SYSTEM) && !defined(SQLITE_SHELL_WASM_MODE)
if( c=='s'
&& (strncmp(azArg[0], "shell", n)==0 || strncmp(azArg[0],"system",n)==0)
@@ -11990,7 +12240,7 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
char **argv;
#endif
#ifdef SQLITE_DEBUG
sqlite3_uint64 mem_main_enter = sqlite3_memory_used();
sqlite3_int64 mem_main_enter = sqlite3_memory_used();
#endif
char *zErrMsg = 0;
#ifdef SQLITE_SHELL_WASM_MODE
@@ -12218,6 +12468,8 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
#endif
}else if( strcmp(z,"-readonly")==0 ){
data.openMode = SHELL_OPEN_READONLY;
}else if( strcmp(z,"-sharedschema")==0 ){
data.openMode = SHELL_OPEN_SHAREDSCHEMA;
}else if( strcmp(z,"-nofollow")==0 ){
data.openFlags = SQLITE_OPEN_NOFOLLOW;
#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_HAVE_ZLIB)
@@ -12342,6 +12594,8 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
#endif
}else if( strcmp(z,"-readonly")==0 ){
data.openMode = SHELL_OPEN_READONLY;
}else if( strcmp(z,"-sharedschema")==0 ){
data.openMode = SHELL_OPEN_SHAREDSCHEMA;
}else if( strcmp(z,"-nofollow")==0 ){
data.openFlags |= SQLITE_OPEN_NOFOLLOW;
}else if( strcmp(z,"-ascii")==0 ){
+3 -2
View File
@@ -612,10 +612,11 @@ int sqlite3_exec(
#define SQLITE_OPEN_EXRESCODE 0x02000000 /* Extended result codes */
/* Reserved: 0x00F00000 */
#define SQLITE_OPEN_SHARED_SCHEMA 0x01000000 /* Ok for sqlite3_open_v2() */
/* Legacy compatibility: */
#define SQLITE_OPEN_MASTER_JOURNAL 0x00004000 /* VFS only */
/*
** CAPI3REF: Device Characteristics
**
@@ -6282,7 +6283,7 @@ sqlite3 *sqlite3_db_handle(sqlite3_stmt*);
**
** ^The sqlite3_db_name(D,N) interface returns a pointer to the schema name
** for the N-th database on database connection D, or a NULL pointer of N is
** out of range. An N alue of 0 means the main database file. An N of 1 is
** out of range. An N value of 0 means the main database file. An N of 1 is
** the "temp" schema. Larger values of N correspond to various ATTACH-ed
** databases.
**
+54
View File
@@ -198,6 +198,11 @@
*/
#include "sqlite3.h"
/*
** Reuse the STATIC_LRU for mutex access to sqlite3_temp_directory.
*/
#define SQLITE_MUTEX_STATIC_TEMPDIR SQLITE_MUTEX_STATIC_VFS1
/*
** Include the configuration header output by 'configure' if we're using the
** autoconf-based build
@@ -1176,6 +1181,7 @@ typedef struct CteUse CteUse;
typedef struct Db Db;
typedef struct DbFixer DbFixer;
typedef struct Schema Schema;
typedef struct SchemaPool SchemaPool;
typedef struct Expr Expr;
typedef struct ExprList ExprList;
typedef struct FKey FKey;
@@ -1314,6 +1320,10 @@ struct Db {
u8 safety_level; /* How aggressive at syncing data to disk */
u8 bSyncSet; /* True if "PRAGMA synchronous=N" has been run */
Schema *pSchema; /* Pointer to database schema (possibly shared) */
#ifdef SQLITE_ENABLE_SHARED_SCHEMA
SchemaPool *pSPool; /* For REUSE_SCHEMA mode */
VTable *pVTable; /* List of all VTable objects (REUSE_SCHEMA mode only) */
#endif
};
/*
@@ -1345,6 +1355,9 @@ struct Schema {
u8 enc; /* Text encoding used by this database */
u16 schemaFlags; /* Flags associated with this schema */
int cache_size; /* Number of pages to use in the cache */
#ifdef SQLITE_ENABLE_SHARED_SCHEMA
Schema *pNext; /* Next Schema object SchemaPool (REUSE_SCHEMA) */
#endif
};
/*
@@ -1669,6 +1682,12 @@ struct sqlite3 {
#endif
};
#ifdef SQLITE_ENABLE_SHARED_SCHEMA
# define IsSharedSchema(db) (((db)->openFlags & SQLITE_OPEN_SHARED_SCHEMA)!=0)
#else
# define IsSharedSchema(db) 0
#endif
/*
** A macro to discover the encoding of a database.
*/
@@ -1750,6 +1769,9 @@ struct sqlite3 {
#define DBFLAG_InternalFunc 0x0020 /* Allow use of internal functions */
#define DBFLAG_EncodingFixed 0x0040 /* No longer possible to change enc. */
#define DBFLAG_SchemaInuse 0x0080 /* Do not release sharable schemas */
#define DBFLAG_FreeSchema 0x0100 /* Free extra shared schemas on release */
/*
** Bits of the sqlite3.dbOptFlags field that are used by the
** sqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS,...) interface to
@@ -2249,6 +2271,9 @@ struct VTable {
u8 eVtabRisk; /* Riskiness of allowing hacker access */
int iSavepoint; /* Depth of the SAVEPOINT stack */
VTable *pNext; /* Next in linked list (see above) */
#ifdef SQLITE_ENABLE_SHARED_SCHEMA
char *zName; /* Table name (REUSE_SCHEMA mode) */
#endif
};
/* Allowed values for VTable.eVtabRisk
@@ -3799,6 +3824,9 @@ struct Trigger {
Schema *pTabSchema; /* Schema containing the table */
TriggerStep *step_list; /* Link list of trigger program steps */
Trigger *pNext; /* Next trigger associated with the table */
#ifdef SQLITE_ENABLE_SHARED_SCHEMA
char *zTabSchema; /* Temp triggers in IsSharedSchema() dbs only */
#endif
};
/*
@@ -3915,6 +3943,7 @@ typedef struct {
int rc; /* Result code stored here */
u32 mInitFlags; /* Flags controlling error messages */
u32 nInitRow; /* Number of rows processed */
u64 cksum; /* Schema checksum for REUSE_SCHEMA mode */
Pgno mxPage; /* Maximum page number. 0 for no limit. */
} InitData;
@@ -4474,6 +4503,7 @@ char *sqlite3VMPrintf(sqlite3*,const char*, va_list);
void sqlite3TreeViewSelect(TreeView*, const Select*, u8);
void sqlite3TreeViewWith(TreeView*, const With*, u8);
void sqlite3TreeViewUpsert(TreeView*, const Upsert*, u8);
#if TREETRACE_ENABLED
void sqlite3TreeViewDelete(const With*, const SrcList*, const Expr*,
const ExprList*,const Expr*, const Trigger*);
void sqlite3TreeViewInsert(const With*, const SrcList*,
@@ -4482,6 +4512,7 @@ char *sqlite3VMPrintf(sqlite3*,const char*, va_list);
void sqlite3TreeViewUpdate(const With*, const SrcList*, const ExprList*,
const Expr*, int, const ExprList*, const Expr*,
const Upsert*, const Trigger*);
#endif
#ifndef SQLITE_OMIT_TRIGGER
void sqlite3TreeViewTriggerStep(TreeView*, const TriggerStep*, u8, u8);
void sqlite3TreeViewTrigger(TreeView*, const Trigger*, u8, u8);
@@ -5064,6 +5095,29 @@ void sqlite3DefaultRowEst(Index*);
void sqlite3RegisterLikeFunctions(sqlite3*, int);
int sqlite3IsLikeFunction(sqlite3*,Expr*,int*,char*);
void sqlite3SchemaClear(void *);
void sqlite3SchemaClearOrDisconnect(sqlite3*, int);
#ifdef SQLITE_ENABLE_SHARED_SCHEMA
int sqlite3SchemaConnect(sqlite3*, int, u64);
int sqlite3SchemaDisconnect(sqlite3 *, int, int);
Schema *sqlite3SchemaExtract(SchemaPool*);
int sqlite3SchemaLoad(sqlite3*, int, int*, char**);
void sqlite3SchemaReleaseAll(sqlite3*);
void sqlite3SchemaRelease(sqlite3*, int);
void sqlite3SchemaAdjustUsed(sqlite3*, int, int, int*);
void sqlite3SchemaWritable(Parse*, int);
void sqlite3UnlockReusableSchema(sqlite3 *db, int bRelease);
int sqlite3LockReusableSchema(sqlite3 *db);
#else
# define sqlite3SchemaWritable(x,y)
# define sqlite3UnlockReusableSchema(x,y)
# define sqlite3LockReusableSchema(x) 0
# define sqlite3SchemaDisconnect(x,y,z) SQLITE_OK
# define sqlite3SchemaLoad(w,x,y,z) SQLITE_OK
# define sqlite3SchemaRelease(y,z)
# define sqlite3SchemaConnect(x,y,z) SQLITE_OK
#endif
Schema *sqlite3SchemaGet(sqlite3 *, Btree *);
int sqlite3SchemaToIndex(sqlite3 *db, Schema *);
KeyInfo *sqlite3KeyInfoAlloc(sqlite3*,int,int);
+21 -1
View File
@@ -288,11 +288,24 @@ int sqlite3_db_status(
case SQLITE_DBSTATUS_SCHEMA_USED: {
int i; /* Used to iterate through schemas */
int nByte = 0; /* Used to accumulate return value */
int bReleaseSchema;
sqlite3BtreeEnterAll(db);
bReleaseSchema = sqlite3LockReusableSchema(db);
db->pnBytesFreed = &nByte;
for(i=0; i<db->nDb; i++){
Schema *pSchema = db->aDb[i].pSchema;
Schema *pSchema;
#ifdef SQLITE_ENABLE_SHARED_SCHEMA
int bUnload = 0;
int nUsed = nByte;
if( db->aDb[i].pSPool ){
char *zDummy = 0;
rc = sqlite3SchemaLoad(db, i, &bUnload, &zDummy);
sqlite3_free(zDummy);
if( rc ) break;
}
#endif /* ifdef SQLITE_ENABLE_SHARED_SCHEMA */
pSchema = db->aDb[i].pSchema;
if( ALWAYS(pSchema!=0) ){
HashElem *p;
@@ -314,7 +327,14 @@ int sqlite3_db_status(
sqlite3DeleteTable(db, (Table *)sqliteHashData(p));
}
}
#ifdef SQLITE_ENABLE_SHARED_SCHEMA
if( db->aDb[i].pSPool ){
if( bUnload ) sqlite3SchemaRelease(db, i);
sqlite3SchemaAdjustUsed(db, i, nUsed, &nByte);
}
#endif /* ifdef SQLITE_ENABLE_SHARED_SCHEMA */
}
sqlite3UnlockReusableSchema(db, bReleaseSchema);
db->pnBytesFreed = 0;
sqlite3BtreeLeaveAll(db);
+13
View File
@@ -3705,6 +3705,9 @@ static int sqliteCmdUsage(
"HANDLE ?FILENAME? ?-vfs VFSNAME? ?-readonly BOOLEAN? ?-create BOOLEAN?"
" ?-nofollow BOOLEAN?"
" ?-nomutex BOOLEAN? ?-fullmutex BOOLEAN? ?-uri BOOLEAN?"
#ifdef SQLITE_ENABLE_SHARED_SCHEMA
" ?-shared-schema BOOLEAN?"
#endif
);
return TCL_ERROR;
}
@@ -3836,6 +3839,16 @@ static int SQLITE_TCLAPI DbMain(
}else{
flags &= ~SQLITE_OPEN_URI;
}
#ifdef SQLITE_ENABLE_SHARED_SCHEMA
}else if( strcmp(zArg, "-shared-schema")==0 ){
int b;
if( Tcl_GetBooleanFromObj(interp, objv[i], &b) ) return TCL_ERROR;
if( b ){
flags |= SQLITE_OPEN_SHARED_SCHEMA;
}else{
flags &= ~SQLITE_OPEN_SHARED_SCHEMA;
}
#endif /* ifdef SQLITE_ENABLE_SHARED_SCHEMA */
}else if( strcmp(zArg, "-translatefilename")==0 ){
if( Tcl_GetBooleanFromObj(interp, objv[i], &bTranslateFileName) ){
return TCL_ERROR;
+6
View File
@@ -783,6 +783,12 @@ Tcl_SetVar2(interp, "sqlite_options", "mergesort", "1", TCL_GLOBAL_ONLY);
Tcl_SetVar2(interp, "sqlite_options", "windowfunc", "1", TCL_GLOBAL_ONLY);
#endif
#ifdef SQLITE_ENABLE_SHARED_SCHEMA
Tcl_SetVar2(interp, "sqlite_options", "sharedschema", "1", TCL_GLOBAL_ONLY);
#else
Tcl_SetVar2(interp, "sqlite_options", "sharedschema", "0", TCL_GLOBAL_ONLY);
#endif
#define LINKVAR(x) { \
static const int cv_ ## x = SQLITE_ ## x; \
Tcl_LinkVar(interp, "SQLITE_" #x, (char *)&(cv_ ## x), \
+282
View File
@@ -0,0 +1,282 @@
/*
** 2006 June 10
**
** 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.
**
*************************************************************************
** Code for testing the virtual table interfaces. This code
** is not included in the SQLite library. It is used for automated
** testing of the SQLite library.
*/
/*
** None of this works unless we have virtual tables.
*/
#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_TEST)
#include <tcl.h>
#ifdef SQLITE_ENABLE_SHARED_SCHEMA
#include "sqliteInt.h"
/* The code in this file defines a sqlite3 virtual-table module with
** the following schema.
*/
#define SCHEMAPOOL_SCHEMA \
"CREATE TABLE x(" \
" cksum INTEGER, " \
" nref INTEGER, " \
" nschema INTEGER, " \
" ndelete INTEGER " \
")"
#define SCHEMAPOOL_NFIELD 4
typedef struct schemapool_vtab schemapool_vtab;
typedef struct schemapool_cursor schemapool_cursor;
/* A schema table object */
struct schemapool_vtab {
sqlite3_vtab base;
};
/* A schema table cursor object */
struct schemapool_cursor {
sqlite3_vtab_cursor base;
sqlite3_int64 *aData;
int iRow;
int nRow;
};
/*
** Table destructor for the schema module.
*/
static int schemaPoolDestroy(sqlite3_vtab *pVtab){
sqlite3_free(pVtab);
return 0;
}
/*
** Table constructor for the schema module.
*/
static int schemaPoolCreate(
sqlite3 *db,
void *pAux,
int argc, const char *const*argv,
sqlite3_vtab **ppVtab,
char **pzErr
){
int rc = SQLITE_NOMEM;
schemapool_vtab *pVtab = sqlite3_malloc(sizeof(schemapool_vtab));
if( pVtab ){
memset(pVtab, 0, sizeof(schemapool_vtab));
rc = sqlite3_declare_vtab(db, SCHEMAPOOL_SCHEMA);
if( rc!=SQLITE_OK ){
sqlite3_free(pVtab);
pVtab = 0;
}
}
*ppVtab = (sqlite3_vtab *)pVtab;
return rc;
}
/*
** Open a new cursor on the schema table.
*/
static int schemaPoolOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){
int rc = SQLITE_NOMEM;
schemapool_cursor *pCur;
pCur = sqlite3_malloc(sizeof(schemapool_cursor));
if( pCur ){
memset(pCur, 0, sizeof(schemapool_cursor));
*ppCursor = (sqlite3_vtab_cursor*)pCur;
rc = SQLITE_OK;
}
return rc;
}
/*
** Close a schema table cursor.
*/
static int schemaPoolClose(sqlite3_vtab_cursor *cur){
schemapool_cursor *pCur = (schemapool_cursor*)cur;
sqlite3_free(pCur->aData);
sqlite3_free(pCur);
return SQLITE_OK;
}
/*
** Retrieve a column of data.
*/
static int schemaPoolColumn(sqlite3_vtab_cursor *cur, sqlite3_context *ctx, int i){
schemapool_cursor *pCur = (schemapool_cursor*)cur;
assert( i==0 || i==1 || i==2 || i==3 );
sqlite3_result_int64(ctx, pCur->aData[pCur->iRow*SCHEMAPOOL_NFIELD + i]);
return SQLITE_OK;
}
/*
** Retrieve the current rowid.
*/
static int schemaPoolRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
schemapool_cursor *pCur = (schemapool_cursor*)cur;
*pRowid = pCur->iRow + 1;
return SQLITE_OK;
}
static int schemaPoolEof(sqlite3_vtab_cursor *cur){
schemapool_cursor *pCur = (schemapool_cursor*)cur;
return pCur->iRow>=pCur->nRow;
}
/*
** Advance the cursor to the next row.
*/
static int schemaPoolNext(sqlite3_vtab_cursor *cur){
schemapool_cursor *pCur = (schemapool_cursor*)cur;
pCur->iRow++;
return SQLITE_OK;
}
struct SchemaPool {
int nRef; /* Number of pointers to this object */
int nDelete; /* Schema objects deleted by ReleaseAll() */
u64 cksum; /* Checksum for this Schema contents */
Schema *pSchema; /* Linked list of Schema objects */
Schema sSchema; /* The single dummy schema object */
SchemaPool *pNext; /* Next element in schemaPoolList */
};
extern SchemaPool *sqlite3SchemaPoolList(void);
/*
** Reset a schemaPool table cursor.
*/
static int schemaPoolFilter(
sqlite3_vtab_cursor *pVtabCursor,
int idxNum, const char *idxStr,
int argc, sqlite3_value **argv
){
SchemaPool *pSPool;
schemapool_cursor *pCur = (schemapool_cursor*)pVtabCursor;
sqlite3_free(pCur->aData);
pCur->aData = 0;
pCur->nRow = 0;
pCur->iRow = 0;
for(pSPool = sqlite3SchemaPoolList(); pSPool; pSPool=pSPool->pNext){
pCur->nRow++;
}
if( pCur->nRow ){
int iRow = 0;
int nByte = SCHEMAPOOL_NFIELD * pCur->nRow * sizeof(i64);
pCur->aData = (i64*)sqlite3_malloc(nByte);
if( pCur->aData==0 ) return SQLITE_NOMEM;
for(pSPool = sqlite3SchemaPoolList(); pSPool; pSPool=pSPool->pNext){
Schema *p;
i64 nSchema = 0;
for(p=pSPool->pSchema; p; p=p->pNext){
nSchema++;
}
pCur->aData[0 + iRow*SCHEMAPOOL_NFIELD] = pSPool->cksum;
pCur->aData[1 + iRow*SCHEMAPOOL_NFIELD] = (i64)pSPool->nRef;
pCur->aData[2 + iRow*SCHEMAPOOL_NFIELD] = nSchema;
pCur->aData[3 + iRow*SCHEMAPOOL_NFIELD] = (i64)pSPool->nDelete;
iRow++;
}
}
return SQLITE_OK;
}
/*
** Analyse the WHERE condition.
*/
static int schemaPoolBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
return SQLITE_OK;
}
/*
** A virtual table module that merely echos method calls into TCL
** variables.
*/
static sqlite3_module schemaPoolModule = {
0, /* iVersion */
schemaPoolCreate,
schemaPoolCreate,
schemaPoolBestIndex,
schemaPoolDestroy,
schemaPoolDestroy,
schemaPoolOpen, /* xOpen - open a cursor */
schemaPoolClose, /* xClose - close a cursor */
schemaPoolFilter, /* xFilter - configure scan constraints */
schemaPoolNext, /* xNext - advance a cursor */
schemaPoolEof, /* xEof */
schemaPoolColumn, /* xColumn - read data */
schemaPoolRowid, /* xRowid - read data */
0, /* xUpdate */
0, /* xBegin */
0, /* xSync */
0, /* xCommit */
0, /* xRollback */
0, /* xFindMethod */
0, /* xRename */
};
/*
** Decode a pointer to an sqlite3 object.
*/
extern int getDbPointer(Tcl_Interp *interp, const char *zA, sqlite3 **ppDb);
/*
** Register the schema virtual table module.
*/
static int SQLITE_TCLAPI register_schemapool_module(
ClientData clientData, /* Not used */
Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
int objc, /* Number of arguments */
Tcl_Obj *CONST objv[] /* Command arguments */
){
sqlite3 *db;
if( objc!=2 ){
Tcl_WrongNumArgs(interp, 1, objv, "DB");
return TCL_ERROR;
}
if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
#ifndef SQLITE_OMIT_VIRTUALTABLE
sqlite3_create_module(db, "schemapool", &schemaPoolModule, 0);
#endif
return TCL_OK;
}
#endif /* ifdef SQLITE_ENABLE_SHARED_SCHEMA */
#endif /* !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_TEST) */
/*
** Register commands with the TCL interpreter.
*/
int Sqlitetestschemapool_Init(Tcl_Interp *interp){
#ifdef SQLITE_ENABLE_SHARED_SCHEMA
static struct {
char *zName;
Tcl_ObjCmdProc *xProc;
void *clientData;
} aObjCmd[] = {
{ "register_schemapool_module", register_schemapool_module, 0 },
};
int i;
for(i=0; i<sizeof(aObjCmd)/sizeof(aObjCmd[0]); i++){
Tcl_CreateObjCommand(interp, aObjCmd[i].zName,
aObjCmd[i].xProc, aObjCmd[i].clientData, 0);
}
#endif /* ifdef SQLITE_ENABLE_SHARED_SCHEMA */
return TCL_OK;
}
+2
View File
@@ -77,6 +77,7 @@ const char *sqlite3TestInit(Tcl_Interp *interp){
extern int Sqlitetest_malloc_Init(Tcl_Interp*);
extern int Sqlitetest_mutex_Init(Tcl_Interp*);
extern int Sqlitetestschema_Init(Tcl_Interp*);
extern int Sqlitetestschemapool_Init(Tcl_Interp*);
extern int Sqlitetestsse_Init(Tcl_Interp*);
extern int Sqlitetesttclvar_Init(Tcl_Interp*);
extern int Sqlitetestfs_Init(Tcl_Interp*);
@@ -148,6 +149,7 @@ const char *sqlite3TestInit(Tcl_Interp *interp){
Sqlitetest_malloc_Init(interp);
Sqlitetest_mutex_Init(interp);
Sqlitetestschema_Init(interp);
Sqlitetestschemapool_Init(interp);
Sqlitetesttclvar_Init(interp);
Sqlitetestfs_Init(interp);
SqlitetestThread_Init(interp);
+1
View File
@@ -614,6 +614,7 @@ int sqlite3RunParser(Parse *pParse, const char *zSql){
mxSqlLen -= n;
if( mxSqlLen<0 ){
pParse->rc = SQLITE_TOOBIG;
pParse->nErr++;
break;
}
#ifndef SQLITE_OMIT_WINDOWFUNC
+9 -3
View File
@@ -100,8 +100,8 @@ void sqlite3TreeViewColumnList(
sqlite3TreeViewLine(pView, "COLUMNS");
for(i=0; i<nCol; i++){
u16 flg = aCol[i].colFlags;
int moreToFollow = i<(nCol - 1);
sqlite3TreeViewPush(&pView, moreToFollow);
int colMoreToFollow = i<(nCol - 1);
sqlite3TreeViewPush(&pView, colMoreToFollow);
sqlite3TreeViewLine(pView, 0);
printf(" %s", aCol[i].zCnName);
switch( aCol[i].eCType ){
@@ -232,7 +232,7 @@ void sqlite3TreeViewSrcList(TreeView *pView, const SrcList *pSrc){
Table *pTab = pItem->pTab;
sqlite3TreeViewColumnList(pView, pTab->aCol, pTab->nCol, 1);
}
assert( pItem->fg.isNestedFrom == IsNestedFrom(pItem->pSelect) );
assert( (int)pItem->fg.isNestedFrom == IsNestedFrom(pItem->pSelect) );
sqlite3TreeViewSelect(pView, pItem->pSelect, (--n)>0);
}
if( pItem->fg.isTabFunc ){
@@ -999,6 +999,7 @@ void sqlite3TreeViewUpsert(
sqlite3TreeViewPop(&pView);
}
#if TREETRACE_ENABLED
/*
** Generate a human-readable diagram of the data structure that go
** into generating an DELETE statement.
@@ -1052,7 +1053,9 @@ void sqlite3TreeViewDelete(
}
sqlite3TreeViewPop(&pView);
}
#endif /* TREETRACE_ENABLED */
#if TREETRACE_ENABLED
/*
** Generate a human-readable diagram of the data structure that go
** into generating an INSERT statement.
@@ -1120,7 +1123,9 @@ void sqlite3TreeViewInsert(
}
sqlite3TreeViewPop(&pView);
}
#endif /* TREETRACE_ENABLED */
#if TREETRACE_ENABLED
/*
** Generate a human-readable diagram of the data structure that go
** into generating an UPDATE statement.
@@ -1196,6 +1201,7 @@ void sqlite3TreeViewUpdate(
}
sqlite3TreeViewPop(&pView);
}
#endif /* TREETRACE_ENABLED */
#ifndef SQLITE_OMIT_TRIGGER
/*
+57 -5
View File
@@ -52,13 +52,34 @@ Trigger *sqlite3TriggerList(Parse *pParse, Table *pTab){
Trigger *pList; /* List of triggers to return */
HashElem *p; /* Loop variable for TEMP triggers */
#ifdef SQLITE_ENABLE_SHARED_SCHEMA
char *zSchema = 0;
sqlite3 *db = pParse->db;
if( IsSharedSchema(db) ){
zSchema = db->aDb[sqlite3SchemaToIndex(db, pTab->pSchema)].zDbSName;
}
#endif
assert( pParse->disableTriggers==0 );
pTmpSchema = pParse->db->aDb[1].pSchema;
p = sqliteHashFirst(&pTmpSchema->trigHash);
pList = pTab->pTrigger;
while( p ){
Trigger *pTrig = (Trigger *)sqliteHashData(p);
if( pTrig->pTabSchema==pTab->pSchema
int bSchemaMatch;
#ifdef SQLITE_ENABLE_SHARED_SCHEMA
if( zSchema ){
/* Shared-schema */
bSchemaMatch = (0==sqlite3StrICmp(pTrig->zTabSchema, zSchema));
}else
#endif
{
/* Non-shared-schema */
bSchemaMatch = (pTrig->pTabSchema==pTab->pSchema);
}
if( bSchemaMatch
&& pTrig->table
&& 0==sqlite3StrICmp(pTrig->table, pTab->zName)
&& pTrig->pTabSchema!=pTmpSchema
@@ -68,7 +89,7 @@ Trigger *sqlite3TriggerList(Parse *pParse, Table *pTab){
}else if( pTrig->op==TK_RETURNING ){
#ifndef SQLITE_OMIT_VIRTUALTABLE
assert( pParse->db->pVtabCtx==0 );
#endif
#endif
assert( pParse->bReturning );
assert( &(pParse->u1.pReturning->retTrig) == pTrig );
pTrig->table = pTab->zName;
@@ -258,6 +279,12 @@ void sqlite3BeginTrigger(
pTrigger->zName = zName;
zName = 0;
pTrigger->table = sqlite3DbStrDup(db, pTableName->a[0].zName);
#ifdef SQLITE_ENABLE_SHARED_SCHEMA
if( IsSharedSchema(db) && iDb==1 ){
int iTabDb = sqlite3SchemaToIndex(db, pTab->pSchema);
pTrigger->zTabSchema = sqlite3DbStrDup(db, db->aDb[iTabDb].zDbSName);
}
#endif /* ifdef SQLITE_ENABLE_SHARED_SCHEMA */
pTrigger->pSchema = db->aDb[iDb].pSchema;
pTrigger->pTabSchema = pTab->pSchema;
pTrigger->op = (u8)op;
@@ -351,6 +378,23 @@ void sqlite3FinishTrigger(
Vdbe *v;
char *z;
/* If this is a new CREATE TABLE statement, and if shadow tables
** are read-only, and the trigger makes a change to a shadow table,
** then raise an error - do not allow the trigger to be created. */
if( sqlite3ReadOnlyShadowTables(db) ){
TriggerStep *pStep;
for(pStep=pTrig->step_list; pStep; pStep=pStep->pNext){
if( pStep->zTarget!=0
&& sqlite3ShadowTableName(db, pStep->zTarget)
){
sqlite3ErrorMsg(pParse,
"trigger \"%s\" may not write to shadow table \"%s\"",
pTrig->zName, pStep->zTarget);
goto triggerfinish_cleanup;
}
}
}
/* Make an entry in the sqlite_schema table */
v = sqlite3GetVdbe(pParse);
if( v==0 ) goto triggerfinish_cleanup;
@@ -364,7 +408,7 @@ void sqlite3FinishTrigger(
pTrig->table, z);
sqlite3DbFree(db, z);
sqlite3ChangeCookie(pParse, iDb);
sqlite3VdbeAddParseSchemaOp(v, iDb,
sqlite3VdbeAddParseSchemaOp(pParse, iDb,
sqlite3MPrintf(db, "type='trigger' AND name='%q'", zName), 0);
}
@@ -583,6 +627,9 @@ void sqlite3DeleteTrigger(sqlite3 *db, Trigger *pTrigger){
sqlite3DeleteTriggerStep(db, pTrigger->step_list);
sqlite3DbFree(db, pTrigger->zName);
sqlite3DbFree(db, pTrigger->table);
#ifdef SQLITE_ENABLE_SHARED_SCHEMA
sqlite3DbFree(db, pTrigger->zTabSchema);
#endif
sqlite3ExprDelete(db, pTrigger->pWhen);
sqlite3IdListDelete(db, pTrigger->pColumns);
sqlite3DbFree(db, pTrigger);
@@ -654,6 +701,7 @@ void sqlite3DropTriggerPtr(Parse *pParse, Trigger *pTrigger){
iDb = sqlite3SchemaToIndex(pParse->db, pTrigger->pSchema);
assert( iDb>=0 && iDb<db->nDb );
sqlite3SchemaWritable(pParse, iDb);
pTable = tableOfTrigger(pTrigger);
assert( (pTable && pTable->pSchema==pTrigger->pSchema) || iDb==1 );
#ifndef SQLITE_OMIT_AUTHORIZATION
@@ -1146,7 +1194,9 @@ static TriggerPrg *codeRowTrigger(
int iEndTrigger = 0; /* Label to jump to if WHEN is false */
Parse sSubParse; /* Parse context for sub-vdbe */
assert( pTrigger->zName==0 || pTab==tableOfTrigger(pTrigger) );
assert( pTrigger->zName==0 || IsSharedSchema(pParse->db)
|| pTab==tableOfTrigger(pTrigger)
);
assert( pTop->pVdbe );
/* Allocate the TriggerPrg and SubProgram objects. To ensure that they
@@ -1253,7 +1303,9 @@ static TriggerPrg *getRowTrigger(
Parse *pRoot = sqlite3ParseToplevel(pParse);
TriggerPrg *pPrg;
assert( pTrigger->zName==0 || pTab==tableOfTrigger(pTrigger) );
assert( pTrigger->zName==0 || IsSharedSchema(pParse->db)
|| pTab==tableOfTrigger(pTrigger)
);
/* It may be that this trigger has already been coded (or is in the
** process of being coded). If this is the case, then an entry with
+1 -1
View File
@@ -190,7 +190,7 @@ void sqlite3ErrorMsg(Parse *pParse, const char *zFormat, ...){
va_list ap;
sqlite3 *db = pParse->db;
assert( db!=0 );
assert( db->pParse==pParse );
assert( db->pParse==pParse || db->pParse->pToplevel==pParse );
db->errByteOffset = -2;
va_start(ap, zFormat);
zMsg = sqlite3VMPrintf(db, zFormat, ap);
+1
View File
@@ -125,6 +125,7 @@ void sqlite3Vacuum(Parse *pParse, Token *pNm, Expr *pInto){
}
if( iDb!=1 ){
int iIntoReg = 0;
sqlite3SchemaWritable(pParse, iDb);
if( pInto && sqlite3ResolveSelfReference(pParse,0,0,pInto,0)==0 ){
iIntoReg = ++pParse->nMem;
sqlite3ExprCode(pParse, pInto, iIntoReg);
+7 -7
View File
@@ -3863,13 +3863,6 @@ case OP_Transaction: {
&& pOp->p5
&& (iMeta!=pOp->p3 || pDb->pSchema->iGeneration!=pOp->p4.i)
){
/*
** IMPLEMENTATION-OF: R-03189-51135 As each SQL statement runs, the schema
** version is checked to ensure that the schema has not changed since the
** SQL statement was prepared.
*/
sqlite3DbFree(db, p->zErrMsg);
p->zErrMsg = sqlite3DbStrDup(db, "database schema has changed");
/* If the schema-cookie from the database file matches the cookie
** stored with the in-memory representation of the schema, do
** not reload the schema from the database file.
@@ -3886,6 +3879,13 @@ case OP_Transaction: {
if( db->aDb[pOp->p1].pSchema->schema_cookie!=iMeta ){
sqlite3ResetOneSchema(db, pOp->p1);
}
/*
** IMPLEMENTATION-OF: R-03189-51135 As each SQL statement runs, the schema
** version is checked to ensure that the schema has not changed since the
** SQL statement was prepared.
*/
sqlite3DbFree(db, p->zErrMsg);
p->zErrMsg = sqlite3DbStrDup(db, "database schema has changed");
p->expired = 1;
rc = SQLITE_SCHEMA;
+1 -1
View File
@@ -222,7 +222,7 @@ VdbeOp *sqlite3VdbeAddOpList(Vdbe*, int nOp, VdbeOpList const *aOp,int iLineno);
#else
# define sqlite3ExplainBreakpoint(A,B) /*no-op*/
#endif
void sqlite3VdbeAddParseSchemaOp(Vdbe*, int, char*, u16);
void sqlite3VdbeAddParseSchemaOp(Parse*,int,char*,u16);
void sqlite3VdbeChangeOpcode(Vdbe*, int addr, u8);
void sqlite3VdbeChangeP1(Vdbe*, int addr, int P1);
void sqlite3VdbeChangeP2(Vdbe*, int addr, int P2);
+5 -1
View File
@@ -381,6 +381,7 @@ int sqlite3VdbeAddFunctionCall(
addr = sqlite3VdbeAddOp4(v, eCallCtx ? OP_PureFunc : OP_Function,
p1, p2, p3, (char*)pCtx, P4_FUNCCTX);
sqlite3VdbeChangeP5(v, eCallCtx & NC_SelfRef);
sqlite3MayAbort(pParse);
return addr;
}
@@ -473,8 +474,10 @@ void sqlite3VdbeExplainPop(Parse *pParse){
** The zWhere string must have been obtained from sqlite3_malloc().
** This routine will take ownership of the allocated memory.
*/
void sqlite3VdbeAddParseSchemaOp(Vdbe *p, int iDb, char *zWhere, u16 p5){
void sqlite3VdbeAddParseSchemaOp(Parse *pParse, int iDb, char *zWhere, u16 p5){
Vdbe *p = pParse->pVdbe;
int j;
sqlite3SchemaWritable(pParse, iDb);
sqlite3VdbeAddOp4(p, OP_ParseSchema, iDb, 0, 0, zWhere, P4_DYNAMIC);
sqlite3VdbeChangeP5(p, p5);
for(j=0; j<p->db->nDb; j++) sqlite3VdbeUsesBtree(p, j);
@@ -716,6 +719,7 @@ int sqlite3VdbeAssertMayAbort(Vdbe *v, int mayAbort){
|| opcode==OP_VDestroy
|| opcode==OP_VCreate
|| opcode==OP_ParseSchema
|| opcode==OP_Function || opcode==OP_PureFunc
|| ((opcode==OP_Halt || opcode==OP_HaltIfNull)
&& ((pOp->p1)!=SQLITE_OK && pOp->p2==OE_Abort))
){
+3
View File
@@ -135,6 +135,7 @@ int sqlite3_blob_open(
Table *pTab;
Incrblob *pBlob = 0;
Parse sParse;
int bUnlock; /* True to unlock reusable schemas before returning */
#ifdef SQLITE_ENABLE_API_ARMOR
if( ppBlob==0 ){
@@ -151,6 +152,7 @@ int sqlite3_blob_open(
sqlite3_mutex_enter(db->mutex);
bUnlock = sqlite3LockReusableSchema(db);
pBlob = (Incrblob *)sqlite3DbMallocZero(db, sizeof(Incrblob));
while(1){
sqlite3ParseObjectInit(&sParse,db);
@@ -336,6 +338,7 @@ int sqlite3_blob_open(
}
blob_open_out:
sqlite3UnlockReusableSchema(db, bUnlock);
if( rc==SQLITE_OK && db->mallocFailed==0 ){
*ppBlob = (sqlite3_blob *)pBlob;
}else{
+47 -8
View File
@@ -192,6 +192,24 @@ void sqlite3VtabLock(VTable *pVTab){
VTable *sqlite3GetVTable(sqlite3 *db, Table *pTab){
VTable *pVtab;
assert( IsVirtual(pTab) );
#ifdef SQLITE_ENABLE_SHARED_SCHEMA
if( IsSharedSchema(db) ){
int iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
if( iDb!=1 ){
VTable **pp;
for(pp=&db->aDb[iDb].pVTable; *pp; pp=&(*pp)->pNext){
if( sqlite3StrICmp(pTab->zName, (*pp)->zName)==0 ) break;
}
pVtab = *pp;
if( pVtab && pTab->nCol<=0 ){
*pp = pVtab->pNext;
sqlite3VtabUnlock(pVtab);
pVtab = 0;
}
return pVtab;
}
}
#endif /* ifdef SQLITE_ENABLE_SHARED_SCHEMA */
for(pVtab=pTab->u.vtab.p; pVtab && pVtab->db!=db; pVtab=pVtab->pNext);
return pVtab;
}
@@ -499,7 +517,7 @@ void sqlite3VtabFinishParse(Parse *pParse, Token *pEnd){
sqlite3VdbeAddOp0(v, OP_Expire);
zWhere = sqlite3MPrintf(db, "name=%Q AND sql=%Q", pTab->zName, zStmt);
sqlite3VdbeAddParseSchemaOp(v, iDb, zWhere, 0);
sqlite3VdbeAddParseSchemaOp(pParse, iDb, zWhere, 0);
sqlite3DbFree(db, zStmt);
iReg = ++pParse->nMem;
@@ -569,6 +587,7 @@ static int vtabCallConstructor(
char *zModuleName;
int iDb;
VtabCtx *pCtx;
int nByte; /* Bytes of space to allocate */
assert( IsVirtual(pTab) );
azArg = (const char *const*)pTab->u.vtab.azArg;
@@ -588,7 +607,11 @@ static int vtabCallConstructor(
return SQLITE_NOMEM_BKPT;
}
pVTable = sqlite3MallocZero(sizeof(VTable));
nByte = sizeof(VTable);
#ifdef SQLITE_ENABLE_SHARED_SCHEMA
nByte += sqlite3Strlen30(pTab->zName) + 1;
#endif
pVTable = (VTable*)sqlite3MallocZero(nByte);
if( !pVTable ){
sqlite3OomFault(db);
sqlite3DbFree(db, zModuleName);
@@ -596,6 +619,10 @@ static int vtabCallConstructor(
}
pVTable->db = db;
pVTable->pMod = pMod;
#ifdef SQLITE_ENABLE_SHARED_SCHEMA
pVTable->zName = (char*)&pVTable[1];
memcpy(pVTable->zName, pTab->zName, nByte-sizeof(VTable));
#endif
pVTable->eVtabRisk = SQLITE_VTABRISK_Normal;
iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
@@ -638,12 +665,23 @@ static int vtabCallConstructor(
int iCol;
u16 oooHidden = 0;
/* If everything went according to plan, link the new VTable structure
** into the linked list headed by pTab->u.vtab.p. Then loop through the
** columns of the table to see if any of them contain the token "hidden".
** If so, set the Column COLFLAG_HIDDEN flag and remove the token from
** the type string. */
pVTable->pNext = pTab->u.vtab.p;
pTab->u.vtab.p = pVTable;
** into the linked list headed by pTab->u.vtab.p. Or, if this is a
** reusable schema, into the linked list headed by Db.pVTable.
**
** Then loop through the columns of the table to see if any of them
** contain the token "hidden". If so, set the Column COLFLAG_HIDDEN flag
** and remove the token from the type string. */
#ifdef SQLITE_ENABLE_SHARED_SCHEMA
if( IsSharedSchema(db) && iDb!=1 ){
pVTable->pNext = db->aDb[iDb].pVTable;
db->aDb[iDb].pVTable = pVTable;
}else
#endif /* ifdef SQLITE_ENABLE_SHARED_SCHEMA */
{
assert( IsVirtual(pTab) );
pVTable->pNext = pTab->u.vtab.p;
pTab->u.vtab.p = pVTable;
}
for(iCol=0; iCol<pTab->nCol; iCol++){
char *zType = sqlite3ColumnType(&pTab->aCol[iCol], "");
@@ -698,6 +736,7 @@ int sqlite3VtabCallConnect(Parse *pParse, Table *pTab){
assert( pTab );
assert( IsVirtual(pTab) );
if( sqlite3GetVTable(db, pTab) ){
assert( !IsVirtual(pTab) || pTab->nCol>0 );
return SQLITE_OK;
}
+10 -8
View File
@@ -1433,7 +1433,7 @@ static int whereKeyStats(
#endif
assert( pRec!=0 );
assert( pIdx->nSample>0 );
assert( pRec->nField>0 && pRec->nField<=pIdx->nSampleCol );
assert( pRec->nField>0 );
/* Do a binary search to find the first sample greater than or equal
** to pRec. If pRec contains a single field, the set of samples to search
@@ -1479,7 +1479,7 @@ static int whereKeyStats(
** it is extended to two fields. The duplicates that this creates do not
** cause any problems.
*/
nField = pRec->nField;
nField = MIN(pRec->nField, pIdx->nSample);
iCol = 0;
iSample = pIdx->nSample * nField;
do{
@@ -4168,6 +4168,7 @@ static int whereLoopAddAll(WhereLoopBuilder *pBuilder){
sqlite3 *db = pWInfo->pParse->db;
int rc = SQLITE_OK;
int bFirstPastRJ = 0;
int hasRightJoin = 0;
WhereLoop *pNew;
@@ -4188,15 +4189,16 @@ static int whereLoopAddAll(WhereLoopBuilder *pBuilder){
** prevents the right operand of a RIGHT JOIN from being swapped with
** other elements even further to the right.
**
** The JT_LTORJ term prevents any FROM-clause term reordering for terms
** to the left of a RIGHT JOIN. This is conservative. Relaxing this
** constraint somewhat to prevent terms from crossing from the right
** side of a LEFT JOIN over to the left side when they are on the
** left side of a RIGHT JOIN would be sufficient for all known failure
** cases. FIX ME: Implement this optimization.
** The JT_LTORJ case and the hasRightJoin flag work together to
** prevent FROM-clause terms from moving from the right side of
** a LEFT JOIN over to the left side of that join if the LEFT JOIN
** is itself on the left side of a RIGHT JOIN.
*/
if( pItem->fg.jointype & JT_LTORJ ) hasRightJoin = 1;
mPrereq |= mPrior;
bFirstPastRJ = (pItem->fg.jointype & JT_RIGHT)!=0;
}else if( !hasRightJoin ){
mPrereq = 0;
}
#ifndef SQLITE_OMIT_VIRTUALTABLE
if( IsVirtual(pItem->pTab) ){
+2 -1
View File
@@ -622,7 +622,8 @@ static int codeEqualityTerm(
}
sqlite3ExprDelete(db, pX);
}else{
aiMap = (int*)sqlite3DbMallocZero(pParse->db, sizeof(int)*nEq);
int n = sqlite3ExprVectorSize(pX->pLeft);
aiMap = (int*)sqlite3DbMallocZero(pParse->db, sizeof(int)*MAX(nEq,n));
eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, aiMap, &iTab);
}
pX = pExpr;
+435
View File
@@ -7033,6 +7033,8 @@ set sqlite_fts3_enable_parentheses $saved
#-------------------------------------------------------------------------
#
set saved $sqlite_fts3_enable_parentheses
set sqlite_fts3_enable_parentheses 1
reset_db
do_test 52.0 {
sqlite3 db {}
@@ -7228,5 +7230,438 @@ do_catchsql_test 52.1 {
SELECT * FROM t1, t2;
} {1 {database disk image is malformed}}
#-------------------------------------------------------------------------
#
reset_db
do_test 53.0 {
sqlite3 db {}
db deserialize [decode_hexdb {
.open --hexdb
| size 8192 pagesize 1024 filename crash-7bc.txt.db
| page 1 offset 0
| 0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00 SQLite format 3.
| 16: 04 00 01 01 00 40 20 20 00 00 00 00 00 00 00 08 .....@ ........
| 32: 00 00 00 00 00 00 00 00 00 00 00 06 00 00 00 04 ................
| 48: 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 ................
| 96: 00 00 00 00 0d 02 f3 00 07 01 51 00 03 c8 03 63 ..........Q....c
| 112: 02 fb 02 0a 02 c0 01 a8 01 51 00 00 00 00 00 00 .........Q......
| 336: 00 55 07 07 17 1b 1b 01 81 01 74 61 62 6c 65 74 .U........tablet
| 352: 31 5f 73 74 61 74 74 31 5f 73 74 61 74 07 43 52 1_statt1_stat.CR
| 368: 45 41 54 45 20 54 41 42 4c 45 20 27 74 31 5f 73 EATE TABLE 't1_s
| 384: 74 61 74 27 28 69 64 20 49 4e 54 45 47 45 52 20 tat'(id INTEGER
| 400: 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 76 61 6c PRIMARY KEY, val
| 416: 75 65 20 42 4c 4f 42 29 60 06 07 17 21 21 01 81 ue BLOB)`...!!..
| 432: 0b 74 61 62 6c 65 74 31 5f 64 6f 63 73 69 7a 65 .tablet1_docsize
| 448: 74 31 5f 64 6f 63 73 69 7a 65 06 43 52 45 41 54 t1_docsize.CREAT
| 464: 45 20 54 41 42 4c 45 20 27 74 31 5f 64 6f 63 73 E TABLE 't1_docs
| 480: 69 7a 65 27 28 64 6f 63 69 64 20 49 4e 54 45 47 ize'(docid INTEG
| 496: 45 52 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 ER PRIMARY KEY,
| 512: 73 69 7a 65 20 42 4c 4f 42 29 81 33 04 07 17 1f size BLOB).3....
| 528: 1f 01 82 35 74 61 62 6c 65 74 31 5f 73 65 67 64 ...5tablet1_segd
| 544: 69 72 74 31 5f 73 65 67 64 69 72 04 43 52 45 41 irt1_segdir.CREA
| 560: 54 45 20 54 41 42 4c 45 20 27 74 31 5f 73 65 67 TE TABLE 't1_seg
| 576: 64 69 72 27 28 6c 65 76 65 6c 20 49 4e 54 45 47 dir'(level INTEG
| 592: 45 52 2c 69 64 78 20 49 4e 54 45 47 45 52 2c 73 ER,idx INTEGER,s
| 608: 74 61 72 74 5f 62 6c 6f 63 6b 20 49 4e 54 45 47 tart_block INTEG
| 624: 45 52 2c 6c 65 61 76 65 73 5f 65 6e 64 5f 62 6c ER,leaves_end_bl
| 640: 6f 63 6b 20 49 4e 54 45 47 45 52 2c 65 6e 64 5f ock INTEGER,end_
| 656: 62 6c 6f 63 6b 20 49 4e 54 45 47 45 52 2c 72 6f block INTEGER,ro
| 672: 6f 74 20 42 4c 4f 42 2c 50 52 49 4d 41 52 59 20 ot BLOB,PRIMARY
| 688: 4b 45 59 28 6c 65 76 65 6c 2c 20 69 64 78 29 29 KEY(level, idx))
| 704: 31 05 06 17 45 1f 01 00 69 6e 64 65 78 73 71 6c 1...E...indexsql
| 720: 69 74 65 5f 61 75 74 6f 69 6e 64 65 78 5f 74 31 ite_autoindex_t1
| 736: 5f 73 65 67 64 69 72 5f 31 74 31 5f 73 65 67 64 _segdir_1t1_segd
| 752: 69 72 05 00 00 00 08 00 00 00 00 66 03 07 17 23 ir.........f...#
| 768: 23 01 81 13 74 61 62 6c 65 74 31 5f 73 65 67 6d #...tablet1_segm
| 784: 65 6e 74 73 74 31 5f 73 65 67 6d 65 6e 74 73 03 entst1_segments.
| 800: 43 52 45 41 54 45 20 54 41 42 4c 45 20 27 74 31 CREATE TABLE 't1
| 816: 5f 73 65 67 6d 65 6e 74 73 27 28 62 6c 6f 63 6b _segments'(block
| 832: 69 64 20 49 4e 53 45 47 45 52 20 50 52 49 4d 41 id INSEGER PRIMA
| 848: 52 59 20 4b 45 59 2c 20 62 6c 6f 63 6b 20 42 4c RY KEY, block BL
| 864: 4f 42 29 63 02 07 17 21 21 01 81 11 74 61 62 6c OB)c...!!...tabl
| 880: 65 74 31 5f 63 6f 6e 74 65 6e 74 74 31 5f 63 6f et1_contentt1_co
| 896: 6e 74 65 6e 74 02 43 52 45 41 54 45 20 54 41 42 ntent.CREATE TAB
| 912: 4c 45 20 27 74 31 5f 63 6f 6e 74 65 6e 74 27 28 LE 't1_content'(
| 928: 64 6f 63 69 64 20 49 4e 54 45 47 45 52 20 50 52 docid INTEGER PR
| 944: 49 4d 41 52 59 20 4b 45 59 2c 20 27 63 30 30 27 IMARY KEY, 'c00'
| 960: 2c 20 27 63 31 62 27 29 36 01 06 17 11 11 08 5b , 'c1b')6......[
| 976: 74 61 62 6c 65 74 31 74 31 43 52 45 41 54 45 20 tablet1t1CREATE
| 992: 56 49 52 54 55 41 4c 20 54 41 42 4c 45 20 74 31 VIRTUAL TABLE t1
| 1008: 20 55 53 49 4e 47 20 66 74 73 34 28 30 2c 62 29 USING fts4(0,b)
| page 2 offset 1024
| 0: 0d 00 00 00 03 00 0f 00 00 23 00 16 00 0f 00 05 .........#......
| 16: 03 04 00 08 0f 61 0b 02 04 00 08 1b 41 54 45 20 .....a......ATE
| 32: 32 3a 50 87 5a 01 05 00 08 8f 37 66 30 30 30 30 2:P.Z.....7f0000
| 48: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 64: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 80: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 96: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 112: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 128: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 144: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 160: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 176: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 192: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 208: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 224: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 240: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 256: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 272: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 288: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 304: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 320: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 336: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 352: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 368: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 384: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 400: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 416: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 432: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 448: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 464: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 480: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 496: 30 40 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0@00000000000000
| 512: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 528: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 544: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 560: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 576: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 592: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 608: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 624: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 640: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 656: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 672: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 688: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 704: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 720: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 736: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 752: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 768: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 784: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 800: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 816: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 832: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 848: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 864: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 880: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 896: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 912: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 928: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 944: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 960: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 976: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 992: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 1008: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| page 3 offset 2048
| 0: 0d 00 00 00 02 03 86 00 03 f4 03 86 00 00 00 00 ................
| 896: 00 00 00 00 00 00 87 62 02 04 00 8f 48 00 d5 07 .......b....H...
| 912: 66 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 f000000000000000
| 928: 30 30 30 30 3a 30 30 30 30 30 30 30 30 30 30 30 0000:00000000000
| 944: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 960: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 976: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 992: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 1008: 00 00 00 08 0a 01 03 00 1a 00 01 30 03 01 02 00 ...........0....
| page 4 offset 3072
| 0: 0d 00 00 00 03 03 9e 00 03 ed 03 bc 03 9e 00 00 ................
| 912: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 1c 03 ................
| 928: 07 08 01 08 08 15 2c 02 30 20 31 36 00 01 30 03 ......,.0 16..0.
| 944: 03 02 00 00 01 61 05 03 01 01 02 00 2f 02 07 08 .....a....../...
| 960: 09 08 08 15 54 30 20 33 36 00 01 30 03 02 02 00 ....T0 36..0....
| 976: 00 01 32 05 02 01 01 03 00 00 03 61 74 65 05 02 ..2........ate..
| 992: 01 01 02 00 00 01 70 05 02 01 01 04 00 11 01 07 ......p.........
| 1008: 08 08 09 01 17 14 02 32 20 39 39 37 01 01 01 66 .......2 997...f
| page 5 offset 4096
| 0: 0a 00 00 00 03 03 ee 00 03 fb 03 f5 03 ee 00 00 ................
| 992: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 06 04 ................
| 1008: 08 01 01 02 03 05 04 08 09 01 02 04 04 08 08 09 ................
| page 6 offset 5120
| 0: 0d 00 00 00 03 03 eb 00 00 00 00 00 00 00 00 00 ................
| 992: 00 00 00 00 00 00 00 00 00 00 00 05 03 03 00 10 ................
| 1008: 01 01 05 02 03 00 10 01 03 05 01 03 00 10 01 01 ................
| page 7 offset 6144
| 0: 0d 00 00 00 01 03 f6 00 03 f6 00 00 00 00 00 00 ................
| 1008: 00 00 00 00 00 00 08 00 03 00 16 03 08 c5 e0 07 ................
| page 8 offset 7168
| 0: 00 00 00 00 30 30 30 30 30 30 30 30 30 30 30 30 ....000000000000
| 16: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 32: 30 30 30 30 30 30 30 30 30 30 30 30 30 bc 30 30 0000000000000.00
| 48: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 64: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 80: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 96: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 112: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 128: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 144: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 160: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 176: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 192: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 c0 30 00000000000000.0
| 208: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 224: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 240: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 256: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 272: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 288: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 304: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 320: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 336: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 352: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 368: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 384: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 400: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 416: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 432: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 448: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 464: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 480: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 496: 30 30 30 30 30 30 30 30 30 30 30 40 30 30 30 30 00000000000@0000
| 512: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 528: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 544: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 560: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 576: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 592: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 608: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 624: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 640: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 656: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 672: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 688: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 704: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 720: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 736: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 752: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 768: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 784: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 800: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 816: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 832: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 848: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 864: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 880: 30 30 30 30 30 30 30 30 30 05 01 00 00 00 00 00 000000000.......
| end crash-7bc.txt.db
}]} {}
do_execsql_test 53.1 {
SELECT*FROM t1 WHERE t1 MATCH'ATE"0"OR"2D:P"""ATE"0"OR"2:P"""';
} {0 {ATE 2:P}}
set sqlite_fts3_enable_parentheses $saved
#-------------------------------------------------------------------------
#
reset_db
do_test 54.0 {
sqlite3 db {}
db deserialize [decode_hexdb {
.open --hexdb
| size 8192 pagesize 1024 filename crash-365.txt.db
| page 1 offset 0
| 0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00 SQLite format 3.
| 16: 04 00 01 01 00 40 20 20 00 00 00 00 00 00 00 08 .....@ ........
| 32: 00 00 00 00 00 00 00 00 00 00 00 06 00 00 00 04 ................
| 96: 00 00 00 00 0d 02 f3 00 07 01 51 00 03 c8 03 63 ..........Q....c
| 112: 02 fb 02 0a 02 c0 01 a8 01 51 00 00 00 00 00 00 .........Q......
| 336: 00 55 07 07 17 1b 1b 01 81 01 74 61 62 6c 65 74 .U........tablet
| 352: 31 5f 73 74 61 74 74 31 5f 73 74 61 74 07 43 52 1_statt1_stat.CR
| 368: 45 41 54 45 20 54 41 42 4c 45 20 27 74 31 5f 73 EATE TABLE 't1_s
| 384: 74 61 74 27 28 69 64 20 49 4e 54 45 47 45 52 20 tat'(id INTEGER
| 400: 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 76 61 6c PRIMARY KEY, val
| 416: 75 65 20 42 4c 4f 42 29 60 06 07 17 21 21 01 81 ue BLOB)`...!!..
| 432: 0b 74 61 62 6c 65 74 31 5f 64 6f 63 73 69 7a 65 .tablet1_docsize
| 448: 74 31 5f 64 6f 63 73 69 7a 65 06 43 52 45 41 54 t1_docsize.CREAT
| 464: 45 20 54 41 42 4c 45 20 27 74 31 5f 64 6f 63 73 E TABLE 't1_docs
| 480: 69 7a 65 27 28 64 6f 63 69 64 20 49 4e 54 45 47 ize'(docid INTEG
| 496: 45 52 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 ER PRIMARY KEY,
| 512: 73 69 7a 65 20 42 4c 4f 42 29 81 33 04 07 17 1f size BLOB).3....
| 528: 1f 01 82 35 74 61 62 6c 65 74 31 5f 73 65 67 64 ...5tablet1_segd
| 544: 69 72 74 31 5f 73 65 67 64 69 72 04 43 52 45 41 irt1_segdir.CREA
| 560: 54 45 20 54 41 42 4c 45 20 27 74 31 5f 73 65 67 TE TABLE 't1_seg
| 576: 64 69 72 27 28 6c 65 76 65 6c 20 49 4e 54 45 47 dir'(level INTEG
| 592: 45 52 2c 69 64 78 20 49 4e 54 45 47 45 52 2c 73 ER,idx INTEGER,s
| 608: 74 61 72 74 5f 62 6c 6f 63 6b 20 49 4e 54 45 47 tart_block INTEG
| 624: 45 52 2c 6c 65 61 76 65 73 5f 65 6e 64 5f 62 6c ER,leaves_end_bl
| 640: 6f 63 6b 20 49 4e 54 45 47 45 52 2c 65 6e 64 5f ock INTEGER,end_
| 656: 62 6c 6f 63 6b 20 49 4e 54 45 47 45 52 2c 72 6f block INTEGER,ro
| 672: 6f 74 20 42 4c 4f 42 2c 50 52 49 4d 41 52 59 20 ot BLOB,PRIMARY
| 688: 4b 45 59 28 6c 65 76 65 6c 2c 20 69 64 78 29 29 KEY(level, idx))
| 704: 31 05 06 17 45 1f 01 00 69 6e 64 65 78 73 71 6c 1...E...indexsql
| 720: 69 74 65 5f 61 75 74 6f 69 6e 64 65 78 5f 74 31 ite_autoindex_t1
| 736: 5f 73 65 67 64 69 72 5f 31 74 31 5f 73 65 67 64 _segdir_1t1_segd
| 752: 69 72 05 00 00 00 08 00 00 00 00 66 03 07 17 23 ir.........f...#
| 768: 23 01 81 13 74 61 62 6c 65 74 31 5f 73 65 67 6d #...tablet1_segm
| 784: 65 6e 74 73 74 31 5f 73 65 67 6d 65 6e 74 73 03 entst1_segments.
| 800: 43 52 45 41 54 45 20 54 41 42 4c 45 20 27 74 31 CREATE TABLE 't1
| 816: 5f 73 65 67 6d 65 6e 74 73 27 28 62 6c 6f 63 6b _segments'(block
| 832: 69 64 20 49 4e 54 45 47 45 52 20 50 52 49 4d 41 id INTEGER PRIMA
| 848: 52 59 20 4b 45 59 2c 20 62 6c 6f 63 6b 20 42 4c RY KEY, block BL
| 864: 4f 42 29 63 02 07 17 21 21 01 81 11 74 61 62 6c OB)c...!!...tabl
| 880: 65 74 31 5f 63 6f 6e 74 65 6e 74 74 31 5f 63 6f et1_contentt1_co
| 896: 6e 74 65 6e 74 02 43 52 45 41 54 45 20 54 41 42 ntent.CREATE TAB
| 912: 4c 45 20 27 74 31 5f 63 6f 6e 74 65 6e 74 27 28 LE 't1_content'(
| 928: 64 6f 63 69 64 20 49 4e 54 45 47 45 52 20 50 52 docid INTEGER PR
| 944: 49 4d 41 52 59 20 4b 45 59 2c 20 27 63 30 30 27 IMARY KEY, 'c00'
| 960: 2c 20 27 63 31 62 27 29 36 01 06 17 11 11 08 5b , 'c1b')6......[
| 976: 74 61 62 6c 65 74 31 74 31 43 52 45 41 54 45 20 tablet1t1CREATE
| 992: 56 49 52 54 55 41 4c 20 54 41 42 4c 45 20 74 31 VIRTUAL TABLE t1
| 1008: 20 55 53 49 4e 47 20 66 74 73 34 28 30 2c 62 29 USING fts4(0,b)
| page 2 offset 1024
| 0: 0d 00 00 00 03 00 0f 00 00 23 00 16 00 0f 00 05 .........#......
| 16: 03 04 00 08 0f 61 0b 02 04 00 08 1b 41 54 45 20 .....a......ATE
| 32: 32 3a 50 87 5a 01 05 00 08 8f 37 66 30 30 30 30 2:P.Z.....7f0000
| 48: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 64: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 80: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 96: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 112: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 128: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 144: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 160: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 176: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 192: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 208: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 224: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 240: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 256: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 272: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 288: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 304: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 320: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 336: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 352: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 368: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 384: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 400: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 416: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 432: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 448: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 464: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 480: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 496: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 512: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 528: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 544: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 560: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 576: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 592: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 608: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 624: 30 30 30 30 30 30 30 30 30 30 1b 30 30 30 30 30 0000000000.00000
| 640: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 656: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 672: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 688: 30 30 30 30 30 30 30 30 2f 30 30 30 30 30 30 30 00000000/0000000
| 704: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 720: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 736: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 752: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 768: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 784: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 800: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 816: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 832: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 848: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 864: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 880: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 896: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 912: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 928: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 944: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 960: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 976: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 992: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 1008: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| page 3 offset 2048
| 0: 0d 00 00 00 02 03 86 00 03 f4 03 86 00 00 00 00 ................
| 896: 00 00 00 00 00 00 87 62 02 04 00 8f 48 00 d5 07 .......b....H...
| 912: 66 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 f000000000000000
| 928: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 944: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 960: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 976: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 992: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 1008: 00 00 00 08 0a 01 03 00 1a 00 01 30 03 01 02 00 ...........0....
| page 4 offset 3072
| 0: 0d 00 00 00 03 03 9e 00 03 ed 03 bc 03 9e 00 01 ................
| 912: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 1c 03 ................
| 928: 07 08 01 08 08 15 2c 02 30 20 31 36 00 01 30 03 ......,.0 16..0.
| 944: 03 02 00 00 01 61 05 03 01 01 02 00 2f 02 07 08 .....a....../...
| 960: 09 08 08 15 54 30 20 33 36 00 01 30 03 02 02 00 ....T0 36..0....
| 976: 00 01 32 05 02 01 01 03 00 00 03 61 74 65 05 02 ..2........ate..
| 992: 01 01 02 00 00 01 70 05 02 01 01 04 00 11 01 07 ......p.........
| 1008: 08 08 09 01 17 14 02 32 20 39 39 37 01 01 01 66 .......2 997...f
| page 5 offset 4096
| 0: 0a 00 00 00 03 03 ee 00 03 fb 03 f5 03 ee 00 00 ................
| 992: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 06 04 ................
| 1008: 08 01 01 02 03 05 04 08 09 01 02 04 04 08 08 09 ................
| page 6 offset 5120
| 0: 0d 00 00 00 03 03 eb 00 03 f9 03 f2 00 00 00 00 ................
| 992: 00 00 00 00 00 00 00 00 00 00 00 05 03 03 00 10 ................
| 1008: 01 01 05 02 03 00 10 01 03 05 01 03 00 10 01 01 ................
| page 7 offset 6144
| 0: 0d 00 00 00 01 03 f6 00 03 f6 00 00 00 00 00 00 ................
| 1008: 00 00 00 00 00 00 08 00 03 00 16 03 03 05 e0 07 ................
| page 8 offset 7168
| 0: 00 00 00 00 30 30 30 30 30 30 30 30 30 30 30 30 ....000000000000
| 16: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 32: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 48: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 64: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 80: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 96: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 112: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 128: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 144: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 160: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 176: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 192: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 208: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 224: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 240: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 256: 30 30 30 30 30 2f 30 30 30 30 30 30 30 30 30 30 00000/0000000000
| 272: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 288: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 304: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 320: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 336: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 352: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 368: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 384: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 400: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 416: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 432: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 448: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 464: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 480: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 496: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 512: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 528: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 544: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 560: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 576: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 592: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 608: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 624: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 640: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 656: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 672: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 688: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 704: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 720: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 736: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 752: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 768: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 784: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 800: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 816: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 832: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 848: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 864: 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 0000000000000000
| 880: 30 30 30 30 30 30 30 30 30 05 01 01 01 02 00 00 000000000.......
| end crash-365.txt.db
}]} {}
do_execsql_test 54.1 {
SELECT rowid, quote(matchinfo(t1,'pcxybspcxybs')) FROM t1 WHERE t1 MATCH'ATE"0"OR"2:P"""';
}
finish_test
+6 -2
View File
@@ -18,6 +18,10 @@ set ::testprefix fts3fault
# If SQLITE_ENABLE_FTS3 is not defined, omit this file.
ifcapable !fts3 { finish_test ; return }
set ::TMPDBERROR [list 1 \
{unable to open a temporary database file for storing temporary tables}
]
# Test error handling in the sqlite3Fts3Init() function. This is the
# function that registers the FTS3 module and various support functions
# with SQLite.
@@ -49,7 +53,7 @@ do_faultsim_test 2 -prep {
} -body {
execsql { ALTER TABLE t1 RENAME TO t2 }
} -test {
faultsim_test_result {0 {}}
faultsim_test_result {0 {}} $::TMPDBERROR
}
# Test error handling in the special case where a single prefix query
@@ -194,7 +198,7 @@ do_faultsim_test 8.2 -faults oom-t* -prep {
} -body {
execsql { SELECT mit(matchinfo(t8, 's')) FROM t8 WHERE t8 MATCH 'a b c' }
} -test {
faultsim_test_result {0 3}
faultsim_test_result {0 3} $::TMPDBERROR
}
do_faultsim_test 8.3 -prep {
faultsim_restore_and_reopen
+4 -1
View File
@@ -215,12 +215,15 @@ do_faultsim_test 8.1 -faults oom* -prep {
faultsim_test_result {0 {}}
}
set ::TMPDBERROR [list 1 \
{unable to open a temporary database file for storing temporary tables}
]
do_faultsim_test 8.2 -faults oom* -prep {
faultsim_restore_and_reopen
} -body {
execsql { ALTER TABLE t8 RENAME TO t8ii }
} -test {
faultsim_test_result {0 {}}
faultsim_test_result {0 {}} $::TMPDBERROR
}
#-------------------------------------------------------------------------
+15
View File
@@ -786,4 +786,19 @@ do_execsql_test join8-25020 {
SELECT 1 FROM t1 LEFT JOIN t2 ON true JOIN t3 ON (b2 IN (a1)) FULL JOIN t4 ON true;
} {1}
# 2022-07-13
# forum/forumpost/174afeae57
#
reset_db
db null -
do_execsql_test join8-26000 {
CREATE TABLE t1(a INT);
CREATE TABLE t2(b INT, c INT);
CREATE VIEW t3(d) AS SELECT NULL FROM t2 FULL OUTER JOIN t1 ON c=a UNION ALL SELECT b FROM t2;
INSERT INTO t1(a) VALUES (NULL);
INSERT INTO t2(b, c) VALUES (99, NULL);
SELECT DISTINCT b, c, d FROM t2, t3 WHERE b<>0
UNION SELECT DISTINCT b, c, d FROM t2, t3 WHERE b ISNULL;
} {99 - - 99 - 99}
finish_test
+18
View File
@@ -867,4 +867,22 @@ do_catchsql_test json-18.5 {
SELECT json_extract('{"":8}', '$.');
} {1 {JSON path error near ''}}
# 2022-08-29 https://sqlite.org/forum/forumpost/9b9e4716c0d7bbd1
# This is not a problem specifically with JSON functions. It is
# a problem with transaction control. But the json() function makes
# the problem more easily accessible, so it is tested here.
#
do_execsql_test json-19.1 {
DROP TABLE IF EXISTS t1;
CREATE TABLE t1(x);
} {}
do_catchsql_test json-19.2 {
BEGIN;
INSERT INTO t1 VALUES(0), (json('not-valid-json'));
} {1 {malformed JSON}}
do_execsql_test json-19.3 {
COMMIT;
SELECT * FROM t1;
} {}
finish_test
+1
View File
@@ -664,6 +664,7 @@ proc do_write_test {name tbl sql} {
if {$::DO_MALLOC_TEST } {
set answers [list {1 {out of memory}} {0 {}}]
lappend answers [list 1 {unable to open a temporary database file for storing temporary tables}]
if {$::DO_MALLOC_TEST==1} {
set modes {100000 persistent}
} else {
+2
View File
@@ -141,3 +141,5 @@ do_eqp_test 111 {
`--RIGHT
`--SCAN generate_series VIRTUAL TABLE INDEX 23:
}
finish_test
+42 -1
View File
@@ -156,6 +156,47 @@ do_execsql_test offset1-1.4.9 {
LIMIT 9 OFFSET 1;
} {2 b 3 c 4 d 5 e 6 w 7 x 8 y 9 z}
# 2022-08-04
# https://sqlite.org/forum/forumpost/6b5e9188f0657616
#
do_execsql_test offset1-2.0 {
CREATE TABLE employees (
id integer primary key,
name text,
city text,
department text,
salary integer
);
INSERT INTO employees VALUES
(11,'Diane','London','hr',70),
(12,'Bob','London','hr',78),
(21,'Emma','London','it',84),
(22,'Grace','Berlin','it',90),
(23,'Henry','London','it',104),
(24,'Irene','Berlin','it',104),
(25,'Frank','Berlin','it',120),
(31,'Cindy','Berlin','sales',96),
(32,'Dave','London','sales',96),
(33,'Alice','Berlin','sales',100);
CREATE VIEW v AS
SELECT * FROM (
SELECT * FROM employees
WHERE salary < 100
ORDER BY salary desc)
UNION ALL
SELECT * FROM (
SELECT * FROM employees
WHERE salary >= 100
ORDER BY salary asc);
} {}
do_execsql_test offset1-2.1 {
SELECT * FROM v LIMIT 5 OFFSET 2;
} {
22 Grace Berlin it 90
21 Emma London it 84
12 Bob London hr 78
11 Diane London hr 70
33 Alice Berlin sales 100
}
finish_test
+22
View File
@@ -239,4 +239,26 @@ do_execsql_test regexp1-2.22 {
SELECT 'abc$¢€xyz' REGEXP '^abc[^\u0025-X][^ -\u007f][^\u20ab]xyz$'
} {1}
# 2022-07-03
# https://sqlite.org/forum/forumpost/96692f8ba5
# The REGEXP extension mishandles the prefix search optimization when
# the prefix contains 3-byte UTF8 characters.
#
reset_db
load_static_extension db regexp
do_execsql_test regexp1-3.1 {
CREATE TABLE t1(id INTEGER PRIMARY KEY, a TEXT);
INSERT INTO t1(id, a) VALUES(1, '日本語');
SELECT a, hex(a), length(a) FROM t1;
} {日本語 E697A5E69CACE8AA9E 3}
do_execsql_test regexp1-3.2 {
SELECT * FROM t1 WHERE a='日本語';
} {1 日本語}
do_execsql_test regexp1-3.3 {
SELECT * FROM t1 WHERE a LIKE '日本語';
} {1 日本語}
do_execsql_test regexp1-3.4 {
SELECT * FROM t1 wHERE a REGEXP '日本語';
} {1 日本語}
finish_test
+394
View File
@@ -0,0 +1,394 @@
# 2017 August 9
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
# May you find forgiveness for yourself and forgive others.
# May you share freely, never taking more than you give.
#
#***********************************************************************
#
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix reuse1
ifcapable !sharedschema {
finish_test
return
}
forcedelete test.db2
sqlite3 db2 test.db2
do_execsql_test 1.0 {
CREATE TABLE t1(x INTEGER PRIMARY KEY, y UNIQUE, z);
CREATE INDEX i1 ON t1(z);
PRAGMA schema_version;
} {2}
do_execsql_test -db db2 1.1 {
CREATE TABLE t1(x INTEGER PRIMARY KEY, y UNIQUE, z);
CREATE INDEX i1 ON t1(z);
PRAGMA schema_version;
} {2}
do_test 1.2 {
db close
db2 close
sqlite3 db2 test.db2 -shared-schema 1
sqlite3 db test.db -shared-schema 1
} {}
do_execsql_test -db db2 1.3.1 {
INSERT INTO t1 VALUES(1, 2, 3);
INSERT INTO t1 VALUES(4, 5, 6);
}
do_execsql_test 1.3.2 {
SELECT * FROM t1;
PRAGMA integrity_check;
} {ok}
do_execsql_test -db db2 1.3.3 {
SELECT * FROM t1;
PRAGMA integrity_check;
} {1 2 3 4 5 6 ok}
sqlite3 db3 test.db2
do_execsql_test -db db3 1.4.1 {
ALTER TABLE t1 ADD COLUMN a;
}
do_execsql_test -db db2 1.4.2 {
SELECT * FROM t1;
} {1 2 3 {} 4 5 6 {}}
do_execsql_test 1.4.3 {
SELECT * FROM t1;
} {}
db3 close
sqlite3 db3 test.db
do_execsql_test -db db3 1.5.0 {
CREATE TRIGGER tr1 AFTER INSERT ON t1 BEGIN
SELECT 1, 2, 3;
END;
}
# Check that the schema cannot be modified if the db was opened with
# SQLITE_OPEN_REUSE_SCHEMA.
#
foreach {tn sql} {
1 { CREATE TABLE t2(x, y) }
2 { CREATE INDEX i2 ON t1(z) }
3 { CREATE VIEW v2 AS SELECT * FROM t2 }
4 { ALTER TABLE t1 RENAME TO t3 }
5 { ALTER TABLE t1 ADD COLUMN xyz }
6 { VACUUM }
7 { DROP INDEX i1 }
8 { DROP TABLE t1 }
9 { DROP TRIGGER tr1 }
10 { ANALYZE }
11 { ALTER TABLE t1 RENAME z TO zzz }
} {
do_catchsql_test 1.5.$tn $sql {1 {attempt to modify read-only schema}}
}
#-------------------------------------------------------------------------
#
reset_db
forcedelete test.db2
ifcapable fts5 {
do_execsql_test 2.0 {
CREATE VIRTUAL TABLE ft USING fts5(a);
INSERT INTO ft VALUES('one'), ('two'), ('three');
ATTACH 'test.db2' AS aux;
CREATE VIRTUAL TABLE aux.ft USING fts5(a);
INSERT INTO aux.ft VALUES('aux1'), ('aux2'), ('aux3');
}
db close
sqlite3 db test.db -shared-schema 1
do_execsql_test 2.1 {
ATTACH 'test.db2' AS aux;
SELECT * FROM main.ft;
} {one two three}
breakpoint
do_execsql_test 2.2 {
SELECT * FROM aux.ft;
} {aux1 aux2 aux3}
do_execsql_test 2.2 {
SELECT * FROM aux.ft_content;
} {1 aux1 2 aux2 3 aux3}
}
#-------------------------------------------------------------------------
#
reset_db
forcedelete test.db2
do_execsql_test 3.0 {
CREATE TABLE t1(a PRIMARY KEY, b, c);
CREATE VIEW v1 AS SELECT * FROM t1;
CREATE TRIGGER v1_ins INSTEAD OF INSERT ON v1 BEGIN
INSERT INTO t1 VALUES(new.a, new.b, new.c);
END;
CREATE TRIGGER v1_del INSTEAD OF DELETE ON v1 BEGIN
DELETE FROM t1 WHERE a=old.a;
END;
CREATE TRIGGER v1_up INSTEAD OF UPDATE ON v1 BEGIN
UPDATE t1 SET a=new.a, b=new.b, c=new.c WHERE a=old.a;
END;
}
forcecopy test.db test.db2
do_test 3.1 {
sqlite3 db2 test.db2
execsql { INSERT INTO t1 VALUES(1, 2, 3) } db
execsql { INSERT INTO t1 VALUES(4, 5, 6) } db2
db2 close
execsql { ATTACH 'test.db2' AS aux; }
} {}
do_execsql_test 3.2 {
SELECT * FROM main.v1;
} {1 2 3}
do_execsql_test 3.3 {
SELECT * FROM aux.v1;
} {4 5 6}
db close
sqlite3 db test.db -shared-schema 1
do_execsql_test 3.4 { ATTACH 'test.db2' AS aux } {}
do_execsql_test 3.5 { SELECT * FROM main.v1 } {1 2 3}
do_execsql_test 3.6 { SELECT * FROM aux.v1 } {4 5 6}
do_execsql_test 3.7.1 { INSERT INTO aux.t1 VALUES(8, 9, 10); }
do_execsql_test 3.7.2 { SELECT * FROM main.v1 } {1 2 3}
do_execsql_test 3.7.3 { SELECT * FROM aux.v1 } {4 5 6 8 9 10}
do_execsql_test 3.8.1 { DELETE FROM aux.t1 WHERE b=5 }
do_execsql_test 3.8.2 { SELECT * FROM main.v1 } {1 2 3}
do_execsql_test 3.8.3 { SELECT * FROM aux.v1 } {8 9 10}
do_execsql_test 3.9.1 { UPDATE aux.t1 SET b='abc' }
do_execsql_test 3.9.2 { SELECT * FROM main.v1 } {1 2 3}
do_execsql_test 3.9.3 { SELECT * FROM aux.v1 } {8 abc 10}
do_execsql_test 3.10.1 { INSERT INTO aux.v1 VALUES(11, 12, 13) }
do_execsql_test 3.10.2 { SELECT * FROM main.v1 } {1 2 3}
do_execsql_test 3.10.3 { SELECT * FROM aux.v1 } {8 abc 10 11 12 13}
do_execsql_test 3.11.1 { DELETE FROM aux.v1 WHERE b='abc' }
do_execsql_test 3.11.2 { SELECT * FROM main.v1 } {1 2 3}
do_execsql_test 3.11.3 { SELECT * FROM aux.v1 } {11 12 13}
do_execsql_test 3.12.1 { UPDATE aux.v1 SET b='def' }
do_execsql_test 3.12.2 { SELECT * FROM main.v1 } {1 2 3}
do_execsql_test 3.12.3 { SELECT * FROM aux.v1 } {11 def 13}
do_execsql_test 3.13.1 {
CREATE TEMP TRIGGER xyz AFTER INSERT ON aux.t1 BEGIN
INSERT INTO v1 VALUES(new.a, new.b, new.c);
END
}
do_execsql_test 3.13.2 {
INSERT INTO aux.v1 VALUES('x', 'y', 'z');
}
do_execsql_test 3.13.3 {
SELECT * FROM v1;
} {1 2 3 x y z}
#-------------------------------------------------------------------------
#
reset_db
forcedelete test.db2
do_execsql_test 4.0 {
CREATE TABLE t1(a PRIMARY KEY, b, c UNIQUE);
CREATE TABLE del(a, b, c);
CREATE TRIGGER tr1 AFTER DELETE ON t1 BEGIN
INSERT INTO del VALUES(old.a, old.b, old.c);
END;
}
forcecopy test.db test.db2
db close
sqlite3 db test.db -shared-schema 1
execsql {
ATTACH 'test.db2' AS aux;
PRAGMA recursive_triggers = 1;
}
do_execsql_test 4.1 {
INSERT INTO main.t1 VALUES(1, 2, 3);
INSERT INTO aux.t1 VALUES(4, 5, 6);
}
do_execsql_test 4.2.1 {
INSERT OR REPLACE INTO aux.t1 VALUES('a', 'b', 6);
SELECT * FROM aux.t1;
} {a b 6}
do_execsql_test 4.2.2 { SELECT * FROM aux.del } {4 5 6}
do_execsql_test 4.2.3 { SELECT * FROM main.del } {}
do_execsql_test 4.3.1 {
INSERT INTO aux.t1 VALUES('x', 'y', 'z');
UPDATE OR REPLACE aux.t1 SET c='z' WHERE a='a';
} {}
do_execsql_test 4.3.2 { SELECT * FROM aux.del } {4 5 6 x y z}
do_execsql_test 4.3.3 { SELECT * FROM main.del } {}
#-------------------------------------------------------------------------
#
reset_db
do_execsql_test 5.0 {
CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c);
CREATE TABLE t2(a INTEGER PRIMARY KEY, b, c);
CREATE INDEX i1 ON t1(b);
INSERT INTO t1 VALUES(1, 2, 3), (4, 5, 6);
ANALYZE;
PRAGMA writable_schema = 1;
DELETE FROM sqlite_stat1;
}
db close
forcecopy test.db test.db2
sqlite3 db test.db -shared-schema 1
execsql { ATTACH 'test.db2' AS aux }
foreach {tn sql} {
1 { CREATE TABLE t3(x) }
2 { DROP TABLE t2 }
3 { CREATE INDEX i2 ON t2(b) }
4 { DROP INDEX i1 }
5 { ALTER TABLE t1 ADD COLUMN d }
6 { ALTER TABLE t1 RENAME TO t3 }
7 { ALTER TABLE t1 RENAME c TO d }
} {
do_catchsql_test 5.1.$tn $sql {1 {attempt to modify read-only schema}}
}
do_execsql_test 5.2.1 { ANALYZE aux.t1 } {}
do_execsql_test 5.2.2 { SELECT * FROM aux.sqlite_stat1 } {t1 i1 {2 1}}
do_execsql_test 5.2.3 { SELECT * FROM main.sqlite_stat1 } {}
do_test 5.3.0 {
sqlite3 db2 test.db2
db2 eval {
PRAGMA writable_schema = 1;
DELETE FROM sqlite_stat1;
}
} {}
do_execsql_test 5.3.1 { SELECT * FROM aux.sqlite_stat1 } {}
do_execsql_test 5.3.2 { ANALYZE aux } {}
do_execsql_test 5.3.3 { SELECT * FROM aux.sqlite_stat1 } {t1 i1 {2 1}}
do_execsql_test 5.3.4 { SELECT * FROM main.sqlite_stat1 } {}
#-------------------------------------------------------------------------
# Attempting to run ANALYZE when the required sqlite_statXX functions
# are missing is an error (because it would modify the database schema).
#
reset_db
do_execsql_test 5.4 {
CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c);
CREATE TABLE t2(a INTEGER PRIMARY KEY, b, c);
CREATE INDEX i1 ON t1(b);
INSERT INTO t1 VALUES(1, 2, 3), (4, 5, 6);
}
db close
sqlite3 db test.db -shared-schema 1
foreach {tn sql} {
1 { ANALYZE }
2 { ANALYZE t1 }
3 { ANALYZE i1 }
4 { ANALYZE main }
5 { ANALYZE main.t1 }
6 { ANALYZE main.i1 }
} {
do_catchsql_test 5.4.$tn $sql {1 {attempt to modify read-only schema}}
}
#-------------------------------------------------------------------------
#
reset_db
do_execsql_test 6.0 {
CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c);
CREATE VIEW v1 AS SELECT * FROM t1;
}
db close
forcecopy test.db test.db2
sqlite3 db test.db -shared-schema 1
execsql { ATTACH 'test.db2' AS aux }
do_execsql_test 6.1 {
INSERT INTO main.t1(a) VALUES(1), (2), (3);
INSERT INTO aux.t1(a) VALUES(4), (5), (6);
CREATE TEMP TABLE t2(i,t);
INSERT INTO t2 VALUES(2, 'two'), (5, 'five');
}
do_execsql_test 6.2 {
SELECT t FROM t2 WHERE i IN (SELECT a FROM aux.t1)
} {five}
do_execsql_test 6.3 {
SELECT t FROM t2 WHERE i IN (SELECT a FROM aux.v1)
} {five}
#-------------------------------------------------------------------------
#
reset_db
do_execsql_test 7.0 {
CREATE TABLE p1(a PRIMARY KEY, b);
CREATE TABLE p2(a PRIMARY KEY, b);
CREATE TABLE c1(x REFERENCES p1 ON UPDATE CASCADE ON DELETE CASCADE);
}
db close
forcecopy test.db test.db2
sqlite3 db test.db -shared-schema 1
execsql { ATTACH 'test.db2' AS aux }
do_execsql_test 7.1 {
INSERT INTO aux.p1 VALUES(1, 'one');
INSERT INTO aux.p1 VALUES(2, 'two');
PRAGMA foreign_keys = on;
}
do_execsql_test 7.2 {
INSERT INTO aux.c1 VALUES(2);
}
do_execsql_test 7.3.1 {
PRAGMA foreign_keys = off;
INSERT INTO main.p2 SELECT * FROM aux.p1;
}
do_execsql_test 7.3.2 {
SELECT * FROM main.p2;
} {1 one 2 two}
do_execsql_test 7.3.3 {
INSERT INTO aux.p2 VALUES(1, 2);
}
do_execsql_test 7.3.4 {
SELECT main.p2.a FROM main.p2, aux.p2;
} {1 2}
do_execsql_test 7.3.5 {
SELECT * FROM main.p2, aux.p2;
} {1 one 1 2 2 two 1 2}
do_execsql_test 7.4 {
SELECT count(*) FROM aux.p2;
} {1}
finish_test
+336
View File
@@ -0,0 +1,336 @@
# 2017 August 9
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
# May you find forgiveness for yourself and forgive others.
# May you share freely, never taking more than you give.
#
#***********************************************************************
#
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix reuse2
ifcapable !sharedschema {
finish_test
return
}
do_execsql_test 1.0 {
CREATE TABLE t1(x INTEGER PRIMARY KEY, y UNIQUE, z);
CREATE INDEX i1 ON t1(z);
PRAGMA schema_version;
} {2}
do_test 1.2 {
catch { db close }
catch { db2 close }
sqlite3 db2 test.db -shared-schema 1
sqlite3 db test.db -shared-schema 1
} {}
do_execsql_test -db db2 1.3.1 {
INSERT INTO t1 VALUES(1, 2, 3);
}
do_execsql_test -db db2 1.3.2 {
INSERT INTO t1 VALUES(4, 5, 6);
}
do_execsql_test 1.3.3 {
SELECT * FROM t1;
} {1 2 3 4 5 6}
#--------------------------------------------------------------------------
reset_db
ifcapable fts5 {
do_execsql_test 2.0 {
CREATE VIRTUAL TABLE ft USING fts5(c);
INSERT INTO ft VALUES('one two three');
}
db close
sqlite3 db test.db -shared-schema 1
do_execsql_test 2.1 {
SELECT * FROM ft
} {{one two three}}
}
#--------------------------------------------------------------------------
reset_db
do_execsql_test 3.0 {
CREATE TABLE t1(x INTEGER PRIMARY KEY, y UNIQUE, z);
CREATE INDEX i1 ON t1(z);
PRAGMA schema_version;
} {2}
do_test 3.1 {
sqlite3 db1 test.db -shared-schema 1
sqlite3 db2 test.db -shared-schema 1
} {}
do_execsql_test -db db1 3.2.1 { SELECT * FROM t1 }
do_execsql_test -db db2 3.2.2 { SELECT * FROM t1 }
register_schemapool_module db
do_execsql_test 3.3 {
SELECT 'nref=' || nRef, 'nschema=' || nSchema, 'ndelete=' || nDelete
FROM schemapool;
} {nref=2 nschema=1 ndelete=0}
sqlite3 db3 test.db -shared-schema 1
register_schemapool_module db3
do_execsql_test 3.5 {
SELECT 'nref=' || nRef, 'nschema=' || nSchema, 'ndelete=' || nDelete
FROM schemapool;
} {nref=2 nschema=1 ndelete=0}
do_execsql_test -db db3 3.6 {
SELECT * FROM t1;
SELECT 'nref=' || nRef, 'nschema=' || nSchema, 'ndelete=' || nDelete
FROM schemapool;
} {nref=3 nschema=1 ndelete=0}
do_execsql_test 3.7 {
CREATE TABLE t2(x);
}
do_execsql_test 3.8 {
SELECT 'nref=' || nRef, 'nschema=' || nSchema, 'ndelete=' || nDelete
FROM schemapool;
} {nref=3 nschema=1 ndelete=0}
do_execsql_test -db db1 3.9.1 { SELECT * FROM t1 }
do_execsql_test 3.9.2 {
SELECT 'nref=' || nRef, 'nschema=' || nSchema, 'ndelete=' || nDelete
FROM schemapool;
} {nref=1 nschema=1 ndelete=0 nref=2 nschema=1 ndelete=0}
do_execsql_test -db db2 3.10.1 { SELECT * FROM t1 }
do_execsql_test 3.10.2 {
SELECT 'nref=' || nRef, 'nschema=' || nSchema, 'ndelete=' || nDelete
FROM schemapool ORDER BY 1;
} {nref=1 nschema=1 ndelete=0 nref=2 nschema=1 ndelete=0}
do_execsql_test -db db3 3.11.1 { SELECT * FROM t1 }
do_execsql_test 3.11.2 {
SELECT 'nref=' || nRef, 'nschema=' || nSchema, 'ndelete=' || nDelete
FROM schemapool;
} {nref=3 nschema=1 ndelete=0}
#--------------------------------------------------------------------------
catch {db1 close}
catch {db2 close}
catch {db3 close}
reset_db
do_execsql_test 4.0.1 {
CREATE TABLE x1(a, b, c);
CREATE INDEX x1a ON x1(a);
CREATE INDEX x1b ON x1(b);
}
do_test 4.0.2 {
db close
for {set i 1} {$i < 6} {incr i} {
forcedelete test.db${i}-journal test.db${i}-wal test.db${i}-wal2
forcecopy test.db test.db${i}
}
sqlite3 db test.db
sqlite3 db2 test.db -shared-schema 1
} {}
register_schemapool_module db
do_execsql_test 4.0.3 {
SELECT 'nref=' || nRef, 'nschema=' || nSchema, 'ndelete=' || nDelete
FROM schemapool;
} {}
do_test 4.1.1 {
execsql {
ATTACH 'test.db1' AS db1;
ATTACH 'test.db2' AS db2;
ATTACH 'test.db3' AS db3;
ATTACH 'test.db4' AS db4;
ATTACH 'test.db5' AS db5;
} db2
} {}
do_execsql_test 4.1.2 {
SELECT 'nref=' || nRef, 'nschema=' || nSchema, 'ndelete=' || nDelete
FROM schemapool;
} {}
do_execsql_test -db db2 4.1.3 {
SELECT * FROM db3.x1
}
do_execsql_test 4.1.4 {
SELECT 'nref=' || nRef, 'nschema=' || nSchema, 'ndelete=' || nDelete
FROM schemapool;
} {nref=1 nschema=1 ndelete=0}
do_execsql_test -db db2 4.1.5 {
SELECT * FROM db2.x1
}
do_execsql_test 4.1.6 {
SELECT 'nref=' || nRef, 'nschema=' || nSchema, 'ndelete=' || nDelete
FROM schemapool;
} {nref=2 nschema=1 ndelete=0}
do_execsql_test -db db2 4.1.7 {
SELECT * FROM x1
}
do_execsql_test 4.1.8 {
SELECT 'nref=' || nRef, 'nschema=' || nSchema, 'ndelete=' || nDelete
FROM schemapool;
} {nref=6 nschema=1 ndelete=0}
do_test 4.2.1 {
catchsql { SELECT * FROM abc } db2
} {1 {no such table: abc}}
do_execsql_test 4.2.2 {
SELECT 'nref=' || nRef, 'nschema=' || nSchema, 'ndelete=' || nDelete
FROM schemapool;
} {nref=6 nschema=1 ndelete=0}
register_schemapool_module db2
do_execsql_test -db db2 4.3.1 {
INSERT INTO x1 VALUES(1, 2, 3);
INSERT INTO db1.x1 VALUES(4, 5, 6);
INSERT INTO db2.x1 VALUES(7, 8, 9);
INSERT INTO db3.x1 VALUES(10, 11, 12);
INSERT INTO db4.x1 VALUES(13, 14, 15);
INSERT INTO db5.x1 VALUES(16, 17, 18);
SELECT 'nref=' || nRef, 'nschema=' || nSchema, 'ndelete=' || nDelete
FROM schemapool;
} {nref=6 nschema=1 ndelete=0}
do_execsql_test -db db2 4.3.2 {
SELECT * FROM db5.x1;
SELECT * FROM db4.x1;
SELECT * FROM db3.x1;
SELECT * FROM db2.x1;
SELECT * FROM db1.x1;
SELECT * FROM x1;
SELECT 'nref=' || nRef, 'nschema=' || nSchema, 'ndelete=' || nDelete
FROM schemapool;
} {
16 17 18 13 14 15 10 11 12 7 8 9 4 5 6 1 2 3
nref=6 nschema=1 ndelete=0
}
do_execsql_test -db db2 4.3.3 {
UPDATE x1 SET a=a+10;
UPDATE db5.x1 SET a=a+10;
SELECT 'nref=' || nRef, 'nschema=' || nSchema, 'ndelete=' || nDelete
FROM schemapool;
} {
nref=6 nschema=1 ndelete=0
}
do_execsql_test -db db2 4.3.4 {
SELECT * FROM db5.x1;
SELECT * FROM db4.x1;
SELECT * FROM db3.x1;
SELECT * FROM db2.x1;
SELECT * FROM db1.x1;
SELECT * FROM x1;
SELECT 'nref=' || nRef, 'nschema=' || nSchema, 'ndelete=' || nDelete
FROM schemapool;
} {
26 17 18 13 14 15 10 11 12 7 8 9 4 5 6 11 2 3
nref=6 nschema=1 ndelete=0
}
do_execsql_test -db db2 4.3.5 {
DELETE FROM db3.x1;
DELETE FROM x1;
SELECT 'nref=' || nRef, 'nschema=' || nSchema, 'ndelete=' || nDelete
FROM schemapool;
} {
nref=6 nschema=1 ndelete=0
}
do_execsql_test -db db2 4.3.6 {
SELECT * FROM db5.x1;
SELECT * FROM db4.x1;
SELECT * FROM db3.x1;
SELECT * FROM db2.x1;
SELECT * FROM db1.x1;
SELECT * FROM x1;
SELECT 'nref=' || nRef, 'nschema=' || nSchema, 'ndelete=' || nDelete
FROM schemapool;
} {
26 17 18 13 14 15 7 8 9 4 5 6
nref=6 nschema=1 ndelete=0
}
do_execsql_test -db db2 4.3.6 {
SELECT * FROM db5.x1, db4.x1, db1.x1;
SELECT 'nref=' || nRef, 'nschema=' || nSchema, 'ndelete=' || nDelete
FROM schemapool;
} {26 17 18 13 14 15 4 5 6 nref=6 nschema=3 ndelete=0}
#--------------------------------------------------------------------------
# Test the incremental-blob API with REUSE_SCHEMA connections.
#
catch {db1 close}
catch {db2 close}
catch {db3 close}
reset_db
do_execsql_test 5.0.1 {
CREATE TABLE bbb(a INTEGER PRIMARY KEY, b);
}
db close
do_test 5.0.2 {
sqlite3 db2 test.db -shared-schema 1
register_schemapool_module db2
for {set i 1} {$i<6} {incr i} {
forcedelete test.db${i}-journal test.db${i}-wal test.db${i}-wal2
forcecopy test.db test.db${i}
sqlite3 db test.db${i}
db eval { INSERT INTO bbb VALUES(123, 'database_' || $i) }
db close
db2 eval "ATTACH 'test.db${i}' AS db${i}"
}
execsql {
SELECT 'nref=' || nRef, 'nschema=' || nSchema, 'ndelete=' || nDelete
FROM schemapool;
} db2
} {nref=6 nschema=1 ndelete=0}
do_test 5.1.1 {
set res [list]
for {set i 1} {$i<6} {incr i} {
set chan [db2 incrblob db${i} bbb b 123]
lappend res [gets $chan]
close $chan
}
set res
} {database_1 database_2 database_3 database_4 database_5}
do_execsql_test -db db2 5.1.2 {
SELECT 'nref=' || nRef, 'nschema=' || nSchema, 'ndelete=' || nDelete
FROM schemapool;
} {nref=6 nschema=1 ndelete=0}
do_test 5.2.1 {
sqlite3_table_column_metadata db2 main bbb a
} {INTEGER BINARY 0 1 0}
do_test 5.2.2 {
sqlite3_table_column_metadata db2 main bbb b
} {{} BINARY 0 0 0}
do_execsql_test -db db2 5.2.3 {
SELECT 'nref=' || nRef, 'nschema=' || nSchema, 'ndelete=' || nDelete
FROM schemapool;
} {nref=6 nschema=1 ndelete=0}
do_execsql_test -db db2 5.2.4 {
PRAGMA integrity_check;
SELECT 'nref=' || nRef, 'nschema=' || nSchema, 'ndelete=' || nDelete
FROM schemapool;
} {ok nref=6 nschema=1 ndelete=5}
finish_test
+355
View File
@@ -0,0 +1,355 @@
# 2019 February 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.
#
#***********************************************************************
#
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix reuse3
ifcapable !sharedschema {
finish_test
return
}
do_execsql_test 1.0 {
CREATE TABLE t1(x INTEGER PRIMARY KEY, y UNIQUE, z);
CREATE INDEX i1 ON t1(z);
CREATE TABLE t2(a);
} {}
db close
sqlite3 db test.db -shared-schema 1
do_execsql_test 1.1 {
CREATE TEMP VIEW v1 AS SELECT * FROM t1;
SELECT * FROM v1;
}
do_execsql_test 1.2 {
CREATE TEMP TRIGGER tr1 AFTER INSERT ON t1 BEGIN
INSERT INTO t2 VALUES(new.x);
END;
}
do_execsql_test 1.3 {
INSERT INTO t1 VALUES(1, 2, 3);
}
do_execsql_test 1.4 {
SELECT * FROM t2
} {1}
do_execsql_test 1.5 {
SELECT * FROM v1
} {1 2 3}
do_execsql_test 1.6 {
BEGIN;
DROP TRIGGER tr1;
ROLLBACK;
}
do_execsql_test 1.7 {
SELECT * FROM v1
} {1 2 3}
do_execsql_test 1.8 {
INSERT INTO t1 VALUES(4, 5, 6);
SELECT * FROM t2
} {1 4}
do_execsql_test 1.9 {
SELECT * FROM v1
} {1 2 3 4 5 6}
#-------------------------------------------------------------------------
# Test error messages when parsing the schema with a REUSE_SCHEMA
# connection.
reset_db
do_execsql_test 2.0 {
CREATE TABLE x1(a, b, c);
CREATE TABLE y1(d, e, f);
PRAGMA writable_schema = 1;
UPDATE sqlite_master SET sql = 'CREATE TBL y1(d, e, f)' WHERE name = 'y1';
}
db close
sqlite3 db test.db -shared-schema 1
do_catchsql_test 2.1 {
SELECT * FROM x1;
} {1 {malformed database schema (y1) - near "TBL": syntax error}}
do_catchsql_test 2.2 {
SELECT * FROM x1;
} {1 {malformed database schema (y1) - near "TBL": syntax error}}
#-------------------------------------------------------------------------
reset_db
do_execsql_test 3.0 {
CREATE TABLE x1(a, b, c);
CREATE INDEX i1 ON x1(a, b, c);
CREATE TRIGGER tr1 AFTER INSERT ON x1 BEGIN
SELECT 1, 2, 3, 4, 5;
END;
INSERT INTO x1 VALUES(1, 2, 3);
}
sqlite3 db1 test.db -shared-schema 1
do_test 3.1 {
execsql { SELECT * FROM x1 } db1
set N [lindex [sqlite3_db_status db1 SCHEMA_USED 0] 1]
expr $N==$N
} 1
sqlite3 db2 test.db -shared-schema 1
do_test 3.2 {
execsql { SELECT * FROM x1 } db2
set N2 [lindex [sqlite3_db_status db2 SCHEMA_USED 0] 1]
expr $N2>($N/2) && $N2<($N/2)+400
} 1
sqlite3 db3 test.db -shared-schema 1
sqlite3 db4 test.db -shared-schema 1
do_test 3.3 {
execsql { SELECT * FROM x1 } db3
execsql { SELECT * FROM x1 } db4
set N4 [lindex [sqlite3_db_status db2 SCHEMA_USED 0] 1]
set M [expr 2*($N-$N2)]
set {} {}
} {}
do_test 3.3.1 { expr {(($M / 4) + $N-$M)} } "#/$N4/"
catch { db1 close }
catch { db2 close }
catch { db3 close }
catch { db4 close }
#-------------------------------------------------------------------------
# 4.1 Test the REINDEX command.
# 4.2 Test CREATE TEMP ... commands.
#
reset_db
do_execsql_test 4.1.0 {
CREATE TABLE x1(a, b, c);
CREATE INDEX x1a ON x1(a);
CREATE INDEX x1b ON x1(b);
CREATE INDEX x1c ON x1(c);
}
db close
sqlite3 db test.db -shared-schema 1
do_execsql_test 4.1.1 {
REINDEX x1;
REINDEX x1a;
REINDEX x1b;
REINDEX x1c;
REINDEX;
}
do_test 4.1.2 {
for {set i 1} {$i < 5} {incr i} {
forcedelete test.db${i} test.db${i}-wal test.db${i}-journal
forcecopy test.db test.db${i}
execsql "ATTACH 'test.db${i}' AS db${i}"
}
register_schemapool_module db
set {} {}
execsql {
SELECT 'nref=' || nRef, 'nschema=' || nSchema, 'ndelete=' || nDelete
FROM schemapool
}
} {nref=5 nschema=1 ndelete=0}
do_execsql_test 4.1.3 {
REINDEX x1;
REINDEX x1a;
REINDEX x1b;
REINDEX x1c;
REINDEX db1.x1a;
REINDEX db2.x1b;
REINDEX db3.x1c;
}
do_execsql_test 4.1.4 {
SELECT 'nref=' || nRef, 'nschema=' || nSchema, 'ndelete=' || nDelete
FROM schemapool
} {nref=5 nschema=1 ndelete=28}
#-------------------------------------------------------------------------
db close
sqlite3 db test.db -shared-schema 1
register_schemapool_module db
do_execsql_test 4.2.0 {
ATTACH 'test.db1' AS db1;
ATTACH 'test.db2' AS db2;
ATTACH 'test.db3' AS db3;
ATTACH 'test.db4' AS db4;
SELECT * FROM db1.x1;
SELECT * FROM db2.x1;
SELECT * FROM db3.x1;
SELECT * FROM db4.x1;
}
do_execsql_test 4.2.1 {
SELECT 'nref=' || nRef, 'nschema=' || nSchema, 'ndelete=' || nDelete
FROM schemapool;
} {nref=5 nschema=1 ndelete=0}
do_execsql_test 4.2.2 {
CREATE TEMP TABLE t1(a, b, c);
SELECT 'nref=' || nRef, 'nschema=' || nSchema, 'ndelete=' || nDelete
FROM schemapool;
} {nref=5 nschema=1 ndelete=0}
do_execsql_test 4.2.3 {
CREATE INDEX t1a ON t1(a);
SELECT 'nref=' || nRef, 'nschema=' || nSchema, 'ndelete=' || nDelete
FROM schemapool;
} {nref=5 nschema=1 ndelete=0}
do_execsql_test 4.2.4 {
CREATE TRIGGER tr1 AFTER INSERT ON t1 BEGIN
SELECT 1,2,3,4;
END;
SELECT 'nref=' || nRef, 'nschema=' || nSchema, 'ndelete=' || nDelete
FROM schemapool;
} {nref=5 nschema=1 ndelete=0}
do_execsql_test 4.2.5 {
DROP TABLE t1;
SELECT 'nref=' || nRef, 'nschema=' || nSchema, 'ndelete=' || nDelete
FROM schemapool;
} {nref=5 nschema=1 ndelete=0}
do_execsql_test 4.2.6 {
CREATE TEMP TRIGGER tr1 AFTER INSERT ON db2.x1 BEGIN
SELECT 1,2,3,4;
END;
SELECT 'nref=' || nRef, 'nschema=' || nSchema, 'ndelete=' || nDelete
FROM schemapool;
} {nref=5 nschema=1 ndelete=0}
do_execsql_test 4.2.7 {
DROP TRIGGER tr1;
SELECT 'nref=' || nRef, 'nschema=' || nSchema, 'ndelete=' || nDelete
FROM schemapool;
} {nref=5 nschema=1 ndelete=4}
#--------------------------------------------------------------------------
reset_db
do_execsql_test 5.0 {
CREATE TABLE t1(a, b);
CREATE TABLE t2(a, b);
CREATE TABLE t3(a, b);
}
sqlite3 db2 test.db -shared-schema 1
register_schemapool_module db2
do_execsql_test 5.1 {
PRAGMA writable_schema = 1;
UPDATE sqlite_master SET sql='CREATE TABLE t3 a,b' WHERE name = 't3';
}
do_test 5.2 {
catchsql { SELECT * FROM t1 } db2
} {1 {malformed database schema (t3) - near "a": syntax error}}
do_test 5.3 {
catchsql { SELECT nref,nschema FROM schemapool } db2
} {1 {vtable constructor failed: schemapool}}
do_execsql_test 5.4 {
PRAGMA writable_schema = 1;
UPDATE sqlite_master SET sql='CREATE TABLE t3(a,b)' WHERE name = 't3';
}
do_test 5.5 {
catchsql { SELECT nref,nschema FROM schemapool } db2
} {0 {1 1}}
db2 close
db close
do_test 5.6.1 {
forcedelete test.db2 test.db2-wal test.db2-journal
forcecopy test.db test.db2
sqlite3 db test.db
sqlite3 db2 test.db -shared-schema 1
sqlite3 db3 test.db2 -shared-schema 1
register_schemapool_module db
} {}
do_execsql_test -db db2 5.6.2 { SELECT * FROM t1 }
do_execsql_test -db db3 5.6.3 { SELECT * FROM t1 }
do_execsql_test 5.6.4 {
SELECT 'nref=' || nRef, 'nschema=' || nSchema FROM schemapool;
CREATE TABLE t4(x);
DROP TABLE t4;
} {nref=2 nschema=1}
do_execsql_test -db db2 5.6.5 { SELECT * FROM t1 }
do_execsql_test -db db3 5.6.6 { SELECT * FROM t1 }
do_execsql_test 5.6.7 {
SELECT 'nref=' || nRef, 'nschema=' || nSchema FROM schemapool;
ATTACH 'test.db2' AS db2;
CREATE TABLE db2.t4(x);
DROP TABLE db2.t4;
} {nref=1 nschema=1 nref=1 nschema=1}
do_execsql_test -db db2 5.6.8 { SELECT * FROM t1 }
do_execsql_test -db db3 5.6.9 { SELECT * FROM t1 }
do_execsql_test 5.6.10 {
SELECT 'nref=' || nRef, 'nschema=' || nSchema FROM schemapool;
} {nref=2 nschema=1}
#-------------------------------------------------------------------------
reset_db
do_execsql_test 6.0 {
CREATE TABLE t1(a, b);
CREATE TABLE t2(a, b);
CREATE TABLE t3(a, b);
}
do_test 6.1 {
db close
sqlite3 db test.db -shared-schema 1
for {set i 1} {$i < 5} {incr i} {
set base "test.db$i"
set nm "aux$i"
forcedelete $base $base-wal $base-journal
forcecopy test.db $base
execsql "ATTACH '$base' AS $nm"
}
} {}
do_test 6.2 {
set N1 [lindex [sqlite3_db_status db SCHEMA_USED 0] 1]
set N2 [lindex [sqlite3_db_status db SCHEMA_USED 0] 1]
expr ($N1==0 && $N2==0)
} {1}
do_test 6.3 {
execsql { SELECT * FROM main.t1 }
set N1 [lindex [sqlite3_db_status db SCHEMA_USED 0] 1]
set N2 [lindex [sqlite3_db_status db SCHEMA_USED 0] 1]
expr {$N1>0 && $N2>0 && $N1==$N2}
} {1}
do_test 6.4 {
execsql { SELECT * FROM aux1.t1 }
set N3 [lindex [sqlite3_db_status db SCHEMA_USED 0] 1]
set N4 [lindex [sqlite3_db_status db SCHEMA_USED 0] 1]
list $N3 $N4
} "#/$N1 $N1/"
finish_test
+173
View File
@@ -0,0 +1,173 @@
# 2019 February 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.
#
#***********************************************************************
#
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix reuse4
ifcapable !sharedschema {
finish_test
return
}
foreach {tn sharedschema} {
1 0
2 1
} {
reset_db
do_execsql_test 1.$tn.0 {
CREATE TABLE x1(a, b);
CREATE INDEX x1a ON x1(a);
CREATE INDEX x1b ON x1(b);
CREATE TABLE x2(a, b);
}
db close
do_test 1.$tn.1 {
for {set i 1} {$i<4} {incr i} {
forcedelete test.db$i test.db$i-journal test.db$i-wal
forcecopy test.db test.db$i
}
sqlite3 db test.db -shared-schema $sharedschema
for {set i 1} {$i<4} {incr i} {
execsql " ATTACH 'test.db$i' AS db$i "
}
} {}
do_execsql_test 1.$tn.2 {
WITH s(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<10 )
INSERT INTO x1 SELECT i, i FROM s;
INSERT INTO db3.x2 SELECT * FROM x1;
INSERT INTO db2.x1 SELECT * FROM db3.x2;
CREATE TEMP TRIGGER tr1 AFTER INSERT ON db2.x2 BEGIN
INSERT INTO x1 VALUES(new.a, new.b);
END;
INSERT INTO db2.x2 SELECT * FROM x1 WHERE a%2;
DELETE FROM x1 WHERE a<3;
INSERT INTO db3.x1 SELECT * FROM db2.x2;
DETACH db3;
ATTACH 'test.db3' AS db3;
UPDATE db3.x1 SET a=a-10 WHERE b NOT IN (SELECT b FROM db2.x2);
CREATE TEMP TABLE x1(a, b);
INSERT INTO db2.x2 VALUES(50, 60), (60, 70), (80, 90);
ALTER TABLE x1 RENAME TO x2;
ALTER TABLE x2 ADD COLUMN c;
ALTER TABLE x2 RENAME a TO aaa;
DELETE FROM x1 WHERE b>8;
UPDATE db3.x2 SET b=b*10;
BEGIN;
CREATE TEMP TABLE x5(x);
INSERT INTO x5 VALUES(1);
ROLLBACK;
INSERT INTO main.x2 VALUES(123, 456);
}
integrity_check 1.$tn.3
do_execsql_test 1.$tn.4 {
SELECT * FROM main.x1; SELECT 'xxx';
SELECT * FROM main.x2; SELECT 'xxx';
SELECT * FROM temp.x2; SELECT 'xxx';
SELECT * FROM db1.x1; SELECT 'xxx';
SELECT * FROM db1.x2; SELECT 'xxx';
SELECT * FROM db2.x1; SELECT 'xxx';
SELECT * FROM db2.x2; SELECT 'xxx';
SELECT * FROM db3.x1; SELECT 'xxx';
SELECT * FROM db3.x2; SELECT 'xxx';
} {
3 3 4 4 5 5 6 6 7 7 8 8 3 3 5 5 7 7 xxx
123 456 xxx
50 60 {} 60 70 {} 80 90 {} xxx
xxx
xxx
1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 10 10 xxx
1 1 3 3 5 5 7 7 9 9 50 60 60 70 80 90 xxx
1 1 3 3 5 5 7 7 9 9 xxx
1 10 2 20 3 30 4 40 5 50 6 60 7 70 8 80 9 90 10 100 xxx
}
do_test 1.$tn.5.1 {
sqlite3 db2 test.db
db2 eval { CREATE TABLE x3(x) }
} {}
do_execsql_test 1.$tn.5.2 {
SELECT * FROM main.x1; SELECT 'xxx';
SELECT * FROM main.x2; SELECT 'xxx';
SELECT * FROM main.x3; SELECT 'xxx';
} {
3 3 4 4 5 5 6 6 7 7 8 8 3 3 5 5 7 7 xxx
123 456 xxx
xxx
}
}
#-------------------------------------------------------------------------
# Test some PRAGMA statements with shared-schema connections.
#
reset_db
do_execsql_test 2.0 {
CREATE TABLE t1(a, b, c);
CREATE INDEX t1abc ON t1(a, b, c);
}
foreach {tn pragma nSchema nDelete} {
1 "PRAGMA synchronous = OFF" 1 0
2 "PRAGMA cache_size = 200" 1 0
3 "PRAGMA aux2.integrity_check" 1 0
4 "PRAGMA integrity_check" 1 5
5 "PRAGMA index_info=t1abc" 1 5
6 "PRAGMA aux3.index_info=t1abc" 1 0
7 "PRAGMA journal_mode" 1 0
8 "PRAGMA aux2.wal_checkpoint" 1 0
9 "PRAGMA wal_checkpoint" 1 0
} {
do_test 2.$tn.1 {
catch { db close }
catch { db2 close }
for {set i 1} {$i < 6} {incr i} {
forcedelete "test.db$i" "test.db${i}-wal" "test.db${i}-journal"
forcecopy test.db test.db$i
}
sqlite3 db2 test.db -shared-schema 1
for {set i 1} {$i < 6} {incr i} {
execsql "ATTACH 'test.db$i' AS aux$i" db2
}
} {}
sqlite3 db test.db
register_schemapool_module db
do_test 2.$tn.2 {
execsql $pragma db2
execsql { SELECT 'nschema='||nschema, 'ndelete='||nDelete FROM schemapool }
} "nschema=$nSchema ndelete=$nDelete"
do_test 2.$tn.3 {
execsql {
SELECT * FROM main.t1,aux1.t1,aux2.t1,aux3.t1,aux4.t1,aux5.t1
} db2
execsql { SELECT 'nschema=' || nschema, 'nref=' || nref FROM schemapool }
} "nschema=6 nref=6"
}
finish_test
+125
View File
@@ -0,0 +1,125 @@
# 2019 February 26
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
# May you find forgiveness for yourself and forgive others.
# May you share freely, never taking more than you give.
#
#***********************************************************************
#
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix reuse5
set CLI [test_find_cli]
ifcapable !sharedschema {
finish_test
return
}
do_execsql_test 1.0 {
CREATE TABLE t1(x, y);
CREATE TABLE t2(a, b, c);
CREATE INDEX t1x ON t1(x);
CREATE INDEX t1y ON t1(y);
CREATE VIEW v1 AS SELECT * FROM t2;
}
foreach {tn sql out1 out2} {
1 {
CREATE TABLE t1(x, y);
CREATE TABLE t2(a, b, c);
CREATE INDEX t1x ON t1(x);
CREATE INDEX t1y ON t1(y);
CREATE VIEW v1 AS SELECT * FROM t2;
} {
test.db2 is compatible
} {}
2 {
CREATE TABLE t1(x, y);
CREATE TABLE t2(a, b, c);
CREATE INDEX t1x ON t1(x);
CREATE INDEX t1y ON t1(y);
CREATE VIEW v1 AS SELECT * FROM t2;
CREATE TABLE x1(x);
DROP TABLE x1;
} {
test.db2 is NOT compatible (schema cookie)
} {
Fixing test.db2... test.db2 is compatible
}
3 {
CREATE TABLE t1(x, y);
CREATE TABLE t2(a, b, c);
CREATE INDEX t1y ON t1(y);
CREATE VIEW v1 AS SELECT * FROM t2;
} {
test.db2 is NOT compatible (objects)
} {}
4 {
CREATE TABLE t1(x, y);
CREATE TABLE t2(a, b, c);
CREATE INDEX t1x ON t1(X);
CREATE INDEX t1y ON t1(y);
CREATE VIEW v1 AS SELECT * FROM t2;
} {
test.db2 is NOT compatible (SQL)
} {}
5 {
CREATE TABLE t1(x, y);
CREATE TABLE t2(a, b, c);
CREATE INDEX t1y ON t1(y);
CREATE INDEX t1x ON t1(x);
CREATE VIEW v1 AS SELECT * FROM t2;
} {
test.db2 is NOT compatible (root pages)
} {
Fixing test.db2... test.db2 is compatible
}
6 {
CREATE TABLE t1(x, y);
CREATE TABLE t2(a, b, c);
CREATE INDEX t1x ON t1(x);
CREATE INDEX t1y ON t1(y);
CREATE VIEW v1 AS SELECT * FROM t2;
DROP INDEX t1x;
CREATE INDEX t1x ON t1(x);
} {
test.db2 is NOT compatible (order of sqlite_master rows)
} {
Fixing test.db2... test.db2 is compatible
}
} {
forcedelete test.db2
sqlite3 db2 test.db2
db2 eval $sql
db2 close
if {$out2==""} {set out2 $out1}
do_test 1.$tn.1 {
catchcmd test.db ".shared-schema check test.db2"
} [list 0 [string trim $out1]]
do_test 1.$tn.2 {
catchcmd test.db ".shared-schema fix test.db2"
} [list 0 [string trim $out2]]
do_test 1.$tn.3 {
catchcmd test.db2 "PRAGMA integrity_check"
} [list 0 ok]
}
finish_test
+143
View File
@@ -0,0 +1,143 @@
# 2019 February 26
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
# May you find forgiveness for yourself and forgive others.
# May you share freely, never taking more than you give.
#
#***********************************************************************
#
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix reuse6
ifcapable !sharedschema {
finish_test
return
}
do_execsql_test 1.0 {
CREATE TABLE t1(x, y);
CREATE TABLE t2(a, b, c);
CREATE INDEX t1x ON t1(x);
CREATE INDEX t1y ON t1(y);
CREATE VIEW v1 AS SELECT * FROM t2;
INSERT INTO t1 VALUES(1, 2), (3, 4), (5, 6);
INSERT INTO t2 VALUES('a', 'b', 'c'), ('d', 'e', 'f'), ('g', 'h', 'i');
ATTACH 'test.db2' AS aux;
CREATE TABLE t3(i, ii);
INSERT INTO t3 VALUES(10, 20);
}
sqlite3 db1 test.db -shared-schema 1
sqlite3 db2 test.db -shared-schema 1
do_execsql_test -db db1 1.1 {
ATTACH 'test.db2' AS aux;
}
do_test 1.2 {
execsql {SELECT * FROM t3} db1
} {10 20}
do_execsql_test -db db2 1.3 {
ATTACH 'test.db2' AS aux;
}
do_test 1.3 {
execsql {SELECT * FROM t3} db1
} {10 20}
do_execsql_test -db db2 1.5 {
SELECT * FROM t3;
} {10 20}
do_test 1.6 {
execsql {SELECT * FROM t3} db1
} {10 20}
db1 close
db2 close
#-------------------------------------------------------------------------
reset_db
forcedelete test.db2
forcedelete test.db3
do_execsql_test 2.0 {
CREATE TABLE t1(x, y);
ATTACH 'test.db2' AS aux2;
CREATE TABLE aux2.t2(x, y);
ATTACH 'test.db3' AS aux3;
CREATE TABLE aux3.t3(x, y);
}
sqlite3 db1 test.db -shared-schema 1
do_execsql_test -db db1 2.1 {
ATTACH 'test.db2' AS aux2;
ATTACH 'test.db3' AS aux3;
}
do_test 2.2.1 {
catchsql { SELECT * FROM aux2.nosuchtable } db1
} {1 {no such table: aux2.nosuchtable}}
do_test 2.2.2 {
sqlite3_errcode db1
} {SQLITE_ERROR}
db1 close
#-------------------------------------------------------------------------
reset_db
forcedelete test.db2
ifcapable fts5 {
do_execsql_test 3.0 {
CREATE VIRTUAL TABLE ft USING fts5(a, b);
ATTACH 'test.db2' AS aux;
CREATE TABLE aux.t1(x, y, z);
}
sqlite3 db1 test.db -shared-schema 1
do_execsql_test -db db1 3.1 {
ATTACH 'test.db2' AS aux;
}
do_execsql_test -db db1 3.2 {
SELECT * FROM main.ft, aux.t1;
}
db1 close
}
#-------------------------------------------------------------------------
reset_db
forcedelete test.db2
ifcapable fts5 {
do_execsql_test 4.0 {
CREATE VIRTUAL TABLE ft USING fts5(a, b);
}
forcecopy test.db test.db2
sqlite3 db1 test.db -shared-schema 1
do_execsql_test -db db1 4.1 {
ATTACH 'test.db2' AS aux;
SELECT * FROM main.ft;
SELECT * FROM aux.ft;
}
do_execsql_test -db db1 4.2 {
SELECT * FROM main.ft, aux.ft
}
}
finish_test
+54
View File
@@ -0,0 +1,54 @@
# 2019 February 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.
#
#***********************************************************************
#
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix reusefault
ifcapable !sharedschema {
finish_test
return
}
do_execsql_test 1.0 {
PRAGMA cache_size = 10;
CREATE TABLE t1(a UNIQUE, b UNIQUE);
INSERT INTO t1 VALUES(1, 2), (3, 4);
}
faultsim_save_and_close
do_faultsim_test 1.1 -prep {
faultsim_restore
sqlite3 db test.db -shared-schema 1
} -body {
execsql { SELECT * FROM t1 }
} -test {
faultsim_test_result {0 {1 2 3 4}}
}
do_faultsim_test 1.2 -prep {
faultsim_restore
sqlite3 db test.db -shared-schema 1
execsql { SELECT * FROM t1 }
sqlite3 db2 test.db
db2 eval {CREATE TABLE a(a)}
db2 close
} -body {
execsql { SELECT * FROM t1 }
} -test {
faultsim_test_result {0 {1 2 3 4}}
}
finish_test
+31
View File
@@ -751,4 +751,35 @@ do_execsql_test 32.1 {
WHERE a=1234 OR a<=567;
} {500 502}
# 2022-07-15
# https://sqlite.org/forum/forumpost/3607259d3c
#
reset_db
do_execsql_test 33.1 {
CREATE TABLE t1(a INT, b INT PRIMARY KEY) WITHOUT ROWID;
INSERT INTO t1(a, b) VALUES (0, 1),(15,-7),(3,100);
ANALYZE;
} {}
do_execsql_test 33.2 {
SELECT * FROM t1 WHERE (b,a) BETWEEN (0,5) AND (99,-2);
} {0 1}
do_execsql_test 33.3 {
SELECT * FROM t1 WHERE (b,a) BETWEEN (-8,5) AND (0,-2);
} {15 -7}
do_execsql_test 33.3 {
SELECT * FROM t1 WHERE (b,a) BETWEEN (3,5) AND (100,4);
} {3 100}
do_execsql_test 33.3 {
SELECT * FROM t1 WHERE (b,a) BETWEEN (3,5) AND (100,2);
} {}
do_execsql_test 33.3 {
SELECT * FROM t1 WHERE (a,b) BETWEEN (-2,99) AND (1,0);
} {0 1}
do_execsql_test 33.3 {
SELECT * FROM t1 WHERE (a,b) BETWEEN (14,99) AND (16,0);
} {15 -7}
do_execsql_test 33.3 {
SELECT * FROM t1 WHERE (a,b) BETWEEN (2,99) AND (4,0);
} {3 100}
finish_test
+8
View File
@@ -118,10 +118,18 @@ do_test select3-2.14 {
} {1 {near ";": syntax error}}
# Cannot have a HAVING without a GROUP BY
#
# Update: As of 3.39.0, you can.
#
do_execsql_test select3-3.1 {
SELECT log, count(*) FROM t1 HAVING log>=4
} {}
do_execsql_test select3-3.2 {
SELECT count(*) FROM t1 HAVING log>=4
} {}
do_execsql_test select3-3.3 {
SELECT count(*) FROM t1 HAVING log!=400
} {31}
# Toss in some HAVING clauses
#
+3
View File
@@ -26,6 +26,9 @@ set testprefix tcl
# Check the error messages generated by tclsqlite
#
set r "sqlite_orig HANDLE ?FILENAME? ?-vfs VFSNAME? ?-readonly BOOLEAN? ?-create BOOLEAN? ?-nofollow BOOLEAN? ?-nomutex BOOLEAN? ?-fullmutex BOOLEAN? ?-uri BOOLEAN?"
ifcapable sharedschema {
append r " ?-shared-schema BOOLEAN?"
}
if {[sqlite3 -has-codec]} {
append r " ?-key CODECKEY?"
}
+24 -19
View File
@@ -38,7 +38,7 @@
#define SEL(e) ((e)->iLine = ((e)->rc ? (e)->iLine : __LINE__))
/* Database functions */
#define opendb(w,x,y,z) (SEL(w), opendb_x(w,x,y,z))
#define opendb(w,x,y,z,f) (SEL(w), opendb_x(w,x,y,z,f))
#define closedb(y,z) (SEL(y), closedb_x(y,z))
/* Functions to execute SQL */
@@ -545,11 +545,14 @@ static void opendb_x(
Error *pErr, /* IN/OUT: Error code */
Sqlite *pDb, /* OUT: Database handle */
const char *zFile, /* Database file name */
int bDelete /* True to delete db file before opening */
int bDelete, /* True to delete db file before opening */
int flags
){
if( pErr->rc==SQLITE_OK ){
int rc;
int flags = SQLITE_OPEN_CREATE | SQLITE_OPEN_READWRITE | SQLITE_OPEN_URI;
if( flags==0 ){
flags = SQLITE_OPEN_CREATE | SQLITE_OPEN_READWRITE | SQLITE_OPEN_URI;
}
if( bDelete ) unlink(zFile);
rc = sqlite3_open_v2(zFile, &pDb->db, flags, 0);
if( rc ){
@@ -985,7 +988,7 @@ static char *walthread1_thread(int iTid, void *pArg){
Sqlite db = {0}; /* SQLite database connection */
int nIter = 0; /* Iterations so far */
opendb(&err, &db, "test.db", 0);
opendb(&err, &db, "test.db", 0, 0);
while( !timetostop(&err) ){
const char *azSql[] = {
"SELECT md5sum(x) FROM t1 WHERE rowid != (SELECT max(rowid) FROM t1)",
@@ -1024,7 +1027,7 @@ static char *walthread1_ckpt_thread(int iTid, void *pArg){
Sqlite db = {0}; /* SQLite database connection */
int nCkpt = 0; /* Checkpoints so far */
opendb(&err, &db, "test.db", 0);
opendb(&err, &db, "test.db", 0, 0);
while( !timetostop(&err) ){
sqlite3_sleep(500);
execsql(&err, &db, "PRAGMA wal_checkpoint");
@@ -1043,7 +1046,7 @@ static void walthread1(int nMs){
Threadset threads = {0}; /* Test threads */
int i; /* Iterator variable */
opendb(&err, &db, "test.db", 1);
opendb(&err, &db, "test.db", 1, 0);
sql_script(&err, &db,
"PRAGMA journal_mode = WAL;"
"CREATE TABLE t1(x PRIMARY KEY);"
@@ -1076,7 +1079,7 @@ static char *walthread2_thread(int iTid, void *pArg){
int journal_exists = 0;
int wal_exists = 0;
opendb(&err, &db, "test.db", 0);
opendb(&err, &db, "test.db", 0, 0);
sql_script(&err, &db, zJournal);
clear_error(&err, SQLITE_BUSY);
@@ -1106,7 +1109,7 @@ static void walthread2(int nMs){
Sqlite db = {0};
Threadset threads = {0};
opendb(&err, &db, "test.db", 1);
opendb(&err, &db, "test.db", 1, 0);
sql_script(&err, &db, "CREATE TABLE t1(x INTEGER PRIMARY KEY, y UNIQUE)");
closedb(&err, &db);
@@ -1126,7 +1129,7 @@ static char *walthread3_thread(int iTid, void *pArg){
i64 iNextWrite; /* Next value this thread will write */
int iArg = PTR2INT(pArg);
opendb(&err, &db, "test.db", 0);
opendb(&err, &db, "test.db", 0, 0);
sql_script(&err, &db, "PRAGMA wal_autocheckpoint = 10");
iNextWrite = iArg+1;
@@ -1163,7 +1166,7 @@ static void walthread3(int nMs){
Threadset threads = {0};
int i;
opendb(&err, &db, "test.db", 1);
opendb(&err, &db, "test.db", 1, 0);
sql_script(&err, &db,
"PRAGMA journal_mode = WAL;"
"CREATE TABLE t1(cnt PRIMARY KEY, sum1, sum2);"
@@ -1186,7 +1189,7 @@ static char *walthread4_reader_thread(int iTid, void *pArg){
Error err = {0}; /* Error code and message */
Sqlite db = {0}; /* SQLite database connection */
opendb(&err, &db, "test.db", 0);
opendb(&err, &db, "test.db", 0, 0);
while( !timetostop(&err) ){
integrity_check(&err, &db);
}
@@ -1201,7 +1204,7 @@ static char *walthread4_writer_thread(int iTid, void *pArg){
Sqlite db = {0}; /* SQLite database connection */
i64 iRow = 1;
opendb(&err, &db, "test.db", 0);
opendb(&err, &db, "test.db", 0, 0);
sql_script(&err, &db, "PRAGMA wal_autocheckpoint = 15;");
while( !timetostop(&err) ){
execsql_i64(
@@ -1221,7 +1224,7 @@ static void walthread4(int nMs){
Sqlite db = {0};
Threadset threads = {0};
opendb(&err, &db, "test.db", 1);
opendb(&err, &db, "test.db", 1, 0);
sql_script(&err, &db,
"PRAGMA journal_mode = WAL;"
"CREATE TABLE t1(a INTEGER PRIMARY KEY, b UNIQUE);"
@@ -1241,7 +1244,7 @@ static char *walthread5_thread(int iTid, void *pArg){
Sqlite db = {0}; /* SQLite database connection */
i64 nRow;
opendb(&err, &db, "test.db", 0);
opendb(&err, &db, "test.db", 0, 0);
nRow = execsql_i64(&err, &db, "SELECT count(*) FROM t1");
closedb(&err, &db);
@@ -1254,7 +1257,7 @@ static void walthread5(int nMs){
Sqlite db = {0};
Threadset threads = {0};
opendb(&err, &db, "test.db", 1);
opendb(&err, &db, "test.db", 1, 0);
sql_script(&err, &db,
"PRAGMA wal_autocheckpoint = 0;"
"PRAGMA page_size = 1024;"
@@ -1345,7 +1348,7 @@ static void cgt_pager_1(int nMs){
Error err = {0};
Sqlite db = {0};
opendb(&err, &db, "test.db", 1);
opendb(&err, &db, "test.db", 1, 0);
sql_script(&err, &db,
"PRAGMA cache_size = 2000;"
"PRAGMA page_size = 1024;"
@@ -1374,7 +1377,7 @@ static char *dynamic_triggers_1(int iTid, void *pArg){
int nDrop = 0;
int nCreate = 0;
opendb(&err, &db, "test.db", 0);
opendb(&err, &db, "test.db", 0, 0);
while( !timetostop(&err) ){
int i;
@@ -1427,7 +1430,7 @@ static char *dynamic_triggers_2(int iTid, void *pArg){
int nInsert = 0;
int nDelete = 0;
opendb(&err, &db, "test.db", 0);
opendb(&err, &db, "test.db", 0, 0);
while( !timetostop(&err) ){
do {
iVal = (iVal+1)%100;
@@ -1452,7 +1455,7 @@ static void dynamic_triggers(int nMs){
Sqlite db = {0};
Threadset threads = {0};
opendb(&err, &db, "test.db", 1);
opendb(&err, &db, "test.db", 1, 0);
sql_script(&err, &db,
"PRAGMA page_size = 1024;"
"PRAGMA journal_mode = WAL;"
@@ -1492,6 +1495,7 @@ static void dynamic_triggers(int nMs){
#include "tt3_lookaside1.c"
#include "tt3_vacuum.c"
#include "tt3_stress.c"
#include "tt3_reuseschema.c"
#include "tt3_shared.c"
int main(int argc, char **argv){
@@ -1517,6 +1521,7 @@ int main(int argc, char **argv){
{ vacuum1, "vacuum1", 10000 },
{ stress1, "stress1", 10000 },
{ stress2, "stress2", 60000 },
{ reuse_schema_1, "reuse_schema_1", 20000 },
{ shared1, "shared1", 10000 },
};
static char *substArgv[] = { 0, "*", 0 };
+2 -2
View File
@@ -70,7 +70,7 @@ static char *checkpoint_starvation_reader(int iTid, void *pArg){
Error err = {0};
Sqlite db = {0};
opendb(&err, &db, "test.db", 0);
opendb(&err, &db, "test.db", 0, 0);
while( !timetostop(&err) ){
i64 iCount1, iCount2;
sql_script(&err, &db, "BEGIN");
@@ -96,7 +96,7 @@ static void checkpoint_starvation_main(int nMs, CheckpointStarvationCtx *p){
int nInsert = 0;
int i;
opendb(&err, &db, "test.db", 1);
opendb(&err, &db, "test.db", 1, 0);
sql_script(&err, &db,
"PRAGMA page_size = 1024;"
"PRAGMA journal_mode = WAL;"
+2 -2
View File
@@ -19,7 +19,7 @@ static char *create_drop_index_thread(int iTid, void *pArg){
Sqlite db = {0}; /* SQLite database connection */
while( !timetostop(&err) ){
opendb(&err, &db, "test.db", 0);
opendb(&err, &db, "test.db", 0, 0);
sql_script(&err, &db,
"DROP INDEX IF EXISTS i1;"
@@ -51,7 +51,7 @@ static void create_drop_index_1(int nMs){
Sqlite db = {0};
Threadset threads = {0};
opendb(&err, &db, "test.db", 1);
opendb(&err, &db, "test.db", 1, 0);
sql_script(&err, &db,
"CREATE TABLE t11(a, b, c, d);"
"WITH data(x) AS (SELECT 1 UNION ALL SELECT x+1 FROM data WHERE x<100) "
+3 -3
View File
@@ -22,7 +22,7 @@ static char *lookaside1_thread_reader(int iTid, void *pArg){
Error err = {0}; /* Error code and message */
Sqlite db = {0}; /* SQLite database connection */
opendb(&err, &db, "test.db", 0);
opendb(&err, &db, "test.db", 0, 0);
while( !timetostop(&err) ){
sqlite3_stmt *pStmt = 0;
@@ -47,7 +47,7 @@ static char *lookaside1_thread_writer(int iTid, void *pArg){
Error err = {0}; /* Error code and message */
Sqlite db = {0}; /* SQLite database connection */
opendb(&err, &db, "test.db", 0);
opendb(&err, &db, "test.db", 0, 0);
do{
sql_script(&err, &db,
@@ -68,7 +68,7 @@ static void lookaside1(int nMs){
Sqlite db = {0};
Threadset threads = {0};
opendb(&err, &db, "test.db", 1);
opendb(&err, &db, "test.db", 1, 0);
sql_script(&err, &db,
"CREATE TABLE t1(x PRIMARY KEY) WITHOUT ROWID;"
"WITH data(x,y) AS ("
+73
View File
@@ -0,0 +1,73 @@
/*
** 2014 December 9
**
** The author disclaims copyright to this source code. In place of
** a legal notice, here is a blessing:
**
** May you do good and not evil.
** May you find forgiveness for yourself and forgive others.
** May you share freely, never taking more than you give.
**
*************************************************************************
**
** reuse_schema_1
*/
static char *reuse_schema_thread(int iTid, void *pArg){
Error err = {0}; /* Error code and message */
Sqlite db = {0}; /* SQLite database connection */
int iRep = 0;
while( !timetostop(&err) ){
int f = SQLITE_OPEN_READWRITE|SQLITE_OPEN_SHARED_SCHEMA;
opendb(&err, &db, "test.db", 0, f);
execsql_i64(&err, &db, "SELECT count(*) FROM t1");
sql_script(&err, &db, "ATTACH 'test.db2' AS aux");
execsql_i64(&err, &db, "SELECT count(*) FROM t1");
closedb(&err, &db);
iRep++;
}
print_and_free_err(&err);
return sqlite3_mprintf("%d", iRep);
}
static void reuse_schema_1(int nMs){
Error err = {0};
Sqlite db = {0};
Threadset threads = {0};
opendb(&err, &db, "test.db", 1, 0);
sql_script(&err, &db,
"CREATE TABLE t1(a, b, c, d);"
"WITH data(x) AS (SELECT 1 UNION ALL SELECT x+1 FROM data WHERE x<100) "
"INSERT INTO t1 SELECT x,x,x,x FROM data;"
);
closedb(&err, &db);
opendb(&err, &db, "test.db2", 1, 0);
sql_script(&err, &db,
#ifdef SQLITE_ENABLE_FTS5
"CREATE VIRTUAL TABLE t2 USING fts5(a, b, c, d);"
#else
"CREATE TABLE t2(a, b, c, d);"
#endif
"WITH data(x) AS (SELECT 1 UNION ALL SELECT x+1 FROM data WHERE x<100) "
"INSERT INTO t2 SELECT x*2,x*2,x*2,x*2 FROM data;"
);
closedb(&err, &db);
setstoptime(&err, nMs);
launch_thread(&err, &threads, reuse_schema_thread, 0);
launch_thread(&err, &threads, reuse_schema_thread, 0);
launch_thread(&err, &threads, reuse_schema_thread, 0);
launch_thread(&err, &threads, reuse_schema_thread, 0);
launch_thread(&err, &threads, reuse_schema_thread, 0);
join_all_threads(&err, &threads);
sqlite3_enable_shared_cache(0);
print_and_free_err(&err);
}
+10 -10
View File
@@ -21,7 +21,7 @@ static char *stress_thread_1(int iTid, void *pArg){
Error err = {0}; /* Error code and message */
Sqlite db = {0}; /* SQLite database connection */
opendb(&err, &db, "test.db", 0);
opendb(&err, &db, "test.db", 0, 0);
while( !timetostop(&err) ){
sql_script(&err, &db, "CREATE TABLE IF NOT EXISTS t1(a PRIMARY KEY, b)");
clear_error(&err, SQLITE_LOCKED);
@@ -40,7 +40,7 @@ static char *stress_thread_2(int iTid, void *pArg){
Error err = {0}; /* Error code and message */
Sqlite db = {0}; /* SQLite database connection */
while( !timetostop(&err) ){
opendb(&err, &db, "test.db", 0);
opendb(&err, &db, "test.db", 0, 0);
sql_script(&err, &db, "SELECT * FROM sqlite_schema;");
clear_error(&err, SQLITE_LOCKED);
closedb(&err, &db);
@@ -59,7 +59,7 @@ static char *stress_thread_3(int iTid, void *pArg){
int i1 = 0;
int i2 = 0;
opendb(&err, &db, "test.db", 0);
opendb(&err, &db, "test.db", 0, 0);
while( !timetostop(&err) ){
sql_script(&err, &db, "SELECT * FROM t1 ORDER BY a;");
i1++;
@@ -82,11 +82,11 @@ static char *stress_thread_4(int iTid, void *pArg){
int i2 = 0;
int iArg = PTR2INT(pArg);
opendb(&err, &db, "test.db", 0);
opendb(&err, &db, "test.db", 0, 0);
while( !timetostop(&err) ){
if( iArg ){
closedb(&err, &db);
opendb(&err, &db, "test.db", 0);
opendb(&err, &db, "test.db", 0, 0);
}
sql_script(&err, &db,
"WITH loop(i) AS (SELECT 1 UNION ALL SELECT i+1 FROM loop LIMIT 200) "
@@ -113,12 +113,12 @@ static char *stress_thread_5(int iTid, void *pArg){
int i1 = 0;
int i2 = 0;
opendb(&err, &db, "test.db", 0);
opendb(&err, &db, "test.db", 0, 0);
while( !timetostop(&err) ){
i64 i = (i1 % 4);
if( iArg ){
closedb(&err, &db);
opendb(&err, &db, "test.db", 0);
opendb(&err, &db, "test.db", 0, 0);
}
execsql(&err, &db, "DELETE FROM t1 WHERE (rowid % 4)==:i", &i);
i1++;
@@ -265,7 +265,7 @@ static char *stress2_workload19(int iTid, void *pArg){
Sqlite db = {0}; /* SQLite database connection */
const char *zDb = (const char*)pArg;
while( !timetostop(&err) ){
opendb(&err, &db, zDb, 0);
opendb(&err, &db, zDb, 0, 0);
sql_script(&err, &db, "SELECT * FROM sqlite_schema;");
clear_error(&err, SQLITE_LOCKED);
closedb(&err, &db);
@@ -290,7 +290,7 @@ static char *stress2_thread_wrapper(int iTid, void *pArg){
while( !timetostop(&err) ){
int cnt;
opendb(&err, &db, pCtx->zDb, 0);
opendb(&err, &db, pCtx->zDb, 0, 0);
for(cnt=0; err.rc==SQLITE_OK && cnt<STRESS2_TABCNT; cnt++){
pCtx->xProc(&err, &db, i1);
i2 += (err.rc==SQLITE_OK);
@@ -342,7 +342,7 @@ static void stress2(int nMs){
Threadset threads = {0};
/* To make sure the db file is empty before commencing */
opendb(&err, &db, zDb, 1);
opendb(&err, &db, zDb, 1, 0);
sql_script(&err, &db,
"CREATE TABLE IF NOT EXISTS t0(x PRIMARY KEY, y, z);"
"CREATE INDEX IF NOT EXISTS i0 ON t0(y);"
+3 -3
View File
@@ -25,7 +25,7 @@ static char *vacuum1_thread_writer(int iTid, void *pArg){
Sqlite db = {0}; /* SQLite database connection */
i64 i = 0;
opendb(&err, &db, "test.db", 0);
opendb(&err, &db, "test.db", 0, 0);
while( !timetostop(&err) ){
i++;
@@ -52,7 +52,7 @@ static char *vacuum1_thread_writer(int iTid, void *pArg){
static char *vacuum1_thread_vacuumer(int iTid, void *pArg){
Error err = {0}; /* Error code and message */
Sqlite db = {0}; /* SQLite database connection */
opendb(&err, &db, "test.db", 0);
opendb(&err, &db, "test.db", 0, 0);
do{
sql_script(&err, &db, "VACUUM");
@@ -69,7 +69,7 @@ static void vacuum1(int nMs){
Sqlite db = {0};
Threadset threads = {0};
opendb(&err, &db, "test.db", 1);
opendb(&err, &db, "test.db", 1, 0);
sql_script(&err, &db,
"CREATE TABLE t1(x PRIMARY KEY, y BLOB);"
"CREATE INDEX i1 ON t1(y);"
+22 -16
View File
@@ -12,7 +12,7 @@
# Flag meanings:
set flagMeaning(NeedSchema) {Force schema load before running}
set flagMeaning(ReadOnly) {Read-only HEADER_VALUE}
set flagMeaning(OneSchema) {Only a single schema required}
set flagMeaning(Result0) {Acts as query when no argument}
set flagMeaning(Result1) {Acts as query when has one argument}
set flagMeaning(SchemaReq) {Schema required - "main" is default}
@@ -150,7 +150,7 @@ set pragma_def {
ARG: SQLITE_CellSizeCk
NAME: default_cache_size
FLAG: NeedSchema Result0 SchemaReq NoColumns1
FLAG: NeedSchema Result0 SchemaReq NoColumns1 OneSchema
COLS: cache_size
IF: !defined(SQLITE_OMIT_PAGER_PRAGMAS) && !defined(SQLITE_OMIT_DEPRECATED)
@@ -163,12 +163,12 @@ set pragma_def {
IF: !defined(SQLITE_OMIT_PAGER_PRAGMAS)
NAME: page_count
FLAG: NeedSchema Result0 SchemaReq
FLAG: NeedSchema Result0 SchemaReq OneSchema
IF: !defined(SQLITE_OMIT_PAGER_PRAGMAS)
NAME: max_page_count
TYPE: PAGE_COUNT
FLAG: NeedSchema Result0 SchemaReq
FLAG: NeedSchema Result0 SchemaReq OneSchema
IF: !defined(SQLITE_OMIT_PAGER_PRAGMAS)
NAME: locking_mode
@@ -176,7 +176,7 @@ set pragma_def {
IF: !defined(SQLITE_OMIT_PAGER_PRAGMAS)
NAME: journal_mode
FLAG: NeedSchema Result0 SchemaReq
FLAG: NeedSchema Result0 SchemaReq OneSchema
IF: !defined(SQLITE_OMIT_PAGER_PRAGMAS)
NAME: journal_size_limit
@@ -184,18 +184,18 @@ set pragma_def {
IF: !defined(SQLITE_OMIT_PAGER_PRAGMAS)
NAME: cache_size
FLAG: NeedSchema Result0 SchemaReq NoColumns1
FLAG: NeedSchema Result0 SchemaReq NoColumns1 OneSchema
IF: !defined(SQLITE_OMIT_PAGER_PRAGMAS)
NAME: mmap_size
IF: !defined(SQLITE_OMIT_PAGER_PRAGMAS)
NAME: auto_vacuum
FLAG: NeedSchema Result0 SchemaReq NoColumns1
FLAG: NeedSchema Result0 SchemaReq NoColumns1 OneSchema
IF: !defined(SQLITE_OMIT_AUTOVACUUM)
NAME: incremental_vacuum
FLAG: NeedSchema NoColumns
FLAG: NeedSchema NoColumns OneSchema
IF: !defined(SQLITE_OMIT_AUTOVACUUM)
NAME: temp_store
@@ -215,7 +215,7 @@ set pragma_def {
IF: !defined(SQLITE_OMIT_PAGER_PRAGMAS) && SQLITE_ENABLE_LOCKING_STYLE
NAME: synchronous
FLAG: NeedSchema Result0 SchemaReq NoColumns1
FLAG: NeedSchema Result0 SchemaReq NoColumns1 OneSchema
IF: !defined(SQLITE_OMIT_PAGER_PRAGMAS)
NAME: table_info
@@ -238,7 +238,7 @@ set pragma_def {
IF: !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
NAME: stats
FLAG: NeedSchema Result0 SchemaReq
FLAG: NeedSchema Result0 SchemaReq OneSchema
COLS: tbl idx wdth hght flgs
IF: !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) && defined(SQLITE_DEBUG)
@@ -290,7 +290,7 @@ set pragma_def {
IF: !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
NAME: foreign_key_list
FLAG: NeedSchema Result1 SchemaOpt
FLAG: NeedSchema Result1 SchemaOpt OneSchema
COLS: id seq table from to on_update on_delete match
IF: !defined(SQLITE_OMIT_FOREIGN_KEY)
@@ -336,14 +336,14 @@ set pragma_def {
NAME: data_version
TYPE: HEADER_VALUE
ARG: BTREE_DATA_VERSION
FLAG: ReadOnly Result0
ARG: BTREE_DATA_VERSION|PRAGMA_HEADER_VALUE_READONLY
FLAG: Result0
IF: !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS)
NAME: freelist_count
TYPE: HEADER_VALUE
ARG: BTREE_FREE_PAGE_COUNT
FLAG: ReadOnly Result0
ARG: BTREE_FREE_PAGE_COUNT|PRAGMA_HEADER_VALUE_READONLY
FLAG: Result0
IF: !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS)
NAME: application_id
@@ -357,7 +357,7 @@ set pragma_def {
IF: !defined(SQLITE_OMIT_COMPILEOPTION_DIAGS)
NAME: wal_checkpoint
FLAG: NeedSchema
FLAG: NeedSchema OneSchema
COLS: busy log checkpointed
IF: !defined(SQLITE_OMIT_WAL)
@@ -516,6 +516,12 @@ foreach f [lsort [array names allflags]] {
set fv [expr {$fv*2}]
}
puts $fd "\n/* For PragTyp_HEADER_VALUE pragmas the Pragma.iArg value is set"
puts $fd "** to the index of the header field to access (always 10 or less)."
puts $fd "** Ored with HEADER_VALUE_READONLY if the field is read only. */"
puts $fd "#define PRAGMA_HEADER_VALUE_READONLY 0x0100"
puts $fd "#define PRAGMA_HEADER_VALUE_MASK 0x00FF\n"
# Sort the column lists so that longer column lists occur first
#
proc colscmp {a b} {