Compare commits

..

107 Commits

Author SHA1 Message Date
stephan 11e1defc8f CLI arg handling robustness improvements.
FossilOrigin-Name: 129aca54f6b791c222b51f3eb01569e1e569269860e153b005140eb65af378b9
2024-09-14 16:30:01 +00:00
drh 3d56d59adc Add the --version option.
FossilOrigin-Name: 9961334c8007e7cb6ae55885075b74acddc4fa701b359cf67e0f3c237d7eba4a
2024-09-14 16:28:38 +00:00
drh 7154803d4c New debugging options: --logfile, --errorfile, --remote-errorfile.
If page 1 changes, always send it last.

FossilOrigin-Name: 2d8cd76691554578e987ce682cf0c42c083711dd1511a178148978182ef43ba2
2024-09-14 16:03:16 +00:00
drh df9b488799 Always show the -v traffic message even if there are multiple -v options.
FossilOrigin-Name: fc05a5b7f77cdbfcc659d49eb09569a64a172362cb90199e2861028085178f10
2024-09-14 11:38:46 +00:00
drh 15e05eab32 Add the --logfile FILE option for debugging.
FossilOrigin-Name: 30e1b92d5663e24d2f325f2bab35f81b55848ef39d15688e40b9005269626303
2024-09-14 11:23:57 +00:00
drh 9d3047bd0d Improved error messages coming out of sqlite3-rsync.
FossilOrigin-Name: 452fb6de3984c3cb10d30b51dcdb2574578ca128a0c519b2bd43df0bdd343083
2024-09-14 10:59:32 +00:00
drh 2b30518804 Make the output from sqlite3-rsync with a single -v option the same as it
is with regular rsync.  Only show the SSH command with two or more -v options,
or if there is an error in popen2().

FossilOrigin-Name: 105ec44b470318fc9ff1773027c4064343f224068c9b6e71c5618f18f7dfcc3f
2024-09-14 10:48:05 +00:00
drh 33f0a3ed13 Merge sqlite_dbpage fixes into the sqlite3-rsync branch.
FossilOrigin-Name: dff76b7a3436031ea5a61b8a44ddfa1d40ea20c983f3d34a8501cd7074db68b8
2024-09-13 23:41:16 +00:00
drh 762946b236 Bug fix in the enhanced sqlite_dbpage for when truncating two or more
ATTACH-ed databases within the same transaction.

FossilOrigin-Name: 6aa9c8e79b440c6419e65990d9ceba8f00a6f975455138cf2aa82b113daec825
2024-09-13 21:47:57 +00:00
drh 8550e4a9f8 Fix harmless compiler warning on Windows.
FossilOrigin-Name: 86e0219d977c493ac19d00c3ddcf560eb317d506c7cf6e4ef17e92daa91e1762
2024-09-13 16:12:54 +00:00
drh 7316b6c072 Improved informational output from sqlite3-rsync.
FossilOrigin-Name: e55e3e8ec2fe3a9190872d999cee55c85bde92667040cc166233faaa2fa34266
2024-09-13 13:53:20 +00:00
drh d61d934f9b Preveious check-in was actually doing an 8-round KeccakF1600. This one
corrects that to just 6 rounds.

FossilOrigin-Name: 3c36f5814f25483586c4fd49ef2fe5c7c0ff8c59672b1622c92061ec0ba8547a
2024-09-13 12:35:04 +00:00
drh d0d3182fa8 Change the hash algorithm from SHA1 to a 6-round KeccakF1600 with a rate
of 160.  This uses about 1/3rd fewer CPU cycles.

FossilOrigin-Name: 96c7f47a8f59e5078bd296979421c1b57fbcb7be261f8a7a0b1d22a4b5914db0
2024-09-13 12:28:11 +00:00
drh 5c6dc45a10 Better initialization of new database files in sqlite3-rsync.
FossilOrigin-Name: 75d5a8eb3d4ece06900109ad4022ba2a3e82de2f0acb012e3a02bfb4326bfa6d
2024-09-12 23:30:29 +00:00
stephan 5735921b0f Add RSYNC_OPT to the sqlite3-rsync build flags.
FossilOrigin-Name: b2a3497e5525dd33faf70961107a0529f476735fef756953c66e105747271c6d
2024-09-12 21:03:11 +00:00
stephan 6677cfeda7 Port some of the shell's CLI flag-handling code into sqlite3-rsync to make the arg handling more robust.
FossilOrigin-Name: 53fb9b11807ff7accd8cd41f9cb6516d2503f161ea976940437a1d3aae868665
2024-09-12 18:15:28 +00:00
drh 40b831851e Replica must be in writable_schema mode.
FossilOrigin-Name: e385525793c7d74ce8ee139c9d6cfc1248834754598f3fd45b22b9426ff106ee
2024-09-12 17:06:02 +00:00
drh 6df1de1c73 Improved --commcheck. Add the infoMsg() function which is useful for
debugging.

FossilOrigin-Name: b979d02ffd1370d8840328bce06c76c224f0fc1fb54b47d6c904547580a820a1
2024-09-12 16:54:34 +00:00
drh 0b8c8c861b Pass the names of both the origin and the replica databases to the remote
side, so that if the remote is the replica, it will have access to the
origin database name in case the replica name is really a directory.

FossilOrigin-Name: 435c30171d3c6073b7aaf5cc11cc4813f6a2d225ae6dce1b0e478f0cd5a0b532
2024-09-12 15:51:56 +00:00
drh f7c96ee98b Add a protocol version number to the first message, and give the two sides
an opportunity to negotiate a suitable protocol number, for future
compatibility.  Send the page size as a power-of-two.

FossilOrigin-Name: df0623aae1154281157409f62d6d3fb3ce41829281d53bc55868ce44b3d36883
2024-09-12 15:36:34 +00:00
drh 165daef043 Add sha1() functions to the CLI. Fix sha1b() such that it actually returns
a BLOB.

FossilOrigin-Name: fe65821a3b912f061026e6fd7174be26897010e6b474e2780350cac60faebaad
2024-09-12 14:43:05 +00:00
drh f1fb5ce10f Improved debugging output.
FossilOrigin-Name: 80461e0d724963aaf2646005298f1194c5f1c4c9ae41c1085d4d137ed485bd9f
2024-09-12 12:04:53 +00:00
drh dc3bec34a6 Progress on the sqlite3-rsync utility. This is an incremental check-in. It
does compile, but it does not work.

FossilOrigin-Name: fa06977b6db7fa745720561ec0b10570cf7e71598dc7a7c5ee650640e5bdf6f5
2024-09-11 17:02:44 +00:00
drh 79254dc363 Improved SSH infrastructure. The foundation is now in place to begin working
on the actual sync protocol.  Still experimental.  Still a work in progress.

FossilOrigin-Name: 9a1a95f523a96303aad57e2422c2b51ea7e125f5490f32f7a2929d49b6c69ef8
2024-09-10 22:14:18 +00:00
drh a9c8f7cf34 Initial infrastructure for the sqlite3-rsync utility. Prototype only.
Does not work.

FossilOrigin-Name: 397b2d37b7a6619b0c1eee201065585d03496f94786b21540f613e4716d56612
2024-09-10 17:05:12 +00:00
drh 38b26d82e6 Add the ability for sqlite_dbpage to truncate the database file by writing
a NULL page.  Experimental.

FossilOrigin-Name: eb3c89ee2e4c5425be75deaf46a06a9cd8b210c695b918dd63a78f930c6e6b63
2024-09-10 12:09:03 +00:00
drh 882aba4090 Generalize the sqlite3_dbpage virtual table so that it is able to write
new pages onto the end of the database file using INSERT.

FossilOrigin-Name: fe0d67e72d4228661c021f227bfc0d5ddb1b726db0f36c7221ead8dd8bd1dc73
2024-09-09 18:45:58 +00:00
drh 9c2f068ebd Move the vfstrace extension out of src/ and into ext/misc/. Make it a
standard part of the CLI.  Improve its output.  Also fix some unrelated
comment typos.

FossilOrigin-Name: 123cb1f579daec3ed092fe9dd1bc0d3250f2b56d4cda1efa92af139029e112e2
2024-09-09 15:39:40 +00:00
drh dbab768d07 Fix dependencies in makefiles to include ext/misc/vfstrace.c as necessary.
Improved xFileControl() output from vfstrace.c.

FossilOrigin-Name: e8f2d6313075c92fdeebcdfd8b50f43e9d45225890b2ef6b77148a766a42e940
2024-09-09 15:33:37 +00:00
drh a40f6eb80e Fix harmless compiler warnings in the vfstrace.c extension.
FossilOrigin-Name: f23954e604bf4da45f07194b54a4fe1c83002ab65d6c6f0ac095e88baba18547
2024-09-09 15:19:26 +00:00
drh a8cf79e322 Fix harmless compiler warnings in FTS5.
FossilOrigin-Name: aa75e701de61fe63ec15c35d70e53e950ff73b0dcb0d871dd8721412f3af297a
2024-09-09 15:12:21 +00:00
drh 5600adf1b1 Move the vfstrace extension out of src/ over into ext/misc/ where it belongs.
Make it part of the standard build for the CLI.  Bring some of the vfstrace
output up-to-date.

FossilOrigin-Name: 055b97de8d2397987d72dbab1cde78ece2d1c066e95042b4ed6b7b36b2cf9006
2024-09-09 14:50:23 +00:00
dan cf25c16a54 Fix a problem with fts5 locale=1 tables and UPDATE statements that may affect more than one row.
FossilOrigin-Name: 70e42f941c0778a04b82655409c7caf4c1039589f7e43a8ec1e736ea8f931b26
2024-09-07 16:22:22 +00:00
drh 8755e695c5 Fix an off-by-one error in the routines that bind the special $test_TTT and
$int_NNN parameters for fuzz testing.  Fix to testing logic only - no changes
to the SQLite core.

FossilOrigin-Name: 6206b90a4ec3f05e3bbb4844e71569bbde7df237550569e6419ff7c3146505dc
2024-09-07 16:04:04 +00:00
dan f1c750e4ca Add tests for an fts5 NEAR() expression with a single argument phrase.
FossilOrigin-Name: e319d43bfd5ee4ed92b93531b239af4d1be0a8215b2a06c3532122ff2c7b6a7c
2024-09-06 20:12:59 +00:00
stephan 6946a7fa50 Resolve the "No rule to make target '0'" error when building with --disable-tcl.
FossilOrigin-Name: d94541ae76b5d8b69f5524f10dcccc0814283f438a03f553848ed631a1983633
2024-09-06 15:01:00 +00:00
drh bc97630313 Fix a harmless stray carriage-return character.
FossilOrigin-Name: 84a6c5f975de36ba93b888e01cc5188717b5644ab8384beb8fd8906bdfc8e227
2024-09-06 14:01:48 +00:00
drh c43d16d69a In testrunner.tcl, correctly capture and display information about the
system under test:  hostname, OS, pointer size, byte-order.

FossilOrigin-Name: ec75cfc5d4b69e4aed64d17748cac15cd62a759a1cbe7feaa4580ad8346b0b95
2024-09-06 13:13:25 +00:00
drh deb6a60a84 Fix harmless compiler warnings.
FossilOrigin-Name: 60fb8ee153ec293b6b3a4170dafa305e4c16af575aced72daef46116d8dc2bb6
2024-09-06 11:21:53 +00:00
drh c4e84b7295 A testcase() macro added to help ensure that the fix to the omit-noop-join
optimization from yesterday does not regress.

FossilOrigin-Name: 224628b1039b996499e0d806fc0215f175da6f1059eb1b9ac491ac11126971ab
2024-09-06 10:35:36 +00:00
drh 56a0480540 Clarification and simplification to the README.md file and to the instructions
for building on Windows.

FossilOrigin-Name: f69ef1a37b2778bdf73ee7e3b3edd74f7344ab8e5eedbedc22203c782e521f5b
2024-09-06 09:49:13 +00:00
drh dc181d41d5 Fix a testrunner status reporting problem introduced by [aa5f10f21dbfb24e].
FossilOrigin-Name: d20c65c3b4256a662ebf7ed024b7b7adaceca90358f58111dc645da322000794
2024-09-05 23:40:13 +00:00
drh 934e796e43 Ensure that the WhereInfo.revMask bitmap is adjusted when tables are removed
from the FROM clause by the Omit-Noop-Join optimization of
[0cd82ee9a8413cf1].  Fix for the issue described by
[forum:/forum/8a1e467e905b8d27|format post 8a1e467e905b8d27].

FossilOrigin-Name: 22ca5a2ffb89ccb5f337993b5a95e27c449c39014284156eabc33da012a8759c
2024-09-05 23:22:55 +00:00
drh 6ffcdb1856 Update notes on build procedures in the README.md file.
FossilOrigin-Name: 1d12744fe7cc294994e53e1ffe72799d0321dd5c1ef031213f083e200918fee5
2024-09-05 15:55:04 +00:00
drh 4987c5c3c2 Testrunner.tcl enhancements: (1) Attempt to build the SQLite tcl extension
if it is not already available.  (2) testrunner target "devtest" is added as
an alias for "mdevtest".  (3) Try to keep summary information at the end of
a test below 80-characters per line.  (4) Update the Makefile.in so that
the "clean" target removes the tcl extension built by item 1 above.

FossilOrigin-Name: aa5f10f21dbfb24ee54ca96bfb7b013ae29e26fec05b80681f19cc63d9face49
2024-09-05 15:28:15 +00:00
drh 21e7816e65 Enhance testrunner.tcl to keep track of the platform and SQLite version
as reported by individual test cases and to report that information in the
summary at the end of each test run.

FossilOrigin-Name: 80ebb7c7e686cd936ac834f2258f585a7004762593e0bc859ecd75d6fb0badfd
2024-09-05 12:06:45 +00:00
drh 6aedd6d9fc Faster implementation of the aggregate_test_counts procedure inside of
testrunner.tcl.

FossilOrigin-Name: a01d869520329fb9e786cdc65f359785a95d19d289e4c6b844c758d6e5385aaf
2024-09-05 11:46:43 +00:00
drh 7bd230cf4d Make the default TCLDIR be C:\Tcl in the Makefile.msc.
FossilOrigin-Name: c2c0a9176ae7291a0b72f3d048a2ef5716c325b9f693cdc5eada552e0c881a9d
2024-09-04 18:51:59 +00:00
drh bb4d2edf10 Fix a bug in the parsing of some corner-case JSON PATH strings that contain
escaped double-quotes.

FossilOrigin-Name: 60ac55c4b76355aaf7cbde38bf1f6082ff5612bf4ffc49ab69d00fd4e3d64e64
2024-09-04 16:01:44 +00:00
drh 109025c0a4 Put a proper shebang at the start of the testrunner.tcl script and make the
script executable.

FossilOrigin-Name: c0c6e9abebf76358625f30a179658319b260baba6eded2a4c5ad356143e36f97
2024-09-04 13:42:19 +00:00
drh 3c72072a6f Make extra efforts to delete the over-size directory names created by
the win32longpath.test module.

FossilOrigin-Name: 3c8035ed3f023fb31f65f298fb9ce19d4fa7a5511bd90877b27969f5f0892472
2024-09-04 13:09:58 +00:00
drh c81ab76cd9 Add the "joblist" command to testrunner.tcl
FossilOrigin-Name: f64469f4806d4d5d7103c171a37a542c7aab9db09a226bccd8411e9ccd55353d
2024-09-04 11:22:47 +00:00
drh fd486258a0 Enhance the "errors" command in testrunner.tcl so that it accepts the
"-s" or "--summary" argument to see a list of failed jobs, and so that
an additional argument is a GLOB pattern that restricts the output to
jobs whose names match that pattern.

FossilOrigin-Name: dcbebe30f594a99e23b5ccd8d199b92118204a3e52e75c78d98c394601252e81
2024-09-03 16:04:34 +00:00
drh 940cdc94f3 Fix ext/consio so that it works correctly with SQLITE_USE_ONLY_WIN32.
FossilOrigin-Name: efc6f3d7e92a25f440fb8d392daf325af5ca7dca104a5bb4bd59f7df93af53b0
2024-09-03 14:15:57 +00:00
drh 23a16c8387 In testrunner.tcl, compile the Windows Default configuration using
SQLITE_ENABLE_STMT_SCANSTATUS.

FossilOrigin-Name: 49e8b1635f29d9fd0dc2ef6e312fd4129f2283f68e9423d95ff9b55077688ad7
2024-09-03 14:00:36 +00:00
drh e6e49bfef2 Fix harmless compiler warnings in the percentile extension.
FossilOrigin-Name: c5557f281c6294b6db6682349d245feac7c6ce7f4f61356f486afdf186c566c4
2024-09-03 12:41:21 +00:00
drh 06638117bb In testrunner.tcl, allow setting njob to zero, which causes no new jobs
to be launched and for the process to shut down once all current jobs are
completed.

FossilOrigin-Name: 0ef65fd4ba17def4c13986365b3af300c4024725af4bc314845d1af8be568ab4
2024-09-03 10:53:32 +00:00
larrybr 22cd1eec5a Cause cfGets() (under SQLITE_USE_ONLY_WIN32) to better emulate fgets().
FossilOrigin-Name: 2d783524d1671d988ebb1b21c83de99c9f335963b6c20cf4df612f58c13da913
2024-09-03 02:09:13 +00:00
drh 7c6f2880aa Fix possible NULL pointer dereference following OOM in the new error reporting
logic of the percentile extension.

FossilOrigin-Name: 7891a266c4425722ae8b9231397ef9e42e2432be9e6b70632dfaf9ff15300d2c
2024-09-02 21:59:31 +00:00
dan 70989b6f59 Fix a technically undefined signed integer overflow in fts5.
FossilOrigin-Name: e6bec37ea1ca51e1d048941ce4c5211d8fc5c5e3556a1441f9c79b036843f9e3
2024-09-02 18:41:59 +00:00
drh ef7c692baf Make the percential extension easier to incorporate as a built-in on Windows
applications.

FossilOrigin-Name: 831e2be4117dc7f5113f66d3e484ca34e4405444ac7b0def12ee9a00608d40da
2024-09-02 17:27:10 +00:00
drh da52f11250 Remove some debug/test code from percentile. Make the extension easier to
statically link.

FossilOrigin-Name: 6e5f146e274b210749dd8923a2da56905eb098b5a66699ff9130e3e51b1ff662
2024-09-02 14:46:56 +00:00
drh 7a29505e57 Enhance the percentile extension to support percentile_cont() and
percentile_disc().  Add support for ordered-set aggregate notation in 
the parser when compiling with SQLITE_ENABLE_ORDERED_SET_AGGREGATES.  A
new function property SQLITE_SELFORDER1 must appear on any aggregate function
that wants to take advantage of the ordered-set aggregate notation.

FossilOrigin-Name: 557bd245ef24af15da1374762bbeb9b8b0241da06e604efdf00d567a9ed09216
2024-09-02 12:07:37 +00:00
drh d281889ac8 Improved error messages on percentile functions. More tests cases for
percentile and for ordered-set aggregates.

FossilOrigin-Name: e1bca168e70335fa2f9537632fd16e374c566a564fab4974c0b8f61cb63d08ce
2024-09-02 11:17:04 +00:00
drh a955ec806a Change the name of the enabling compile-time macro to
SQLITE_ENABLE_ORDERED_SET_AGGREGATES.

FossilOrigin-Name: 3b1cdddf8339cc339ec74cd8be2bfa42e62b500048a444eb9e5d9817bc4702ae
2024-09-02 09:40:37 +00:00
drh b5df31d15f More internal documentation improvements.
FossilOrigin-Name: 8b91b74931c36e1955ef933a07d8ec40c8b54c882efe7084d179168867c5244f
2024-09-01 23:56:14 +00:00
drh b9a6e42a55 Improved documentation of recent enhancements to the percentile extension.
FossilOrigin-Name: 51e7b4c9cf19a5986432a76c5fd30cef715c170a403d7b4304a8c5888c445a91
2024-09-01 23:47:20 +00:00
drh 1c30df3598 The WITHIN GROUP (ORDER BY ...) syntax is now a compile-time option:
SQLITE_ENABLE_ORDERED_SET_FUNCS.  There is no increment in the code size
if the option is omitted.

FossilOrigin-Name: c9367e2532d653738af27c4d92810eb648a9e12f72d7223017c87cb0dddc6804
2024-09-01 23:27:34 +00:00
drh ca447020ae Implement percentile_cont() and percentile_disc().
FossilOrigin-Name: b1a93f67d6b21df6fe3247c9333fead61dd425574f66ea3eb06b80c2b06f616a
2024-09-01 20:24:24 +00:00
drh 7aa01a0ffc No prepare-time penality for ordered-set aggregates for applications that
do not use them.

FossilOrigin-Name: e070c16d2183312e416ff6af770346041e4d3836c4db2c9ea6049f63fb0eaa07
2024-09-01 19:19:26 +00:00
drh 5d5d6194c9 Merge fixes from trunk into the ordere-set-agg branch.
FossilOrigin-Name: 7528ddcfdf155116353266e00e6408c526e29f04cb00ca2d9e84b105329b17c0
2024-09-01 18:57:52 +00:00
drh c97ad9b4e1 Improved sort function in the percentile extension.
FossilOrigin-Name: 9f84e8d59bcda642e732565e840f6a880a01b2fc65af2651248f6a8a6e1cb65a
2024-09-01 18:54:31 +00:00
drh 41155d8885 Fix to the quicksort algorithm in the percentile extension.
FossilOrigin-Name: 54313f74b24c46f1afa1ff082ef569fa46938527095be358015e7047e17702ac
2024-09-01 10:52:20 +00:00
drh df2d14b86e Add error checking: Do not allow functions other than those in the
percentile extension to use the ordered-set aggregate notation.

FossilOrigin-Name: 317d901429303340290334dbe7680a36339df0a50b586e3f71b6c5e5eba6d411
2024-08-31 22:22:24 +00:00
drh a239ece378 Demonstration of how ordered-set aggregates might be parsed and integrated
into the existing parse tree, should we decide to support them.

FossilOrigin-Name: ef9777890001ba0122d3add799795e118fd87243f42731ab84d4748b67605647
2024-08-31 20:09:37 +00:00
drh c1042cd133 Include percentile() and merge() in the fuzzcheck test utility.
FossilOrigin-Name: d1d0942a947803d45a1fd9068f3518cf412178b6b9bafcb82db44c52d5820c11
2024-08-31 19:24:17 +00:00
drh 65b1244781 Omit the percentile_cont() function added by [095c22e62248f8ef] (and not yet
released) since its usage conflicts with the PG percentile_cont() function.

FossilOrigin-Name: 3fe0a852978f3f1218e37a58f0d3b54016d4116a3301aa32efa7c4c12c767755
2024-08-31 18:35:10 +00:00
drh 49af3dfbf4 Allow percentile() and median() to act as window functions.
FossilOrigin-Name: 94cf96af8fee55449080655bddf81cbf5c078a02d7bb5dd7e4903b36f83a8c07
2024-08-31 18:08:31 +00:00
drh a5315a6ece Still more test cases.
FossilOrigin-Name: f09904608195dac38172b0dd4dcab3190f33c116d468beff27f913a7433b400e
2024-08-31 17:50:06 +00:00
drh f138110dfd Add more test cases.
FossilOrigin-Name: 0d0e5456793b4bef673ebc7fcc1c393a6d3c817363d948ddfe06d60eab56dc24
2024-08-31 17:27:55 +00:00
drh ad8ec9db63 Avoid unnecessary sort operations when running one of the percentile
aggregates as a window function.

FossilOrigin-Name: 5d311536211eb1e3c887ceb7e6516d3900e6eebbccc8c445dd43cdd556182728
2024-08-31 16:55:14 +00:00
drh 129767958a Test cases added.
FossilOrigin-Name: 25e68229843cc84978955817285550085d1306ba4ce3b0517dd00e5d05b9ae0a
2024-08-31 15:02:07 +00:00
drh 90fa4c7b2c Enhance the percentile() and median() extension functions so that they can be
window functions.

FossilOrigin-Name: 4d0e3df4b9c609755977b8a462126242d2be1310c0122a8d4ba76d98d32a7230
2024-08-31 14:31:17 +00:00
drh 3196c349d1 Do not fail the omittest if ICU libraries are not installed.
FossilOrigin-Name: ddc55efd2d59df3f20743b0533550436da945453c069025a3f871d28d40e13d4
2024-08-30 17:33:25 +00:00
drh 0337b9a628 New makefile target: "tidy". The "tidy" target removes all build products
be leaves behind test results.  The "clean" target has been enhanced to do a
better job.  The tool/omittest.tcl script is rewritten to work on the
configure-generated Makefile and to require no arguments.

FossilOrigin-Name: e48add02695a41b26a04e7942b5333e2bf4dc5598e363367aea3a4690982667d
2024-08-30 16:51:41 +00:00
drh 6cb12337b9 A couple of #defines so that the build work with SQLITE_OMIT_FLOATING_POINT.
FossilOrigin-Name: be768f80c703ac1645251ccbac83e07b3ea4cc231c8ea7e66374a4f78361f10b
2024-08-30 16:43:36 +00:00
drh c589d5ab06 Rework the tool/omittest.tcl script so that it works with the
configure-generated Makefile, and requires no arguments.
Update the configure-generated Makefile with a new "tidy" target which
is like "clean" except that is preserves test logs.  Use "make tidy" to
force everything to be recompiled from scratch without destroying logs.

FossilOrigin-Name: 99491df19d68df1f0515bd5ec9240ef3dd6e0fa38a6c837a38a16a873f8e2cbb
2024-08-30 16:24:49 +00:00
drh 28db1a68ba Improvements to "make clean" on unix.
FossilOrigin-Name: a1d775f07528192b09566ff1546b067ffbee0db5812e424e6b7f3cc33a67dc83
2024-08-30 12:10:28 +00:00
drh 11397ce104 In the testrunner.tcl status report, try to provide a rough estimate of
the time remaining.

FossilOrigin-Name: 90bc616d20e8c247691c45de2a28d41c1632b21152dc34253eefc179a90ab31f
2024-08-30 01:11:19 +00:00
drh 494ba30c9b Sync the autoconf/Makefile.msc with the main ./Makefile.msc
FossilOrigin-Name: 9de47c3611ca05e03a661807a06c6c5c0b5c6548ea7a8d73cb63832d2dff9d0e
2024-08-29 23:32:16 +00:00
drh 6a18c9e06a All makefiles are responsive to OPTIONS=... command-line arguments, and add
the RHS value of OPTIONS= to builds and to lemon and other build steps that
might respond to -D or -U options.

FossilOrigin-Name: 854b3776ee1fcaa5931e3a0ed104978ca350d218e553586d1c40c2420e1be498
2024-08-29 18:32:56 +00:00
dan ccd34894e1 Fix a case where the BTCF_AtLast flag was being left set incorrectly. This was causing obscure window function queries to fail.
FossilOrigin-Name: e042eb024738a83eed92cd2dfac3d2a50d2589715a3d81b1a494564dd7d8e7fa
2024-08-29 16:27:57 +00:00
drh c1547d1f7a Do not allow sqlite3_blob_open() to work on a any table that contains
generated columns, even columns of the table which are not generated themselves,
because such columns might be part of the expression of a STORED column.
This restriction could be relaxed some, but that would be a lot of code
for something that nobody ever uses.

FossilOrigin-Name: 6e84947123339f0ea2b7dabc6134a621eed09317f81647f15870ed50a0f7d1bc
2024-08-28 19:13:16 +00:00
dan 50ca8af6f2 Fix a dropped error code in fts5.
FossilOrigin-Name: df55502e4f412e5b1daccf82f11fa4eb932047d9972dcd16e36be00cf09f78e1
2024-08-28 15:54:46 +00:00
drh 8db3fc5488 Update the README.md file to recommend running "devtest" instead of "mdevtest".
FossilOrigin-Name: eb016f66ea2c7ebacf8c57495843db3414602d062e4a430f2cc603c88b10c3f9
2024-08-28 13:55:46 +00:00
drh ba5994b181 Maybe [7420b13238da4e6b] was not such a good idea. Restore "make test" so
that it works as before - running a single-threaded test over the source tree
with options specified by ./configure and similar.  Instead, change the
"make devtest" target so that runs the automated multi-threaded tests on 
a standard configuration.

FossilOrigin-Name: dc9fee980d4f4b5a569628702e52cef9e5d8e6c69c2b84546dce47e3e514775e
2024-08-28 13:51:51 +00:00
drh 3341f5ce85 Minor wording change on testrunner output.
FossilOrigin-Name: 115e68597957a9ee80de7f554ee3768c992051687c8f07eaf3a9fcaab7efd44e
2024-08-28 13:34:20 +00:00
drh d6b56d65a8 Update the "make test" target so that it is really just "mdevtest" with
"srctree-check" and "sourcetest".

FossilOrigin-Name: 7420b13238da4e6bfb1589eaf3cfd842fe3c4b0f3b6a3b49c24cd70589bf4809
2024-08-28 12:10:51 +00:00
drh 4f2f91bf08 Further improvements to the status display in order to maximum the amount of
information shown on the limited screen realestate available when running
via "watch" or in continuous monitoring mode.  All details are still shown
when doing a stand-alone "status".

FossilOrigin-Name: 557a2c65f5ae1d8cb1858c17da0fe64fbfba83d787cfb7f2f21582960a8b9eac
2024-08-28 11:03:58 +00:00
drh 242e064978 Only limit the number of failures reported by testrunner status if using
VT100 cursor movement.  For a straight-up "status" command, show everything.

FossilOrigin-Name: 791237e0f4b67f0197ae11e966554edeade0c443289d2ade00470d23bf5e8ec8
2024-08-28 10:36:18 +00:00
drh 4a90f81a6d In the testrunner status display, limit the number of reported failed jobs
to avoid overflowing the terminal when there are many failures.

FossilOrigin-Name: ffeaa4d5d73871cbdf1ef70b9845d921ebdb96e964d232661a5048cab7d744ed
2024-08-28 10:25:44 +00:00
drh a88d61824d Disable shell test cases that require virtual tables when testfixture is
built using SQLITE_OMIT_VIRTUALTABLE.

FossilOrigin-Name: 8c73d54fd1e250fcd7f30741cfbd169af9aaecc2096c0c8a9486abaa064d69af
2024-08-28 09:47:29 +00:00
drh af43eddc23 Reenable SQLITE_OMIT_VIRTUALTABLE on the Device-One alignment for testrunner.
FossilOrigin-Name: 8f2cb357634ec0b5aef14f3d967e76db236f8899f3201efc80c264f548cc1b0b
2024-08-28 09:31:17 +00:00
drh b5b4ca2a11 Changes to the way "release" tests were constructed in [d03d35eebaf82709]
were incorrect.  Fixed here.  Also enhance --explain to chose permutation
configurations and so that PATTERNS on the the command line can match
against permutation configurations.

FossilOrigin-Name: 1f962ffc9e956a9d6311ed9c02fea13c0fe056283ee2c650a2312a258808b3b3
2024-08-27 22:28:03 +00:00
drh c3c645ef46 Improvements to --status overwrite in testrunner.
FossilOrigin-Name: 26372762ab1451eb95d29367f5b2534bde616a37e5e757e72ba2cfe42571d180
2024-08-27 21:44:45 +00:00
dan f5a9b58c8b Avoid reading the structure record from within the fts5 xConnect method.
FossilOrigin-Name: 6a6ce343b249e269229867b2c2f107a49ac8a8f24ad66801718ef01159655319
2024-08-27 20:37:30 +00:00
drh ce018f5bb3 Further minor improvements and tweaks to the testrunner --status display.
FossilOrigin-Name: 7d1ccc6dfc9abe053baaf39f68e9fb14001f5032a52b85fe1e4b752e48317536
2024-08-27 19:49:51 +00:00
61 changed files with 4121 additions and 1002 deletions
+82 -45
View File
@@ -83,9 +83,13 @@ TEMP_STORE = -DSQLITE_TEMP_STORE=@TEMP_STORE@
# based on configuration. (-DSQLITE_OMIT*, -DSQLITE_ENABLE*).
# The same set of OMIT and ENABLE flags should be passed to the
# LEMON parser generator and the mkkeywordhash tool as well.
OPT_FEATURE_FLAGS = @OPT_FEATURE_FLAGS@
#
# Add OPTIONS=... on the command line to append additional options
# to the OPT_FEATURE_FLAGS.
#
OPT_FEATURE_FLAGS = @OPT_FEATURE_FLAGS@ $(OPTIONS)
TCC += $(OPT_FEATURE_FLAGS)
TCC += $(OPT_FEATURE_FLAGS)
# Add in any optional parameters specified on the make commane line
# ie. make "OPTS=-DSQLITE_ENABLE_FOO=1 -DSQLITE_OMIT_FOO=1".
@@ -646,6 +650,7 @@ FUZZCHECK_SRC += $(TOP)/test/fuzzinvariants.c
FUZZCHECK_SRC += $(TOP)/ext/recover/dbdata.c
FUZZCHECK_SRC += $(TOP)/ext/recover/sqlite3recover.c
FUZZCHECK_SRC += $(TOP)/test/vt02.c
FUZZCHECK_SRC += $(TOP)/ext/misc/percentile.c
FUZZCHECK_SRC += $(TOP)/ext/misc/randomjson.c
DBFUZZ_OPT =
ST_OPT = -DSQLITE_OS_KV_OPTIONAL
@@ -656,11 +661,16 @@ SQLITE3_SHELL_TARGET_ = sqlite3$(TEXE)
SQLITE3_SHELL_TARGET_1 =
SQLITE3_SHELL_TARGET = $(SQLITE3_SHELL_TARGET_@HAVE_WASI_SDK@)
# Use $(libtclsqlite3.la_$(HAVE_TCL)) to resolve to either
# libtclsqlite3.la or an empty value.
libtclsqlite3.la_0 =
libtclsqlite3.la_1 = libtclsqlite3.la
# This is the default Makefile target. The objects listed here
# are what get build when you type just "make" with no arguments.
#
all: sqlite3.h libsqlite3.la $(SQLITE3_SHELL_TARGET) \
$(HAVE_TCL:1=libtclsqlite3.la)
$(libtclsqlite3.la_$(HAVE_TCL))
Makefile: $(TOP)/Makefile.in
./config.status
@@ -690,6 +700,20 @@ sqldiff$(TEXE): $(TOP)/tool/sqldiff.c sqlite3.lo sqlite3.h
dbhash$(TEXE): $(TOP)/tool/dbhash.c sqlite3.lo sqlite3.h
$(LTLINK) -o $@ $(TOP)/tool/dbhash.c sqlite3.lo $(TLIBS)
RSYNC_SRC = \
$(TOP)/tool/sqlite3-rsync.c \
sqlite3.c
RSYNC_OPT = \
-DSQLITE_ENABLE_DBPAGE_VTAB \
-USQLITE_THREADSAFE \
-DSQLITE_THREADSAFE=0 \
-DSQLITE_OMIT_LOAD_EXTENSION \
-DSQLITE_OMIT_DEPRECATED
sqlite3-rsync$(TEXE): $(RSYNC_SRC)
$(TCC) -o $@ $(RSYNC_OPT) $(RSYNC_SRC) $(TLIBS)
scrub$(TEXE): $(TOP)/ext/misc/scrub.c sqlite3.lo
$(LTLINK) -o $@ -I. -DSCRUB_STANDALONE \
$(TOP)/ext/misc/scrub.c sqlite3.lo $(TLIBS)
@@ -1178,11 +1202,14 @@ SHELL_DEP = \
$(TOP)/ext/misc/ieee754.c \
$(TOP)/ext/misc/memtrace.c \
$(TOP)/ext/misc/pcachetrace.c \
$(TOP)/ext/misc/percentile.c \
$(TOP)/ext/misc/regexp.c \
$(TOP)/ext/misc/series.c \
$(TOP)/ext/misc/sha1.c \
$(TOP)/ext/misc/shathree.c \
$(TOP)/ext/misc/sqlar.c \
$(TOP)/ext/misc/uint.c \
$(TOP)/ext/misc/vfstrace.c \
$(TOP)/ext/misc/zipfile.c \
$(TOP)/ext/recover/dbdata.c \
$(TOP)/ext/recover/sqlite3recover.c \
@@ -1363,9 +1390,14 @@ tcltest: ./testfixture$(TEXE)
testrunner: testfixture$(TEXE)
./testfixture$(TEXE) $(TOP)/test/testrunner.tcl
# Runs both fuzztest and testrunner, consecutively.
# This is the testing target preferred by the core SQLite developers.
# It runs tests under a standard configuration, regardless of how
# ./configure was run. The devs run "make devtest" prior to each
# check-in, at a minimum. Probably other tests too, but at least this
# one.
#
devtest: srctree-check testfixture$(TEXE) fuzztest testrunner
devtest: srctree-check sourcetest
$(TCLSH_CMD) $(TOP)/test/testrunner.tcl mdevtest $(TSTRNNR_OPTS)
mdevtest: srctree-check has_tclsh85
$(TCLSH_CMD) $(TOP)/test/testrunner.tcl mdevtest $(TSTRNNR_OPTS)
@@ -1381,16 +1413,19 @@ srctree-check: $(TOP)/tool/srctree-check.tcl
# Testing for a release
#
releasetest: srctree-check testfixture$(TEXE)
./testfixture$(TEXE) $(TOP)/test/testrunner.tcl release $(TSTRNNR_OPTS)
releasetest: srctree-check has_tclsh85 verify-source
$(TCLSH_CMD) $(TOP)/test/testrunner.tcl release $(TSTRNNR_OPTS)
# Minimal testing that runs in less than 3 minutes
#
quicktest: ./testfixture$(TEXE)
./testfixture$(TEXE) $(TOP)/test/extraquick.test $(TESTOPTS)
# This is the common case. Run many tests that do not take too long,
# including fuzzcheck, sqlite3_analyzer, and sqldiff tests.
# Try to run tests on whatever options are specified by the
# ./configure. The developers seldom use this target. Instead
# they use "make devtest" which runs tests on a standard set of
# options regardless of how SQLite is configured. This "test"
# target is provided for legacy only.
#
test: srctree-check fuzztest sourcetest $(TESTPROGS) tcltest
@@ -1407,8 +1442,8 @@ valgrindtest: $(TESTPROGS) valgrindfuzz
smoketest: $(TESTPROGS) fuzzcheck$(TEXE)
./testfixture$(TEXE) $(TOP)/test/main.test $(TESTOPTS)
shelltest: $(TESTPROGS)
./testfixture$(TEXT) $(TOP)/test/permutations.test shell
shelltest:
$(TCLSH_CMD) $(TOP)/test/testrunner.tcl release shell
sqlite3_analyzer.c: sqlite3.c $(TOP)/src/tclsqlite.c $(TOP)/tool/spaceanal.tcl $(TOP)/tool/mkccode.tcl $(TOP)/tool/sqlite3_analyzer.c.in has_tclsh85
$(TCLSH_CMD) $(TOP)/tool/mkccode.tcl $(TOP)/tool/sqlite3_analyzer.c.in >sqlite3_analyzer.c
@@ -1552,7 +1587,12 @@ lib_install: libsqlite3.la
$(INSTALL) -d $(DESTDIR)$(libdir)
$(LTINSTALL) libsqlite3.la $(DESTDIR)$(libdir)
install: sqlite3$(TEXE) lib_install sqlite3.h sqlite3.pc ${HAVE_TCL:1=tcl_install}
# Use $(tcl_install_$(HAVE_TCL)) to resolve to either tcl_install or
# an empty value.
tcl_install_0 =
tcl_install_1 = tcl_install
install: sqlite3$(TEXE) lib_install sqlite3.h sqlite3.pc $(tcl_install_$(HAVE_TCL))
$(INSTALL) -d $(DESTDIR)$(bindir)
$(LTINSTALL) sqlite3$(TEXE) $(DESTDIR)$(bindir)
$(INSTALL) -d $(DESTDIR)$(includedir)
@@ -1594,43 +1634,40 @@ tclextension-uninstall:
tclextension-list:
$(TCLSH_CMD) $(TOP)/tool/buildtclext.tcl --info
clean:
rm -f *.lo *.la *.o sqlite3$(TEXE) libsqlite3.la
rm -f sqlite3.h opcodes.*
rm -rf .libs .deps
rm -f lemon$(BEXE) lempar.c parse.* sqlite*.tar.gz
rm -f mkkeywordhash$(BEXE) keywordhash.h
rm -f mksourceid$(BEXE)
rm -f *.da *.bb *.bbg gmon.out
rm -rf tsrc .target_source
rm -f tclsqlite3$(TEXE)
rm -f testfixture$(TEXE) test.db
# Remove build products sufficient so that subsequent makes will recompile
# everything from scratch. Do not remove:
#
# * test results and test logs
# * output from ./configure
#
tidy:
rm -f *.lo *.la *.o *.c *.da *.bb *.bbg gmon.* *.rws sqlite3$(TEXE)
rm -f fts5.h keywordhash.h opcodes.h sqlite3.h sqlite3ext.h sqlite3session.h
rm -rf .libs .deps tsrc .target_source
rm -f lemon$(BEXE) sqlite*.tar.gz
rm -f mkkeywordhash$(BEXE) mksourceid$(BEXE)
rm -f parse.* fts5parse.*
rm -f tclsqlite3$(TEXE) $(TESTPROGS)
rm -f LogEst$(TEXE) fts3view$(TEXE) rollback-test$(TEXE) showdb$(TEXE)
rm -f showjournal$(TEXE) showstat4$(TEXE) showwal$(TEXE) speedtest1$(TEXE)
rm -f wordcount$(TEXE) changeset$(TEXE)
rm -f version-info$(TEXT)
rm -f sqlite3.dll sqlite3.lib sqlite3.exp sqlite3.def
rm -f sqlite3.c
rm -f sqlite3rc.h
rm -f shell.c sqlite3ext.h
rm -f sqlite3_analyzer$(TEXE) sqlite3_analyzer.c
rm -f sqlite-*-output.vsix
rm -f mptester mptester.exe
rm -f rbu rbu.exe
rm -f srcck1 srcck1.exe
rm -f fuzzershell fuzzershell.exe
rm -f fuzzcheck fuzzcheck.exe
rm -f sqldiff sqldiff.exe
rm -f dbhash dbhash.exe
rm -f fts5.* fts5parse.*
rm -f threadtest5
rm -f src-verify
rm -f custom.rws
rm -f has_tclsh84 has_tclsh85
rm -f wordcount$(TEXE) changeset$(TEXE) version-info$(TEXE)
rm -f *.dll *.lib *.exp *.def *.pc *.vsix *.so *.dylib pkgIndex.tcl
rm -f sqlite3_analyzer$(TEXE)
rm -f mptester$(TEXE) rbu$(TEXE) srcck1$(TEXE)
rm -f fuzzershell$(TEXE) fuzzcheck$(TEXE) sqldiff$(TEXE) dbhash$(TEXE)
rm -f threadtest5$(TEXE)
rm -f src-verify has_tclsh*
# Removes build products and test logs. Retains ./configure outputs.
#
clean: tidy
rm -rf omittest* testrunner* testdir*
# Clean up everything. No exceptions.
#
distclean: clean
rm -f sqlite_cfg.h config.log config.status libtool Makefile sqlite3.pc \
$(TESTPROGS)
rm -f sqlite_cfg.h config.log config.status Makefile $(LIBTOOL)
#
# Windows section
+48 -6
View File
@@ -379,6 +379,7 @@ SQLITE_TCL_DEP =
# the Windows platform.
#
!IFNDEF OPT_FEATURE_FLAGS
OPT_FEATURE_FLAGS = $(OPT_XTRA)
!IF $(MINIMAL_AMALGAMATION)==0
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_FTS3=1
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_FTS5=1
@@ -392,6 +393,14 @@ OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_BYTECODE_VTAB=1
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_COLUMN_METADATA=1
!ENDIF
# Additional feature-options above and beyond what are normally used can be
# be added using OPTIONS=.... on the command-line. These values are
# appended to the OPT_FEATURE_FLAGS variable.
#
!IFDEF OPTIONS
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) $(OPTIONS)
!ENDIF
# Should the session extension be enabled? If so, add compilation options
# to enable it.
#
@@ -929,7 +938,7 @@ TCLSUFFIX =
!ENDIF
!IFNDEF TCLDIR
TCLDIR = $(TOP)\compat\tcl
TCLDIR = C:\Tcl
!ENDIF
!IFNDEF TCLINCDIR
@@ -1758,6 +1767,7 @@ FUZZCHECK_SRC = $(FUZZCHECK_SRC) $(TOP)\test\fuzzinvariants.c
FUZZCHECK_SRC = $(FUZZCHECK_SRC) $(TOP)\test\vt02.c
FUZZCHECK_SRC = $(FUZZCHECK_SRC) $(TOP)\ext\recover\dbdata.c
FUZZCHECK_SRC = $(FUZZCHECK_SRC) $(TOP)\ext\recover\sqlite3recover.c
FUZZCHECK_SRC = $(FUZZCHECK_SRC) $(TOP)\ext\misc\percentile.c
FUZZCHECK_SRC = $(FUZZCHECK_SRC) $(TOP)\ext\misc\randomjson.c
OSSSHELL_SRC = $(TOP)\test\ossshell.c $(TOP)\test\ossfuzz.c
@@ -1857,6 +1867,19 @@ sqldiff.exe: $(TOP)\tool\sqldiff.c $(TOP)\ext\consio\console_io.h $(TOP)\ext\con
dbhash.exe: $(TOP)\tool\dbhash.c $(SQLITE3C) $(SQLITE3H)
$(LTLINK) $(NO_WARN) $(TOP)\tool\dbhash.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
RSYNC_SRC = \
$(TOP)\tool\sqlite3-rsync.c \
$(SQLITE3C)
RSYNC_OPT = \
-DSQLITE_ENABLE_DBPAGE_VTAB \
-DSQLITE_THREADSAFE=0 \
-DSQLITE_OMIT_LOAD_EXTENSION \
-DSQLITE_OMIT_DEPRECATED
sqlite3-rsync.exe: $(RSYNC_SRC) $(LIBRESOBJS)
$(LTLINK) $(RSYNC_OPT) $(NO_WARN) $(RSYNC_SRC) /link $(LDFLAGS) $(LTLINKOPTS) $(LIBRESOBJS)
scrub.exe: $(TOP)\ext\misc\scrub.c $(SQLITE3C) $(SQLITE3H)
$(LTLINK) $(NO_WARN) -DSCRUB_STANDALONE=1 $(TOP)\ext\misc\scrub.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
@@ -2304,11 +2327,14 @@ SHELL_DEP = \
$(TOP)\ext\misc\ieee754.c \
$(TOP)\ext\misc\memtrace.c \
$(TOP)\ext\misc\pcachetrace.c \
$(TOP)\ext\misc\percentile.c \
$(TOP)\ext\misc\regexp.c \
$(TOP)\ext\misc\series.c \
$(TOP)\ext\misc\sha1.c \
$(TOP)\ext\misc\shathree.c \
$(TOP)\ext\misc\sqlar.c \
$(TOP)\ext\misc\uint.c \
$(TOP)\ext\misc\vfstrace.c \
$(TOP)\ext\misc\zipfile.c \
$(TOP)\ext\recover\dbdata.c \
$(TOP)\ext\recover\sqlite3recover.c \
@@ -2535,6 +2561,13 @@ queryplantest: testfixture.exe shell
fuzztest: fuzzcheck.exe
.\fuzzcheck.exe $(FUZZDATA)
# Legacy testing target for third-party integrators. The SQLite
# developers seldom use this target themselves. Instead
# they use "nmake /f Makefile.msc devtest" which runs tests on
# a standard set of options
#
test: $(TESTPROGS) sourcetest fuzztest tcltest
# Minimal testing that runs in less than 3 minutes (on a fast machine)
#
quicktest: testfixture.exe sourcetest
@@ -2544,7 +2577,6 @@ quicktest: testfixture.exe sourcetest
# This is the common case. Run many tests that do not take too long,
# including fuzzcheck, sqlite3_analyzer, and sqldiff tests.
#
test: $(TESTPROGS) sourcetest fuzztest tcltest
# The veryquick.test TCL tests.
#
@@ -2558,17 +2590,27 @@ tcltest: testfixture.exe
testrunner: testfixture.exe
.\testfixture.exe $(TOP)\test\testrunner.tcl
# Runs both fuzztest and testrunner, consecutively.
# This is the testing target preferred by the core SQLite developers.
# It runs tests under a standard configuration. The devs run
# "nmake /f Makefile.msc devtest" prior to each check-in, at a minimum.
# Probably other tests too, but at least this one.
#
devtest: testfixture.exe fuzztest testrunner
devtest: srctree-check sourcetest
$(TCLSH_CMD) $(TOP)\test\testrunner.tcl mdevtest
mdevtest:
$(TCLSH_CMD) $(TOP)\test\testrunner.tcl mdevtest
# Validate that various generated files in the source tree
# are up-to-date.
#
srctree-check: $(TOP)\tool\srctree-check.tcl
$(TCLSH_CMD) $(TOP)\tool\srctree-check.tcl
# Testing for a release
#
releasetest: testfixture.exe
testfixture.exe $(TOP)\test\testrunner.tcl release
releasetest:
$(TCLSH_CMD) $(TOP)\test\testrunner.tcl release
smoketest: $(TESTPROGS)
+55 -29
View File
@@ -73,23 +73,26 @@ archives or [SQLite archives](https://sqlite.org/cli.html#sqlar) as follows:
then click on the "Tarball" or "ZIP Archive" links on the information
page.
To access sources directly using Fossil, first install Fossil version 2.0 or later.
Source tarballs and precompiled binaries available
[here](https://www.fossil-scm.org/home/uv/download.html). Fossil is
To access sources directly using [Fossil](https://fossil-scm.org/home),
first install Fossil version 2.0 or later.
Source tarballs and precompiled binaries available at
<https://fossil-scm.org/home/uv/download.html>. Fossil is
a stand-alone program. To install, simply download or build the single
executable file and put that file someplace on your $PATH.
Then run commands like this:
mkdir -p ~/sqlite ~/Fossils
mkdir -p ~/sqlite
cd ~/sqlite
fossil clone https://www.sqlite.org/src ~/Fossils/sqlite.fossil
fossil open ~/Fossils/sqlite.fossil
fossil open https://sqlite.org/src
After setting up a repository using the steps above, you can do
bandwidth-efficient updates to the latest version using:
The "fossil open" command will take two or three minutes. Afterwards,
you can do fast, bandwidth-efficient updates to the whatever versions
of SQLite you like. Some examples:
fossil update trunk ;# latest trunk check-in
fossil update release ;# latest official release
fossil update trunk ;# latest trunk check-in
fossil update release ;# latest official release
fossil update trunk:2024-01-01 ;# First trunk check-in after 2024-01-01
fossil update version-3.39.0 ;# Version 3.39.0
Or type "fossil ui" to get a web-based user interface.
@@ -103,17 +106,19 @@ script found at the root of the source tree. Then run "make".
For example:
tar xzf sqlite.tar.gz ;# Unpack the source tree into "sqlite"
mkdir bld ;# Build will occur in a sibling directory
cd bld ;# Change to the build directory
../sqlite/configure ;# Run the configure script
make sqlite3 ;# Builds the "sqlite3" command-line tool
make sqlite3.c ;# Build the "amalgamation" source file
make mdevtest ;# Run development tests (requires tcl-dev)
make releasetest ;# Run full release tests (requires tcl-dev)
make sqldiff ;# Builds the "sqldiff" command-line tool
make sqlite3_analyzer ;# Builds the "sqlite3_analyzer" tool (requires tcl-dev)
make tclextension-install ;# Build and install the SQLite TCL extension
apt install gcc make tcl-dev ;# Make sure you have all the necessary build tools
tar xzf sqlite.tar.gz ;# Unpack the source tree into "sqlite"
mkdir bld ;# Build will occur in a sibling directory
cd bld ;# Change to the build directory
../sqlite/configure ;# Run the configure script
make sqlite3 ;# Builds the "sqlite3" command-line tool
make sqlite3.c ;# Build the "amalgamation" source file
make sqldiff ;# Builds the "sqldiff" command-line tool
# Makefile targets below this point require tcl-dev
make tclextension-install ;# Build and install the SQLite TCL extension
make devtest ;# Run development tests
make releasetest ;# Run full release tests
make sqlite3_analyzer ;# Builds the "sqlite3_analyzer" tool
See the makefile for additional targets. For debugging builds, the
core developers typically run "configure" with options like this:
@@ -124,9 +129,19 @@ For release builds, the core developers usually do:
../sqlite/configure --enable-all
Almost all makefile targets require a "tclsh" TCL interpreter
version 8.6 or later. The targets marked with "(requires tcl-dev)" also require
the TCL development libraries.
Almost all makefile targets require a "tclsh" TCL interpreter version 8.6 or
later. The "tclextension-install" target and the test targets that follow
all require TCL development libraries too. ("apt install tcl-dev"). It is
helpful, but is not required, to install the SQLite TCL extension (the
"tclextension-install" target) prior to running tests. The "releasetest"
target has additional requiremenst, such as "valgrind".
On "make" command-lines, one can add "OPTIONS=..." to specify additional
compile-time options over and above those set by ./configure. For example,
to compile with the SQLITE_OMIT_DEPRECATED compile-time option, one could say:
./configure --enable-all
make OPTIONS=-DSQLITE_OMIT_DEPRECATED sqlite3
The configure script uses autoconf 2.61 and libtool. If the configure
script does not work out for you, there is a generic makefile named
@@ -136,7 +151,7 @@ show what changes are needed.
## Compiling for Windows Using MSVC
On Windows, all applicable build products can be compiled with MSVC.
On Windows, everything can be compiled with MSVC.
You will also need a working installation of TCL.
See the [compile-for-windows.md](doc/compile-for-windows.md) document for
additional information about how to install MSVC and TCL and configure your
@@ -150,19 +165,30 @@ TCL library, using a command like this:
SQLite uses "tclsh.exe" as part of the build process, and so that
program will need to be somewhere on your %PATH%. SQLite itself
does not contain any TCL code, but it does use TCL to help with the
build process and to run tests.
build process and to run tests. You may need to install TCL development
libraries in order to successfully complete some makefile targets.
It is helpful, but is not required, to install the SQLite TCL extension
(the "tclextension-install" target) prior to running tests.
Build using Makefile.msc. Example:
nmake /f Makefile.msc sqlite3.exe
nmake /f Makefile.msc sqlite3.c
nmake /f Makefile.msc mdevtest
nmake /f Makefile.msc releasetest
nmake /f Makefile.msc sqldiff.exe
# Makefile targets below this point require TCL development libraries
nmake /f Makefile.msc tclextension-install
nmake /f Makefile.msc devtest
nmake /f Makefile.msc releasetest
nmake /f Makefile.msc sqlite3_analyzer.exe
There are many other makefile targets. See comments in Makefile.msc for
details.
As with the unix Makefile, the OPTIONS=... argument can be passed on the nmake
command-line to enable new compile-time options. For example:
nmake /f Makefile.msc OPTIONS=-DSQLITE_OMIT_DEPRECATED sqlite3.exe
## Source Tree Map
* **src/** - This directory contains the primary source code for the
@@ -360,7 +386,7 @@ implementation. It will not be the easiest library in the world to hack.
* **VERSION**, **manifest**, and **manifest.uuid** - These files define
the current SQLite version number. The "VERSION" file is human generated,
but the "manifest" and "manifest.uuid" files are automatically generated
by the [Fossil version control system](https://fossil-scm/).
by the [Fossil version control system](https://fossil-scm.org/).
There are many other source files. Each has a succinct header comment that
describes its purpose and role within the larger system.
+9
View File
@@ -301,6 +301,7 @@ SQLITE3EXEPDB = /pdb:sqlite3sh.pdb
# the Windows platform.
#
!IFNDEF OPT_FEATURE_FLAGS
OPT_FEATURE_FLAGS = $(OPT_XTRA)
!IF $(MINIMAL_AMALGAMATION)==0
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_FTS3=1
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_FTS5=1
@@ -314,6 +315,14 @@ OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_BYTECODE_VTAB=1
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_COLUMN_METADATA=1
!ENDIF
# Additional feature-options above and beyond what are normally used can be
# be added using OPTIONS=.... on the command-line. These values are
# appended to the OPT_FEATURE_FLAGS variable.
#
!IFDEF OPTIONS
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) $(OPTIONS)
!ENDIF
# Should the session extension be enabled? If so, add compilation options
# to enable it.
#
+12 -1
View File
@@ -57,11 +57,22 @@ canonical source on a new Windows 11 PC, as of 2023-11-01:
<ul>
<li> `nmake /f makefile.msc`
<li> `nmake /f makefile.msc sqlite3.c`
<li> `nmake /f makefile.msc sqlite3.exe`
<li> `nmake /f makefile.msc sqldiff.exe`
<li> `nmake /f makefile.msc tclextension-install`
<li> `nmake /f makefile.msc devtest`
<li> `nmake /f makefile.msc releasetest`
<li> `nmake /f makefile.msc sqlite3.exe`
<li> `nmake /f makefile.msc sqlite3_analyzer.exe`
</ul>
It is not required that you run the "tclextension-install" target prior to
running tests. However, the tests will run more smoothly if you do.
The version of SQLite used for the TCL extension does *not* need to
correspond to the version of SQLite under test. So you can install the
SQLite TCL extension once, and then use it to test many different versions
of SQLite.
7. For a debugging build of the CLI, where the ".treetrace" and ".wheretrace"
commands work, add the DEBUG=3 argument to nmake. Like this:
<ul>
+8 -1
View File
@@ -655,6 +655,10 @@ cfWrite(const void *buf, size_t osz, size_t ocnt, FILE *pf){
return rv;
}
/* An fgets() equivalent, using Win32 file API for actual input.
** Input ends when given buffer is filled or a newline is read.
** If the FILE object is in text mode, swallows 0x0D. (ASCII CR)
*/
SQLITE_INTERNAL_LINKAGE char *
cfGets(char *cBuf, int n, FILE *pf){
int nci = 0;
@@ -665,7 +669,10 @@ cfGets(char *cBuf, int n, FILE *pf){
while( nci < n-1 ){
DWORD nr;
if( !ReadFile(fai.fh, cBuf+nci, 1, &nr, 0) || nr==0 ) break;
if( nr>0 && (!eatCR || cBuf[nci]!='\r') ) nci += nr;
if( nr>0 && (!eatCR || cBuf[nci]!='\r') ){
nci += nr;
if( cBuf[nci-nr]=='\n' ) break;
}
}
if( nci < n ) cBuf[nci] = 0;
return (nci>0)? cBuf : 0;
+2
View File
@@ -647,6 +647,8 @@ int sqlite3Fts5ExtractText(
void sqlite3Fts5ClearLocale(Fts5Config *pConfig);
int sqlite3Fts5IsLocaleValue(Fts5Config *pConfig, sqlite3_value *pVal);
/*
** End of interface to code in fts5.c.
**************************************************************************/
+1 -1
View File
@@ -2185,7 +2185,7 @@ static void fts5SegIterNext_None(
if( iOff<pIter->iEndofDoclist ){
/* Next entry is on the current page */
i64 iDelta;
u64 iDelta;
iOff += sqlite3Fts5GetVarint(&pIter->pLeaf->p[iOff], (u64*)&iDelta);
pIter->iLeafOffset = iOff;
pIter->iRowid += iDelta;
+106 -77
View File
@@ -83,8 +83,17 @@ struct Fts5Global {
Fts5TokenizerModule *pTok; /* First in list of all tokenizer modules */
Fts5TokenizerModule *pDfltTok; /* Default tokenizer module */
Fts5Cursor *pCsr; /* First in list of all open cursors */
u32 aLocaleHdr[4];
};
/*
** Size of header on fts5_locale() values. And macro to access a buffer
** containing a copy of the header from an Fts5Config pointer.
*/
#define FTS5_LOCALE_HDR_SIZE sizeof( ((Fts5Global*)0)->aLocaleHdr )
#define FTS5_LOCALE_HDR(pConfig) ((const u8*)(pConfig->pGlobal->aLocaleHdr))
/*
** Each auxiliary function registered with the FTS5 module is represented
** by an object of the following type. All such objects are stored as part
@@ -247,12 +256,6 @@ struct Fts5Cursor {
#define BitFlagAllTest(x,y) (((x) & (y))==(y))
#define BitFlagTest(x,y) (((x) & (y))!=0)
/*
** The subtype value and header bytes used by fts5_locale().
*/
#define FTS5_LOCALE_SUBTYPE ((unsigned int)'L')
#define FTS5_LOCALE_HEADER "\x00\xE0\xB2\xEB"
/*
** Macros to Set(), Clear() and Test() cursor flags.
@@ -427,8 +430,7 @@ static int fts5InitVtab(
/* Load the initial configuration */
if( rc==SQLITE_OK ){
rc = sqlite3Fts5IndexLoadConfig(pTab->p.pIndex);
sqlite3Fts5IndexRollback(pTab->p.pIndex);
rc = sqlite3Fts5ConfigLoad(pTab->p.pConfig, pTab->p.pConfig->iCookie-1);
}
if( rc==SQLITE_OK && pConfig->eContent==FTS5_CONTENT_NORMAL ){
@@ -1275,6 +1277,22 @@ void sqlite3Fts5ClearLocale(Fts5Config *pConfig){
fts5SetLocale(pConfig, 0, 0);
}
/*
** Return true if the value passed as the only argument is an
** fts5_locale() value.
*/
int sqlite3Fts5IsLocaleValue(Fts5Config *pConfig, sqlite3_value *pVal){
int ret = 0;
if( sqlite3_value_type(pVal)==SQLITE_BLOB ){
if( sqlite3_value_bytes(pVal)>(int)FTS5_LOCALE_HDR_SIZE
&& 0==memcmp(sqlite3_value_blob(pVal), FTS5_LOCALE_HDR(pConfig), 4)
){
ret = 1;
}
}
return ret;
}
/*
** This function is used to extract utf-8 text from an sqlite3_value. This
** is usually done in order to tokenize it. For example, when:
@@ -1293,17 +1311,15 @@ void sqlite3Fts5ClearLocale(Fts5Config *pConfig){
** 2) Combination text/locale blobs created by fts5_locale(). There
** are several cases for these:
**
** * Blobs tagged with FTS5_LOCALE_SUBTYPE.
** * Blobs read from the content table of a locale=1 external-content
** table, and
** * Blobs that have the 16-byte header, and
** * Blobs read from the content table of a locale=1 regular
** content table.
**
** The first two cases above should have the 4 byte FTS5_LOCALE_HEADER
** header. It is an error if a blob with the subtype or a blob read
** from the content table of an external content table does not have
** the required header. A blob read from the content table of a regular
** locale=1 table does not have the header. This is to save space.
** The first case above has the 16 byte FTS5_LOCALE_HDR(pConfig)
** header. It is an error if a blob read from the content table of
** an external content table does not have the required header. A blob
** read from the content table of a regular locale=1 table does not
** have the header. This is to save space.
**
** If successful, SQLITE_OK is returned and output parameters (*ppText)
** and (*pnText) are set to point to a buffer containing the extracted utf-8
@@ -1331,53 +1347,54 @@ int sqlite3Fts5ExtractText(
const char *pText = 0;
int nText = 0;
int rc = SQLITE_OK;
int bDecodeBlob = 0;
/* 0: Do not decode blob
** 1: Decode blob, expect fts5_locale() header
** 2: Decode blob, expect no fts5_locale() header
*/
int eDecodeBlob = 0;
assert( pbResetTokenizer==0 || *pbResetTokenizer==0 );
assert( bContent==0 || pConfig->eContent!=FTS5_CONTENT_NONE );
assert( bContent==0 || sqlite3_value_subtype(pVal)==0 );
if( sqlite3_value_type(pVal)==SQLITE_BLOB ){
if( sqlite3_value_subtype(pVal)==FTS5_LOCALE_SUBTYPE
|| (bContent && pConfig->bLocale)
if( bContent
&& pConfig->bLocale
&& pConfig->eContent==FTS5_CONTENT_NORMAL
){
bDecodeBlob = 1;
eDecodeBlob = 2;
}else if( sqlite3Fts5IsLocaleValue(pConfig, pVal) ){
eDecodeBlob = 1;
}else if( bContent && pConfig->bLocale ){
return SQLITE_ERROR;
}
}
if( bDecodeBlob ){
const int SZHDR = sizeof(FTS5_LOCALE_HEADER)-1;
if( eDecodeBlob ){
const u8 *pBlob = sqlite3_value_blob(pVal);
int nBlob = sqlite3_value_bytes(pVal);
int nLocale = 0;
/* Unless this blob was read from the %_content table of an
** FTS5_CONTENT_NORMAL table, it should have the 4 byte fts5_locale()
** header. Check for this. If it is not found, return an error. */
if( (!bContent || pConfig->eContent!=FTS5_CONTENT_NORMAL) ){
if( nBlob<SZHDR || memcmp(FTS5_LOCALE_HEADER, pBlob, SZHDR) ){
rc = SQLITE_ERROR;
}else{
pBlob += 4;
nBlob -= 4;
}
if( eDecodeBlob==1 ){
pBlob += FTS5_LOCALE_HDR_SIZE;
nBlob -= FTS5_LOCALE_HDR_SIZE;
}
if( rc==SQLITE_OK ){
int nLocale = 0;
for(nLocale=0; nLocale<nBlob; nLocale++){
if( pBlob[nLocale]==0x00 ) break;
}
if( nLocale==nBlob || nLocale==0 ){
rc = SQLITE_ERROR;
}else{
pText = (const char*)&pBlob[nLocale+1];
nText = nBlob-nLocale-1;
for(nLocale=0; nLocale<nBlob; nLocale++){
if( pBlob[nLocale]==0x00 ) break;
}
if( nLocale==nBlob || nLocale==0 ){
rc = SQLITE_ERROR;
}else{
pText = (const char*)&pBlob[nLocale+1];
nText = nBlob-nLocale-1;
if( pbResetTokenizer ){
fts5SetLocale(pConfig, (const char*)pBlob, nLocale);
*pbResetTokenizer = 1;
}
if( pbResetTokenizer ){
fts5SetLocale(pConfig, (const char*)pBlob, nLocale);
*pbResetTokenizer = 1;
}
}
@@ -1967,21 +1984,22 @@ static int fts5UpdateMethod(
else{
int eType1 = sqlite3_value_numeric_type(apVal[1]);
/* Ensure that no fts5_locale() values are written to locale=0 tables.
** And that no blobs except fts5_locale() blobs are written to indexed
** (i.e. not UNINDEXED) columns of locale=1 tables. */
int ii;
for(ii=0; ii<pConfig->nCol; ii++){
if( sqlite3_value_type(apVal[ii+2])==SQLITE_BLOB ){
int bSub = (sqlite3_value_subtype(apVal[ii+2])==FTS5_LOCALE_SUBTYPE);
if( (pConfig->bLocale && !bSub && pConfig->abUnindexed[ii]==0)
|| (pConfig->bLocale==0 && bSub)
){
if( pConfig->bLocale==0 ){
fts5SetVtabError(pTab, "fts5_locale() requires locale=1");
sqlite3_value *pVal = apVal[ii+2];
if( sqlite3_value_type(pVal)==SQLITE_BLOB ){
int isLocale = sqlite3Fts5IsLocaleValue(pConfig, pVal);
if( pConfig->bLocale ){
if( isLocale==0 && pConfig->abUnindexed[ii]==0 ){
rc = SQLITE_MISMATCH;
goto update_out;
}
}else{
if( isLocale ){
fts5SetVtabError(pTab, "fts5_locale() requires locale=1");
rc = SQLITE_MISMATCH;
goto update_out;
}
rc = SQLITE_MISMATCH;
goto update_out;
}
}
}
@@ -2068,9 +2086,11 @@ static int fts5SyncMethod(sqlite3_vtab *pVtab){
** Implementation of xBegin() method.
*/
static int fts5BeginMethod(sqlite3_vtab *pVtab){
fts5CheckTransactionState((Fts5FullTable*)pVtab, FTS5_BEGIN, 0);
fts5NewTransaction((Fts5FullTable*)pVtab);
return SQLITE_OK;
int rc = fts5NewTransaction((Fts5FullTable*)pVtab);
if( rc==SQLITE_OK ){
fts5CheckTransactionState((Fts5FullTable*)pVtab, FTS5_BEGIN, 0);
}
return rc;
}
/*
@@ -2715,21 +2735,21 @@ static int fts5ApiColumnLocale(
/* Load the value into pVal. pVal is a locale/text pair iff:
**
** 1) It is an SQLITE_BLOB, and
** 2) Either the subtype is FTS5_LOCALE_SUBTYPE, or else the
** value was loaded from an FTS5_CONTENT_NORMAL table, and
** 3) It does not begin with an 0x00 byte.
** 2) Either the FTS5_LOCALE_HDR header is present, or else the
** value was loaded from an FTS5_CONTENT_NORMAL table.
**
** If condition (1) is met but condition (2) is not, it is an error.
*/
sqlite3_value *pVal = sqlite3_column_value(pCsr->pStmt, iCol+1);
if( sqlite3_value_type(pVal)==SQLITE_BLOB ){
const u8 *pBlob = (const u8*)sqlite3_value_blob(pVal);
int nBlob = sqlite3_value_bytes(pVal);
if( pConfig->eContent==FTS5_CONTENT_EXTERNAL ){
const int SZHDR = sizeof(FTS5_LOCALE_HEADER)-1;
if( nBlob<SZHDR || memcmp(FTS5_LOCALE_HEADER, pBlob, SZHDR) ){
if( sqlite3Fts5IsLocaleValue(pConfig, pVal)==0 ){
rc = SQLITE_ERROR;
}
pBlob += 4;
nBlob -= 4;
pBlob += FTS5_LOCALE_HDR_SIZE;
nBlob -= FTS5_LOCALE_HDR_SIZE;
}
if( rc==SQLITE_OK ){
int nLocale = 0;
@@ -2986,18 +3006,19 @@ static void fts5ExtractValueFromColumn(
&& sqlite3_value_type(pVal)==SQLITE_BLOB
&& pConfig->abUnindexed[iCol]==0
){
const int SZHDR = sizeof(FTS5_LOCALE_HEADER)-1;
const u8 *pBlob = sqlite3_value_blob(pVal);
int nBlob = sqlite3_value_bytes(pVal);
int ii;
if( pConfig->eContent==FTS5_CONTENT_EXTERNAL ){
if( nBlob<SZHDR || memcmp(pBlob, FTS5_LOCALE_HEADER, SZHDR) ){
if( nBlob<(int)FTS5_LOCALE_HDR_SIZE
|| memcmp(pBlob, FTS5_LOCALE_HDR(pConfig), FTS5_LOCALE_HDR_SIZE)
){
sqlite3_result_error_code(pCtx, SQLITE_ERROR);
return;
}else{
pBlob += 4;
nBlob -= 4;
pBlob += FTS5_LOCALE_HDR_SIZE;
nBlob -= FTS5_LOCALE_HDR_SIZE;
}
}
@@ -3633,13 +3654,12 @@ static void fts5LocaleFunc(
if( zLocale==0 || zLocale[0]=='\0' ){
sqlite3_result_text(pCtx, zText, nText, SQLITE_TRANSIENT);
}else{
Fts5Global *p = (Fts5Global*)sqlite3_user_data(pCtx);
u8 *pBlob = 0;
u8 *pCsr = 0;
int nBlob = 0;
const int nHdr = 4;
assert( sizeof(FTS5_LOCALE_HEADER)==nHdr+1 );
nBlob = nHdr + nLocale + 1 + nText;
nBlob = FTS5_LOCALE_HDR_SIZE + nLocale + 1 + nText;
pBlob = (u8*)sqlite3_malloc(nBlob);
if( pBlob==0 ){
sqlite3_result_error_nomem(pCtx);
@@ -3647,8 +3667,8 @@ static void fts5LocaleFunc(
}
pCsr = pBlob;
memcpy(pCsr, FTS5_LOCALE_HEADER, nHdr);
pCsr += nHdr;
memcpy(pCsr, (const u8*)p->aLocaleHdr, FTS5_LOCALE_HDR_SIZE);
pCsr += FTS5_LOCALE_HDR_SIZE;
memcpy(pCsr, zLocale, nLocale);
pCsr += nLocale;
(*pCsr++) = 0x00;
@@ -3656,7 +3676,6 @@ static void fts5LocaleFunc(
assert( &pCsr[nText]==&pBlob[nBlob] );
sqlite3_result_blob(pCtx, pBlob, nBlob, sqlite3_free);
sqlite3_result_subtype(pCtx, FTS5_LOCALE_SUBTYPE);
}
}
@@ -3758,6 +3777,16 @@ static int fts5Init(sqlite3 *db){
pGlobal->api.xFindTokenizer = fts5FindTokenizer;
pGlobal->api.xCreateTokenizer_v2 = fts5CreateTokenizer_v2;
pGlobal->api.xFindTokenizer_v2 = fts5FindTokenizer_v2;
/* Initialize pGlobal->aLocaleHdr[] to a 128-bit pseudo-random vector.
** The constants below were generated randomly. */
sqlite3_randomness(sizeof(pGlobal->aLocaleHdr), pGlobal->aLocaleHdr);
pGlobal->aLocaleHdr[0] ^= 0xF924976D;
pGlobal->aLocaleHdr[1] ^= 0x16596E13;
pGlobal->aLocaleHdr[2] ^= 0x7C80BEAA;
pGlobal->aLocaleHdr[3] ^= 0x9B03A67F;
assert( sizeof(pGlobal->aLocaleHdr)==16 );
rc = sqlite3_create_module_v2(db, "fts5", &fts5Mod, p, fts5ModuleDestroy);
if( rc==SQLITE_OK ) rc = sqlite3Fts5IndexInit(db);
if( rc==SQLITE_OK ) rc = sqlite3Fts5ExprInit(pGlobal, db);
+12 -9
View File
@@ -891,23 +891,26 @@ int sqlite3Fts5StorageContentInsert(
/* This is an UPDATE statement, and column (i-2) was not modified.
** Retrieve the value from Fts5Storage.pSavedRow instead. */
pVal = sqlite3_column_value(p->pSavedRow, i-1);
}else if( sqlite3_value_subtype(pVal)==FTS5_LOCALE_SUBTYPE ){
}else if( sqlite3_value_type(pVal)==SQLITE_BLOB && pConfig->bLocale ){
assert( pConfig->bLocale );
assert( i>1 );
if( pConfig->abUnindexed[i-2] ){
/* At attempt to insert an fts5_locale() value into an UNINDEXED
** column. Strip the locale away and just bind the text. */
const char *pText = 0;
int nText = 0;
rc = sqlite3Fts5ExtractText(pConfig, pVal, 0, 0, &pText, &nText);
sqlite3_bind_text(pInsert, i, pText, nText, SQLITE_TRANSIENT);
if( sqlite3Fts5IsLocaleValue(pConfig, pVal) ){
/* At attempt to insert an fts5_locale() value into an UNINDEXED
** column. Strip the locale away and just bind the text. */
const char *pText = 0;
int nText = 0;
rc = sqlite3Fts5ExtractText(pConfig, pVal, 0, 0, &pText, &nText);
sqlite3_bind_text(pInsert, i, pText, nText, SQLITE_TRANSIENT);
continue;
}
}else{
const u8 *pBlob = (const u8*)sqlite3_value_blob(pVal);
int nBlob = sqlite3_value_bytes(pVal);
assert( nBlob>4 );
sqlite3_bind_blob(pInsert, i, pBlob+4, nBlob-4, SQLITE_TRANSIENT);
sqlite3_bind_blob(pInsert, i, pBlob+16, nBlob-16, SQLITE_TRANSIENT);
continue;
}
continue;
}
rc = sqlite3_bind_value(pInsert, i, pVal);
+7 -7
View File
@@ -680,11 +680,11 @@ do_test 12.0 {
do_catchsql_test 11.1 {
SELECT * FROM t1 WHERE t1 MATCH 'abandon';
} {1 {vtable constructor failed: t1}}
} {1 {database disk image is malformed}}
do_catchsql_test 11.2 {
INSERT INTO t1(t1, rank) VALUES('merge', 500);
} {1 {vtable constructor failed: t1}}
} {1 {database disk image is malformed}}
#-------------------------------------------------------------------------
#
@@ -1040,7 +1040,7 @@ do_test 16.0 {
do_catchsql_test 16.1 {
INSERT INTO t1(t1) VALUES('integrity-check');
} {1 {vtable constructor failed: t1}}
} {1 {database disk image is malformed}}
#--------------------------------------------------------------------------
reset_db
@@ -1126,7 +1126,7 @@ do_test 17.0 {
do_catchsql_test 17.1 {
SELECT * FROM t1 WHERE t1 MATCH 'abandon';
} {1 {vtable constructor failed: t1}}
} {1 {database disk image is malformed}}
#--------------------------------------------------------------------------
reset_db
@@ -1630,7 +1630,7 @@ do_test 20.0 {
do_catchsql_test 20.1 {
SELECT * FROM t1 WHERE t1 MATCH 'abandon';
} {1 {vtable constructor failed: t1}}
} {1 {database disk image is malformed}}
#-------------------------------------------------------------------------
reset_db
@@ -2100,7 +2100,7 @@ do_test 22.0 {
do_catchsql_test 22.1 {
INSERT INTO t1(t1) VALUES('optimize');
} {1 {vtable constructor failed: t1}}
} {1 {database disk image is malformed}}
#--------------------------------------------------------------------------
reset_db
@@ -3700,7 +3700,7 @@ do_catchsql_test 32.1 {
highlight(t1, 2, '[', ']')
FROM t1('g + h')
WHERE rank MATCH 'bm25(1.0, 1.0)' ORDER BY rank;
} {1 {vtable constructor failed: t1}}
} {1 {database disk image is malformed}}
do_catchsql_test 32.2 {
SELECT * FROM t3;
+3 -12
View File
@@ -32,20 +32,11 @@ sqlite3 db test.db
do_catchsql_test 1.2 {
SELECT * FROM t1
} {1 {vtable constructor failed: t1}}
} {1 {database disk image is malformed}}
do_catchsql_test 1.3 {
DROP TABLE t1
} {1 {vtable constructor failed: t1}}
do_test 1.4 {
sqlite3_db_config db DEFENSIVE 0
} {0}
do_test 1.5 {
sqlite3_fts5_drop_corrupt_table db main t1
} {}
do_test 1.6 {
sqlite3_db_config db DEFENSIVE -1
} {0}
do_execsql_test 1.7 {
} {0 {}}
do_execsql_test 1.4 {
SELECT * FROM sqlite_schema
}
+1 -1
View File
@@ -90,7 +90,7 @@ set ::res [db eval {SELECT rowid, x1 FROM x1 WHERE x1 MATCH '*reads'}]
do_faultsim_test 4 -faults oom-* -body {
db eval {SELECT rowid, x, x1 FROM x1 WHERE x1 MATCH '*reads'}
} -test {
faultsim_test_result {0 {0 {} 3}}
faultsim_test_result {0 {0 {} 2}}
}
#-------------------------------------------------------------------------
+21
View File
@@ -256,6 +256,27 @@ do_faultsim_test 10 -faults oom* -prep {
faultsim_test_result {0 hello}
}
#-------------------------------------------------------------------------
reset_db
do_execsql_test 11.0 {
CREATE VIRTUAL TABLE f1 USING fts5(content);
CREATE TABLE g1(id, content);
INSERT INTO g1 VALUES(30000, 'a b c');
INSERT INTO g1 VALUES(40000, 'd e f');
}
faultsim_save_and_close
do_faultsim_test 11 -faults oom* -prep {
faultsim_restore_and_reopen
} -body {
execsql {
INSERT INTO f1(rowid, content) SELECT id, content FROM g1;
}
} -test {
faultsim_test_result {0 {}}
}
finish_test
+56
View File
@@ -0,0 +1,56 @@
# 2024 September 3
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
# May you find forgiveness for yourself and forgive others.
# May you share freely, never taking more than you give.
#
#***********************************************************************
#
# This file contains tests focused on the integrity-check procedure.
#
source [file join [file dirname [info script]] fts5_common.tcl]
set testprefix fts5integrity2
# If SQLITE_ENABLE_FTS5 is not defined, omit this file.
ifcapable !fts5 {
finish_test
return
}
do_execsql_test 2.0 {
CREATE VIRTUAL TABLE t2 USING fts5(a, detail='none');
BEGIN;
INSERT INTO t2(rowid, a) VALUES(-1, 'hello world');
INSERT INTO t2(rowid, a) VALUES(9223372036854775807, 'hello world');
COMMIT;
}
do_execsql_test 2.1 {
SELECT rowid FROM t2('hello AND world');
} {-1 9223372036854775807}
#-------------------------------------------------------------------------
do_execsql_test 2.0 {
CREATE VIRTUAL TABLE t1 USING fts5(a, detail='none');
CREATE TABLE r1(r);
WITH c(x) AS (VALUES(1) UNION SELECT x<<1 FROM c)
INSERT INTO r1(r) SELECT -1-x FROM c;
INSERT INTO t1(rowid, a) SELECT r, 'abc' FROM r1;
}
do_execsql_test 2.1 {
PRAGMA integrity_check;
} {ok}
do_execsql_test 2.2 {
SELECT rowid FROM t1('abc') ORDER BY +rowid;
} [db eval {SELECT r FROM r1 ORDER BY r}]
finish_test
+27 -3
View File
@@ -488,7 +488,7 @@ foreach_detail_mode $::testprefix {
do_catchsql_test 10.2.$tn.4 "
SELECT * FROM ft( test_setsubtype($v, 76) );
" {1 {SQL logic error}}
" {1 {fts5: syntax error near ""}}
do_execsql_test 10.2.$tn.5 {
INSERT INTO ft(rowid, x) VALUES(1, 'hello world');
@@ -523,11 +523,11 @@ foreach_detail_mode $::testprefix {
do_catchsql_test 10.2.$tn.11 "
INSERT INTO ft(ft, rowid, x) VALUES('delete', 1, test_setsubtype($v,76) )
" {1 {SQL logic error}}
" {0 {}}
do_catchsql_test 10.2.$tn.12 "
INSERT INTO ft(rowid, x) VALUES(2, test_setsubtype($v,76) )
" {1 {SQL logic error}}
" {1 {datatype mismatch}}
do_execsql_test 10.2.$tn.13 {
INSERT INTO ft2(rowid, x) VALUES(1, 'hello world');
@@ -663,5 +663,29 @@ do_catchsql_test 13.2.7 {
FROM ft('one AND three') ORDER BY rowid
} {1 {non-integer argument passed to function fts5_get_locale()}}
#-------------------------------------------------------------------------
# Check that UPDATE statements that may affect more than one row work.
#
reset_db
do_execsql_test 14.1 {
CREATE VIRTUAL TABLE ft USING fts5(a, b, locale=1);
}
do_execsql_test 14.2 {
INSERT INTO ft VALUES('hello', 'world');
}
do_execsql_test 14.3 {
UPDATE ft SET b = fts5_locale('en_AU', 'world');
}
do_catchsql_test 14.4 {
INSERT INTO ft VALUES(X'abcd', X'1234');
} {1 {datatype mismatch}}
do_execsql_test 14.4 {
SELECT * FROM ft
} {hello world}
finish_test
+4 -4
View File
@@ -44,12 +44,12 @@ do_catchsql_test 1.2.2 {
do_catchsql_test 1.3.1 {
SELECT highlight(t1, 4, '<b>', '</b>') FROM t1('*reads');
} {1 {no such cursor: 1}}
} {1 {no such cursor: 0}}
do_catchsql_test 1.3.2 {
SELECT a FROM t1
WHERE rank = (SELECT highlight(t1, 4, '<b>', '</b>') FROM t1('*reads'));
} {1 {no such cursor: 1}}
} {1 {no such cursor: 0}}
db close
sqlite3 db test.db
@@ -57,12 +57,12 @@ sqlite3 db test.db
do_catchsql_test 1.3.3 {
SELECT a FROM t1
WHERE rank = (SELECT highlight(t1, 4, '<b>', '</b>') FROM t1('*reads'));
} {1 {no such cursor: 1}}
} {1 {no such cursor: 0}}
fts5_aux_test_functions db
do_catchsql_test 1.3.4 {
SELECT fts5_columntext(t1) FROM t1('*reads');
} {1 {no such cursor: 1}}
} {1 {no such cursor: 0}}
#-------------------------------------------------------------------------
reset_db
+11 -5
View File
@@ -93,15 +93,21 @@ foreach {tn cols tokens} {
10 {b} "i e"
11 {a} "i e"
} {
set fts "{$cols}:[join $tokens +]"
set where [list]
foreach c $cols { lappend where "pmatch($c, '$tokens')" }
set where [join $where " OR "]
set res [db eval "SELECT rowid FROM t3 WHERE $where"]
do_execsql_test "1.$tn.$fts->([llength $res] rows)" {
SELECT rowid FROM t3($fts)
} $res
foreach fts [list \
"{$cols}:[join $tokens +]" \
"{$cols}:NEAR([join $tokens +])" \
"{$cols}:NEAR([join $tokens +],1)" \
"{$cols}:NEAR([join $tokens +],111)" \
] {
set res [db eval "SELECT rowid FROM t3 WHERE $where"]
do_execsql_test "1.$tn.$fts->([llength $res] rows)" {
SELECT rowid FROM t3($fts)
} $res
}
}
do_execsql_test 2.0 {
+1 -1
View File
@@ -350,7 +350,7 @@ do_execsql_test 14.3 {
do_execsql_test 14.4 {
SELECT rowid, x, x1 FROM x1 WHERE x1 MATCH '*reads'
} {0 {} 3}
} {0 {} 2}
#-------------------------------------------------------------------------
reset_db
+303 -89
View File
@@ -11,7 +11,7 @@
******************************************************************************
**
** This file contains code to implement the percentile(Y,P) SQL function
** as described below:
** and similar as described below:
**
** (1) The percentile(Y,P) function is an aggregate function taking
** exactly two arguments.
@@ -60,31 +60,105 @@
**
** (13) A separate median(Y) function is the equivalent percentile(Y,50).
**
** (14) A separate percentile_cond(Y,X) function is the equivalent of
** percentile(Y,X*100.0).
** (14) A separate percentile_cont(Y,P) function is equivalent to
** percentile(Y,P/100.0). In other words, the fraction value in
** the second argument is in the range of 0 to 1 instead of 0 to 100.
**
** (15) A separate percentile_disc(Y,P) function is like
** percentile_cont(Y,P) except that instead of returning the weighted
** average of the nearest two input values, it returns the next lower
** value. So the percentile_disc(Y,P) will always return a value
** that was one of the inputs.
**
** (16) All of median(), percentile(Y,P), percentile_cont(Y,P) and
** percentile_disc(Y,P) can be used as window functions.
**
** Differences from standard SQL:
**
** * The percentile_cont(X,P) function is equivalent to the following in
** standard SQL:
**
** (percentile_cont(P) WITHIN GROUP (ORDER BY X))
**
** The SQLite syntax is much more compact. The standard SQL syntax
** is also supported if SQLite is compiled with the
** -DSQLITE_ENABLE_ORDERED_SET_AGGREGATES option.
**
** * No median(X) function exists in the SQL standard. App developers
** are expected to write "percentile_cont(0.5)WITHIN GROUP(ORDER BY X)".
**
** * No percentile(Y,P) function exists in the SQL standard. Instead of
** percential(Y,P), developers must write this:
** "percentile_cont(P/100.0) WITHIN GROUP (ORDER BY Y)". Note that
** the fraction parameter to percentile() goes from 0 to 100 whereas
** the fraction parameter in SQL standard percentile_cont() goes from
** 0 to 1.
**
** Implementation notes as of 2024-08-31:
**
** * The regular aggregate-function versions of these routines work
** by accumulating all values in an array of doubles, then sorting
** that array using quicksort before computing the answer. Thus
** the runtime is O(NlogN) where N is the number of rows of input.
**
** * For the window-function versions of these routines, the array of
** inputs is sorted as soon as the first value is computed. Thereafter,
** the array is kept in sorted order using an insert-sort. This
** results in O(N*K) performance where K is the size of the window.
** One can imagine alternative implementations that give O(N*logN*logK)
** performance, but they require more complex logic and data structures.
** The developers have elected to keep the asymptotically slower
** algorithm for now, for simplicity, under the theory that window
** functions are seldom used and when they are, the window size K is
** often small. The developers might revisit that decision later,
** should the need arise.
*/
#include "sqlite3ext.h"
SQLITE_EXTENSION_INIT1
#if defined(SQLITE3_H)
/* no-op */
#elif defined(SQLITE_STATIC_PERCENTILE)
# include "sqlite3.h"
#else
# include "sqlite3ext.h"
SQLITE_EXTENSION_INIT1
#endif
#include <assert.h>
#include <string.h>
#include <stdlib.h>
/* The following object is the session context for a single percentile()
** function. We have to remember all input Y values until the very end.
/* The following object is the group context for a single percentile()
** aggregate. Remember all input Y values until the very end.
** Those values are accumulated in the Percentile.a[] array.
*/
typedef struct Percentile Percentile;
struct Percentile {
unsigned nAlloc; /* Number of slots allocated for a[] */
unsigned nUsed; /* Number of slots actually used in a[] */
double rPct; /* 1.0 more than the value for P */
char bSorted; /* True if a[] is already in sorted order */
char bKeepSorted; /* True if advantageous to keep a[] sorted */
char bPctValid; /* True if rPct is valid */
double rPct; /* Fraction. 0.0 to 1.0 */
double *a; /* Array of Y values */
};
/* Details of each function in the percentile family */
typedef struct PercentileFunc PercentileFunc;
struct PercentileFunc {
const char *zName; /* Function name */
char nArg; /* Number of arguments */
char mxFrac; /* Maximum value of the "fraction" input */
char bDiscrete; /* True for percentile_disc() */
};
static const PercentileFunc aPercentFunc[] = {
{ "median", 1, 1, 0 },
{ "percentile", 2, 100, 0 },
{ "percentile_cont", 2, 1, 0 },
{ "percentile_disc", 2, 1, 1 },
};
/*
** Return TRUE if the input floating-point number is an infinity.
*/
static int isInfinity(double r){
static int percentIsInfinity(double r){
sqlite3_uint64 u;
assert( sizeof(u)==sizeof(r) );
memcpy(&u, &r, sizeof(u));
@@ -92,13 +166,64 @@ static int isInfinity(double r){
}
/*
** Return TRUE if two doubles differ by 0.001 or less
** Return TRUE if two doubles differ by 0.001 or less.
*/
static int sameValue(double a, double b){
static int percentSameValue(double a, double b){
a -= b;
return a>=-0.001 && a<=0.001;
}
/*
** Search p (which must have p->bSorted) looking for an entry with
** value y. Return the index of that entry.
**
** If bExact is true, return -1 if the entry is not found.
**
** If bExact is false, return the index at which a new entry with
** value y should be insert in order to keep the values in sorted
** order. The smallest return value in this case will be 0, and
** the largest return value will be p->nUsed.
*/
static int percentBinarySearch(Percentile *p, double y, int bExact){
int iFirst = 0; /* First element of search range */
int iLast = p->nUsed - 1; /* Last element of search range */
while( iLast>=iFirst ){
int iMid = (iFirst+iLast)/2;
double x = p->a[iMid];
if( x<y ){
iFirst = iMid + 1;
}else if( x>y ){
iLast = iMid - 1;
}else{
return iMid;
}
}
if( bExact ) return -1;
return iFirst;
}
/*
** Generate an error for a percentile function.
**
** The error format string must have exactly one occurrance of "%%s()"
** (with two '%' characters). That substring will be replaced by the name
** of the function.
*/
static void percentError(sqlite3_context *pCtx, const char *zFormat, ...){
PercentileFunc *pFunc = (PercentileFunc*)sqlite3_user_data(pCtx);
char *zMsg1;
char *zMsg2;
va_list ap;
va_start(ap, zFormat);
zMsg1 = sqlite3_vmprintf(zFormat, ap);
va_end(ap);
zMsg2 = zMsg1 ? sqlite3_mprintf(zMsg1, pFunc->zName) : 0;
sqlite3_result_error(pCtx, zMsg2, -1);
sqlite3_free(zMsg1);
sqlite3_free(zMsg2);
}
/*
** The "step" function for percentile(Y,P) is called once for each
** input row.
@@ -112,28 +237,20 @@ static void percentStep(sqlite3_context *pCtx, int argc, sqlite3_value **argv){
if( argc==1 ){
/* Requirement 13: median(Y) is the same as percentile(Y,50). */
rPct = 50.0;
}else if( sqlite3_user_data(pCtx)==0 ){
/* Requirement 3: P must be a number between 0 and 100 */
eType = sqlite3_value_numeric_type(argv[1]);
rPct = sqlite3_value_double(argv[1]);
if( (eType!=SQLITE_INTEGER && eType!=SQLITE_FLOAT)
|| rPct<0.0 || rPct>100.0 ){
sqlite3_result_error(pCtx, "2nd argument to percentile() is not "
"a number between 0.0 and 100.0", -1);
return;
}
rPct = 0.5;
}else{
/* Requirement 3: P must be a number between 0 and 1 */
/* Requirement 3: P must be a number between 0 and 100 */
PercentileFunc *pFunc = (PercentileFunc*)sqlite3_user_data(pCtx);
eType = sqlite3_value_numeric_type(argv[1]);
rPct = sqlite3_value_double(argv[1]);
rPct = sqlite3_value_double(argv[1])/(double)pFunc->mxFrac;
if( (eType!=SQLITE_INTEGER && eType!=SQLITE_FLOAT)
|| rPct<0.0 || rPct>1.0 ){
sqlite3_result_error(pCtx, "2nd argument to percentile_cont() is not "
"a number between 0.0 and 1.0", -1);
|| rPct<0.0 || rPct>1.0
){
percentError(pCtx, "the fraction argument to %%s()"
" is not between 0.0 and %.1f",
(double)pFunc->mxFrac);
return;
}
rPct *= 100.0;
}
/* Allocate the session context. */
@@ -142,11 +259,12 @@ static void percentStep(sqlite3_context *pCtx, int argc, sqlite3_value **argv){
/* Remember the P value. Throw an error if the P value is different
** from any prior row, per Requirement (2). */
if( p->rPct==0.0 ){
p->rPct = rPct+1.0;
}else if( !sameValue(p->rPct,rPct+1.0) ){
sqlite3_result_error(pCtx, "2nd argument to percentile() is not the "
"same for all input rows", -1);
if( !p->bPctValid ){
p->rPct = rPct;
p->bPctValid = 1;
}else if( !percentSameValue(p->rPct,rPct) ){
percentError(pCtx, "the fraction argument to %%s()"
" is not the same for all input rows");
return;
}
@@ -157,15 +275,14 @@ static void percentStep(sqlite3_context *pCtx, int argc, sqlite3_value **argv){
/* If not NULL, then Y must be numeric. Otherwise throw an error.
** Requirement 4 */
if( eType!=SQLITE_INTEGER && eType!=SQLITE_FLOAT ){
sqlite3_result_error(pCtx, "1st argument to percentile() is not "
"numeric", -1);
percentError(pCtx, "input to %%s() is not numeric");
return;
}
/* Throw an error if the Y value is infinity or NaN */
y = sqlite3_value_double(argv[0]);
if( isInfinity(y) ){
sqlite3_result_error(pCtx, "Inf input to percentile()", -1);
if( percentIsInfinity(y) ){
percentError(pCtx, "Inf input to %%s()");
return;
}
@@ -182,50 +299,80 @@ static void percentStep(sqlite3_context *pCtx, int argc, sqlite3_value **argv){
p->nAlloc = n;
p->a = a;
}
p->a[p->nUsed++] = y;
if( p->nUsed==0 ){
p->a[p->nUsed++] = y;
p->bSorted = 1;
}else if( !p->bSorted || y>=p->a[p->nUsed-1] ){
p->a[p->nUsed++] = y;
}else if( p->bKeepSorted ){
int i;
i = percentBinarySearch(p, y, 0);
if( i<(int)p->nUsed ){
memmove(&p->a[i+1], &p->a[i], (p->nUsed-i)*sizeof(p->a[0]));
}
p->a[i] = y;
p->nUsed++;
}else{
p->a[p->nUsed++] = y;
p->bSorted = 0;
}
}
/*
** Sort an array of doubles.
** Interchange two doubles.
*/
static void sortDoubles(double *a, int n){
int iLt; /* Entries with index less than iLt are less than rPivot */
int iGt; /* Entries with index iGt or more are greater than rPivot */
#define SWAP_DOUBLE(X,Y) {double ttt=(X);(X)=(Y);(Y)=ttt;}
/*
** Sort an array of doubles.
**
** Algorithm: quicksort
**
** This is implemented separately rather than using the qsort() routine
** from the standard library because:
**
** (1) To avoid a dependency on qsort()
** (2) To avoid the function call to the comparison routine for each
** comparison.
*/
static void percentSort(double *a, unsigned int n){
int iLt; /* Entries before a[iLt] are less than rPivot */
int iGt; /* Entries at or after a[iGt] are greater than rPivot */
int i; /* Loop counter */
double rPivot; /* The pivot value */
double rTmp; /* Temporary used to swap two values */
if( n<2 ) return;
if( n>5 ){
rPivot = (a[0] + a[n/2] + a[n-1])/3.0;
}else{
rPivot = a[n/2];
assert( n>=2 );
if( a[0]>a[n-1] ){
SWAP_DOUBLE(a[0],a[n-1])
}
iLt = i = 0;
iGt = n;
while( i<iGt ){
if( n==2 ) return;
iGt = n-1;
i = n/2;
if( a[0]>a[i] ){
SWAP_DOUBLE(a[0],a[i])
}else if( a[i]>a[iGt] ){
SWAP_DOUBLE(a[i],a[iGt])
}
if( n==3 ) return;
rPivot = a[i];
iLt = i = 1;
do{
if( a[i]<rPivot ){
if( i>iLt ){
rTmp = a[i];
a[i] = a[iLt];
a[iLt] = rTmp;
}
if( i>iLt ) SWAP_DOUBLE(a[i],a[iLt])
iLt++;
i++;
}else if( a[i]>rPivot ){
do{
iGt--;
}while( iGt>i && a[iGt]>rPivot );
rTmp = a[i];
a[i] = a[iGt];
a[iGt] = rTmp;
SWAP_DOUBLE(a[i],a[iGt])
}else{
i++;
}
}
if( iLt>=2 ) sortDoubles(a, iLt);
if( n-iGt>=2 ) sortDoubles(a+iGt, n-iGt);
}while( i<iGt );
if( iLt>=2 ) percentSort(a, iLt);
if( n-iGt>=2 ) percentSort(a+iGt, n-iGt);
/* Uncomment for testing */
#if 0
for(i=0; i<n-1; i++){
@@ -234,12 +381,61 @@ static void sortDoubles(double *a, int n){
#endif
}
/*
** Called to compute the final output of percentile() and to clean
** up all allocated memory.
** The "inverse" function for percentile(Y,P) is called to remove a
** row that was previously inserted by "step".
*/
static void percentFinal(sqlite3_context *pCtx){
static void percentInverse(sqlite3_context *pCtx,int argc,sqlite3_value **argv){
Percentile *p;
int eType;
double y;
int i;
assert( argc==2 || argc==1 );
/* Allocate the session context. */
p = (Percentile*)sqlite3_aggregate_context(pCtx, sizeof(*p));
assert( p!=0 );
/* Ignore rows for which Y is NULL */
eType = sqlite3_value_type(argv[0]);
if( eType==SQLITE_NULL ) return;
/* If not NULL, then Y must be numeric. Otherwise throw an error.
** Requirement 4 */
if( eType!=SQLITE_INTEGER && eType!=SQLITE_FLOAT ){
return;
}
/* Ignore the Y value if it is infinity or NaN */
y = sqlite3_value_double(argv[0]);
if( percentIsInfinity(y) ){
return;
}
if( p->bSorted==0 ){
assert( p->nUsed>1 );
percentSort(p->a, p->nUsed);
p->bSorted = 1;
}
p->bKeepSorted = 1;
/* Find and remove the row */
i = percentBinarySearch(p, y, 1);
if( i>=0 ){
p->nUsed--;
if( i<(int)p->nUsed ){
memmove(&p->a[i], &p->a[i+1], (p->nUsed - i)*sizeof(p->a[0]));
}
}
}
/*
** Compute the final output of percentile(). Clean up all allocated
** memory if and only if bIsFinal is true.
*/
static void percentCompute(sqlite3_context *pCtx, int bIsFinal){
Percentile *p;
PercentileFunc *pFunc = (PercentileFunc*)sqlite3_user_data(pCtx);
unsigned i1, i2;
double v1, v2;
double ix, vx;
@@ -247,21 +443,38 @@ static void percentFinal(sqlite3_context *pCtx){
if( p==0 ) return;
if( p->a==0 ) return;
if( p->nUsed ){
sortDoubles(p->a, p->nUsed);
ix = (p->rPct-1.0)*(p->nUsed-1)*0.01;
if( p->bSorted==0 ){
assert( p->nUsed>1 );
percentSort(p->a, p->nUsed);
p->bSorted = 1;
}
ix = p->rPct*(p->nUsed-1);
i1 = (unsigned)ix;
i2 = ix==(double)i1 || i1==p->nUsed-1 ? i1 : i1+1;
v1 = p->a[i1];
v2 = p->a[i2];
vx = v1 + (v2-v1)*(ix-i1);
if( pFunc->bDiscrete ){
vx = p->a[i1];
}else{
i2 = ix==(double)i1 || i1==p->nUsed-1 ? i1 : i1+1;
v1 = p->a[i1];
v2 = p->a[i2];
vx = v1 + (v2-v1)*(ix-i1);
}
sqlite3_result_double(pCtx, vx);
}
sqlite3_free(p->a);
memset(p, 0, sizeof(*p));
if( bIsFinal ){
sqlite3_free(p->a);
memset(p, 0, sizeof(*p));
}else{
p->bKeepSorted = 1;
}
}
static void percentFinal(sqlite3_context *pCtx){
percentCompute(pCtx, 1);
}
static void percentValue(sqlite3_context *pCtx){
percentCompute(pCtx, 0);
}
#ifdef _WIN32
#if defined(_WIN32) && !defined(SQLITE3_H) && !defined(SQLITE_STATIC_PERCENTILE)
__declspec(dllexport)
#endif
int sqlite3_percentile_init(
@@ -270,20 +483,21 @@ int sqlite3_percentile_init(
const sqlite3_api_routines *pApi
){
int rc = SQLITE_OK;
unsigned int i;
#if defined(SQLITE3_H) || defined(SQLITE_STATIC_PERCENTILE)
(void)pApi; /* Unused parameter */
#else
SQLITE_EXTENSION_INIT2(pApi);
#endif
(void)pzErrMsg; /* Unused parameter */
rc = sqlite3_create_function(db, "percentile", 2,
SQLITE_UTF8|SQLITE_INNOCUOUS, 0,
0, percentStep, percentFinal);
if( rc==SQLITE_OK ){
rc = sqlite3_create_function(db, "median", 1,
SQLITE_UTF8|SQLITE_INNOCUOUS, 0,
0, percentStep, percentFinal);
}
if( rc==SQLITE_OK ){
rc = sqlite3_create_function(db, "percentile_cont", 2,
SQLITE_UTF8|SQLITE_INNOCUOUS, &percentStep,
0, percentStep, percentFinal);
for(i=0; i<sizeof(aPercentFunc)/sizeof(aPercentFunc[0]); i++){
rc = sqlite3_create_window_function(db,
aPercentFunc[i].zName,
aPercentFunc[i].nArg,
SQLITE_UTF8|SQLITE_INNOCUOUS|SQLITE_SELFORDER1,
(void*)&aPercentFunc[i],
percentStep, percentFinal, percentValue, percentInverse, 0);
if( rc ) break;
}
return rc;
}
+25 -9
View File
@@ -196,7 +196,8 @@ static void hash_step_vformat(
** zOut[]. zOut[] must be at least 41 bytes long. */
static void hash_finish(
SHA1Context *p, /* The SHA1 context to finish and render */
char *zOut /* Store hexadecimal hash here */
char *zOut, /* Store hex or binary hash here */
int bAsBinary /* 1 for binary hash, 0 for hex hash */
){
unsigned int i;
unsigned char finalcount[8];
@@ -215,11 +216,15 @@ static void hash_finish(
for (i = 0; i < 20; i++){
digest[i] = (unsigned char)((p->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255);
}
for(i=0; i<20; i++){
zOut[i*2] = zEncode[(digest[i]>>4)&0xf];
zOut[i*2+1] = zEncode[digest[i] & 0xf];
if( bAsBinary ){
memcpy(zOut, digest, 20);
}else{
for(i=0; i<20; i++){
zOut[i*2] = zEncode[(digest[i]>>4)&0xf];
zOut[i*2+1] = zEncode[digest[i] & 0xf];
}
zOut[i*2]= 0;
}
zOut[i*2]= 0;
}
/* End of the hashing logic
*****************************************************************************/
@@ -251,8 +256,13 @@ static void sha1Func(
}else{
hash_step(&cx, sqlite3_value_text(argv[0]), nByte);
}
hash_finish(&cx, zOut);
sqlite3_result_text(context, zOut, 40, SQLITE_TRANSIENT);
if( sqlite3_user_data(context)!=0 ){
hash_finish(&cx, zOut, 1);
sqlite3_result_blob(context, zOut, 20, SQLITE_TRANSIENT);
}else{
hash_finish(&cx, zOut, 0);
sqlite3_result_blob(context, zOut, 40, SQLITE_TRANSIENT);
}
}
/*
@@ -365,7 +375,7 @@ static void sha1QueryFunc(
}
sqlite3_finalize(pStmt);
}
hash_finish(&cx, zOut);
hash_finish(&cx, zOut, 0);
sqlite3_result_text(context, zOut, 40, SQLITE_TRANSIENT);
}
@@ -379,11 +389,17 @@ int sqlite3_sha_init(
const sqlite3_api_routines *pApi
){
int rc = SQLITE_OK;
static int one = 1;
SQLITE_EXTENSION_INIT2(pApi);
(void)pzErrMsg; /* Unused parameter */
rc = sqlite3_create_function(db, "sha1", 1,
SQLITE_UTF8 | SQLITE_INNOCUOUS | SQLITE_DETERMINISTIC,
0, sha1Func, 0, 0);
0, sha1Func, 0, 0);
if( rc==SQLITE_OK ){
rc = sqlite3_create_function(db, "sha1b", 1,
SQLITE_UTF8 | SQLITE_INNOCUOUS | SQLITE_DETERMINISTIC,
(void*)&one, sha1Func, 0, 0);
}
if( rc==SQLITE_OK ){
rc = sqlite3_create_function(db, "sha1_query", 1,
SQLITE_UTF8|SQLITE_DIRECTONLY, 0,
+150 -55
View File
@@ -182,7 +182,7 @@ static const char *vfstraceNextSystemCall(sqlite3_vfs*, const char *zName);
** xyzzy.txt -> xyzzy.txt
*/
static const char *fileTail(const char *z){
int i;
size_t i;
if( z==0 ) return 0;
i = strlen(z)-1;
while( i>0 && z[i-1]!='/' ){ i--; }
@@ -207,36 +207,34 @@ static void vfstrace_printf(
}
/*
** Convert value rc into a string and print it using zFormat. zFormat
** should have exactly one %s
** Try to convert an error code into a symbolic name for that error code.
*/
static void vfstrace_print_errcode(
vfstrace_info *pInfo,
const char *zFormat,
int rc
){
char zBuf[50];
char *zVal;
static const char *vfstrace_errcode_name(int rc ){
const char *zVal = 0;
switch( rc ){
case SQLITE_OK: zVal = "SQLITE_OK"; break;
case SQLITE_ERROR: zVal = "SQLITE_ERROR"; break;
case SQLITE_PERM: zVal = "SQLITE_PERM"; break;
case SQLITE_ABORT: zVal = "SQLITE_ABORT"; break;
case SQLITE_BUSY: zVal = "SQLITE_BUSY"; break;
case SQLITE_NOMEM: zVal = "SQLITE_NOMEM"; break;
case SQLITE_READONLY: zVal = "SQLITE_READONLY"; break;
case SQLITE_INTERRUPT: zVal = "SQLITE_INTERRUPT"; break;
case SQLITE_IOERR: zVal = "SQLITE_IOERR"; break;
case SQLITE_CORRUPT: zVal = "SQLITE_CORRUPT"; break;
case SQLITE_FULL: zVal = "SQLITE_FULL"; break;
case SQLITE_CANTOPEN: zVal = "SQLITE_CANTOPEN"; break;
case SQLITE_PROTOCOL: zVal = "SQLITE_PROTOCOL"; break;
case SQLITE_EMPTY: zVal = "SQLITE_EMPTY"; break;
case SQLITE_SCHEMA: zVal = "SQLITE_SCHEMA"; break;
case SQLITE_CONSTRAINT: zVal = "SQLITE_CONSTRAINT"; break;
case SQLITE_MISMATCH: zVal = "SQLITE_MISMATCH"; break;
case SQLITE_MISUSE: zVal = "SQLITE_MISUSE"; break;
case SQLITE_NOLFS: zVal = "SQLITE_NOLFS"; break;
case SQLITE_OK: zVal = "SQLITE_OK"; break;
case SQLITE_INTERNAL: zVal = "SQLITE_INTERNAL"; break;
case SQLITE_ERROR: zVal = "SQLITE_ERROR"; break;
case SQLITE_PERM: zVal = "SQLITE_PERM"; break;
case SQLITE_ABORT: zVal = "SQLITE_ABORT"; break;
case SQLITE_BUSY: zVal = "SQLITE_BUSY"; break;
case SQLITE_LOCKED: zVal = "SQLITE_LOCKED"; break;
case SQLITE_NOMEM: zVal = "SQLITE_NOMEM"; break;
case SQLITE_READONLY: zVal = "SQLITE_READONLY"; break;
case SQLITE_INTERRUPT: zVal = "SQLITE_INTERRUPT"; break;
case SQLITE_IOERR: zVal = "SQLITE_IOERR"; break;
case SQLITE_CORRUPT: zVal = "SQLITE_CORRUPT"; break;
case SQLITE_NOTFOUND: zVal = "SQLITE_NOTFOUND"; break;
case SQLITE_FULL: zVal = "SQLITE_FULL"; break;
case SQLITE_CANTOPEN: zVal = "SQLITE_CANTOPEN"; break;
case SQLITE_PROTOCOL: zVal = "SQLITE_PROTOCOL"; break;
case SQLITE_EMPTY: zVal = "SQLITE_EMPTY"; break;
case SQLITE_SCHEMA: zVal = "SQLITE_SCHEMA"; break;
case SQLITE_TOOBIG: zVal = "SQLITE_TOOBIG"; break;
case SQLITE_CONSTRAINT: zVal = "SQLITE_CONSTRAINT"; break;
case SQLITE_MISMATCH: zVal = "SQLITE_MISMATCH"; break;
case SQLITE_MISUSE: zVal = "SQLITE_MISUSE"; break;
case SQLITE_NOLFS: zVal = "SQLITE_NOLFS"; break;
case SQLITE_IOERR_READ: zVal = "SQLITE_IOERR_READ"; break;
case SQLITE_IOERR_SHORT_READ: zVal = "SQLITE_IOERR_SHORT_READ"; break;
case SQLITE_IOERR_WRITE: zVal = "SQLITE_IOERR_WRITE"; break;
@@ -266,11 +264,30 @@ static void vfstrace_print_errcode(
case SQLITE_LOCKED_SHAREDCACHE: zVal = "SQLITE_LOCKED_SHAREDCACHE"; break;
case SQLITE_BUSY_RECOVERY: zVal = "SQLITE_BUSY_RECOVERY"; break;
case SQLITE_CANTOPEN_NOTEMPDIR: zVal = "SQLITE_CANTOPEN_NOTEMPDIR"; break;
default: {
sqlite3_snprintf(sizeof(zBuf), zBuf, "%d", rc);
zVal = zBuf;
break;
}
return zVal;
}
/*
** Convert value rc into a string and print it using zFormat. zFormat
** should have exactly one %s
*/
static void vfstrace_print_errcode(
vfstrace_info *pInfo,
const char *zFormat,
int rc
){
const char *zVal;
char zBuf[50];
zVal = vfstrace_errcode_name(rc);
if( zVal==0 ){
zVal = vfstrace_errcode_name(rc&0xff);
if( zVal ){
sqlite3_snprintf(sizeof(zBuf), zBuf, "%s | 0x%x", zVal, rc&0xffff00);
}else{
sqlite3_snprintf(sizeof(zBuf), zBuf, "%d (0x%x)", rc, rc);
}
zVal = zBuf;
}
vfstrace_printf(pInfo, zFormat, zVal);
}
@@ -457,12 +474,14 @@ static int vfstraceFileControl(sqlite3_file *pFile, int op, void *pArg){
vfstrace_info *pInfo = p->pInfo;
int rc;
char zBuf[100];
char zBuf2[100];
char *zOp;
char *zRVal = 0;
switch( op ){
case SQLITE_FCNTL_LOCKSTATE: zOp = "LOCKSTATE"; break;
case SQLITE_GET_LOCKPROXYFILE: zOp = "GET_LOCKPROXYFILE"; break;
case SQLITE_SET_LOCKPROXYFILE: zOp = "SET_LOCKPROXYFILE"; break;
case SQLITE_LAST_ERRNO: zOp = "LAST_ERRNO"; break;
case SQLITE_FCNTL_LOCKSTATE: zOp = "LOCKSTATE"; break;
case SQLITE_GET_LOCKPROXYFILE: zOp = "GET_LOCKPROXYFILE"; break;
case SQLITE_SET_LOCKPROXYFILE: zOp = "SET_LOCKPROXYFILE"; break;
case SQLITE_LAST_ERRNO: zOp = "LAST_ERRNO"; break;
case SQLITE_FCNTL_SIZE_HINT: {
sqlite3_snprintf(sizeof(zBuf), zBuf, "SIZE_HINT,%lld",
*(sqlite3_int64*)pArg);
@@ -474,20 +493,62 @@ static int vfstraceFileControl(sqlite3_file *pFile, int op, void *pArg){
zOp = zBuf;
break;
}
case SQLITE_FCNTL_FILE_POINTER: zOp = "FILE_POINTER"; break;
case SQLITE_FCNTL_SYNC_OMITTED: zOp = "SYNC_OMITTED"; break;
case SQLITE_FCNTL_WIN32_AV_RETRY: zOp = "WIN32_AV_RETRY"; break;
case SQLITE_FCNTL_PERSIST_WAL: zOp = "PERSIST_WAL"; break;
case SQLITE_FCNTL_OVERWRITE: zOp = "OVERWRITE"; break;
case SQLITE_FCNTL_VFSNAME: zOp = "VFSNAME"; break;
case SQLITE_FCNTL_TEMPFILENAME: zOp = "TEMPFILENAME"; break;
case 0xca093fa0: zOp = "DB_UNCHANGED"; break;
case SQLITE_FCNTL_FILE_POINTER: zOp = "FILE_POINTER"; break;
case SQLITE_FCNTL_WIN32_AV_RETRY: zOp = "WIN32_AV_RETRY"; break;
case SQLITE_FCNTL_PERSIST_WAL: {
sqlite3_snprintf(sizeof(zBuf), zBuf, "PERSIST_WAL,%d", *(int*)pArg);
zOp = zBuf;
break;
}
case SQLITE_FCNTL_OVERWRITE: zOp = "OVERWRITE"; break;
case SQLITE_FCNTL_VFSNAME: zOp = "VFSNAME"; break;
case SQLITE_FCNTL_POWERSAFE_OVERWRITE: zOp = "POWERSAFE_OVERWRITE"; break;
case SQLITE_FCNTL_PRAGMA: {
const char *const* a = (const char*const*)pArg;
sqlite3_snprintf(sizeof(zBuf), zBuf, "PRAGMA,[%s,%s]",a[1],a[2]);
zOp = zBuf;
break;
}
case SQLITE_FCNTL_BUSYHANDLER: zOp = "BUSYHANDLER"; break;
case SQLITE_FCNTL_TEMPFILENAME: zOp = "TEMPFILENAME"; break;
case SQLITE_FCNTL_MMAP_SIZE: {
sqlite3_int64 iMMap = *(sqlite3_int64*)pArg;
sqlite3_snprintf(sizeof(zBuf), zBuf, "MMAP_SIZE,%lld",iMMap);
zOp = zBuf;
break;
}
case SQLITE_FCNTL_TRACE: zOp = "TRACE"; break;
case SQLITE_FCNTL_HAS_MOVED: zOp = "HAS_MOVED"; break;
case SQLITE_FCNTL_SYNC: zOp = "SYNC"; break;
case SQLITE_FCNTL_COMMIT_PHASETWO: zOp = "COMMIT_PHASETWO"; break;
case SQLITE_FCNTL_WIN32_SET_HANDLE: zOp = "WIN32_SET_HANDLE"; break;
case SQLITE_FCNTL_WAL_BLOCK: zOp = "WAL_BLOCK"; break;
case SQLITE_FCNTL_ZIPVFS: zOp = "ZIPVFS"; break;
case SQLITE_FCNTL_RBU: zOp = "RBU"; break;
case SQLITE_FCNTL_VFS_POINTER: zOp = "VFS_POINTER"; break;
case SQLITE_FCNTL_JOURNAL_POINTER: zOp = "JOURNAL_POINTER"; break;
case SQLITE_FCNTL_WIN32_GET_HANDLE: zOp = "WIN32_GET_HANDLE"; break;
case SQLITE_FCNTL_PDB: zOp = "PDB"; break;
case SQLITE_FCNTL_BEGIN_ATOMIC_WRITE: zOp = "BEGIN_ATOMIC_WRITE"; break;
case SQLITE_FCNTL_COMMIT_ATOMIC_WRITE: zOp = "COMMIT_ATOMIC_WRITE"; break;
case SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE: {
zOp = "ROLLBACK_ATOMIC_WRITE";
break;
}
case SQLITE_FCNTL_LOCK_TIMEOUT: {
sqlite3_snprintf(sizeof(zBuf), zBuf, "LOCK_TIMEOUT,%d", *(int*)pArg);
zOp = zBuf;
break;
}
case SQLITE_FCNTL_DATA_VERSION: zOp = "DATA_VERSION"; break;
case SQLITE_FCNTL_SIZE_LIMIT: zOp = "SIZE_LIMIT"; break;
case SQLITE_FCNTL_CKPT_DONE: zOp = "CKPT_DONE"; break;
case SQLITE_FCNTL_RESERVE_BYTES: zOp = "RESERVED_BYTES"; break;
case SQLITE_FCNTL_CKPT_START: zOp = "CKPT_START"; break;
case SQLITE_FCNTL_EXTERNAL_READER: zOp = "EXTERNAL_READER"; break;
case SQLITE_FCNTL_CKSM_FILE: zOp = "CKSM_FILE"; break;
case SQLITE_FCNTL_RESET_CACHE: zOp = "RESET_CACHE"; break;
case 0xca093fa0: zOp = "DB_UNCHANGED"; break;
default: {
sqlite3_snprintf(sizeof zBuf, zBuf, "%d", op);
zOp = zBuf;
@@ -497,15 +558,37 @@ static int vfstraceFileControl(sqlite3_file *pFile, int op, void *pArg){
vfstrace_printf(pInfo, "%s.xFileControl(%s,%s)",
pInfo->zVfsName, p->zFName, zOp);
rc = p->pReal->pMethods->xFileControl(p->pReal, op, pArg);
vfstrace_print_errcode(pInfo, " -> %s\n", rc);
if( op==SQLITE_FCNTL_VFSNAME && rc==SQLITE_OK ){
*(char**)pArg = sqlite3_mprintf("vfstrace.%s/%z",
if( rc==SQLITE_OK ){
switch( op ){
case SQLITE_FCNTL_VFSNAME: {
*(char**)pArg = sqlite3_mprintf("vfstrace.%s/%z",
pInfo->zVfsName, *(char**)pArg);
zRVal = *(char**)pArg;
break;
}
case SQLITE_FCNTL_MMAP_SIZE: {
sqlite3_snprintf(sizeof(zBuf2), zBuf2, "%lld", *(sqlite3_int64*)pArg);
zRVal = zBuf2;
break;
}
case SQLITE_FCNTL_HAS_MOVED:
case SQLITE_FCNTL_PERSIST_WAL: {
sqlite3_snprintf(sizeof(zBuf2), zBuf2, "%d", *(int*)pArg);
zRVal = zBuf2;
break;
}
case SQLITE_FCNTL_PRAGMA:
case SQLITE_FCNTL_TEMPFILENAME: {
zRVal = *(char**)pArg;
break;
}
}
}
if( (op==SQLITE_FCNTL_PRAGMA || op==SQLITE_FCNTL_TEMPFILENAME)
&& rc==SQLITE_OK && *(char**)pArg ){
vfstrace_printf(pInfo, "%s.xFileControl(%s,%s) returns %s",
pInfo->zVfsName, p->zFName, zOp, *(char**)pArg);
if( zRVal ){
vfstrace_print_errcode(pInfo, " -> %s", rc);
vfstrace_printf(pInfo, ", %s\n", zRVal);
}else{
vfstrace_print_errcode(pInfo, " -> %s\n", rc);
}
return rc;
}
@@ -840,14 +923,14 @@ int vfstrace_register(
sqlite3_vfs *pNew;
sqlite3_vfs *pRoot;
vfstrace_info *pInfo;
int nName;
int nByte;
size_t nName;
size_t nByte;
pRoot = sqlite3_vfs_find(zOldVfsName);
if( pRoot==0 ) return SQLITE_NOTFOUND;
nName = strlen(zTraceName);
nByte = sizeof(*pNew) + sizeof(*pInfo) + nName + 1;
pNew = sqlite3_malloc( nByte );
pNew = sqlite3_malloc64( nByte );
if( pNew==0 ) return SQLITE_NOMEM;
memset(pNew, 0, nByte);
pInfo = (vfstrace_info*)&pNew[1];
@@ -890,3 +973,15 @@ int vfstrace_register(
pInfo->zVfsName, pRoot->zName);
return sqlite3_vfs_register(pNew, makeDefault);
}
/*
** Look for the named VFS. If it is a TRACEVFS, then unregister it
** and delete it.
*/
void vfstrace_unregister(const char *zTraceName){
sqlite3_vfs *pVfs = sqlite3_vfs_find(zTraceName);
if( pVfs==0 ) return;
if( pVfs->xOpen!=vfstraceOpen ) return;
sqlite3_vfs_unregister(pVfs);
sqlite3_free(pVfs);
}
+35 -6
View File
@@ -336,6 +336,27 @@ struct RbuFrame {
u32 iWalFrame;
};
#ifndef UNUSED_PARAMETER
/*
** The following macros are used to suppress compiler warnings and to
** make it clear to human readers when a function parameter is deliberately
** left unused within the body of a function. This usually happens when
** a function is called via a function pointer. For example the
** implementation of an SQL aggregate step callback may not use the
** parameter indicating the number of arguments passed to the aggregate,
** if it knows that this is enforced elsewhere.
**
** When a function parameter is not used at all within the body of a function,
** it is generally named "NotUsed" or "NotUsed2" to make things even clearer.
** However, these macros may also be used to suppress warnings related to
** parameters that may or may not be used depending on compilation options.
** For example those parameters only used in assert() statements. In these
** cases the parameters are named as per the usual conventions.
*/
#define UNUSED_PARAMETER(x) (void)(x)
#define UNUSED_PARAMETER2(x,y) UNUSED_PARAMETER(x),UNUSED_PARAMETER(y)
#endif
/*
** RBU handle.
**
@@ -387,7 +408,7 @@ struct sqlite3rbu {
int rc; /* Value returned by last rbu_step() call */
char *zErrmsg; /* Error message if rc!=SQLITE_OK */
int nStep; /* Rows processed for current object */
int nProgress; /* Rows processed for all objects */
sqlite3_int64 nProgress; /* Rows processed for all objects */
RbuObjIter objiter; /* Iterator for skipping through tbl/idx */
const char *zVfsName; /* Name of automatically created rbu vfs */
rbu_file *pTargetFd; /* File handle open on target db */
@@ -504,7 +525,7 @@ static unsigned int rbuDeltaGetInt(const char **pz, int *pLen){
v = (v<<6) + c;
}
z--;
*pLen -= z - zStart;
*pLen -= (int)(z - zStart);
*pz = (char*)z;
return v;
}
@@ -689,6 +710,7 @@ static void rbuFossilDeltaFunc(
char *aOut;
assert( argc==2 );
UNUSED_PARAMETER(argc);
nOrig = sqlite3_value_bytes(argv[0]);
aOrig = (const char*)sqlite3_value_blob(argv[0]);
@@ -2268,13 +2290,13 @@ static char *rbuObjIterGetIndexWhere(sqlite3rbu *p, RbuObjIter *pIter){
else if( c==')' ){
nParen--;
if( nParen==0 ){
int nSpan = &zSql[i] - pIter->aIdxCol[iIdxCol].zSpan;
int nSpan = (int)(&zSql[i] - pIter->aIdxCol[iIdxCol].zSpan);
pIter->aIdxCol[iIdxCol++].nSpan = nSpan;
i++;
break;
}
}else if( c==',' && nParen==1 ){
int nSpan = &zSql[i] - pIter->aIdxCol[iIdxCol].zSpan;
int nSpan = (int)(&zSql[i] - pIter->aIdxCol[iIdxCol].zSpan);
pIter->aIdxCol[iIdxCol++].nSpan = nSpan;
pIter->aIdxCol[iIdxCol].zSpan = &zSql[i+1];
}else if( c=='"' || c=='\'' || c=='`' ){
@@ -2964,6 +2986,8 @@ static void rbuFileSuffix3(const char *zBase, char *z){
for(i=sz-1; i>0 && z[i]!='/' && z[i]!='.'; i--){}
if( z[i]=='.' && sz>i+4 ) memmove(&z[i+1], &z[sz-3], 4);
}
#else
UNUSED_PARAMETER2(zBase,z);
#endif
}
@@ -3548,7 +3572,7 @@ static void rbuSaveState(sqlite3rbu *p, int eStage){
"(%d, %Q), "
"(%d, %Q), "
"(%d, %d), "
"(%d, %d), "
"(%d, %lld), "
"(%d, %lld), "
"(%d, %lld), "
"(%d, %lld), "
@@ -3906,6 +3930,7 @@ static void rbuIndexCntFunc(
sqlite3 *db = (rbuIsVacuum(p) ? p->dbRbu : p->dbMain);
assert( nVal==1 );
UNUSED_PARAMETER(nVal);
rc = prepareFreeAndCollectError(db, &pStmt, &zErrmsg,
sqlite3_mprintf("SELECT count(*) FROM sqlite_schema "
@@ -4181,7 +4206,7 @@ sqlite3rbu *sqlite3rbu_vacuum(
){
if( zTarget==0 ){ return rbuMisuseError(); }
if( zState ){
int n = strlen(zState);
size_t n = strlen(zState);
if( n>=7 && 0==memcmp("-vactmp", &zState[n-7], 7) ){
return rbuMisuseError();
}
@@ -4398,6 +4423,7 @@ int sqlite3rbu_savestate(sqlite3rbu *p){
*/
static int xDefaultRename(void *pArg, const char *zOld, const char *zNew){
int rc = SQLITE_OK;
UNUSED_PARAMETER(pArg);
#if defined(_WIN32_WCE)
{
LPWSTR zWideOld;
@@ -5302,6 +5328,9 @@ static int rbuVfsCurrentTime(sqlite3_vfs *pVfs, double *pTimeOut){
** No-op.
*/
static int rbuVfsGetLastError(sqlite3_vfs *pVfs, int a, char *b){
UNUSED_PARAMETER(pVfs);
UNUSED_PARAMETER(a);
UNUSED_PARAMETER(b);
return 0;
}
+4 -4
View File
@@ -383,10 +383,10 @@ static int SQLITE_TCLAPI test_session_cmd(
{ "rowid", SQLITE_SESSION_OBJCONFIG_ROWID },
{ 0, 0 }
};
size_t sz = sizeof(aOpt[0]);
int sz = (int)sizeof(aOpt[0]);
int iArg;
int iOpt;
Tcl_Size iOpt;
if( Tcl_GetIndexFromObjStruct(interp,objv[2],aOpt,sz,"option",0,&iOpt) ){
return TCL_ERROR;
}
@@ -803,7 +803,7 @@ static int SQLITE_TCLAPI testSqlite3changesetApply(
if( bV2 ){
while( objc>1 ){
const char *z1 = Tcl_GetString(objv[1]);
int n = strlen(z1);
int n = (int)strlen(z1);
if( n>3 && n<=12 && 0==sqlite3_strnicmp("-nosavepoint", z1, n) ){
flags |= SQLITE_CHANGESETAPPLY_NOSAVEPOINT;
}
@@ -1119,7 +1119,7 @@ static int SQLITE_TCLAPI test_sqlite3session_foreach(
while( objc>1 ){
char *zOpt = Tcl_GetString(objv[1]);
int nOpt = strlen(zOpt);
int nOpt = (int)strlen(zOpt);
if( zOpt[0]!='-' ) break;
if( nOpt<=7 && 0==sqlite3_strnicmp(zOpt, "-invert", nOpt) ){
isInvert = 1;
+59 -43
View File
@@ -42,6 +42,10 @@
# build the SQLite library and testing tools.
################################################################################
# If OPTIONS... is specified on the command-line, append its value to OPTS
#
OPTS += $(OPTIONS)
# This is how we compile
#
TCCX = $(TCC) $(OPTS) -I. -I$(TOP)/src -I$(TOP)
@@ -537,6 +541,7 @@ FUZZSRC += $(TOP)/test/vt02.c
FUZZSRC += $(TOP)/test/fuzzinvariants.c
FUZZSRC += $(TOP)/ext/recover/dbdata.c
FUZZSRC += $(TOP)/ext/recover/sqlite3recover.c
FUZZSRC += $(TOP)/ext/misc/percentile.c
FUZZSRC += $(TOP)/ext/misc/randomjson.c
DBFUZZ_OPT =
KV_OPT = -DSQLITE_THREADSAFE=0 -DSQLITE_DIRECT_OVERFLOW_READ
@@ -563,6 +568,19 @@ dbhash$(EXE): $(TOP)/tool/dbhash.c sqlite3.c sqlite3.h
$(TCCX) -o dbhash$(EXE) -DSQLITE_THREADSAFE=0 \
$(TOP)/tool/dbhash.c sqlite3.c $(TLIBS) $(THREADLIB)
RSYNC_SRC = \
$(TOP)/tool/sqlite3-rsync.c \
sqlite3.c
RSYNC_OPT = \
-DSQLITE_ENABLE_DBPAGE_VTAB \
-DSQLITE_THREADSAFE=0 \
-DSQLITE_OMIT_LOAD_EXTENSION \
-DSQLITE_OMIT_DEPRECATED
sqlite3-rsync$(EXE): $(RSYNC_SRC)
$(TCC) -o $@ $(RSYNC_OPT) $(RSYNC_SRC) $(TLIBS)
scrub$(EXE): $(TOP)/ext/misc/scrub.c sqlite3.o
$(TCC) -I. -DSCRUB_STANDALONE -o scrub$(EXE) $(TOP)/ext/misc/scrub.c sqlite3.o $(THREADLIB)
@@ -760,11 +778,14 @@ SHELL_DEP = \
$(TOP)/ext/misc/ieee754.c \
$(TOP)/ext/misc/memtrace.c \
$(TOP)/ext/misc/pcachetrace.c \
$(TOP)/ext/misc/percentile.c \
$(TOP)/ext/misc/regexp.c \
$(TOP)/ext/misc/series.c \
$(TOP)/ext/misc/sha1.c \
$(TOP)/ext/misc/shathree.c \
$(TOP)/ext/misc/sqlar.c \
$(TOP)/ext/misc/uint.c \
$(TOP)/ext/misc/vfstrace.c \
$(TOP)/ext/misc/zipfile.c \
$(TOP)/ext/recover/dbdata.c \
$(TOP)/ext/recover/sqlite3recover.c \
@@ -958,9 +979,14 @@ tcltest: ./testfixture$(EXE)
testrunner: testfixture$(EXE)
./testfixture$(EXE) $(TOP)/test/testrunner.tcl
# Runs both fuzztest and testrunner, consecutively.
# This is the testing target preferred by the core SQLite developers.
# It runs tests under a standard configuration, regardless of how
# ./configure was run. The devs run "make devtest" prior to each
# check-in, at a minimum. Probably other tests too, but at least this
# one.
#
devtest: testfixture$(EXE) fuzztest testrunner
devtest: srctree-check sourcetest
tclsh $(TOP)/test/testrunner.tcl mdevtest
mdevtest:
tclsh $(TOP)/test/testrunner.tcl mdevtest
@@ -971,10 +997,19 @@ mdevtest:
quicktest: ./testfixture$(EXE)
./testfixture$(EXE) $(TOP)/test/extraquick.test $(TESTOPTS)
# The default test case. Runs most of the faster standard TCL tests,
# and fuzz tests, and sqlite3_analyzer and sqldiff tests.
test: fuzztest sourcetest $(TESTPROGS) tcltest
# Validate that various generated files in the source tree
# are up-to-date.
#
srctree-check: $(TOP)/tool/srctree-check.tcl
tclsh $(TOP)/tool/srctree-check.tcl
# Try to run tests on whatever options are specified by the
# environment variables. The SQLite developers seldom use this target.
# Instead# they use "make devtest" which runs tests on a standard set of
# options regardless of how SQLite is configured. This "test"
# target is provided for legacy only.
#
test: fuzztest sourcetest $(TESTPROGS) tcltest
# Run a test using valgrind. This can take a really long time
# because valgrind is so much slower than a native machine.
@@ -1112,41 +1147,22 @@ install: sqlite3 libsqlite3.a sqlite3.h
mv sqlite3.h /usr/include
clean:
rm -f *.o sqlite3 sqlite3.exe libsqlite3.a sqlite3.h opcodes.*
rm -f lemon lemon.exe lempar.c parse.* sqlite*.tar.gz
rm -f mkkeywordhash mkkeywordhash.exe keywordhash.h
rm -f $(PUBLISH)
rm -f *.da *.bb *.bbg gmon.out
rm -rf tsrc target_source
rm -f testloadext.dll libtestloadext.so
rm -f amalgamation-testfixture amalgamation-testfixture.exe
rm -f fts3-testfixture fts3-testfixture.exe
rm -f testfixture testfixture.exe
rm -f threadtest3 threadtest3.exe
rm -f LogEst LogEst.exe
rm -f fts3view fts3view.exe
rm -f rollback-test rollback-test.exe
rm -f showdb showdb.exe
rm -f showjournal showjournal.exe
rm -f showstat4 showstat4.exe
rm -f showwal showwal.exe
rm -f changeset changeset.exe
rm -f speedtest1 speedtest1.exe
rm -f wordcount wordcount.exe
rm -f rbu rbu.exe
rm -f srcck1 srcck1.exe
rm -f sqlite3.c sqlite3-*.c fts?amal.c tclsqlite3.c
rm -f sqlite3rc.h
rm -f shell.c sqlite3ext.h
rm -f sqlite3_analyzer sqlite3_analyzer.exe sqlite3_analyzer.c
rm -f sqlite3_expert sqlite3_expert.exe
rm -f sqlite-*-output.vsix
rm -f mptester mptester.exe
rm -f fuzzershell fuzzershell.exe
rm -f fuzzcheck fuzzcheck.exe
rm -f sessionfuzz
rm -f sqldiff sqldiff.exe
rm -f fts5.* fts5parse.*
rm -f lsm.h lsm1.c
rm -f threadtest5
rm -f src-verify
rm -f *.lo *.la *.o *.c *.h *.da *.bb *.bbg gmon.* *.rws sqlite3$(TEXE)
rm -rf .libs .deps tsrc libtool target_source testrunner_*
rm -f lemon$(BEXE) sqlite*.tar.gz
rm -f mkkeywordhash$(BEXE) mksourceid$(BEXE)
rm -f parse.* fts5parse.*
rm -rf tsrc .target_source testrunner_bld_* testdir*
rm -f tclsqlite3$(TEXE)
rm -f $(TESTPROGS) testrunner.*
rm -f LogEst$(TEXE) fts3view$(TEXE) rollback-test$(TEXE) showdb$(TEXE)
rm -f showjournal$(TEXE) showstat4$(TEXE) showwal$(TEXE) speedtest1$(TEXE)
rm -f wordcount$(TEXE) changeset$(TEXE) version-info$(TEXE)
rm -f *.dll *.lib *.exp *.def *.pc *.vsix
rm -f sqlite3_analyzer$(TEXE)
rm -f mptester$(TEXE) rbu$(TEXE) srcck1$(TEXE)
rm -f fuzzershell$(TEXE) fuzzcheck$(TEXE) sqldiff$(TEXE) dbhash$(TEXE)
rm -f threadtest5$(TEXE)
rm -f src-verify has_tclsh*
distclean: clean
+65 -63
View File
@@ -1,12 +1,12 @@
C Fix\stypo\sin\sthe\sprevious\scheck-in.\s\sEnsure\sthat\s--status\sheader\slines\sdo\snot\noverflow\sand\swrap.
D 2024-08-27T19:48:19.164
C CLI\sarg\shandling\srobustness\simprovements.
D 2024-09-14T16:30:01.739
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
F Makefile.in 101cb90f75c16ca3f8e7088364322441f9b01d6fdcef4a9c7f5fdcf78a3601a4
F Makefile.in 31368ad3e1800bb5f311adede543ee456ca7d2595403c7f131797ae65a7d415c
F Makefile.linux-gcc f3842a0b1efbfbb74ac0ef60e56b301836d05b4d867d014f714fa750048f1ab6
F Makefile.msc 6c3fe8b6ce60e73f34a148c957d78b4648745c8d30e792423aa1a8d8bf12d065
F README.md 3d47ef5758e2de29d6f4e1aca714d51424baba86c8b561fef330f6ef2dc9282c
F Makefile.msc 62ace0005c53b52f189c20c1d6d8fa4dbd2a37c90d9c1362b60f4fb4c841fa15
F README.md c3c0f19532ce28f6297a71870f3c7b424729f0e6d9ab889616d3587dd2332159
F VERSION 0db40f92c04378404eb45bff93e9e42c148c7e54fd3da99469ed21e22411f5a6
F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50
F art/icon-243x273.gif 9750b734f82fdb3dc43127753d5e6fbf3b62c9f4e136c2fbf573b2f57ea87af5
@@ -17,7 +17,7 @@ F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2
F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903
F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347
F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac
F autoconf/Makefile.msc 7ac6c331fc3b8aa57b6782db995b8c0e49230352decd4e2662fd07c06a9ed623
F autoconf/Makefile.msc 2aced6442addab13ed115696eba28d9ed29caa3dd604a31392c2c7a5da301492
F autoconf/README.first 6c4f34fe115ff55d4e8dbfa3cecf04a0188292f7
F autoconf/README.txt 42cfd21d0b19dc7d5d85fb5c405c5f3c6a4c923021c39128f6ba685355d8fd56
F autoconf/configure.ac ec7fa914c5e74ff212fe879f9bb6918e1234497e05facfb641f30c4d5893b277
@@ -39,7 +39,7 @@ F configure 49523f0a070b583cea040d26eff53a65fb0893eca4663b1343a4d5a9a964da53 x
F configure.ac a100ebf7a07f5dedd319ef547dd467d1676ed059b85a7877aa9c44ac309f7000
F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad
F doc/F2FS.txt c1d4a0ae9711cfe0e1d8b019d154f1c29e0d3abfe820787ba1e9ed7691160fcd
F doc/compile-for-windows.md e8635eea9153dcd6a51fd2740666ebc4492b3813cb1ac31cd8e99150df91762d
F doc/compile-for-windows.md 4d4bfafda42a7a33f166d23aed4db1bb4ea1e5751595a5cced2bad349fd14652
F doc/json-enhancements.md e356fc834781f1f1aa22ee300027a270b2c960122468499bf347bb123ce1ea4f
F doc/jsonb.md 5fab4b8613aa9153fbeb6259297bd4697988af8b3d23900deba588fa7841456b
F doc/lemon.html 8b266ff711d2ec7f867c3dca37634963f48a630329908cc282beebfa8c708706
@@ -53,7 +53,7 @@ F ext/README.md fd5f78013b0a2bc6f0067afb19e6ad040e89a10179b4f6f03eee58fac5f169bd
F ext/async/README.txt e12275968f6fde133a80e04387d0e839b0c51f91
F ext/async/sqlite3async.c 6f247666b495c477628dd19364d279c78ea48cd90c72d9f9b98ad1aff3294f94
F ext/async/sqlite3async.h 46b47c79357b97ad85d20d2795942c0020dc20c532114a49808287f04aa5309a
F ext/consio/console_io.c 6e02dea912a49f55785b0027fe77960aafee6c236307c23f82ec86a69f1a2001 x
F ext/consio/console_io.c d2b74afae8d301de2e8447b1045fcd33eb59df13bf581d906d99c74fe5d2b13f x
F ext/consio/console_io.h b5ebe34aa15b357621ebbea3d3f2e2b24750d4280b5802516409e23947fd9ee5
F ext/expert/README.md b321c2762bb93c18ea102d5a5f7753a4b8bac646cb392b3b437f633caf2020c3
F ext/expert/expert.c d548d603a4cc9e61f446cc179c120c6713511c413f82a4a32b1e1e69d3f086a4
@@ -93,15 +93,15 @@ F ext/fts3/unicode/mkunicode.tcl 63db9624ccf70d4887836c320eda93ab552f21008f3be7e
F ext/fts3/unicode/parseunicode.tcl a981bd6466d12dd17967515801c3ff23f74a281be1a03cf1e6f52a6959fc77eb
F ext/fts5/extract_api_docs.tcl 009cf59c77afa86d137b0cca3e3b1a5efbe2264faa2df233f9a7aa8563926d15
F ext/fts5/fts5.h efaaac0df3d3bc740383044c144b582f47921aafa21d7b10eb98f42c24c740b0
F ext/fts5/fts5Int.h 26a71a09cefa4ef6b4516b204ed48da3e1380970a19b3482eea7c5d805655360
F ext/fts5/fts5Int.h 7ab1d838adc4f22fdad5e1ba19182d6899ebded1d3ecadbe995322b0f0de7b9f
F ext/fts5/fts5_aux.c 65a0468dd177d6093aa9ae1622e6d86b0136b8d267c62c0ad6493ad1e9a3d759
F ext/fts5/fts5_buffer.c 0eec58bff585f1a44ea9147eae5da2447292080ea435957f7488c70673cb6f09
F ext/fts5/fts5_config.c 353d2a0d12678cae6ab5b9ce54aed8dac0825667b69248b5a4ed81cbefc109ea
F ext/fts5/fts5_expr.c 9a56f53700d1860f0ee2f373c2b9074eaf2a7aa0637d0e27a6476de26a3fee33
F ext/fts5/fts5_hash.c adda4272be401566a6e0ba1acbe70ee5cb97fce944bc2e04dc707152a0ec91b1
F ext/fts5/fts5_index.c eb9a0dda3bc6ef969a6be8d2746af56856e67251810ddba08622b45be8477abe
F ext/fts5/fts5_main.c 0dbe241c50b62e24a229a176d66d580e359b3c32cb0970c39bb6dd6b86e125d5
F ext/fts5/fts5_storage.c 9a9b880be12901f1962ae2a5a7e1b74348b3099a1e728764e419f75d98e3e612
F ext/fts5/fts5_index.c 571483823193f09439356741669aa8c81da838ae6f5e1bfa7517f7ee2fb3addd
F ext/fts5/fts5_main.c c75bf3452858bca85c7e31dbedaefe7435d212c6e47f40725b3dce29366f0eee
F ext/fts5/fts5_storage.c 42cde97eb7d8506a8d2c7ea80b292fc3017b1f5469e1acb0035a69c345e6cf71
F ext/fts5/fts5_tcl.c 4db9258a7882c5eac0da4433042132aaf15b87dd1e1636c7a6ca203abd2c8bfe
F ext/fts5/fts5_test_mi.c 08c11ec968148d4cb4119d96d819f8c1f329812c568bac3684f5464be177d3ee
F ext/fts5/fts5_test_tok.c 3cb0a9b508b30d17ef025ccddd26ae3dc8ddffbe76c057616e59a9aa85d36f3b
@@ -148,12 +148,12 @@ F ext/fts5/test/fts5contentless4.test ec34dc69ef474ca9997dae6d91e072906e0e9a5a4b
F ext/fts5/test/fts5contentless5.test 40cdcb4fe751672450829c5a96bd32c25fc2f6076279dd2ce5c58ac9a390132a
F ext/fts5/test/fts5corrupt.test 6485f721b88ba355ca5d701e7ee87a4efa3ea578d8e6adb26f51ef956c8328bd
F ext/fts5/test/fts5corrupt2.test 335911e3f68b9625d850325f9e29a128db3f4276a8c9d4e32134580da8f924c4
F ext/fts5/test/fts5corrupt3.test 621e9bca3e7299f487e1b29ff4179d9fc9560f5847dfc5b50a16010c9d2a0e5f
F ext/fts5/test/fts5corrupt3.test 4fc3bf129f1616bea00884a23fd9d7b0e46d01791d2b57fe8d68ac36e8d3ff7c
F ext/fts5/test/fts5corrupt4.test dc08d19f5b8943e95a7778a7d8da592042504faf18dd93f68f7d7a0d7d7dd733
F ext/fts5/test/fts5corrupt5.test 11b47126f5772cc37b67e3e8b2ed05895c4d07c05338bc07e4eea225bfe32c76
F ext/fts5/test/fts5corrupt6.test 2d72db743db7b5d9c9a6d0cfef24d799ed1aa5e8192b66c40e871a37ed9eed06
F ext/fts5/test/fts5corrupt7.test 4e830875c33b9ea3c4cf1ba71e692b63893cbb4faae8c69b1071889dc26e211c
F ext/fts5/test/fts5corrupt8.test f78b6de9e4327e16ba7a7958b1ce576f9b5d886b4b97690f90b7f3cf654da458
F ext/fts5/test/fts5corrupt8.test b81d802e41631e98100f49a1aadeeffef860e30a62d6ed7d743c2797c477239e
F ext/fts5/test/fts5delete.test 619295b20dbc1d840b403ee07c878f52378849c3c02e44f2ee143b3e978a0aa7
F ext/fts5/test/fts5detail.test 54015e9c43ec4ba542cfb93268abdf280e0300f350efd08ee411284b03595cc4
F ext/fts5/test/fts5determin.test 1b77879b2ae818b5b71c859e534ee334dac088b7cf3ff3bf76a2c82b1c788d11
@@ -165,7 +165,7 @@ F ext/fts5/test/fts5expr.test c7e208813df7a90badc856fde3796da79569b39382e0fdb430
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 87a10d0caee57da587c7588b0c8d25d2930197399b4812ad1e4d574c75324cee
F ext/fts5/test/fts5fault4.test a5c0e849127c24e1751bc453a817f09a1b8d460e75f9ae4764017e216a870db3
F ext/fts5/test/fts5fault5.test a336e4e11847de24c9497f80cce18e00bb3fab7fb11f97d04eb9af898900a762
F ext/fts5/test/fts5fault6.test 40f49976c6ca8927bf7d65d0b8df46009d7ea172e1d4050b294610e7ea0a2979
F ext/fts5/test/fts5fault7.test 0acbec416edb24b8881f154e99c31e9ccf73f539cfcd164090be139e9e97ed4c
@@ -178,21 +178,22 @@ F ext/fts5/test/fts5faultE.test 844586ce71dab4be85bb86880e87b624d089f851654cd22e
F ext/fts5/test/fts5faultF.test 4abef99f86e99d9f0c6460dd68c586a766b6b9f1f660ada55bf2e8266bd1bbc1
F ext/fts5/test/fts5faultG.test 0544411ffcb3e19b42866f757a8a5e0fb8fef3a62c06f61d14deebc571bb7ea9
F ext/fts5/test/fts5faultH.test 2b2b5b8cb1b3fd7679f488c06e22af44107fbc6137eaf45b3e771dc7b149312d
F ext/fts5/test/fts5faultI.test e1e8a927122a8c3be8614a59717e838cad0505ba0a6f404983da8430e7aeb14d
F ext/fts5/test/fts5faultI.test ae4b83ac953200bd7b66d53038f7d6a4fc29cd64831b8e1795538babcea7c638
F ext/fts5/test/fts5first.test bfd685b96905bf541d99d8644e0a7219d1d833455a08ab64e344071a613b6ba9
F ext/fts5/test/fts5full.test 97d263c1072f4a560929cca31e70f65d2ae232610e17e6affcf7e979df59547b
F ext/fts5/test/fts5fuzz1.test 238d8c45f3b81342aa384de3e581ff2fa330bf922a7b69e484bbc06051a1080e
F ext/fts5/test/fts5hash.test fd3e0367fbf0b0944d6936fdb22696350f57b9871069c6766251578a103e8a14
F ext/fts5/test/fts5integrity.test 646796671205dae46af5bb12a49b5696483cfe8e12d71d21454940b13ace95ab
F ext/fts5/test/fts5integrity2.test 4c3636615c0201232c44a8105d5cb14fd5499fd0ee3014d7ffd7e83aac76ece8
F ext/fts5/test/fts5interrupt.test 20d04204d3e341b104c0c24a41596b6393a3a81eba1044c168db0e106f9ac92c
F ext/fts5/test/fts5lastrowid.test f36298a1fb9f988bde060a274a7ce638faa9c38a31400f8d2d27ea9373e0c4a1
F ext/fts5/test/fts5leftjoin.test c0b4cafb9661379e576dc4405c0891d8fcc2782680740513c4d1fc114b43d4ad
F ext/fts5/test/fts5limits.test 8ab67cf5d311c124b6ceb0062d0297767176df4572d955fce79fa43004dff01c
F ext/fts5/test/fts5locale.test 797cf6f5e017462ab11313ce884b9f1df8ff063811e74ef42190cd19ed6b600b
F ext/fts5/test/fts5locale.test 58ce0515c4f49cbb9905e3711168050d58fc184daf885c9ef7483e20aab63e5a
F ext/fts5/test/fts5matchinfo.test 877520582feb86bbfd95ab780099bcba4526f18ac75ee34979144cf86ba3a5a3
F ext/fts5/test/fts5merge.test 2654df0bcdb2d117c2d38b6aeb0168061be01c643f9e9194b36c43a2970e8082
F ext/fts5/test/fts5merge2.test 3ebad1a59d6ad3fb66eff6523a09e95dc6367cbefb3cd73196801dea0425c8e2
F ext/fts5/test/fts5misc.test 60bb2be4a2d83d7a45047c1812781e2e337a27efa539d86356ef7f4acaf08eab
F ext/fts5/test/fts5misc.test 8c3cc771f773dc4bb4973620c51e7729e324ca2cc80eb8894f1c2c605e361f0b
F ext/fts5/test/fts5multi.test a15bc91cdb717492e6e1b66fec1c356cb57386b980c7ba5af1915f97fe878581
F ext/fts5/test/fts5multiclient.test 5ff811c028d6108045ffef737f1e9f05028af2458e456c0937c1d1b8dea56d45
F ext/fts5/test/fts5near.test 33d60867581066e5db7016deb5d651628125d7ff4e0233a88175aa5b65874c74
@@ -205,7 +206,7 @@ F ext/fts5/test/fts5origintext2.test f4505ff79bf7369f2b8b10b9cef7476049d844e20b3
F ext/fts5/test/fts5origintext3.test 45c33cf0c91a9ca0e36d298462db3edc7c8fe45fd185649a9dbfd66bb670058b
F ext/fts5/test/fts5origintext4.test 0d3ef0a8038f471dbc83001c34fe5f7ae39b571bfc209670771eb28bc0fc50e8
F ext/fts5/test/fts5origintext5.test ee12b440ec335e5b422d1668aca0051b52ff28b6ee67073e8bbc29f509fd562b
F ext/fts5/test/fts5phrase.test 6260b8be40d51ec287992cd983a5e58a9be92e5dc6e01d48cbce1ad0e95a99d8
F ext/fts5/test/fts5phrase.test bb2554bb61d15f859678c96dc89a7de415cd5fc3b7b54c29b82a0d0ad138091c
F ext/fts5/test/fts5plan.test f8b0d752a818059a934cdc96c0f77de058a67a0a57bb3a8181d28307ab5b1626
F ext/fts5/test/fts5porter.test 15b514fac8690b58e99c330efe5bf5615bc43f2fae4a3cca3f923dbaff55a0c0
F ext/fts5/test/fts5porter2.test 94f0e4351e2c99b4e74f1fae05a4ddf1cb5b926620a8c14554160d075ddc7a59
@@ -226,7 +227,7 @@ F ext/fts5/test/fts5secure6.test 74bf04733cc523bccca519bb03d3b4e2ed6f6e3db7c59bf
F ext/fts5/test/fts5secure7.test fd03d0868d64340a1db8615b02e5508fea409de13910114e4f19eaefc120777a
F ext/fts5/test/fts5secure8.test 808ade9d172ed07b24b85c57dd53b6d2b1aba018b4e634d267ce572221de80e0
F ext/fts5/test/fts5securefault.test c34a28c7cd2f31a8b8907563889e1329a97da975c08df2d951422bcef8e2ebc5
F ext/fts5/test/fts5simple.test ed7c3815c9fa1c16166258cb98edb2e014c63c7589958d76c5487df0df913d61
F ext/fts5/test/fts5simple.test 302cdb4f8a3350b091f4f1bccd82d05610428657f6f9e81c17703ba48267ec40
F ext/fts5/test/fts5simple2.test d10d963a357b8ec77b99032e4c816459b4dbdb1f6eee25eada7ef3ed245cb2dc
F ext/fts5/test/fts5simple3.test 146ec3dc8f5763d6212641c9f0a2f1cba41679353d2add7b963beceb115dc7f4
F ext/fts5/test/fts5synonym.test becc8cea6cfc958a50b30c572c68cbfdf7455971d0fe988202ce67638d2c6cf6
@@ -410,7 +411,7 @@ F ext/misc/nextchar.c 7877914c2a80c2f181dd04c3dbef550dfb54c93495dc03da2403b5dd58
F ext/misc/noop.c f1a21cc9b7a4e667e5c8458d80ba680b8bd4315a003f256006046879f679c5a0
F ext/misc/normalize.c bd84355c118e297522aba74de34a4fd286fc775524e0499b14473918d09ea61f
F ext/misc/pcachetrace.c f4227ce03fb16aa8d6f321b72dd051097419d7a028a9853af048bee7645cb405
F ext/misc/percentile.c af1941dc87d45dd0c2698a3087fbfe9ee0d157e5e72da521430c4b784abcbe81
F ext/misc/percentile.c 42eb041edab407e512aaa087f99ed9287fe0b3224f7a6d194456c00fc1454312
F ext/misc/prefixes.c 82645f79229877afab08c8b08ca1e7fa31921280906b90a61c294e4f540cd2a6
F ext/misc/qpvtab.c fc189e127f68f791af90a487f4460ec91539a716daf45a0c357e963fd47cc06c
F ext/misc/randomjson.c ef835fc64289e76ac4873b85fe12f9463a036168d7683cf2b773e36e6262c4ed
@@ -419,7 +420,7 @@ F ext/misc/remember.c add730f0f7e7436cd15ea3fd6a90fd83c3f706ab44169f7f048438b7d6
F ext/misc/rot13.c 51ac5f51e9d5fd811db58a9c23c628ad5f333c173f1fc53c8491a3603d38556c
F ext/misc/scrub.c 2a44b0d44c69584c0580ad2553f6290a307a49df4668941d2812135bfb96a946
F ext/misc/series.c a6089b5e8e3002bd1e5d9877cee6aead0b9a6426e406c09a399817db9e9ae823
F ext/misc/sha1.c 4011aef176616872b2a0d5bccf0ecfb1f7ce3fe5c3d107f3a8e949d8e1e3f08d
F ext/misc/sha1.c cb5002148c2661b5946f34561701e9105e9d339b713ec8ac057fd888b196dcb9
F ext/misc/shathree.c 1821d90a0040c9accdbe3e3527d378d30569475d758aa70f6848924c0b430e8c
F ext/misc/showauth.c 732578f0fe4ce42d577e1c86dc89dd14a006ab52
F ext/misc/spellfix.c c0aa7b80d6df45f7da59d912b38752bcac1af53a5766966160e6c5cdd397dbea
@@ -434,6 +435,7 @@ F ext/misc/urifuncs.c f71360d14fa9e7626b563f1f781c6148109462741c5235ac63ae0f8917
F ext/misc/uuid.c 5bb2264c1b64d163efa46509544fd7500cb8769cb7c16dd52052da8d961505cf
F ext/misc/vfslog.c 3932ab932eeb2601dbc4447cb14d445aaa9fbe43b863ef5f014401c3420afd20
F ext/misc/vfsstat.c a85df08654743922a19410d7b1e3111de41bb7cd07d20dd16eda4e2b808d269d
F ext/misc/vfstrace.c 03f90dd465968e01f5d1d3e79c36cbc53a5bfe1bd55d239435ce94df19d5b0ac
F ext/misc/vtablog.c 1100250ce8782db37c833e3a9a5c9a3ecf1af5e15b8325572b82e6e0a138ffb5
F ext/misc/vtshim.c 1976e6dd68dd0d64508c91a6dfab8e75f8aaf6cd
F ext/misc/wholenumber.c 0fa0c082676b7868bf2fa918e911133f2b349bcdceabd1198bba5f65b4fc0668
@@ -483,7 +485,7 @@ F ext/rbu/rbuvacuum.test 542561741ff2b262e3694bc6012b44694ee62c545845319a06f3237
F ext/rbu/rbuvacuum2.test ae097d04feb041446a74fac94b24bffeb3fdd60e32b848c5611e507ab702b81b
F ext/rbu/rbuvacuum3.test 3ce42695fdf21aaa3499e857d7d4253bc499ad759bcd6c9362042c13cd37d8de
F ext/rbu/rbuvacuum4.test ffccd22f67e2d0b380d2889685742159dfe0d19a3880ca3d2d1d69eefaebb205
F ext/rbu/sqlite3rbu.c 4a3376c0fb9a844a799ac529fb81260523f6b13c9f629bc270c632dbae5fc1f8
F ext/rbu/sqlite3rbu.c c07817e89477b8fc286ab6ed87da5bc82fc3490bbbe9e9b22eb2d900e81ee5dc
F ext/rbu/sqlite3rbu.h 9d923eb135c5d04aa6afd7c39ca47b0d1d0707c100e02f19fdde6a494e414304
F ext/rbu/test_rbu.c b9727c3394307d058e806c1da0f8bb7b24daf3c6bb94cb10cca88ea4d5c806c0
F ext/recover/dbdata.c 5295f4f922b60d7035b6b9fd5846b13071b9d97ed7fad8496837bb7640d24771
@@ -594,7 +596,7 @@ F ext/session/sessionstat1.test 5e718d5888c0c49bbb33a7a4f816366db85f59f6a4f97544
F ext/session/sessionwor.test 6fd9a2256442cebde5b2284936ae9e0d54bde692d0f5fd009ecef8511f4cf3fc
F ext/session/sqlite3session.c c7473aafbd88f796391a8c25aa90975a8f3729ab7f4f8cf74ab9d3b014e10abe
F ext/session/sqlite3session.h 683ccbf16e2c2521661fc4c1cf918ce57002039efbcabcd8097fa4bca569104b
F ext/session/test_session.c 6acbe67db80ab0806147eb62a12f9e3a44930f4a740b68b0a4340dddda2c10d7
F ext/session/test_session.c aa29abdcc9011ac02f4fa38e8ede226106eaeee7c3ea7d8b2b999a124e0c368c
F ext/userauth/sqlite3userauth.h 7f3ea8c4686db8e40b0a0e7a8e0b00fac13aa7a3
F ext/userauth/user-auth.txt ca7e9ee82ca4e1c1744295f8184dd70edfae1992865d26c64303f539eb6c084c
F ext/userauth/userauth.c 7f00cded7dcaa5d47f54539b290a43d2e59f4b1eb5f447545fa865f002fc80cb
@@ -685,7 +687,7 @@ F ext/wasm/wasmfs.make 8a4955882aaa0783b3f60a9484a1f0f3d8b6f775c0fcd17c082f31966
F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x
F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8
F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0
F main.mk 9541ffdce424ddddb463e2480c3f1cb4067bbd3a6d2c84b3f083cb128a2fa721
F main.mk 8b9c0252aef57b5b2a10f34b8b46e89f9ed06bdccef1df98673a12f34e9b3e79
F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271
F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504
F mptest/crash01.test 61e61469e257df0850df4293d7d4d6c2af301421
@@ -704,31 +706,31 @@ F src/auth.c 4c1ea890e0069ad73bead5d17a5b12c34cfa4f1a24175c8147ea439b64be271c
F src/backup.c 5c97e8023aab1ce14a42387eb3ae00ba5a0644569e3476f38661fa6f824c3523
F src/bitvec.c 9eac5f42c11914d5ef00a75605bb205e934f435c579687f985f1f8b0995c8645
F src/btmutex.c 79a43670447eacc651519a429f6ece9fd638563cf95b469d6891185ddae2b522
F src/btree.c 8b42fc7d9efdb2df05c30e8f91ff6cfbd979724ae24bf90269028468b7a13333
F src/btree.c 8c5592c618741c5fc9733e7efe3927bfafad3e999d15b0a0f3f1d3f3e17b919e
F src/btree.h 55066f513eb095db935169dab1dc2f7c7a747ef223c533f5d4ad4dfed346cbd0
F src/btreeInt.h 98aadb6dcb77b012cab2574d6a728fad56b337fc946839b9898c4b4c969e30b6
F src/build.c 3a1840d9d171ce2d24f4c1f7acda7266ab796c664290c1acba65ff98ce2bd01e
F src/callback.c db3a45e376deff6a16c0058163fe0ae2b73a2945f3f408ca32cf74960b28d490
F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e
F src/ctime.c 64e4b1227b4ed123146f0aa2989131d1fbd9b927b11e80c9d58c6a68f9cd5ce3
F src/ctime.c b224d3db0f28c4a5f1407c50107a0a8133bd244ff3c7f6f8cedeb896a8cf1b64
F src/date.c 89ce1ff20512a7fa5070ba6e7dd5c171148ca7d580955795bf97c79c2456144a
F src/dbpage.c 80e46e1df623ec40486da7a5086cb723b0275a6e2a7b01d9f9b5da0f04ba2782
F src/dbpage.c 12e49515d67d4a59625d71f9aa42499556cfdc2e4f1ea49086e674a7f47f46e5
F src/dbstat.c 73362c0df0f40ad5523a6f5501224959d0976757b511299bf892313e79d14f5c
F src/delete.c 444c4d1eaac40103461e3b6f0881846dd3aafc1cec1dd169d3482fa331667da7
F src/expr.c 6d5f2c38fe3ec06a7eac599dac822788b36064124e20112a844e9cd5156cb239
F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007
F src/fkey.c 928ed2517e8732113d2b9821aa37af639688d752f4ea9ac6e0e393d713eeb76f
F src/func.c 1f61e32e7a357e615b5d2e774bee563761fce4f2fd97ecb0f72c33e62a2ada5f
F src/func.c df400a1d3f4625997d4dd8a81951c303e066277c29b861d37e03cd152d7858dd
F src/global.c 61a419dd9e993b9be0f91de4c4ccf322b053eb829868e089f0321dd669be3b90
F src/hash.c 9ee4269fb1d6632a6fecfb9479c93a1f29271bddbbaf215dd60420bcb80c7220
F src/hash.h 3340ab6e1d13e725571d7cee6d3e3135f0779a7d8e76a9ce0a85971fa3953c51
F src/hwtime.h f9c2dfb84dce7acf95ce6d289e46f5f9d3d1afd328e53da8f8e9008e3b3caae6
F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71
F src/insert.c f8d1a0f8ee258411009c6b7f2d93170e351bd19f5ad89d57e1180644297cbe70
F src/json.c 5b6a1d6015997b9ee848a32948720bdb26a0ef2de5a2127ebf7355ce66dbdc0d
F src/json.c 68a98c020c22127f2d65f08855f7fc7460ff352a6ce0b543d8931dde83319c22
F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa
F src/loadext.c 7432c944ff197046d67a1207790a1b13eec4548c85a9457eb0896bb3641dfb36
F src/main.c a520c325c7400b249242945f2c602acb19662c40f5db1c04d88664cfaa8b85ac
F src/main.c e7b53893f9fb3ad76baa8513f85c167b34d5c8e25ce64608db440f5637d0fe9e
F src/malloc.c 410e570b30c26cc36e3372577df50f7a96ee3eed5b2b161c6b6b48773c650c5e
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
F src/mem1.c 3bb59158c38e05f6270e761a9f435bf19827a264c13d1631c58b84bdc96d73b2
@@ -754,7 +756,7 @@ F src/os_win.c 6ff43bac175bd9ed79e7c0f96840b139f2f51d01689a638fd05128becf94908a
F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a
F src/pager.c b08600ebf0db90b6d1e9b8b6577c6fa3877cbe1a100bd0b2899e4c6e9adad4b3
F src/pager.h 4b1140d691860de0be1347474c51fee07d5420bd7f802d38cbab8ea4ab9f538a
F src/parse.y 5972b7d00af4c8d96fdad781af1ea1d5d51fc3b907ad61bda60e49503274e5ed
F src/parse.y a7a8d42eeff01d267444ddb476029b0b1726fb70ae3d77984140f17ad02e2d61
F src/pcache.c 588cc3c5ccaaadde689ed35ce5c5c891a1f7b1f4d1f56f6cf0143b74d8ee6484
F src/pcache.h 1497ce1b823cf00094bb0cf3bac37b345937e6f910890c626b16512316d3abf5
F src/pcache1.c 49516ad7718a3626f28f710fa7448ef1fce3c07fd169acbb4817341950264319
@@ -766,17 +768,17 @@ F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c
F src/resolve.c 2c127880c0634962837f16f2f48a295e514357af959330cc038de73015d5b5e8
F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97
F src/select.c 4b14337a2742f0c0beeba490e9a05507e9b4b12184b9cd12773501d08d48e3fe
F src/shell.c.in 40de636c1d90fb8a9ca7f49dc8f50d930f1b60736e73aca5eb37c4c7d0e47f9d
F src/sqlite.h.in f07bff4225a1244efd604a0ffef81ed69f29d3dbaed7e22f906f26229ba3ca9e
F src/shell.c.in 375f8a183126be96ec73db4e42c57917ff10a0900846b1b722dd4f8cef537812
F src/sqlite.h.in 77f55bd1978a04a14db211732f0a609077cf60ba4ccf9baf39988f508945419c
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
F src/sqlite3ext.h 3f046c04ea3595d6bfda99b781926b17e672fd6d27da2ba6d8d8fc39981dcb54
F src/sqliteInt.h 28c878bdf528879afefe1994ac007d094f8061f2fdacdc55d6055d7e9341151e
F src/sqliteInt.h 889cd632f4386bbd8619b166abb7d25f1c8ce6514e90cb7f22f63bd530fc6107
F src/sqliteLimit.h 6878ab64bdeb8c24a1d762d45635e34b96da21132179023338c93f820eee6728
F src/status.c cb11f8589a6912af2da3bb1ec509a94dd8ef27df4d4c1a97e0bcf2309ece972b
F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1
F src/tclsqlite.c c6888598f08dee3d9112a38ef42c8f5c89ca7f3190f4694744d0b84250f4bf8c
F src/tclsqlite.h c6af51f31a2b2172d674608763a4b98fdf5cd587e4025053e546fb8077757262
F src/test1.c 3f18399557d954bc85f4564aec8ea1777d2161a81d98a3ff6c9e9046bf3554c1
F src/test1.c 8d7cd219c004cd2ced60659ebf045025cc5c16ce19d12459589dacd4310f7f07
F src/test2.c 7ebc518e6735939d8979273a6f7b1d9b5702babf059f6ad62499f7f60a9eb9a3
F src/test3.c e7573aa0f78ee4e070a4bc8c3493941c1aa64d5c66d4825c74c0f055451f432b
F src/test4.c 13e57ae7ec7a959ee180970aef09deed141252fe9bb07c61054f0dfa4f1dfd5d
@@ -790,7 +792,7 @@ F src/test_backup.c bd901e3c116c7f3b3bbbd4aae4ce87d99b400c9cbb0a9e7b4610af451d97
F src/test_bestindex.c 3401bee51665cbf7f9ed2552b5795452a8b86365e4c9ece745b54155a55670c6
F src/test_blob.c bcdf6a6c22d0bcc13c41479d63692ef413add2a4d30e1e26b9f74ab85b9fb4d5
F src/test_btree.c 28283787d32b8fa953eb77412ad0de2c9895260e4e5bd5a94b3c7411664f90d5
F src/test_config.c 46eaf39842cace9d540aeefb50fe24dd3204a622893a97952cbb49c20b2f8b21
F src/test_config.c 345b8e383f71cecc36d0fa05f2f06639c254b188f98101c3c97749df43037086
F src/test_delete.c e2fe07646dff6300b48d49b2fee2fe192ed389e834dd635e3b3bac0ce0bf9f8f
F src/test_demovfs.c 3efa2adf4f21e10d95521721687d5ca047aea91fa62dd8cc22ac9e5a9c942383
F src/test_devsym.c 649434ed34d0b03fbd5a6b42df80f0f9a7e53f94dd1710aad5dd8831e91c4e86
@@ -822,7 +824,6 @@ F src/test_tclvar.c ae873248a0188459b1c16ca7cc431265dacce524399e8b46725c2b3b7e04
F src/test_thread.c d7a8bcea7445f37cc2a1f7f81dd6059634f45e0c61bfe80182b02872fb0328bb
F src/test_vdbecov.c 5c426d9cd2b351f5f9ceb30cabf8c64a63bfcad644c507e0bd9ce2f6ae1a3bf3
F src/test_vfs.c f298475e468c7e14945b20af885917181090c265aa3c4ade897849c9fbd396f2
F src/test_vfstrace.c a2ea82df2ed8927e9eba49bdba1aa1aeb1dcb13dbf6558cff036da813031de9a
F src/test_windirent.c a895e2c068a06644eef91a7f0a32182445a893b9a0f33d0cdb4283dca2486ac1
F src/test_windirent.h da2e5b73c32d09905fbdd00f27cd802212a32a58ead882736fe4f5eb775ebc50
F src/test_window.c 6d80e11fba89a1796525e6f0048ff0c7789aa2c6b0b11c80827dc1437bd8ea72
@@ -841,17 +842,17 @@ F src/vdbe.h c2549a215898a390de6669cfa32adba56f0d7e17ba5a7f7b14506d6fd5f0c36a
F src/vdbeInt.h 949669dfd8a41550d27dcb905b494f2ccde9a2e6c1b0b04daa1227e2e74c2b2c
F src/vdbeapi.c 80235ac380e9467fec1cb0883354d841f2a771976e766995f7e0c77f845406df
F src/vdbeaux.c 25d685cafe119ff890c94345e884ea558a6b5d823bfa52ba708eb8ff3c70aa71
F src/vdbeblob.c 13f9287b55b6356b4b1845410382d6bede203ceb29ef69388a4a3d007ffacbe5
F src/vdbeblob.c 255be187436da38b01f276c02e6a08103489bbe2a7c6c21537b7aecbe0e1f797
F src/vdbemem.c 831a244831eaa45335f9ae276b50a7a82ee10d8c46c2c72492d4eb8c98d94d89
F src/vdbesort.c d0a3c7056c081703c8b6d91ad60f17da5e062a5c64bf568ed0fa1b5f4cae311f
F src/vdbetrace.c fe0bc29ebd4e02c8bc5c1945f1d2e6be5927ec12c06d89b03ef2a4def34bf823
F src/vdbevtab.c fc46b9cbd759dc013f0b3724549cc0d71379183c667df3a5988f7e2f1bd485f3
F src/vtab.c 5fb499d20494b7eecaadb7584634af9afcb374cb0524912b475fcb1712458a1b
F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9
F src/wal.c 887fc4ca3f020ebb2e376f222069570834ac63bf50111ef0cbf3ae417048ed89
F src/wal.c ef68130ba330ee18c1cb22da36a881c82e3a3b109badbdc6a9b9acaf788a6688
F src/wal.h ba252daaa94f889f4b2c17c027e823d9be47ce39da1d3799886bbd51f0490452
F src/walker.c d5006d6b005e4ea7302ad390957a8d41ed83faa177e412f89bc5600a7462a014
F src/where.c c046dd58c3410f7b7528e1e6317cb876398557bad346d568ed8562321a7d002d
F src/where.c 7fb55836eb7fd07f0a0d8400c50619fc02cda1f46a617cfb003c2990f040193d
F src/whereInt.h a5d079c346a658b7a6e9e47bb943d021e02fa1e6aed3b964ca112112a4892192
F src/wherecode.c 5172d647798134e7c92536ddffe7e530c393d79b5dedd648b88faf2646c65baf
F src/whereexpr.c 44f41ae554c7572e1de1485b3169b233ee04d464b2ee5881687ede3bf07cacfa
@@ -1183,7 +1184,7 @@ F test/fts3conf.test c9cd45433b6787d48a43e84949aa2eb8b3b3d242bac7276731c1476290d
F test/fts3corrupt.test 6732477c5ace050c5758a40a8b5706c8c0cccd416b9c558e0e15224805a40e57
F test/fts3corrupt2.test e318f0676e5e78d5a4b702637e2bb25265954c08a1b1e4aaf93c7880bb0c67d0
F test/fts3corrupt3.test 0d5b69a0998b4adf868cc301fc78f3d0707745f1d984ce044c205cdb764b491f
F test/fts3corrupt4.test 48bd57baed9654e511709a02dbef2d22ee54c012ad466e8648f0f825233faa08
F test/fts3corrupt4.test 294684add5f235ea8a77a350b66eb74a80ac8ecee6ac38c07885348f5fb2e233
F test/fts3corrupt5.test 0549f85ec4bd22e992f645f13c59b99d652f2f5e643dac75568bfd23a6db7ed5
F test/fts3corrupt6.test f417c910254f32c0bc9ead7affa991a1d5aec35b3b32a183ffb05eea78289525
F test/fts3cov.test 7eacdbefd756cfa4dc2241974e3db2834e9b372ca215880e00032222f32194cf
@@ -1266,7 +1267,7 @@ F test/fuzz3.test 70ba57260364b83e964707b9d4b5625284239768ab907dd387c740c0370ce3
F test/fuzz4.test c229bcdb45518a89e1d208a21343e061503460ac69fae1539320a89f572eb634
F test/fuzz_common.tcl b7197de6ed1ee8250a4f82d67876f4561b42ee8cbbfc6160dcb66331bad3f830
F test/fuzz_malloc.test f348276e732e814802e39f042b1f6da6362a610af73a528d8f76898fde6b22f2
F test/fuzzcheck.c 6e87c27df3d95c556870187987dff6efdc712b5cea60abedc8ab9215f471907a
F test/fuzzcheck.c 89b71d92b150a532e945e489d6e0721a4b15353c9255e079c198ed2a1958018b
F test/fuzzdata1.db 3e86d9cf5aea68ddb8e27c02d7dfdaa226347426c7eb814918e4d95475bf8517
F test/fuzzdata2.db 128b3feeb78918d075c9b14b48610145a0dd4c8d6f1ca7c2870c7e425f5bf31f
F test/fuzzdata3.db c6586d3e3cef0fbc18108f9bb649aa77bfc38aba
@@ -1278,7 +1279,7 @@ F test/fuzzdata8.db 4a53b6d077c6a5c23b609d8d3ac66996fa55ba3f8d02f9b6efdd0214a767
F test/fuzzer1.test 3d4c4b7e547aba5e5511a2991e3e3d07166cfbb8
F test/fuzzer2.test a85ef814ce071293bce1ad8dffa217cbbaad4c14
F test/fuzzerfault.test f64c4aef4c9e9edf1d6dc0d3f1e65dcc81e67c996403c88d14f09b74807a42bc
F test/fuzzinvariants.c 81167c9a7e82c0539a1d704aeb3384046d01f4108cda160a2447cb2a149d6362
F test/fuzzinvariants.c 057e910241d85aa4aaf75cef1a7adc45c632b173288d07d9dbbef4e6bda83d5a
F test/gcfault.test 4ea410ac161e685f17b19e1f606f58514a2850e806c65b846d05f60d436c5b0d
F test/gencol1.test e169bdfa11c7ed5e9f322a98a7db3afe9e66235750b68c923efee8e1876b46ec
F test/genesis.tcl 1e2e2e8e5cc4058549a154ff1892fe5c9de19f98
@@ -1345,7 +1346,7 @@ F test/ioerr5.test 5984da7bf74b6540aa356f2ab0c6ae68a6d12039a3d798a9ac6a100abc17d
F test/ioerr6.test a395a6ab144b26a9e3e21059a1ab6a7149cca65b
F test/istrue.test e7f285bb70282625c258e866ce6337d4c762922f5a300e1b50f958aef6e7d9c9
F test/join.test f7abfef3faeaf2800308872e33a57e5b6e4a2b44fb8c6b90c6068412e71a6cf4
F test/join2.test 8561fe82ce434ac96de91544072e578dc2cadddf2d9bc9cd802f866a9b92502e
F test/join2.test f59d63264fb24784ae9c3bc9d867eb569cd6d442da5660f8852effe5c1938c27
F test/join3.test 6f0c774ff1ba0489e6c88a3e77b9d3528fb4fda0
F test/join4.test 1a352e4e267114444c29266ce79e941af5885916
F test/join5.test 380d12a9350f99f0cc681a4f1fea999886f18b3fe0d71a9b3065bcaead1e007f
@@ -1380,7 +1381,7 @@ F test/json106.test 4aed3afd16549045d198a8d9cea00deea96e1f2ecf55864dce96cac558b8
F test/json107.test 59054e815c8f6b67d634d44ace421cf975828fb5651c4460aa66015c8e19d562
F test/json108.test 0a5f1e2d4b35a1bc33052563d2a5ede03052e2099e58cb424547656c898e0f49
F test/json501.test b95e2d14988b682a5cadf079dd6162f0f85fb74cd59c6b1f1624110104a974eb
F test/json502.test 84634d3dbb521d2814e43624025b760c6198456c8197bbec6c977c0236648f5b
F test/json502.test 4ef68e4f272dfb083d4cbceb4e9e51d67ec1186a185e0c13637c50a4dc2f9796
F test/jsonb01.test f4cdfb4cf5a0c940091b17675ed9583f45add0c938f07d65b0de0e19d3a9a101
F test/keyword1.test 37ef6bba5d2ed5b07ecdd6810571de2956599dff
F test/kvtest.c 6e0228409ea7ca0497dad503fbd109badb5e59545d131014b6aaac68b56f484a
@@ -1517,7 +1518,7 @@ F test/parser1.test 6ccdf5e459a5dc4673d3273dc311a7e9742ca952dd0551a6a6320d27035c
F test/pcache.test c8acbedd3b6fd0f9a7ca887a83b11d24a007972b
F test/pcache2.test af7f3deb1a819f77a6d0d81534e97d1cf62cd442
F test/pendingrace.test e99efc5ab3584da3dfc8cd6a0ec4e5a42214820574f5ea24ee93f1d84655f463
F test/percentile.test 74e383216a075251512d6ba98beb9dccd6da465e3f73817fc438379e3a628de7
F test/percentile.test 52ba89d6ee6b65f770972b67dace358bab7cdbd532803d3db157845268e789cd
F test/permutations.test 405542f1d659942994a6b38a9e024cf5cfd23eaa68c806aeb24a72d7c9186e80
F test/pg_common.tcl 3b27542224db1e713ae387459b5d117c836a5f6e328846922993b6d2b7640d9f
F test/pragma.test 11cb9310c42f921918f7f563e3c0b6e70f9f9c3a6a1cf12af8fccb6c574f3882
@@ -1626,10 +1627,10 @@ F test/sharedB.test 1a84863d7a2204e0d42f2e1606577c5e92e4473fa37ea0f5bdf829e4bf8e
F test/shared_err.test 32634e404a3317eeb94abc7a099c556a346fdb8fb3858dbe222a4cbb8926a939
F test/sharedlock.test 5ede3c37439067c43b0198f580fd374ebf15d304
F test/shell1.test 490bf9d0c7c9564fea318c46d49369f4690b825b584c9a544dbdccf61bc0babc
F test/shell2.test 56da24128304c9ab67da2964cc80beff7b35761c446ec6e6e98bff2775b15026
F test/shell2.test 01a01f76ed98088ce598794fbf5b359e148271541a8ddbf79d21cc353cc67a24
F test/shell3.test db1953a8e59d08e9240b7cc5948878e184f7eb2623591587f8fd1f1a5bd536d8
F test/shell4.test 522fdc628c55eff697b061504fb0a9e4e6dfc5d9087a633ab0f3dd11bcc4f807
F test/shell5.test bafa4c0b67b7a8027e729970a625c9225cb7ef854acc4e52624c45074faaaddf
F test/shell5.test 0e5f8ce08206b9998a778cfe1989e20e47839153c05af2da29198150172e22fc
F test/shell6.test e3b883b61d4916b6906678a35f9d19054861123ad91b856461e0a456273bdbb8
F test/shell7.test 43fd8e511c533bab5232e95c7b4be93b243451709e89582600d4b6e67693d5c3
F test/shell8.test aea51ecbcd4494c746b096aeff51d841d04d5f0dc4b62eb42427f16109b87acd
@@ -1713,9 +1714,9 @@ F test/temptable.test d2c9b87a54147161bcd1822e30c1d1cd891e5b30
F test/temptable2.test 76821347810ecc88203e6ef0dd6897b6036ac788e9dd3e6b04fd4d1631311a16
F test/temptable3.test d11a0974e52b347e45ee54ef1923c91ed91e4637
F test/temptrigger.test 38f0ca479b1822d3117069e014daabcaacefffcc
F test/tester.tcl 2c203a2dd664298f239f0ec3ce22fbc65b5f021c1e09edbae8452af8a694e052
F test/testrunner.tcl c27905c57f54450411be922037d227fee65b08928d09715d784380a398b0e758
F test/testrunner_data.tcl 6a0facfbff26f2f8573ebaeb209426bbb59809d5c0f6925f983bd030ab5248cd
F test/tester.tcl 7b44f1a9b9a2de8112695b908afc21dd9a68cd2d44e84b73f1b27b53492c0d59
F test/testrunner.tcl 3dd75b45593d2afa2e3bca76121297a9f163bebb98474b13536f326829a71db1 x
F test/testrunner_data.tcl dbc0bb1c5b912dfd1e32b25d544318e412edd6085bd5fc9e6619cb93a739b786
F test/thread001.test a0985c117eab62c0c65526e9fa5d1360dd1cac5b03bde223902763274ce21899
F test/thread002.test c24c83408e35ba5a952a3638b7ac03ccdf1ce4409289c54a050ac4c5f1de7502
F test/thread003.test ee4c9efc3b86a6a2767516a37bd64251272560a7
@@ -2050,7 +2051,7 @@ F test/wherelimit3.test 22d73e046870cf8bbe15573eda6b432b07ebe64a88711f9f849c6b36
F test/widetab1.test c296a98e123762de79917350e45fa33fdf88577a2571eb3a64c8bf7e44ef74d1
F test/win32heap.test 10fd891266bd00af68671e702317726375e5407561d859be1aa04696f2aeee74
F test/win32lock.test e0924eb8daac02bf80e9da88930747bd44dd9b230b7759fed927b1655b467c9c
F test/win32longpath.test 42210789bcfc5c0ac202643d6d0237db08df2c9218f2070d9a69e8af1eccf7d7
F test/win32longpath.test 304006024ca47104bf5a7415ef31ca83ecfc29351af202baf8588b880cffc116
F test/win32nolock.test ac4f08811a562e45a5755e661f45ca85892bdbbc
F test/window1.test 79dc3b9a2226f622d7e104a1fc750d1c4c3c08d6147b59085bdbe05352947ffa
F test/window2.tcl 492c125fa550cda1dd3555768a2303b3effbeceee215293adf8871efc25f1476
@@ -2070,7 +2071,7 @@ F test/windowA.test 6d63dc1260daa17141a55007600581778523a8b420629f1282d2acfc36af
F test/windowB.test aad7c31739999f68a98a813cfd78390918fc70f56d2d925317a1523cab548ecf
F test/windowC.test 6fd75f5bb2f1343d34e470e36e68f0ff638d8a42f6aa7d99471261b31a0d42f2
F test/windowD.test 65cf5a765fb8072450e8a0de2979ce7f09a38d87724fe1280c6444073e3da49b
F test/windowE.test c98507e0b0d95980ad25845db758557757be2d7054198ccf522c7d277057a3df
F test/windowE.test d045a5fbaaf50ecac9483e1249dd317ba4f9d189c405a730ba6effdefb87b94f
F test/windowerr.tcl f5acd6fbc210d7b5546c0e879d157888455cd4a17a1d3f28f07c1c8a387019e0
F test/windowerr.test a8b752402109c15aa1c5efe1b93ccb0ce1ef84fa964ae1cd6684dd0b3cc1819b
F test/windowfault.test 15094c1529424e62f798bc679e3fe9dfab6e8ba2f7dfe8c923b6248c31660a7c
@@ -2101,7 +2102,7 @@ F tool/GetFile.cs 47852aa0d806fe47ed1ac5138bdce7f000fe87aaa7f28107d0cb1e26682aeb
F tool/GetTclKit.bat d84033c6a93dfe735d247f48ba00292a1cc284dcf69963e5e672444e04534bbf
F tool/Replace.cs 02c67258801c2fb5f63231e0ac0f220b4b36ba91
F tool/build-all-msvc.bat c817b716e0edeecaf265a6775b63e5f45c34a6544f1d4114a222701ed5ac79ab x
F tool/build-shell.sh f193b5e3eb4afcb4abbf96bf1475be6cfb74763ee2e50c82bc7ca105e8a136c5
F tool/build-shell.sh 369c4b171cc877ad974fef691e4da782b4c1e99fe8f4361316c735f64d49280f
F tool/buildtclext.tcl b64d250517b148e644d26fcbc097851867a0df52cd4bafe9bcd94b8421e1428a
F tool/cg_anno.tcl c1f875f5a4c9caca3d59937b16aff716f8b1883935f1b4c9ae23124705bc8099 x
F tool/checkSpacing.c 810e51703529a204fc4e1eb060e9ab663e3c06d2
@@ -2131,8 +2132,8 @@ F tool/max-limits.c cbb635fbb37ae4d05f240bfb5b5270bb63c54439
F tool/merge-test.tcl de76b62f2de2a92d4c1ca4f976bce0aea6899e0229e250479b229b2a1914b176
F tool/mkautoconfamal.sh cbdcf993fa83dccbef7fb77b39cdeb31ef9f77d9d88c9e343b58d35ca3898a6a
F tool/mkccode.tcl 86463e68ce9c15d3041610fedd285ce32a5cf7a58fc88b3202b8b76837650dbe x
F tool/mkctimec.tcl 060e9785e9503bf51f8b1b11b542bdeef90fd0ceb0738154f6762acec0c61e5f x
F tool/mkkeywordhash.c b9faa0ae7e14e4dbbcd951cddd786bf46b8a65bb07b129ba8c0cfade723aaffd
F tool/mkctimec.tcl e3af51acc2ef92062fe6d622de010a27a34b497258a248dada04388b916c61c6 x
F tool/mkkeywordhash.c 6b0be901c47f9ad42215fc995eb2f4384ac49213b1fba395102ec3e999acf559
F tool/mkmsvcmin.tcl d76c45efda1cce2d4005bcea7b8a22bb752e3256009f331120fb4fecb14ebb7a
F tool/mkopcodec.tcl 33d20791e191df43209b77d37f0ff0904620b28465cca6990cf8d60da61a07ef
F tool/mkopcodeh.tcl 2b4e6967a670ef21bf53a164964c35c6163277d002a4c6f56fa231d68c88d023
@@ -2149,9 +2150,9 @@ F tool/mktoolzip.tcl c7a9b685f5131d755e7d941cec50cee7f34178b9e34c9a89811eeb08617
F tool/mkvsix.tcl 67b40996a50f985a573278eea32fc5a5eb6110bdf14d33f1d8086e48c69e540a
F tool/offsets.c 8ed2b344d33f06e71366a9b93ccedaa38c096cc1dbd4c3c26ad08c6115285845
F tool/omittest-msvc.tcl d6b8f501ac1d7798c4126065030f89812379012cad98a1735d6d7221492abc08
F tool/omittest.tcl e99c9fecc3f7a8ca2fa75d8ec8bdbb5acce33dc69f0c280aae53064693387f65
F tool/omittest.tcl 5ca5e4e01716d5f35b48b00fd351d929f01fbb98169a5a3cd00baf3d2e2019a9
F tool/opcodesum.tcl 740ed206ba8c5040018988129abbf3089a0ccf4a
F tool/pagesig.c ff0ca355fd3c2398e933da5e22439bbff89b803b
F tool/pagesig.c f98909b4168d9cac11a2de7f031adea0e2f3131faa7515a72807c03ec58eafeb
F tool/replace.tcl 511c61acfe563dfb58675efb4628bb158a13d48ff8322123ac447e9d25a82d9a
F tool/restore_jrnl.tcl 1079ecba47cc82fa82115b81c1f68097ab1f956f357ee8da5fc4b2589af6bd98
F tool/rollback-test.c 9fc98427d1e23e84429d7e6d07d9094fbdec65a5
@@ -2173,6 +2174,7 @@ F tool/speedtest8inst1.c 7ce07da76b5e745783e703a834417d725b7d45fd
F tool/spellsift.tcl 52b4b04dc4333c7ab024f09d9d66ed6b6f7c6eb00b38497a09f338fa55d40618 x
F tool/split-sqlite3c.tcl 5aa60643afca558bc732b1444ae81a522326f91e1dc5665b369c54f09e20de60
F tool/sqldiff.c 847fc8fcfddf5ce4797b7394cad6372f2f5dc17d8186e2ef8fb44d50fae4f44a
F tool/sqlite3-rsync.c 00c9b4483851ca0337dff4b544ee39dffa8cdbe9dc55cd51d391590fd1f03763
F tool/sqlite3_analyzer.c.in 8da2b08f56eeac331a715036cf707cc20f879f231362be0c22efd682e2b89b4f
F tool/sqltclsh.c.in 1bcc2e9da58fadf17b0bf6a50e68c1159e602ce057210b655d50bad5aaaef898
F tool/sqltclsh.tcl 862f4cf1418df5e1315b5db3b5ebe88969e2a784525af5fbf9596592f14ed848
@@ -2211,8 +2213,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
P 7c195f132cb48ee44124eb4af3532937493429f7c45f6ac611f7a9b128799ad7
R 15868716c90b102057036239341d8066
U drh
Z fde036223228b7af985cf94952c295a1
P 9961334c8007e7cb6ae55885075b74acddc4fa701b359cf67e0f3c237d7eba4a
R 88be3363ce7bdb6c2bdb93ef027d46e9
U stephan
Z 5b00ba151c4dd893eaaa646fc9f450ae
# Remove this line to create a well-formed Fossil manifest.
+1 -1
View File
@@ -1 +1 @@
2eaea67495fd9961b7145d829789889bf1d8fa7a834d40d1be43e7c74c233bc2
129aca54f6b791c222b51f3eb01569e1e569269860e153b005140eb65af378b9
+1 -1
View File
@@ -5989,7 +5989,7 @@ int sqlite3BtreeIndexMoveto(
&& indexCellCompare(pCur, 0, pIdxKey, xRecordCompare)<=0
&& pIdxKey->errCode==SQLITE_OK
){
pCur->curFlags &= ~BTCF_ValidOvfl;
pCur->curFlags &= ~(BTCF_ValidOvfl|BTCF_AtLast);
if( !pCur->pPage->isInit ){
return SQLITE_CORRUPT_BKPT;
}
+3
View File
@@ -295,6 +295,9 @@ static const char * const sqlite3azCompileOpt[] = {
#ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC
"ENABLE_OFFSET_SQL_FUNC",
#endif
#ifdef SQLITE_ENABLE_ORDERED_SET_AGGREGATES
"ENABLE_ORDERED_SET_AGGREGATES",
#endif
#ifdef SQLITE_ENABLE_OVERSIZE_CELL_CHECK
"ENABLE_OVERSIZE_CELL_CHECK",
#endif
+73 -23
View File
@@ -28,7 +28,13 @@
**
** The data field of sqlite_dbpage table can be updated. The new
** value must be a BLOB which is the correct page size, otherwise the
** update fails. Rows may not be deleted or inserted.
** update fails. INSERT operations also work, and operate as if they
** where REPLACE. The size of the database can be extended by INSERT-ing
** new pages on the end.
**
** Rows may not be deleted. However, doing an INSERT to page number N
** with NULL page data causes the N-th page and all subsequent pages to be
** deleted and the database to be truncated.
*/
#include "sqliteInt.h" /* Requires access to internal data structures */
@@ -51,6 +57,8 @@ struct DbpageCursor {
struct DbpageTable {
sqlite3_vtab base; /* Base class. Must be first */
sqlite3 *db; /* The database */
int nTrunc; /* Entries in aTrunc[] */
Pgno *aTrunc; /* Truncation size for each database */
};
/* Columns */
@@ -59,7 +67,6 @@ struct DbpageTable {
#define DBPAGE_COLUMN_SCHEMA 2
/*
** Connect to or create a dbpagevfs virtual table.
*/
@@ -100,6 +107,8 @@ static int dbpageConnect(
** Disconnect from or destroy a dbpagevfs virtual table.
*/
static int dbpageDisconnect(sqlite3_vtab *pVtab){
DbpageTable *pTab = (DbpageTable *)pVtab;
sqlite3_free(pTab->aTrunc);
sqlite3_free(pVtab);
return SQLITE_OK;
}
@@ -321,11 +330,11 @@ static int dbpageUpdate(
DbPage *pDbPage = 0;
int rc = SQLITE_OK;
char *zErr = 0;
const char *zSchema;
int iDb;
Btree *pBt;
Pager *pPager;
int szPage;
int isInsert;
(void)pRowid;
if( pTab->db->flags & SQLITE_Defensive ){
@@ -336,21 +345,29 @@ static int dbpageUpdate(
zErr = "cannot delete";
goto update_fail;
}
pgno = sqlite3_value_int(argv[0]);
if( sqlite3_value_type(argv[0])==SQLITE_NULL
|| (Pgno)sqlite3_value_int(argv[1])!=pgno
){
zErr = "cannot insert";
goto update_fail;
if( sqlite3_value_type(argv[0])==SQLITE_NULL ){
pgno = (Pgno)sqlite3_value_int(argv[2]);
isInsert = 1;
}else{
pgno = sqlite3_value_int(argv[0]);
if( (Pgno)sqlite3_value_int(argv[1])!=pgno ){
zErr = "cannot insert";
goto update_fail;
}
isInsert = 0;
}
zSchema = (const char*)sqlite3_value_text(argv[4]);
iDb = ALWAYS(zSchema) ? sqlite3FindDbName(pTab->db, zSchema) : -1;
if( NEVER(iDb<0) ){
zErr = "no such schema";
goto update_fail;
if( sqlite3_value_type(argv[4])==SQLITE_NULL ){
iDb = 0;
}else{
const char *zSchema = (const char*)sqlite3_value_text(argv[4]);
iDb = sqlite3FindDbName(pTab->db, zSchema);
if( iDb<0 ){
zErr = "no such schema";
goto update_fail;
}
}
pBt = pTab->db->aDb[iDb].pBt;
if( NEVER(pgno<1) || NEVER(pBt==0) || NEVER(pgno>sqlite3BtreeLastPage(pBt)) ){
if( pgno<1 || NEVER(pBt==0) ){
zErr = "bad page number";
goto update_fail;
}
@@ -358,18 +375,31 @@ static int dbpageUpdate(
if( sqlite3_value_type(argv[3])!=SQLITE_BLOB
|| sqlite3_value_bytes(argv[3])!=szPage
){
zErr = "bad page value";
goto update_fail;
if( sqlite3_value_type(argv[3])==SQLITE_NULL && isInsert ){
if( iDb>=pTab->nTrunc ){
testcase( pTab->aTrunc!=0 );
pTab->aTrunc = sqlite3_realloc(pTab->aTrunc, (iDb+1)*sizeof(Pgno));
if( pTab->aTrunc ){
int j;
for(j=pTab->nTrunc; j<iDb; j++) pTab->aTrunc[j] = 0;
pTab->nTrunc = iDb+1;
}else{
return SQLITE_NOMEM;
}
}
pTab->aTrunc[iDb] = pgno;
}else{
zErr = "bad page value";
goto update_fail;
}
}
pPager = sqlite3BtreePager(pBt);
rc = sqlite3PagerGet(pPager, pgno, (DbPage**)&pDbPage, 0);
if( rc==SQLITE_OK ){
const void *pData = sqlite3_value_blob(argv[3]);
assert( pData!=0 || pTab->db->mallocFailed );
if( pData
&& (rc = sqlite3PagerWrite(pDbPage))==SQLITE_OK
){
memcpy(sqlite3PagerGetData(pDbPage), pData, szPage);
if( (rc = sqlite3PagerWrite(pDbPage))==SQLITE_OK && pData ){
unsigned char *aPage = sqlite3PagerGetData(pDbPage);
memcpy(aPage, pData, szPage);
}
}
sqlite3PagerUnref(pDbPage);
@@ -393,6 +423,26 @@ static int dbpageBegin(sqlite3_vtab *pVtab){
Btree *pBt = db->aDb[i].pBt;
if( pBt ) (void)sqlite3BtreeBeginTrans(pBt, 1, 0);
}
if( pTab->nTrunc>0 ){
memset(pTab->aTrunc, 0, sizeof(pTab->aTrunc[0])*pTab->nTrunc);
}
return SQLITE_OK;
}
/* Invoke sqlite3PagerTruncate() as necessary, just prior to COMMIT
*/
static int dbpageSync(sqlite3_vtab *pVtab){
int iDb;
DbpageTable *pTab = (DbpageTable *)pVtab;
for(iDb=0; iDb<pTab->nTrunc; iDb++){
if( pTab->aTrunc[iDb]>0 ){
Btree *pBt = pTab->db->aDb[iDb].pBt;
Pager *pPager = sqlite3BtreePager(pBt);
sqlite3PagerTruncateImage(pPager, pTab->aTrunc[iDb]);
pTab->aTrunc[iDb] = 0;
}
}
return SQLITE_OK;
}
@@ -417,7 +467,7 @@ int sqlite3DbpageRegister(sqlite3 *db){
dbpageRowid, /* xRowid - read data */
dbpageUpdate, /* xUpdate */
dbpageBegin, /* xBegin */
0, /* xSync */
dbpageSync, /* xSync */
0, /* xCommit */
0, /* xRollback */
0, /* xFindMethod */
+6 -2
View File
@@ -2049,7 +2049,11 @@ static void minMaxFinalize(sqlite3_context *context){
** group_concat(EXPR, ?SEPARATOR?)
** string_agg(EXPR, SEPARATOR)
**
** The SEPARATOR goes before the EXPR string. This is tragic. The
** Content is accumulated in GroupConcatCtx.str with the SEPARATOR
** coming before the EXPR value, except for the first entry which
** omits the SEPARATOR.
**
** It is tragic that the SEPARATOR goes before the EXPR string. The
** groupConcatInverse() implementation would have been easier if the
** SEPARATOR were appended after EXPR. And the order is undocumented,
** so we could change it, in theory. But the old behavior has been
@@ -2153,7 +2157,7 @@ static void groupConcatInverse(
/* pGCC is always non-NULL since groupConcatStep() will have always
** run first to initialize it */
if( ALWAYS(pGCC) ){
int nVS;
int nVS; /* Number of characters to remove */
/* Must call sqlite3_value_text() to convert the argument into text prior
** to invoking sqlite3_value_bytes(), in case the text encoding is UTF16 */
(void)sqlite3_value_text(argv[0]);
+3 -1
View File
@@ -2847,7 +2847,9 @@ static u32 jsonLookupStep(
zPath++;
if( zPath[0]=='"' ){
zKey = zPath + 1;
for(i=1; zPath[i] && zPath[i]!='"'; i++){}
for(i=1; zPath[i] && zPath[i]!='"'; i++){
if( zPath[i]=='\\' && zPath[i+1]!=0 ) i++;
}
nKey = i-1;
if( zPath[i] ){
i++;
+2 -1
View File
@@ -1926,7 +1926,8 @@ int sqlite3CreateFunc(
assert( SQLITE_FUNC_CONSTANT==SQLITE_DETERMINISTIC );
assert( SQLITE_FUNC_DIRECT==SQLITE_DIRECTONLY );
extraFlags = enc & (SQLITE_DETERMINISTIC|SQLITE_DIRECTONLY|
SQLITE_SUBTYPE|SQLITE_INNOCUOUS|SQLITE_RESULT_SUBTYPE);
SQLITE_SUBTYPE|SQLITE_INNOCUOUS|
SQLITE_RESULT_SUBTYPE|SQLITE_SELFORDER1);
enc &= (SQLITE_FUNC_ENCMASK|SQLITE_ANY);
/* The SQLITE_INNOCUOUS flag is the same bit as SQLITE_FUNC_UNSAFE. But
+71 -1
View File
@@ -264,6 +264,9 @@ columnname(A) ::= nm(A) typetoken(Y). {sqlite3AddColumn(pParse,A,Y);}
CURRENT FOLLOWING PARTITION PRECEDING RANGE UNBOUNDED
EXCLUDE GROUPS OTHERS TIES
%endif SQLITE_OMIT_WINDOWFUNC
%ifdef SQLITE_ENABLE_ORDERED_SET_AGGREGATES
WITHIN
%endif SQLITE_ENABLE_ORDERED_SET_AGGREGATES
%ifndef SQLITE_OMIT_GENERATED_COLUMNS
GENERATED ALWAYS
%endif
@@ -1179,6 +1182,65 @@ expr(A) ::= idj(X) LP STAR RP. {
A = sqlite3ExprFunction(pParse, 0, &X, 0);
}
%ifdef SQLITE_ENABLE_ORDERED_SET_AGGREGATES
%include {
/* Generate an expression node that represents an ordered-set aggregate function.
**
** SQLite does not do anything special to evaluate ordered-set aggregates. The
** aggregate function itself is expected to do any required ordering on its own.
** This is just syntactic sugar.
**
** This syntax: percentile(f) WITHIN GROUP ( ORDER BY y )
**
** Is equivalent to: percentile(y,f)
**
** The purpose of this function is to generate an Expr node from the first syntax
** into a TK_FUNCTION node that looks like it came from the second syntax.
**
** Only functions that have the SQLITE_SELFORDER1 perperty are allowed to do this
** transformation. Because DISTINCT is not allowed in the ordered-set aggregate
** syntax, an error is raised if DISTINCT is used.
*/
static Expr *sqlite3ExprAddOrderedsetFunction(
Parse *pParse, /* Parsing context */
Token *pFuncname, /* Name of the function */
int isDistinct, /* DISTINCT or ALL qualifier */
ExprList *pOrig, /* Arguments to the function */
Expr *pOrderby /* Expression in the ORDER BY clause */
){
ExprList *p; /* Modified argument list */
Expr *pExpr; /* Final result */
p = sqlite3ExprListAppend(pParse, 0, pOrderby);
if( pOrig ){
int i;
for(i=0; i<pOrig->nExpr; i++){
p = sqlite3ExprListAppend(pParse, p, pOrig->a[i].pExpr);
pOrig->a[i].pExpr = 0;
}
sqlite3ExprListDelete(pParse->db, pOrig);
}
pExpr = sqlite3ExprFunction(pParse, p, pFuncname, 0);
if( pParse->nErr==0 ){
FuncDef *pDef;
u8 enc = ENC(pParse->db);
assert( pExpr!=0 ); /* Because otherwise pParse->nErr would not be zero */
assert( p!=0 ); /* Because otherwise pParse->nErr would not be zero */
pDef = sqlite3FindFunction(pParse->db, pExpr->u.zToken, -2, enc, 0);
if( pDef==0 || (pDef->funcFlags & SQLITE_SELFORDER1)==0 ){
sqlite3ErrorMsg(pParse, "%#T() is not an ordered-set aggregate", pExpr);
}else if( isDistinct==SF_Distinct ){
sqlite3ErrorMsg(pParse, "DISTINCT not allowed on ordered-set aggregate %T()",
pFuncname);
}
}
return pExpr;
}
}
expr(A) ::= idj(X) LP distinct(D) exprlist(Y) RP WITHIN GROUP LP ORDER BY expr(E) RP. {
A = sqlite3ExprAddOrderedsetFunction(pParse, &X, D, Y, E);
}
%endif SQLITE_ENABLE_ORDERED_SET_AGGREGATES
%ifndef SQLITE_OMIT_WINDOWFUNC
expr(A) ::= idj(X) LP distinct(D) exprlist(Y) RP filter_over(Z). {
A = sqlite3ExprFunction(pParse, Y, &X, D);
@@ -1193,7 +1255,15 @@ expr(A) ::= idj(X) LP STAR RP filter_over(Z). {
A = sqlite3ExprFunction(pParse, 0, &X, 0);
sqlite3WindowAttach(pParse, A, Z);
}
%endif
%ifdef SQLITE_ENABLE_ORDERED_SET_AGGREGATES
expr(A) ::= idj(X) LP distinct(D) exprlist(Y) RP WITHIN GROUP LP ORDER BY expr(E) RP
filter_over(Z). {
A = sqlite3ExprAddOrderedsetFunction(pParse, &X, D, Y, E);
sqlite3WindowAttach(pParse, A, Z);
}
%endif SQLITE_ENABLE_ORDERED_SET_AGGREGATES
%endif SQLITE_OMIT_WINDOWFUNC
term(A) ::= CTIME_KW(OP). {
A = sqlite3ExprFunction(pParse, 0, &OP, 0);
+9 -14
View File
@@ -1209,6 +1209,7 @@ INCLUDE test_windirent.c
INCLUDE ../ext/misc/memtrace.c
INCLUDE ../ext/misc/pcachetrace.c
INCLUDE ../ext/misc/shathree.c
INCLUDE ../ext/misc/sha1.c
INCLUDE ../ext/misc/uint.c
INCLUDE ../ext/misc/decimal.c
INCLUDE ../ext/misc/percentile.c
@@ -1236,6 +1237,7 @@ INCLUDE ../ext/expert/sqlite3expert.c
INCLUDE ../ext/intck/sqlite3intck.h
INCLUDE ../ext/intck/sqlite3intck.c
INCLUDE ../ext/misc/stmtrand.c
INCLUDE ../ext/misc/vfstrace.c
#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB)
#define SQLITE_SHELL_HAVE_RECOVER 1
@@ -5391,6 +5393,7 @@ static void open_db(ShellState *p, int openFlags){
#ifndef SQLITE_OMIT_LOAD_EXTENSION
sqlite3_enable_load_extension(p->db, 1);
#endif
sqlite3_sha_init(p->db, 0, 0);
sqlite3_shathree_init(p->db, 0, 0);
sqlite3_uint_init(p->db, 0, 0);
sqlite3_stmtrand_init(p->db, 0, 0);
@@ -12254,9 +12257,7 @@ static const char zOptions[] =
" -unsafe-testing allow unsafe commands and modes for testing\n"
" -version show SQLite version\n"
" -vfs NAME use NAME as the default VFS\n"
#ifdef SQLITE_ENABLE_VFSTRACE
" -vfstrace enable tracing of all VFS calls\n"
#endif
#ifdef SQLITE_HAVE_ZLIB
" -zip open the file as a ZIP Archive\n"
#endif
@@ -12382,6 +12383,7 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
int readStdin = 1;
int nCmd = 0;
int nOptsEnd = argc;
int bEnableVfstrace = 0;
char **azCmd = 0;
const char *zVfs = 0; /* Value of -vfs command-line option */
#if !SQLITE_SHELL_IS_UTF8
@@ -12576,17 +12578,9 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
case 2: sqlite3_config(SQLITE_CONFIG_MULTITHREAD); break;
default: sqlite3_config(SQLITE_CONFIG_SERIALIZED); break;
}
#ifdef SQLITE_ENABLE_VFSTRACE
}else if( cli_strcmp(z,"-vfstrace")==0 ){
extern int vfstrace_register(
const char *zTraceName,
const char *zOldVfsName,
int (*xOut)(const char*,void*),
void *pOutArg,
int makeDefault
);
vfstrace_register("trace",0,(int(*)(const char*,void*))fputs,stderr,1);
#endif
bEnableVfstrace = 1;
#ifdef SQLITE_ENABLE_MULTIPLEX
}else if( cli_strcmp(z,"-multiplex")==0 ){
extern int sqlite3_multiplex_initialize(const char*,int);
@@ -12642,7 +12636,7 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
}
}
#ifndef SQLITE_SHELL_FIDDLE
verify_uninitialized();
if( !bEnableVfstrace ) verify_uninitialized();
#endif
@@ -12831,10 +12825,8 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
#endif
}else if( cli_strcmp(z,"-vfs")==0 ){
i++;
#ifdef SQLITE_ENABLE_VFSTRACE
}else if( cli_strcmp(z,"-vfstrace")==0 ){
i++;
#endif
#ifdef SQLITE_ENABLE_MULTIPLEX
}else if( cli_strcmp(z,"-multiplex")==0 ){
i++;
@@ -13002,6 +12994,9 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
/* Clear the global data structure so that valgrind will detect memory
** leaks */
memset(&data, 0, sizeof(data));
if( bEnableVfstrace ){
vfstrace_unregister("trace");
}
#ifdef SQLITE_DEBUG
if( sqlite3_memory_used()>mem_main_enter ){
eputf("Memory leaked: %u bytes\n",
+10
View File
@@ -5615,6 +5615,15 @@ int sqlite3_create_window_function(
** [sqlite3_result_subtype()] should avoid setting this property, as the
** purpose of this property is to disable certain optimizations that are
** incompatible with subtypes.
**
** [[SQLITE_SELFORDER1]] <dt>SQLITE_SELFORDER1</dt><dd>
** The SQLITE_SELFORDER1 flag indicates that the function is an aggregate
** that internally orders the values provided to the first argument. The
** ordered-set aggregate SQL notation with a single ORDER BY term can be
** used to invoke this function. If the ordered-set aggregate notation is
** used on a function that lacks this flag, then an error is raised. Note
** that the ordered-set aggregate syntax is only available if SQLite is
** built using the -DSQLITE_ENABLE_ORDERED_SET_AGGREGATES compile-time option.
** </dd>
** </dl>
*/
@@ -5623,6 +5632,7 @@ int sqlite3_create_window_function(
#define SQLITE_SUBTYPE 0x000100000
#define SQLITE_INNOCUOUS 0x000200000
#define SQLITE_RESULT_SUBTYPE 0x001000000
#define SQLITE_SELFORDER1 0x002000000
/*
** CAPI3REF: Deprecated Functions
+2
View File
@@ -658,6 +658,8 @@
#ifdef SQLITE_OMIT_FLOATING_POINT
# define double sqlite_int64
# define float sqlite_int64
# define fabs(X) ((X)<0?-(X):(X))
# define sqlite3IsOverflow(X) 0
# define LONGDOUBLE_TYPE sqlite_int64
# ifndef SQLITE_BIG_DBL
# define SQLITE_BIG_DBL (((sqlite3_int64)1)<<50)
+1 -1
View File
@@ -2343,7 +2343,7 @@ static int SQLITE_TCLAPI test_stmt_scanstatus(
}
for(ii=0; ii<(int)nFlag; ii++){
int iVal = 0;
int res = Tcl_GetIndexFromObjStruct(
res = Tcl_GetIndexFromObjStruct(
interp, aFlag[ii], aTbl, sizeof(aTbl[0]), "flag", 0, &iVal
);
if( res ) return TCL_ERROR;
+16
View File
@@ -189,6 +189,14 @@ static void set_options(Tcl_Interp *interp){
Tcl_SetVar2(interp, "sqlite_options", "offset_sql_func","0",TCL_GLOBAL_ONLY);
#endif
#ifdef SQLITE_ENABLE_ORDERED_SET_AGGREGATES
Tcl_SetVar2(interp, "sqlite_options",
"ordered_set_aggregates","1",TCL_GLOBAL_ONLY);
#else
Tcl_SetVar2(interp, "sqlite_options",
"ordered_set_aggregates","0",TCL_GLOBAL_ONLY);
#endif
#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
Tcl_SetVar2(interp, "sqlite_options", "preupdate", "1", TCL_GLOBAL_ONLY);
#else
@@ -341,6 +349,14 @@ static void set_options(Tcl_Interp *interp){
Tcl_SetVar2(interp, "sqlite_options", "columnmetadata", "0", TCL_GLOBAL_ONLY);
#endif
#ifdef SQLITE_ENABLE_ORDEREDSETFUNC
Tcl_SetVar2(interp, "sqlite_options", "ordered_set_funcs", "1",
TCL_GLOBAL_ONLY);
#else
Tcl_SetVar2(interp, "sqlite_options", "ordered_set_funcs", "0",
TCL_GLOBAL_ONLY);
#endif
#ifdef SQLITE_ENABLE_OVERSIZE_CELL_CHECK
Tcl_SetVar2(interp, "sqlite_options", "oversize_cell_check", "1",
TCL_GLOBAL_ONLY);
+5
View File
@@ -167,6 +167,11 @@ int sqlite3_blob_open(
pTab = 0;
sqlite3ErrorMsg(&sParse, "cannot open table without rowid: %s", zTable);
}
if( pTab && (pTab->tabFlags&TF_HasGenerated)!=0 ){
pTab = 0;
sqlite3ErrorMsg(&sParse, "cannot open table with generated columns: %s",
zTable);
}
#ifndef SQLITE_OMIT_VIEW
if( pTab && IsView(pTab) ){
pTab = 0;
+1 -1
View File
@@ -44,7 +44,7 @@
** 28: Checksum-2 (second part of checksum for first 24 bytes of header).
**
** Immediately following the wal-header are zero or more frames. Each
** frame consists of a 24-byte frame-header followed by a <page-size> bytes
** frame consists of a 24-byte frame-header followed by <page-size> bytes
** of page data. The frame-header is six big-endian 32-bit unsigned
** integer values, as follows:
**
+5 -1
View File
@@ -6199,6 +6199,7 @@ static SQLITE_NOINLINE Bitmask whereOmitNoopJoin(
WhereTerm *pTerm, *pEnd;
SrcItem *pItem;
WhereLoop *pLoop;
Bitmask m1;
pLoop = pWInfo->a[i].pWLoop;
pItem = &pWInfo->pTabList->a[pLoop->iTab];
if( (pItem->fg.jointype & (JT_LEFT|JT_RIGHT))!=JT_LEFT ) continue;
@@ -6225,7 +6226,10 @@ static SQLITE_NOINLINE Bitmask whereOmitNoopJoin(
}
}
if( pTerm<pEnd ) continue;
WHERETRACE(0xffffffff, ("-> drop loop %c not used\n", pLoop->cId));
WHERETRACE(0xffffffff,("-> omit unused FROM-clause term %c\n",pLoop->cId));
m1 = MASKBIT(i)-1;
testcase( ((pWInfo->revMask>>1) & ~m1)!=0 );
pWInfo->revMask = (m1 & pWInfo->revMask) | ((pWInfo->revMask>>1) & ~m1);
notReady &= ~pLoop->maskSelf;
for(pTerm=pWInfo->sWC.a; pTerm<pEnd; pTerm++){
if( (pTerm->prereqAll & pLoop->maskSelf)!=0 ){
+1 -1
View File
@@ -4404,7 +4404,7 @@ do_catchsql_test 25.5 {
do_catchsql_test 25.6 {
INSERT INTO t1(t1) SELECT x FROM t2;
INSERT INTO t1(t1) SELECT x FROM t2;
} {1 {database disk image is malformed}}
} {0 {}}
#-------------------------------------------------------------------------
reset_db
+11 -8
View File
@@ -159,10 +159,11 @@ static struct GlobalVars {
} g;
/*
** Include the external vt02.c and randomjson.c modules.
** Include various extensions.
*/
extern int sqlite3_vt02_init(sqlite3*,char**,const sqlite3_api_routines*);
extern int sqlite3_randomjson_init(sqlite3*,char**,const sqlite3_api_routines*);
extern int sqlite3_percentile_init(sqlite3*,char**,const sqlite3_api_routines*);
/*
@@ -1037,17 +1038,18 @@ static int recoverDatabase(sqlite3 *db){
static void bindDebugParameters(sqlite3_stmt *pStmt){
int nVar = sqlite3_bind_parameter_count(pStmt);
int i;
for(i=0; i<nVar; i++){
const char *zVar = sqlite3_bind_parameter_name(pStmt, i+1);
for(i=1; i<=nVar; i++){
const char *zVar = sqlite3_bind_parameter_name(pStmt, i);
if( zVar==0 ) continue;
if( strncmp(zVar, "$int_", 5)==0 ){
sqlite3_bind_int(pStmt, i+1, atoi(&zVar[5]));
sqlite3_bind_int(pStmt, i, atoi(&zVar[5]));
}else
if( strncmp(zVar, "$text_", 6)==0 ){
char *zBuf = sqlite3_malloc64( strlen(zVar)-5 );
size_t szVar = strlen(zVar);
char *zBuf = sqlite3_malloc64( szVar-5 );
if( zBuf ){
memcpy(zBuf, &zVar[6], strlen(zVar)-5);
sqlite3_bind_text64(pStmt, i+1, zBuf, -1, sqlite3_free, SQLITE_UTF8);
memcpy(zBuf, &zVar[6], szVar-5);
sqlite3_bind_text64(pStmt, i, zBuf, szVar-6, sqlite3_free, SQLITE_UTF8);
}
}
}
@@ -1329,7 +1331,8 @@ int runCombinedDbSqlInput(
/* Add the vt02 virtual table */
sqlite3_vt02_init(cx.db, 0, 0);
/* Add the random_json() and random_json5() functions */
/* Activate extensions */
sqlite3_percentile_init(cx.db, 0, 0);
sqlite3_randomjson_init(cx.db, 0, 0);
/* Add support for sqlite_dbdata and sqlite_dbptr virtual tables used
+7 -6
View File
@@ -47,17 +47,18 @@ static void reportInvariantFailed(
static void bindDebugParameters(sqlite3_stmt *pStmt){
int nVar = sqlite3_bind_parameter_count(pStmt);
int i;
for(i=0; i<nVar; i++){
const char *zVar = sqlite3_bind_parameter_name(pStmt, i+1);
for(i=1; i<=nVar; i++){
const char *zVar = sqlite3_bind_parameter_name(pStmt, i);
if( zVar==0 ) continue;
if( strncmp(zVar, "$int_", 5)==0 ){
sqlite3_bind_int(pStmt, i+1, atoi(&zVar[5]));
sqlite3_bind_int(pStmt, i, atoi(&zVar[5]));
}else
if( strncmp(zVar, "$text_", 6)==0 ){
char *zBuf = sqlite3_malloc64( strlen(zVar)-5 );
size_t szVar = strlen(zVar);
char *zBuf = sqlite3_malloc64( szVar-5 );
if( zBuf ){
memcpy(zBuf, &zVar[6], strlen(zVar)-5);
sqlite3_bind_text64(pStmt, i+1, zBuf, -1, sqlite3_free, SQLITE_UTF8);
memcpy(zBuf, &zVar[6], szVar-5);
sqlite3_bind_text64(pStmt, i, zBuf, szVar-6, sqlite3_free, SQLITE_UTF8);
}
}
}
+21
View File
@@ -428,4 +428,25 @@ do_eqp_test 12.3 {
`--SEARCH t1 USING INTEGER PRIMARY KEY (rowid=?) LEFT-JOIN
}
# 2024-09-05 https://sqlite.org/forum/forumpost/8a1e467e905b8d27
# When performing the Omit-Noop-Join optimization, if FROM clause terms
# to the right of the omitted join have the reverse-order bit set in the
# WhereInfo.revMask bitmask, those bits need to be shifted to account
# for the omitted join.
#
reset_db
do_execsql_test 13.0 {
CREATE TABLE t1(a1 INTEGER PRIMARY KEY, b1 INT);
CREATE TABLE t2(c2 INT, d2 INTEGER PRIMARY KEY);
CREATE TABLE t3(e3 INTEGER PRIMARY KEY);
INSERT INTO t1 VALUES(33,0);
INSERT INTO t2 VALUES(33,1),(33,2);
}
do_execsql_test 13.1 {
SELECT t1.a1, t2.d2
FROM (t1 LEFT JOIN t3 ON t3.e3=t1.b1) JOIN t2 ON t2.c2=t1.a1
WHERE t1.a1=33
ORDER BY t2.d2 DESC;
} {33 2 33 1}
finish_test
+13
View File
@@ -64,4 +64,17 @@ ifcapable vtab {
} {{\x17} 1 integer 1 1 null {$."\x17"} {$}}
}
# JSON PATH parsing bug involving backslash escapes, reported via
# private email from Florent De'Neve on 2024-09-04.
#
do_execsql_test 5.1 {
SELECT json_extract('{"A\"Key":1}', '$.A"Key');
} 1
do_execsql_test 5.2 {
SELECT json_extract('{"A\"Key":1}', '$."A\"Key"');
} 1
do_execsql_test 5.3 {
SELECT JSON_SET('{}', '$."\"Key"', 1);
} {{{"\"Key":1}}}
finish_test
+425 -61
View File
@@ -9,7 +9,8 @@
#
#***********************************************************************
# This file implements regression tests for SQLite library. The
# focus of this file is percentile.c extension
# focus of this file is percentile.c extension. This also tests
# the SQLITE_ENABLE_ORDERED_SET_AGGREGATES compile-time option.
#
set testdir [file dirname $argv0]
@@ -25,35 +26,65 @@ do_test percentile-1.0 {
}
execsql {SELECT percentile(x,0) FROM t1}
} {1.0}
foreach {in out} {
100 11.0
50 8.0
12.5 4.0
15 4.4
20 5.2
80 11.0
89 11.0
foreach {in out disc} {
100 11.0 11.0
50 8.0 8.0
12.5 4.0 4.0
15 4.4 4.0
20 5.2 4.0
80 11.0 11.0
89 11.0 11.0
} {
do_test percentile-1.1.$in {
do_test percentile-1.1.$in.1 {
execsql {SELECT percentile(x,$in) FROM t1}
} $out
do_test percentile-1.1.$in.2 {
execsql {SELECT percentile_cont(x,$in*0.01) FROM t1}
} $out
do_test percentile-1.1.$in.3 {
execsql {SELECT percentile_disc(x,$in*0.01) FROM t1}
} $disc
if {$in==50} {
do_test percentile-1.1.$in.4 {
execsql {SELECT median(x) FROM t1}
} $out
}
ifcapable ordered_set_aggregates {
do_test percentile-1.1.$in.5 {
execsql {SELECT percentile($in)WITHIN GROUP(ORDER BY x) FROM t1}
} $out
do_test percentile-1.1.$in.6 {
execsql {SELECT percentile_cont($in*0.01) WITHIN GROUP(ORDER BY x)
FROM t1}
} $out
do_test percentile-1.1.$in.7 {
execsql {SELECT percentile_disc($in*0.01) WITHIN GROUP(ORDER BY x)
FROM t1}
} $disc
if {$in==50} {
do_test percentile-1.1.$in.8 {
execsql {SELECT median() WITHIN GROUP (ORDER BY x) FROM t1}
} $out
}
}
}
do_execsql_test percentile-1.1.median {
SELECT median(x) FROM t1;
} 8.0
foreach {in out} {
1.0 11.0
0.5 8.0
0.125 4.0
0.15 4.4
0.2 5.2
0.8 11.0
0.89 11.0
} {
do_test percentile-1.1b-$in {
execsql {SELECT percentile_cont(x,$in) FROM t1}
} $out
ifcapable ordered_set_aggregates {
do_execsql_test percentile-1.1.median {
SELECT median() WITHIN GROUP (ORDER BY x) FROM t1;
} 8.0
do_execsql_test percentile-1.1.distinct.1 {
SELECT median(DISTINCT x) FROM t1;
} 7.0
do_catchsql_test percentile-1.1.distinct.2 {
SELECT percentile(DISTINCT 50) WITHIN GROUP (ORDER BY x) FROM t1;
} {1 {DISTINCT not allowed on ordered-set aggregate percentile()}}
} else {
do_catchsql_test percentile-1.1.median {
SELECT median() WITHIN GROUP (ORDER BY x) FROM t1;
} {1 {near "(": syntax error}}
}
# Add some NULL values.
@@ -61,28 +92,69 @@ foreach {in out} {
do_test percentile-1.2 {
execsql {INSERT INTO t1 VALUES(NULL),(NULL);}
} {}
foreach {in out} {
100 11.0
50 8.0
12.5 4.0
15 4.4
20 5.2
80 11.0
89 11.0
foreach {in out disc} {
100 11.0 11.0
50 8.0 8.0
12.5 4.0 4.0
15 4.4 4.0
20 5.2 4.0
80 11.0 11.0
89 11.0 11.0
} {
do_test percentile-1.3.$in {
do_test percentile-1.3.$in.1 {
execsql {SELECT percentile(x,$in) FROM t1}
} $out
do_test percentile-1.3.$in.2 {
execsql {SELECT percentile_cont(x,$in*0.01) FROM t1}
} $out
do_test percentile-1.3.$in.3 {
execsql {SELECT percentile_disc(x,$in*0.01) FROM t1}
} $disc
if {$in==50} {
do_test percentile-1.3.$in.4 {
execsql {SELECT median(x) FROM t1}
} $out
}
ifcapable ordered_set_aggregates {
do_test percentile-1.3.$in.5 {
execsql {SELECT percentile($in)WITHIN GROUP(ORDER BY x) FROM t1}
} $out
do_test percentile-1.3.$in.6 {
execsql {SELECT percentile_cont($in*0.01) WITHIN GROUP(ORDER BY x)
FROM t1}
} $out
do_test percentile-1.3.$in.7 {
execsql {SELECT percentile_disc($in*0.01) WITHIN GROUP(ORDER BY x)
FROM t1}
} $disc
if {$in==50} {
do_test percentile-1.3.$in.8 {
execsql {SELECT median() WITHIN GROUP (ORDER BY x) FROM t1}
} $out
}
}
}
# The second argument to percentile can change some, but not much.
#
do_test percentile-1.4 {
do_test percentile-1.4.1 {
catchsql {SELECT round(percentile(x, 15+0.000001*rowid),1) FROM t1}
} {0 4.4}
do_test percentile-1.5 {
catchsql {SELECT round(percentile(x, 15+0.1*rowid),1) FROM t1}
} {1 {2nd argument to percentile() is not the same for all input rows}}
do_test percentile-1.4.2 {
catchsql {SELECT round(percentile_cont(x,(15+0.000001*rowid)*0.01),1) FROM t1}
} {0 4.4}
do_test percentile-1.4.3 {
catchsql {SELECT percentile_disc(x, (15+0.000001*rowid)*0.01) FROM t1}
} {0 4.0}
do_test percentile-1.5.1 {
catchsql {SELECT percentile(x, 15+0.1*rowid) FROM t1}
} {1 {the fraction argument to percentile() is not the same for all input rows}}
do_test percentile-1.5.2 {
catchsql {SELECT percentile_cont(x, (15+0.1*rowid)*0.01) FROM t1}
} {1 {the fraction argument to percentile_cont() is not the same for all input rows}}
do_test percentile-1.5.3 {
catchsql {SELECT percentile_disc(x, (15+0.1*rowid)*0.01) FROM t1}
} {1 {the fraction argument to percentile_disc() is not the same for all input rows}}
# Input values in a random order
#
@@ -92,65 +164,152 @@ do_test percentile-1.6 {
INSERT INTO t2 SELECT x+0.0 FROM t1 ORDER BY random();
}
} {}
foreach {in out} {
100 11.0
50 8.0
12.5 4.0
15 4.4
20 5.2
80 11.0
89 11.0
foreach {in out disc} {
100 11.0 11.0
50 8.0 8.0
12.5 4.0 4.0
15 4.4 4.0
20 5.2 4.0
80 11.0 11.0
89 11.0 11.0
} {
do_test percentile-1.7.$in {
do_test percentile-1.7.$in.1 {
execsql {SELECT percentile(x,$in) FROM t2}
} $out
do_test percentile-1.7.$in.2 {
execsql {SELECT percentile_cont(x,$in*0.01) FROM t2}
} $out
do_test percentile-1.7.$in.3 {
execsql {SELECT percentile_disc(x,$in*0.01) FROM t2}
} $disc
if {$in==50} {
do_test percentile-1.7.$in.4 {
execsql {SELECT median(x) FROM t2}
} $out
}
ifcapable ordered_set_aggregates {
do_test percentile-1.7.$in.5 {
execsql {SELECT percentile($in)WITHIN GROUP(ORDER BY x) FROM t2}
} $out
do_test percentile-1.7.$in.6 {
execsql {SELECT percentile_cont($in*0.01) WITHIN GROUP(ORDER BY x)
FROM t2}
} $out
do_test percentile-1.7.$in.7 {
execsql {SELECT percentile_disc($in*0.01) WITHIN GROUP(ORDER BY x)
FROM t2}
} $disc
if {$in==50} {
do_test percentile-1.7.$in.8 {
execsql {SELECT median() WITHIN GROUP (ORDER BY x) FROM t2}
} $out
}
}
}
# Wrong number of arguments
#
do_test percentile-1.8 {
do_test percentile-1.8.1 {
catchsql {SELECT percentile(x,0,1) FROM t1}
} {1 {wrong number of arguments to function percentile()}}
do_test percentile-1.9 {
do_test percentile-1.8.2 {
catchsql {SELECT percentile_cont(x,0,1) FROM t1}
} {1 {wrong number of arguments to function percentile_cont()}}
do_test percentile-1.8.3 {
catchsql {SELECT percentile_disc(x,0,1) FROM t1}
} {1 {wrong number of arguments to function percentile_disc()}}
do_test percentile-1.8.4 {
catchsql {SELECT median(x,0) FROM t1}
} {1 {wrong number of arguments to function median()}}
ifcapable ordered_set_aggregates {
do_test percentile-1.8.5 {
catchsql {SELECT percentile(0,1) WITHIN GROUP(ORDER BY x) FROM t1}
} {1 {wrong number of arguments to function percentile()}}
do_test percentile-1.8.2 {
catchsql {SELECT percentile_cont(0,1)WITHIN GROUP (ORDER BY x) FROM t1}
} {1 {wrong number of arguments to function percentile_cont()}}
do_test percentile-1.8.3 {
catchsql {SELECT percentile_disc(0,1)WITHIN GROUP (ORDER BY x) FROM t1}
} {1 {wrong number of arguments to function percentile_disc()}}
do_test percentile-1.8.4 {
catchsql {SELECT median(x) WITHIN GROUP (ORDER BY x) FROM t1}
} {1 {wrong number of arguments to function median()}}
}
do_test percentile-1.9.1 {
catchsql {SELECT percentile(x) FROM t1}
} {1 {wrong number of arguments to function percentile()}}
do_test percentile-1.9.2 {
catchsql {SELECT percentile_cont(x) FROM t1}
} {1 {wrong number of arguments to function percentile_cont()}}
do_test percentile-1.9.3 {
catchsql {SELECT percentile_disc(x) FROM t1}
} {1 {wrong number of arguments to function percentile_disc()}}
do_test percentile-1.9.4 {
catchsql {SELECT median() FROM t1}
} {1 {wrong number of arguments to function median()}}
ifcapable ordered_set_aggregates {
do_test percentile-1.9.5 {
catchsql {SELECT percentile() WITHIN GROUP(ORDER BY x) FROM t1}
} {1 {wrong number of arguments to function percentile()}}
do_test percentile-1.9.6 {
catchsql {SELECT percentile_cont()WITHIN GROUP (ORDER BY x) FROM t1}
} {1 {wrong number of arguments to function percentile_cont()}}
do_test percentile-1.9.7 {
catchsql {SELECT percentile_disc()WITHIN GROUP (ORDER BY x) FROM t1}
} {1 {wrong number of arguments to function percentile_disc()}}
}
# Second argument must be numeric
#
do_test percentile-1.10 {
catchsql {SELECT percentile(x,null) FROM t1}
} {1 {2nd argument to percentile() is not a number between 0.0 and 100.0}}
} {1 {the fraction argument to percentile() is not between 0.0 and 100.0}}
do_test percentile-1.11 {
catchsql {SELECT percentile(x,'fifty') FROM t1}
} {1 {2nd argument to percentile() is not a number between 0.0 and 100.0}}
} {1 {the fraction argument to percentile() is not between 0.0 and 100.0}}
do_test percentile-1.12 {
catchsql {SELECT percentile(x,x'3530') FROM t1}
} {1 {2nd argument to percentile() is not a number between 0.0 and 100.0}}
do_test percentile-1.12b {
catchsql {SELECT percentile_cont(x,x'3530') FROM t1}
} {1 {2nd argument to percentile_cont() is not a number between 0.0 and 1.0}}
} {1 {the fraction argument to percentile() is not between 0.0 and 100.0}}
# Second argument is out of range
#
do_test percentile-1.13 {
catchsql {SELECT percentile(x,-0.0000001) FROM t1}
} {1 {2nd argument to percentile() is not a number between 0.0 and 100.0}}
} {1 {the fraction argument to percentile() is not between 0.0 and 100.0}}
do_test percentile-1.14 {
catchsql {SELECT percentile(x,100.0000001) FROM t1}
} {1 {2nd argument to percentile() is not a number between 0.0 and 100.0}}
do_test percentile-1.14b {
} {1 {the fraction argument to percentile() is not between 0.0 and 100.0}}
do_test percentile-1.14.2 {
catchsql {SELECT percentile_cont(x,1.0000001) FROM t1}
} {1 {2nd argument to percentile_cont() is not a number between 0.0 and 1.0}}
} {1 {the fraction argument to percentile_cont() is not between 0.0 and 1.0}}
do_test percentile-1.14.3 {
catchsql {SELECT percentile_disc(x,1.0000001) FROM t1}
} {1 {the fraction argument to percentile_disc() is not between 0.0 and 1.0}}
# First argument is not NULL and is not NUMERIC
#
do_test percentile-1.15 {
do_test percentile-1.15.1 {
catchsql {
BEGIN;
UPDATE t1 SET x='50' WHERE x IS NULL;
SELECT percentile(x, 50) FROM t1;
}
} {1 {1st argument to percentile() is not numeric}}
} {1 {input to percentile() is not numeric}}
do_test percentile-1.15.2 {
catchsql {
SELECT percentile_cont(x, 0.50) FROM t1;
}
} {1 {input to percentile_cont() is not numeric}}
do_test percentile-1.15.3 {
catchsql {
SELECT percentile_disc(x, 0.50) FROM t1;
}
} {1 {input to percentile_disc() is not numeric}}
do_test percentile-1.15.4 {
catchsql {
SELECT median(x) FROM t1;
}
} {1 {input to median() is not numeric}}
do_test percentile-1.16 {
catchsql {
ROLLBACK;
@@ -158,7 +317,7 @@ do_test percentile-1.16 {
UPDATE t1 SET x=x'3530' WHERE x IS NULL;
SELECT percentile(x, 50) FROM t1;
}
} {1 {1st argument to percentile() is not numeric}}
} {1 {input to percentile() is not numeric}}
do_test percentile-1.17 {
catchsql {
ROLLBACK;
@@ -186,7 +345,7 @@ do_test percentile-1.19 {
# Infinity as an input
#
do_test percentile-1.20 {
do_test percentile-1.20.1 {
catchsql {
DELETE FROM t1;
INSERT INTO t1 SELECT x+0.0 FROM t2;
@@ -194,6 +353,43 @@ do_test percentile-1.20 {
SELECT percentile(x,50) from t1;
}
} {1 {Inf input to percentile()}}
do_test percentile-1.20.2 {
catchsql {
SELECT percentile_cont(x,0.50) from t1;
}
} {1 {Inf input to percentile_cont()}}
do_test percentile-1.20.3 {
catchsql {
SELECT percentile_disc(x,0.50) from t1;
}
} {1 {Inf input to percentile_disc()}}
do_test percentile-1.20.4 {
catchsql {
SELECT median(x) from t1;
}
} {1 {Inf input to median()}}
ifcapable ordered_set_aggregates {
do_test percentile-1.20.5 {
catchsql {
SELECT percentile(50) WITHIN GROUP (ORDER BY x) from t1;
}
} {1 {Inf input to percentile()}}
do_test percentile-1.20.6 {
catchsql {
SELECT percentile_cont(0.50) WITHIN GROUP (ORDER BY x) from t1;
}
} {1 {Inf input to percentile_cont()}}
do_test percentile-1.20.7 {
catchsql {
SELECT percentile_disc(0.50) WITHIN GROUP(ORDER BY X) from t1;
}
} {1 {Inf input to percentile_disc()}}
do_test percentile-1.20.8 {
catchsql {
SELECT median() WITHIN GROUP (ORDER BY x) from t1;
}
} {1 {Inf input to median()}}
}
do_test percentile-1.21 {
catchsql {
UPDATE t1 SET x=-1.0e300*1.0e300 WHERE rowid=5;
@@ -229,4 +425,172 @@ ifcapable vtab {
}
}
# median() as a window function. (2024-08-31)
#
do_execsql_test percentile-3.0 {
DROP TABLE IF EXISTS t1;
CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c, d);
INSERT INTO t1 VALUES (1, 'A', 'one', 8.4),
(2, 'B', 'two', 7.1),
(3, 'C', 'three', 5.9),
(4, 'D', 'one', 11.0),
(5, 'E', 'two', 12.5),
(6, 'F', 'three', 0.0),
(7, 'G', 'one', 2.7);
}
foreach {id oba expr} {
1 0 "median(d)"
2 0 "percentile(d,50)"
3 0 "percentile_cont(d,0.5)"
4 1 "median() WITHIN GROUP (ORDER BY d)"
5 1 "percentile(50) WITHIN GROUP (ORDER BY d)"
6 1 "percentile_cont(0.5) WITHIN GROUP (ORDER BY d)"
} {
if {$oba} {
ifcapable !ordered_set_aggregates break
}
set sql "SELECT a, b, c, d, \
group_concat(b,'.') OVER w1 AS 'elements', \
$expr OVER w1 AS 'median' \
FROM t1 \
WINDOW w1 AS (ORDER BY c, a ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING)"
do_execsql_test percentile-3.$id.1 $sql {
1 A one 8.4 A.D 9.7
4 D one 11.0 A.D.G 8.4
7 G one 2.7 D.G.C 5.9
3 C three 5.9 G.C.F 2.7
6 F three 0.0 C.F.B 5.9
2 B two 7.1 F.B.E 7.1
5 E two 12.5 B.E 9.8
}
set sql "SELECT a, b, c, d, \
group_concat(b,'.') OVER w1 AS 'elements', \
$expr OVER w1 AS 'median' \
FROM t1 \
WINDOW w1 AS (ORDER BY c, a \
ROWS BETWEEN UNBOUNDED PRECEDING AND 1 FOLLOWING)"
do_execsql_test percentile-3.$id.2 $sql {
1 A one 8.4 A.D 9.7
4 D one 11.0 A.D.G 8.4
7 G one 2.7 A.D.G.C 7.15
3 C three 5.9 A.D.G.C.F 5.9
6 F three 0.0 A.D.G.C.F.B 6.5
2 B two 7.1 A.D.G.C.F.B.E 7.1
5 E two 12.5 A.D.G.C.F.B.E 7.1
}
set sql "SELECT a, b, c, d, \
group_concat(b,'.') OVER w1 AS 'elements', \
$expr OVER w1 AS 'median' \
FROM t1 \
WINDOW w1 AS (ORDER BY c, a \
ROWS BETWEEN 1 PRECEDING AND UNBOUNDED FOLLOWING)"
do_execsql_test percentile-3.$id.3 $sql {
1 A one 8.4 A.D.G.C.F.B.E 7.1
4 D one 11.0 A.D.G.C.F.B.E 7.1
7 G one 2.7 D.G.C.F.B.E 6.5
3 C three 5.9 G.C.F.B.E 5.9
6 F three 0.0 C.F.B.E 6.5
2 B two 7.1 F.B.E 7.1
5 E two 12.5 B.E 9.8
}
}
# Test case adapted from examples shown at
# https://database.guide/3-functions-to-calculate-the-median-in-sql/
#
do_execsql_test percential-4.0 {
CREATE TABLE products(
vendorId INT,
productId INTEGER PRIMARY KEY,
productName REAL,
price REAL
);
INSERT INTO products VALUES
(1001, 17, 'Left-handed screwdriver', 25.99),
(1001, 49, 'Right-handed screwdriver', 25.99),
(1001, 216, 'Long weight (blue)', 14.75),
(1001, 31, 'Long weight (green)', 11.99),
(1002, 37, 'Sledge hammer', 33.49),
(1003, 7, 'Chainsaw', 245.00),
(1003, 8, 'Straw dog box', 55.99),
(1003, 12, 'Hammock', 11.01),
(1004, 113, 'Teapot', 12.45),
(1004, 117, 'Bottomless coffee mug', 9.99);
}
do_execsql_test percentile-4.1 {
SELECT VendorId, ProductId, /* ProductName,*/ Price,
avg(price) OVER (PARTITION BY vendorId) AS "Average",
median(price) OVER (PARTITION BY vendorId) AS "Median"
FROM products
ORDER BY vendorId, productId;
} {
1001 17 25.99 19.68 20.37
1001 31 11.99 19.68 20.37
1001 49 25.99 19.68 20.37
1001 216 14.75 19.68 20.37
1002 37 33.49 33.49 33.49
1003 7 245.0 104.0 55.99
1003 8 55.99 104.0 55.99
1003 12 11.01 104.0 55.99
1004 113 12.45 11.22 11.22
1004 117 9.99 11.22 11.22
}
do_execsql_test percentile-4.2 {
SELECT vendorId, median(price) FROM products
GROUP BY 1 ORDER BY 1;
} {1001 20.37 1002 33.49 1003 55.99 1004 11.22}
do_execsql_test percentile-5.0 {
CREATE TABLE user(name TEXT, class TEXT, cost REAL);
INSERT INTO user VALUES
('Alice', 'Y', 3578.27),
('Bob', 'X', 3399.99),
('Cindy', 'Z', 699.10),
('Dave', 'Y', 3078.27),
('Emma', 'Z', 2319.99),
('Fred', 'Y', 539.99),
('Gina', 'X', 2320.49),
('Hank', 'W', 24.99),
('Irma', 'W', 24.99),
('Jake', 'X', 2234.99),
('Kim', 'Y', 4319.99),
('Liam', 'X', 4968.59),
('Mia', 'W', 59.53),
('Nate', 'W', 23.50);
}
do_execsql_test percentile-5.1 {
SELECT name, class, cost,
percentile(cost, 0) OVER w1 AS 'P0',
percentile(cost, 25) OVER w1 AS 'P1',
percentile(cost, 50) OVER w1 AS 'P2',
percentile(cost, 75) OVER w1 AS 'P3',
percentile(cost, 100) OVER w1 AS 'P4'
FROM user
WINDOW w1 AS (PARTITION BY class)
ORDER BY class, cost;
} {
Nate W 23.5 23.5 24.6175 24.99 33.625 59.53
Hank W 24.99 23.5 24.6175 24.99 33.625 59.53
Irma W 24.99 23.5 24.6175 24.99 33.625 59.53
Mia W 59.53 23.5 24.6175 24.99 33.625 59.53
Jake X 2234.99 2234.99 2299.115 2860.24 3792.14 4968.59
Gina X 2320.49 2234.99 2299.115 2860.24 3792.14 4968.59
Bob X 3399.99 2234.99 2299.115 2860.24 3792.14 4968.59
Liam X 4968.59 2234.99 2299.115 2860.24 3792.14 4968.59
Fred Y 539.99 539.99 2443.7 3328.27 3763.7 4319.99
Dave Y 3078.27 539.99 2443.7 3328.27 3763.7 4319.99
Alice Y 3578.27 539.99 2443.7 3328.27 3763.7 4319.99
Kim Y 4319.99 539.99 2443.7 3328.27 3763.7 4319.99
Cindy Z 699.1 699.1 1104.3225 1509.545 1914.7675 2319.99
Emma Z 2319.99 699.1 1104.3225 1509.545 1914.7675 2319.99
}
# Fuzzer find.
do_execsql_test percentile-6.0 {
WITH RECURSIVE c(n) AS (VALUES(1) UNION ALL SELECT n+1 FROM c WHERE n<12)
SELECT median(iif(n%2,0.1,1.0)) FROM c;
} 0.55
finish_test
+4
View File
@@ -217,6 +217,7 @@ do_test shell2-1.4.9 {
done
2}}
ifcapable vtab {
# Verify that generate_series stays sane near 64-bit range boundaries.
# See overflow report at https://sqlite.org/forum/forumpost/5d34ce5280
do_test shell2-1.4.10 {
@@ -247,7 +248,9 @@ do_test shell2-1.4.10 {
0
1
2}}
} ;# ifcapable vtab
ifcapable vtab {
# Bug discovered while messing around, .import hangs with
# bit 7 set in column separator.
do_test shell2-1.4.11 {
@@ -262,6 +265,7 @@ do_test shell2-1.4.11 {
.import dummy.csv t
SELECT count(*) FROM t;}]]
} {0 1}
} ;# ifcapable vtab
# Bug from forum post 7cbe081746dd3803
# Keywords as column names were producing an error message.
+8
View File
@@ -84,6 +84,14 @@ do_test shell5-1.4.1 {
.import FOO t1}]
} {1 {Error: cannot open "FOO"}}
# the remainder of these test cases require virtual tables.
#
ifcapable !vtab {
puts "Skipping subsequent tests due to SQLITE_OMIT_VIRTUALTABLE"
finish_test
return
}
# empty import file
do_test shell5-1.4.2 {
forcedelete shell5.csv
+7 -2
View File
@@ -1279,10 +1279,15 @@ proc finalize_testing {} {
out of $nTest tests"
} else {
set cpuinfo {}
if {[catch {exec hostname} hname]==0} {set cpuinfo [string trim $hname]}
if {[catch {exec hostname} hname]==0} {
regsub {\.local$} $hname {} hname
set cpuinfo [string trim $hname]
}
append cpuinfo " $::tcl_platform(os)"
append cpuinfo " [expr {$::tcl_platform(pointerSize)*8}]-bit"
append cpuinfo " [string map {E -e} $::tcl_platform(byteOrder)]"
if {[string match big* $::tcl_platform(byteOrder)]} {
append cpuinfo " [string map {E -e} $::tcl_platform(byteOrder)]"
}
output2 "SQLite [sqlite3 -sourceid]"
output2 "$nErr errors out of $nTest tests on $cpuinfo"
}
Regular → Executable
+205 -52
View File
@@ -1,3 +1,6 @@
#!/bin/sh
# Script to runs tests for SQLite. Run with option "help" for more info. \
exec tclsh "$0" "$@"
set dir [pwd]
set testdir [file normalize [file dirname $argv0]]
@@ -14,8 +17,14 @@ cd $dir
# recommend that the user build one.
#
proc find_interpreter {} {
global dir
set interpreter [file tail [info nameofexec]]
set rc [catch { package require sqlite3 }]
if {$rc} {
if {[file readable pkgIndex.tcl] && [catch {source pkgIndex.tcl}]==0} {
set rc [catch { package require sqlite3 }]
}
}
if {$rc} {
if { [string match -nocase testfixture* $interpreter]==0
&& [file executable ./testfixture]
@@ -28,8 +37,30 @@ proc find_interpreter {} {
}
}
if {$rc} {
puts stderr "Failed to find tcl package sqlite3"
puts stderr "Run \"make testfixture\" and then try again..."
puts "Cannot find tcl package sqlite3: Trying to build it now..."
if {$::tcl_platform(platform)=="windows"} {
set bat [open make-tcl-extension.bat w]
puts $bat "nmake /f Makefile.msc tclextension"
close $bat
catch {exec -ignorestderr -- make-tcl-extension.bat}
} else {
catch {exec make tclextension}
}
if {[file readable pkgIndex.tcl] && [catch {source pkgIndex.tcl}]==0} {
set rc [catch { package require sqlite3 }]
}
if {$rc==0} {
puts "The SQLite tcl extension was successfully built and loaded."
puts "Run \"make tclextension-install\" to avoid having to rebuild\
it in the future."
} else {
puts "Unable to build the SQLite tcl extension"
}
}
if {$rc} {
puts stderr "Cannot find a working instance of the SQLite tcl extension."
puts stderr "Run \"make tclextension\" or \"make testfixture\" and\
try again..."
exit 1
}
}
@@ -54,8 +85,9 @@ proc usage {} {
Usage:
$a0 ?SWITCHES? ?PERMUTATION? ?PATTERNS?
$a0 PERMUTATION FILE
$a0 errors ?-v|--verbose?
$a0 errors ?-v|--verbose? ?-s|--summary? ?PATTERN?
$a0 help
$a0 joblist ?PATTERN?
$a0 njob ?NJOB?
$a0 script ?-msvc? CONFIG
$a0 status ?-d SECS? ?--cls?
@@ -112,10 +144,12 @@ The "script" command outputs the script used to build a configuration.
Add the "-msvc" option for a Windows-compatible script. For a list of
available configurations enter "$a0 script help".
The "errors" commands shows the output of all tests that failed in the
The "errors" commands shows the output of tests that failed in the
most recent run. Complete output is shown if the -v or --verbose options
are used. Otherwise, an attempt is made to minimize the output to show
only the parts that contain the error messages.
only the parts that contain the error messages. The --summary option just
shows the jobs that failed. If PATTERN are provided, the error information
is only provided for jobs that match PATTERN.
Full documentation here: https://sqlite.org/src/doc/trunk/doc/testrunner.md
}]]
@@ -284,6 +318,8 @@ set TRG(schema) {
state TEXT CHECK( state IN ('','ready','running','done','failed','omit') ),
ntest INT, -- Number of test cases run
nerr INT, -- Number of errors reported
svers TEXT, -- Reported SQLite version
pltfm TEXT, -- Host platform reported
output TEXT -- test output
);
@@ -356,8 +392,8 @@ if {([llength $argv]==2 || [llength $argv]==1)
sqlite3 mydb $TRG(dbname)
if {[llength $argv]==2} {
set param [lindex $argv 1]
if {[string is integer $param]==0 || $param<1 || $param>128} {
puts stderr "parameter must be an integer between 1 and 128"
if {[string is integer $param]==0 || $param<0 || $param>128} {
puts stderr "parameter must be an integer between 0 and 128"
exit 1
}
@@ -470,18 +506,25 @@ proc show_status {db cls} {
# overwrite.
puts -nonewline "\033\[H"
flush stdout
set clreol "\033\[K"
} else {
set clreol ""
}
puts [format %-79.79s "Command: \[testrunner.tcl$cmdline\]$clreol"]
puts [format %-79.79s "Cores: $nJob max $S(running) active"]
puts [format %-79.79s "Summary: [elapsetime $tm], $fin/$total tasks,\
puts [format %-79.79s "Command: \[testrunner.tcl$cmdline\]"]
puts [format %-79.79s "Summary: [elapsetime $tm], $fin/$total jobs,\
$ne errors, $nt tests"]
set srcdir [file dirname [file dirname $TRG(info_script)]]
set line "Running: $S(running) (max: $nJob)"
if {$S(running)>0 && $fin>100 && $fin>0.05*$total} {
# Only estimate the time remaining after completing at least 100
# jobs amounting to 10% of the total. Never estimate less than
# 2% of the total time used so far.
set tmleft [expr {($tm/$fin)*($total-$fin)}]
if {$tmleft<0.02*$tm} {
set tmleft [expr {$tm*0.02}]
}
append line " est time left [elapsetime $tmleft]"
}
puts [format %-79.79s $line]
if {$S(running)>0} {
puts "Running: "
$db eval {
SELECT * FROM jobs WHERE state='running' ORDER BY starttime
} job {
@@ -489,15 +532,30 @@ proc show_status {db cls} {
}
}
if {$S(failed)>0} {
puts "Failures: "
# $toshow is the number of failures to report. In $cls mode,
# status tries to limit the number of failure reported so that
# the status display does not overflow a 24-line terminal. It will
# always show at least the most recent 4 failures, even if an overflow
# is needed. No limit is imposed for a status within $cls.
#
if {$cls && $S(failed)>18-$S(running)} {
set toshow [expr {18-$S(running)}]
if {$toshow<4} {set toshow 4}
set shown " (must recent $toshow shown)"
} else {
set toshow $S(failed)
set shown ""
}
puts [format %-79s "Failed: $S(failed) $shown"]
$db eval {
SELECT * FROM jobs WHERE state='failed' ORDER BY starttime
SELECT * FROM jobs WHERE state='failed'
ORDER BY endtime DESC LIMIT $toshow
} job {
display_job [array get job]
}
set nOmit [$db one {SELECT count(*) FROM jobs WHERE state='omit'}]
if {$nOmit} {
puts [format %-79s "$nOmit jobs omitted due to failures$clreol"]
puts [format %-79s " ... $nOmit jobs omitted due to failures"]
}
}
if {$cls} {
@@ -555,44 +613,80 @@ if {[llength $argv]>=1
exit
}
#--------------------------------------------------------------------------
# Check if this is the "joblist" command:
#
if {[llength $argv]>=1
&& [string compare -nocase "joblist" [lindex $argv 0]]==0
} {
set pattern {}
for {set ii 1} {$ii<[llength $argv]} {incr ii} {
set a0 [lindex $argv $ii]
if {$pattern==""} {
set pattern [string trim $a0 *]
} else {
puts "unknown option: \"$a0\""
exit 1
}
}
set SQL {SELECT displaytype, displayname, state FROM jobs}
if {$pattern!=""} {
regsub -all {[^a-zA-Z0-9*.-/]} $pattern ? pattern
append SQL " WHERE displayname GLOB '*$pattern*'"
}
append SQL " ORDER BY starttime"
if {![file readable $TRG(dbname)]} {
puts "Database missing: $TRG(dbname)"
exit
}
sqlite3 mydb $TRG(dbname)
mydb timeout 2000
mydb eval $SQL {
set label UNKNOWN
switch -- $state {
ready {set label READY}
done {set label DONE}
failed {set label FAILED}
omit {set label OMIT}
running {set label RUNNING}
}
puts [format {%-7s %-5s %s} $label $displaytype $displayname]
}
mydb close
exit
}
# Scan the output of all jobs looking for the summary lines that
# report the number of test cases and the number of errors.
# Aggregate these numbers and return them.
#
proc aggregate_test_counts {db} {
set ncase 0
set nerr 0
$db eval {SELECT output FROM jobs WHERE displaytype IN ('tcl','fuzz')} {
set n 0
set m 0
if {[regexp {(\d+) errors out of (\d+) tests} $output all n m]
&& [string is integer -strict $n]
&& [string is integer -strict $m]} {
incr ncase $m
incr nerr $n
} elseif {[regexp {sessionfuzz.*: *(\d+) cases, (\d+) crash} $output \
all m n]
&& [string is integer -strict $m]
&& [string is integer -strict $n]} {
incr ncase $m
incr nerr $n
}
}
return [list $nerr $ncase]
set ne 0
set nt 0
$db eval {SELECT sum(nerr) AS ne, sum(ntest) as nt FROM jobs} break
return [list $ne $nt]
}
#--------------------------------------------------------------------------
# Check if this is the "errors" command:
#
if {[llength $argv]>=1 && [llength $argv]<=2
if {[llength $argv]>=1
&& ([string compare -nocase errors [lindex $argv 0]]==0 ||
[string match err* [lindex $argv 0]]==1)
} {
set verbose 0
set pattern {}
set summary 0
for {set ii 1} {$ii<[llength $argv]} {incr ii} {
set a0 [lindex $argv $ii]
if {$a0=="-v" || $a0=="--verbose" || $a0=="-verbose"} {
set verbose 1
} elseif {$a0=="-s" || $a0=="--summary" || $a0=="-summary"} {
set summary 1
} elseif {$pattern==""} {
set pattern *[string trim $a0 *]*
} else {
puts "unknown option: \"$a0\"". Use --help for more info."
exit 1
@@ -600,9 +694,22 @@ if {[llength $argv]>=1 && [llength $argv]<=2
}
set cnt 0
sqlite3 mydb $TRG(dbname)
mydb timeout 2000
mydb eval {SELECT displaytype, displayname, output
FROM jobs WHERE state='failed'} {
mydb timeout 5000
if {$summary} {
set sql "SELECT displayname FROM jobs WHERE state='failed'"
} else {
set sql "SELECT displaytype, displayname, output FROM jobs \
WHERE state='failed'"
}
if {$pattern!=""} {
regsub -all {[^a-zA-Z0-9*/ ?]} $pattern . pattern
append sql " AND displayname GLOB '$pattern'"
}
mydb eval $sql {
if {$summary} {
puts "FAILED: $displayname"
continue
}
puts "**** $displayname ****"
if {$verbose || $displaytype!="tcl"} {
puts $output
@@ -615,9 +722,13 @@ if {[llength $argv]>=1 && [llength $argv]<=2
}
incr cnt
}
set summary [aggregate_test_counts mydb]
mydb close
puts "Total [lindex $summary 0] errors out of [lindex $summary 1] tests"
if {$pattern==""} {
set summary [aggregate_test_counts mydb]
mydb close
puts "Total [lindex $summary 0] errors out of [lindex $summary 1] tests"
} else {
mydb close
}
exit
}
@@ -880,7 +991,7 @@ proc add_tcl_jobs {build config patternlist {shelldepid ""}} {
} else {
set p "$p*"
}
if {[string match $p [file tail $f]]} {
if {[string match $p "$config [file tail $f]"]} {
set bMatch 1
break
}
@@ -1083,6 +1194,7 @@ proc add_jobs_from_cmdline {patternlist} {
}
}
devtest -
mdevtest {
set config_set {
All-O0
@@ -1100,13 +1212,34 @@ proc add_jobs_from_cmdline {patternlist} {
}
release {
set config_set {}
set patternlist [lrange $patternlist 1 end]
foreach b [trd_builds $TRG(platform)] {
if {$TRG(config)!="" && ![regexp "\\y$b\\y" $TRG(config)]} continue
if {[regexp "\\y$b\\y" $TRG(omitconfig)]} continue
lappend config_set $b
set bld [add_build_job $b $TRG(testfixture)]
foreach c [trd_configs $TRG(platform) $b] {
add_tcl_jobs $bld $c $patternlist SHELL
}
if {$patternlist==""} {
foreach e [trd_extras $TRG(platform) $b] {
if {$e=="fuzztest"} {
add_fuzztest_jobs $b
} else {
add_make_job $bld $e
}
}
}
if {[trdb one "SELECT EXISTS(SELECT 1
FROM jobs WHERE depid='SHELL')"]} {
set sbld [add_shell_build_job $b [lindex $bld 1] [lindex $bld 0]]
set sbldid [lindex $sbld 0]
trdb eval {
UPDATE jobs SET depid=$sbldid WHERE depid='SHELL'
}
}
}
add_devtest_jobs $config_set [lrange $patternlist 1 end]
}
list {
@@ -1149,10 +1282,13 @@ proc mark_job_as_finished {jobid output state endtm} {
set ntest 1
set nerr 0
if {$endtm>0} {
if {[regexp {\y(\d+) errors out of (\d+) tests} $output all a b]} {
set re {\y(\d+) errors out of (\d+) tests( on [^\n]+\n)?}
if {[regexp $re $output all a b pltfm]} {
set nerr $a
set ntest $b
}
regexp {\ySQLite \d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d [0-9a-fA-F]+} \
$output svers
}
r_write_db {
if {$state=="failed"} {
@@ -1161,10 +1297,11 @@ proc mark_job_as_finished {jobid output state endtm} {
} else {
set childstate ready
}
if {[info exists pltfm]} {set pltfm [string trim $pltfm]}
trdb eval {
UPDATE jobs
SET output=$output, state=$state, endtime=$endtm,
ntest=$ntest, nerr=$nerr
ntest=$ntest, nerr=$nerr, svers=$svers, pltfm=$pltfm
WHERE jobid=$jobid;
UPDATE jobs SET state=$childstate WHERE depid=$jobid;
}
@@ -1417,7 +1554,16 @@ proc run_testset {} {
FROM jobs WHERE endtime>0
} break;
set et [elapsetime $totaltime]
puts "$totalerr errors out of $totaltest tests in about $et"
set pltfm {}
trdb eval {
SELECT pltfm, count(*) FROM jobs WHERE pltfm IS NOT NULL
ORDER BY 2 DESC LIMIT 1
} break
puts "$totalerr errors out of $totaltest tests in $et $pltfm"
trdb eval {
SELECT DISTINCT substr(svers,1,79) as v1 FROM jobs WHERE svers IS NOT NULL
} {puts $v1}
}
# Handle the --buildonly option, if it was specified.
@@ -1448,7 +1594,14 @@ proc explain_layer {indent depid} {
puts "${indent}$displayname in $dirname"
explain_layer "${indent} " $jobid
} elseif {$showtests} {
puts "${indent}[lindex $displayname end]"
set tail [lindex $displayname end]
set e1 [lindex $displayname 1]
if {[string match config=* $e1]} {
set cfg [string range $e1 7 end]
puts "${indent}($cfg) $tail"
} else {
puts "${indent}$tail"
}
}
}
}
@@ -1463,7 +1616,7 @@ if {$TRG(explain)} {
explain_tests
} else {
if {$TRG(nJob)>1} {
puts "splitting work across $TRG(nJob) jobs"
puts "splitting work across $TRG(nJob) cores"
}
puts "built testset in [expr $tm/1000]ms.."
handle_buildonly
+3 -1
View File
@@ -88,6 +88,7 @@ namespace eval trd {
--disable-amalgamation --disable-shared
--enable-session
-DSQLITE_ENABLE_RBU
-DSQLITE_ENABLE_STMT_SCANSTATUS
}
# These two are used by [testrunner.tcl mdevtest] (All-O0) and
@@ -95,6 +96,7 @@ namespace eval trd {
#
set build(All-Debug) {
--enable-debug --enable-all
-DSQLITE_ENABLE_ORDERED_SET_AGGREGATES
}
set build(All-O0) {
-O0 --enable-all
@@ -218,7 +220,7 @@ namespace eval trd {
-DSQLITE_MAX_PAGE_SIZE=4096
-DSQLITE_OMIT_LOAD_EXTENSION=1
-DSQLITE_OMIT_PROGRESS_CALLBACK=1
-DSQLITE_OMIT_VIRTUALTABLEx=1
-DSQLITE_OMIT_VIRTUALTABLE=1
-DSQLITE_ENABLE_HIDDEN_COLUMNS
-DSQLITE_TEMP_STORE=3
}
+11
View File
@@ -127,6 +127,17 @@ foreach tn {1a 1b 1c 1d 1e 1f} {
db3 close
}
# These over-length file and directory names are difficult to delete.
# The "file delete -force" might not work, depending on the TCL build
# being used. So first try to delete using the windows rmdir command.
#
set fd [open cleanup.bat w]
puts $fd "rmdir /q /s $longPath(1)"
close $fd
if {[catch {exec cleanup.bat} msg]} {
puts "Command \[cleanup.bat\] returns $msg"
}
file delete -force $fileName
file delete -force $longPath(3)
file delete -force $longPath(2)
+32
View File
@@ -73,6 +73,38 @@ do_catchsql_test 2.2 {
WINDOW w1 AS (PARTITION BY x OVER w1);
} {1 {near "OVER": syntax error}}
#-------------------------------------------------------------------------
reset_db
do_execsql_test 3.0 {
BEGIN TRANSACTION;
CREATE TABLE t2(c1 INT, c2 REAL);
INSERT INTO t2 VALUES
(447,0.0), (448,0.0), (449,0.0), (452,0.0), (453,0.0), (454,0.0), (455,0.0),
(456,0.0), (459,0.0), (460,0.0), (462,0.0), (463,0.0), (466,0.0), (467,0.0),
(468,0.0), (469,0.0), (470,0.0), (473,0.0), (474,0.0), (475,0.0), (476,0.0),
(477,0.0), (480,0.0), (481,0.0), (482,0.0), (483,0.0), (484,0.0), (487,0.0),
(488,0.0), (489,0.0), (490,0.0), (491,0.0), (494,0.0), (495,0.0), (496,0.0),
(497,0.0), (498,0.0), (501,0.0), (502,0.0), (503,0.0), (504,0.0), (505,0.0),
(508,0.0), (509,0.0), (510,0.0), (511,0.0), (512,0.0), (515,0.0), (516,0.0),
(517,0.0), (518,0.0), (519,0.0), (522,0.0), (523,0.0), (524,0.0), (525,0.0),
(526,0.0), (529,0.0), (530,0.0), (531,0.0), (532,0.0), (533,0.0), (536,0.0),
(537,1.0), (538,0.0), (539,0.0), (540,0.0), (543,0.0), (544,0.0);
COMMIT;
}
do_execsql_test 3.1 {
select c1, max(c2) over (order by c1 range 366.0 preceding) from t2;
} {
447 0.0 448 0.0 449 0.0 452 0.0 453 0.0 454 0.0 455 0.0 456 0.0 459 0.0
460 0.0 462 0.0 463 0.0 466 0.0 467 0.0 468 0.0 469 0.0 470 0.0 473 0.0
474 0.0 475 0.0 476 0.0 477 0.0 480 0.0 481 0.0 482 0.0 483 0.0 484 0.0
487 0.0 488 0.0 489 0.0 490 0.0 491 0.0 494 0.0 495 0.0 496 0.0 497 0.0
498 0.0 501 0.0 502 0.0 503 0.0 504 0.0 505 0.0 508 0.0 509 0.0 510 0.0
511 0.0 512 0.0 515 0.0 516 0.0 517 0.0 518 0.0 519 0.0 522 0.0 523 0.0
524 0.0 525 0.0 526 0.0 529 0.0 530 0.0 531 0.0 532 0.0 533 0.0 536 0.0
537 1.0 538 1.0 539 1.0 540 1.0 543 1.0 544 1.0
}
finish_test
+1 -1
View File
@@ -17,5 +17,5 @@ gcc -o sqlite3 -g -Os -I. \
-DSQLITE_ENABLE_RTREE \
-DHAVE_READLINE \
../sqlite/src/shell.c \
../sqlite/src/test_vfstrace.c \
../sqlite/ext/misc/vfstrace.c \
sqlite3.c -ldl -lreadline -lncurses
+2
View File
@@ -159,6 +159,7 @@ set boolean_defnil_options {
SQLITE_ENABLE_MULTIPLEX
SQLITE_ENABLE_NORMALIZE
SQLITE_ENABLE_NULL_TRIM
SQLITE_ENABLE_ORDERED_SET_AGGREGATES
SQLITE_ENABLE_OFFSET_SQL_FUNC
SQLITE_ENABLE_OVERSIZE_CELL_CHECK
SQLITE_ENABLE_PREUPDATE_HOOK
@@ -448,6 +449,7 @@ if {[catch {set cfd [open $destfile w]}]!=0} {
puts stderr "File '$destfile' unwritable."
exit 1;
}
fconfigure $cfd -translation binary
puts $cfd $::headWarning;
puts $cfd $::headCode;
+6
View File
@@ -164,6 +164,11 @@ struct Keyword {
#else
# define RETURNING 0x00400000
#endif
#ifndef SQLITE_ENABLE_ORDERED_SET_AGGREGATES
# define ORDERSET 0
#else
# define ORDERSET 0x00800000
#endif
/*
@@ -316,6 +321,7 @@ static Keyword aKeywordTable[] = {
{ "WHERE", "TK_WHERE", ALWAYS, 10 },
{ "WINDOW", "TK_WINDOW", WINDOWFUNC, 3 },
{ "WITH", "TK_WITH", CTE, 4 },
{ "WITHIN", "TK_WITHIN", ORDERSET, 1 },
{ "WITHOUT", "TK_WITHOUT", ALWAYS, 1 },
};
+201 -351
View File
@@ -1,370 +1,220 @@
# Documentation for this script. This may be output to stderr
#!/usr/bin/tclsh
#
# Documentation for this script. This may be output to
# if the script is invoked incorrectly.
#
set ::USAGE_MESSAGE {
This Tcl script is used to test the various compile time options
available for omitting code (the SQLITE_OMIT_xxx options). It
should be invoked as follows:
available for building SQLite, especially options taht omit
features (the SQLITE_OMIT_xxx options). It should be invoked as follows:
<script> ?test-symbol? ?-makefile PATH-TO-MAKEFILE? ?-skip_run?
./configure CFLAGS=-O0
tclsh test/omittest.tcl
The default value for ::MAKEFILE is "../Makefile.linux.gcc".
If -skip_run option is given then only the compile part is attempted.
This script builds the testfixture program and runs the SQLite test suite
once with each SQLITE_OMIT_ option defined and then once with all options
defined together. Each run is performed in a seperate directory created
as a sub-directory of the current directory by the script. The output
of the build is saved in <sub-directory>/build.log. The output of the
test-suite is saved in <sub-directory>/test.log.
Almost any SQLite makefile (except those generated by configure - see below)
should work. The following properties are required:
* The makefile should support the "testfixture" target.
* The makefile should support the "test" target.
* The makefile should support the variable "OPTS" as a way to pass
options from the make command line to lemon and the C compiler.
More precisely, the following two invocations must be supported:
$::MAKEBIN -f $::MAKEFILE testfixture OPTS="-DSQLITE_OMIT_ALTERTABLE=1"
$::MAKEBIN -f $::MAKEFILE test
Makefiles generated by the sqlite configure program cannot be used as
they do not respect the OPTS variable.
}
# Build a testfixture executable and run quick.test using it. The first
# parameter is the name of the directory to create and use to run the
# test in. The second parameter is a list of OMIT symbols to define
# when doing so. For example:
# List of all options to be tested.
#
# run_quick_test /tmp/testdir {SQLITE_OMIT_TRIGGER SQLITE_OMIT_VIEW}
#
#
proc run_quick_test {dir omit_symbol_list} {
# Compile the value of the OPTS Makefile variable.
set opts ""
if {$::tcl_platform(platform)=="windows"} {
append opts "OPTS += -DSQLITE_OS_WIN=1\n"
set target "testfixture.exe"
} else {
append opts "OPTS += -DSQLITE_OS_UNIX=1\n"
}
foreach sym $omit_symbol_list {
append opts "OPTS += -D${sym}=1\n"
}
set CompileOptionsToTest {
SQLITE_OMIT_ALTERTABLE
SQLITE_OMIT_ANALYZE
SQLITE_OMIT_ATTACH
SQLITE_OMIT_AUTHORIZATION
SQLITE_OMIT_AUTOINCREMENT
SQLITE_OMIT_AUTOINIT
SQLITE_OMIT_AUTOMATIC_INDEX
SQLITE_OMIT_AUTORESET
SQLITE_OMIT_AUTOVACUUM
SQLITE_OMIT_AUXILIARY_SAFETY_CHECKS
SQLITE_OMIT_BETWEEN_OPTIMIZATION
SQLITE_OMIT_BLOB_LITERAL
SQLITE_OMIT_CASE_SENSITIVE_LIKE_PRAGMA
SQLITE_OMIT_CAST
SQLITE_OMIT_CHECK
SQLITE_OMIT_COMPILEOPTION_DIAGS
SQLITE_OMIT_COMPLETE
SQLITE_OMIT_COMPOUND_SELECT
SQLITE_OMIT_CONFLICT_CLAUSE
SQLITE_OMIT_CTE
SQLITE_OMIT_DATETIME_FUNCS
SQLITE_OMIT_DECLTYPE
SQLITE_OMIT_DEPRECATED
SQLITE_OMIT_DESERIALIZE
SQLITE_OMIT_DISKIO
SQLITE_OMIT_EXPLAIN
SQLITE_OMIT_FLAG_PRAGMAS
SQLITE_OMIT_FLOATING_POINT
SQLITE_OMIT_FOREIGN_KEY
SQLITE_OMIT_GENERATED_COLUMNS
SQLITE_OMIT_GET_TABLE
SQLITE_OMIT_HEX_INTEGER
SQLITE_OMIT_INCRBLOB
SQLITE_OMIT_INTEGRITY_CHECK
SQLITE_OMIT_INTROSPECTION_PRAGMAS
SQLITE_OMIT_JSON
SQLITE_OMIT_LIKE_OPTIMIZATION
SQLITE_OMIT_LOAD_EXTENSION
SQLITE_OMIT_LOCALTIME
SQLITE_OMIT_LOOKASIDE
SQLITE_OMIT_MEMORYDB
SQLITE_OMIT_OR_OPTIMIZATION
SQLITE_OMIT_PAGER_PRAGMAS
SQLITE_OMIT_PARSER_TRACE
SQLITE_OMIT_POPEN
SQLITE_OMIT_PRAGMA
SQLITE_OMIT_PROGRESS_CALLBACK
SQLITE_OMIT_QUICKBALANCE
SQLITE_OMIT_RANDOMNESS
SQLITE_OMIT_REINDEX
SQLITE_OMIT_SCHEMA_PRAGMAS
SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS
SQLITE_OMIT_SHARED_CACHE
SQLITE_OMIT_SHUTDOWN_DIRECTORIES
SQLITE_OMIT_SUBQUERY
SQLITE_OMIT_TCL_VARIABLE
SQLITE_OMIT_TEMPDB
SQLITE_OMIT_TEST_CONTROL
SQLITE_OMIT_TRACE
SQLITE_OMIT_TRIGGER
SQLITE_OMIT_TRUNCATE_OPTIMIZATION
SQLITE_OMIT_TWOSIZE_LOOKASIDE
SQLITE_OMIT_UPSERT
SQLITE_OMIT_UTF
SQLITE_OMIT_VACUUM
SQLITE_OMIT_VIEW
SQLITE_OMIT_VIRTUALTABLE
SQLITE_OMIT_WAL
SQLITE_OMIT_WINDOWFUNC
SQLITE_OMIT_WSD
SQLITE_OMIT_XFER_OPT
SQLITE_ALLOW_ROWID_IN_VIEW
SQLITE_DISABLE_DIRSYNC
SQLITE_DISABLE_FTS
SQLITE_DISABLE_INTRINSIC
SQLITE_DISABLE_LFS
SQLITE_DISABLE_PAGECACHE_OVERFLOW_STATS
SQLITE_DISABLE_SKIPAHEAD_DISTINCT
SQLITE_ENABLE_API_ARMOR
SQLITE_ENABLE_ATOMIC_WRITE
SQLITE_ENABLE_BATCH_ATOMIC_WRITE
SQLITE_ENABLE_BYTECODE_VTAB
SQLITE_ENABLE_CEROD
SQLITE_ENABLE_COLUMN_METADATA
SQLITE_ENABLE_COLUMN_USED_MASK
SQLITE_ENABLE_COMMENTS
SQLITE_ENABLE_CORRUPT_PGNO
SQLITE_ENABLE_COSTMULT
SQLITE_ENABLE_CURSOR_HINTS
SQLITE_ENABLE_DBPAGE_VTAB
SQLITE_ENABLE_DBSTAT_VTAB
SQLITE_ENABLE_EXPENSIVE_ASSERT
SQLITE_ENABLE_EXPLAIN_COMMENTS
SQLITE_ENABLE_FTS
SQLITE_ENABLE_GEOPOLY
SQLITE_ENABLE_HIDDEN_COLUMNS
SQLITE_ENABLE_ICU
SQLITE_ENABLE_ICU_COLLATIONS
SQLITE_ENABLE_INTERNAL_FUNCTIONS
SQLITE_ENABLE_IOTRACE
SQLITE_ENABLE_LOAD_EXTENSION
SQLITE_ENABLE_LOCKING_STYLE
SQLITE_ENABLE_MATH_FUNCTIONS
SQLITE_ENABLE_MEMORY_MANAGEMENT
SQLITE_ENABLE_MEMSYS
SQLITE_ENABLE_MODULE_COMMENTS
SQLITE_ENABLE_MULTIPLEX
SQLITE_ENABLE_MULTITHREADED_CHECKS
SQLITE_ENABLE_NORMALIZE
SQLITE_ENABLE_NULL_TRIM
SQLITE_ENABLE_OFFSET_SQL_FUNC
SQLITE_ENABLE_OVERSIZE_CELL_CHECK
SQLITE_ENABLE_PREUPDATE_HOOK
SQLITE_ENABLE_QPSG
SQLITE_ENABLE_RBU
SQLITE_ENABLE_RTREE
SQLITE_ENABLE_SELECTTRACE
SQLITE_ENABLE_SESSION
SQLITE_ENABLE_SETLK_TIMEOUT
SQLITE_ENABLE_SNAPSHOT
SQLITE_ENABLE_SORTER_MMAP
SQLITE_ENABLE_SORTER_REFERENCE
SQLITE_ENABLE_SORTER_REFERENCES
SQLITE_ENABLE_SQLLOG
SQLITE_ENABLE_STAT
SQLITE_ENABLE_STMT_SCANSTATUS
SQLITE_ENABLE_STMTVTAB
SQLITE_ENABLE_TREETRACE
SQLITE_ENABLE_UNKNOWN_FUNCTION
SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION
SQLITE_ENABLE_UNLOCK_NOTIFY
SQLITE_ENABLE_UPDATE_DELETE_LIMIT
SQLITE_ENABLE_URI_00_ERROR
SQLITE_ENABLE_VFSTRACE
SQLITE_ENABLE_WHERETRACE
SQLITE_ENABLE_ZIPVFS
}
# Create the directory and do the build. If an error occurs return
# early without attempting to run the test suite.
file mkdir $dir
puts -nonewline "Building $dir..."
flush stdout
catch {
file copy -force ./config.h $dir
file copy -force ./libtool $dir
}
set fd [open $::MAKEFILE]
set mkfile [read $fd]
close $fd
regsub {\ninclude} $mkfile "\n$opts\ninclude" mkfile
set fd [open $dir/makefile w]
puts $fd $mkfile
close $fd
set rc [catch {
exec $::MAKEBIN -C $dir -f makefile clean $::TARGET >& $dir/build.log
}]
if {$rc} {
puts "No good. See $dir/build.log."
return
} else {
puts "Ok"
}
# Create an empty file "$dir/sqlite3". This is to trick the makefile out
# of trying to build the sqlite shell. The sqlite shell won't build
# with some of the OMIT options (i.e OMIT_COMPLETE).
set sqlite3_dummy $dir/sqlite3
if {$::tcl_platform(platform)=="windows"} {
append sqlite3_dummy ".exe"
}
if {![file exists $sqlite3_dummy]} {
set wr [open $sqlite3_dummy w]
puts $wr "dummy"
close $wr
# Parse command-line options.
#
for {set i 0} {$i<[llength $argv]} {incr i} {
set arg [lindex $argv $i]
switch -- $arg {
-start -
--start {
incr i
set startat [lindex $argv $i]
}
}
}
if {$::SKIP_RUN} {
# puts "Skip testing $dir."
} else {
# Run the test suite.
puts -nonewline "Testing $dir..."
flush stdout
set rc [catch {
exec $::MAKEBIN -C $dir -f makefile test >& $dir/test.log
}]
if {$rc} {
puts "No good. See $dir/test.log."
# Additional options required for some settings.
#
set More(SQLITE_OMIT_DISKIO) {-DSQLITE_OMIT_WAL}
# Compile-time options for Mac only
#
set MacOnly(SQLITE_ENABLE_LOCKING_STYLE) 1
# Compile-time options that might fail, depending on what libraries
# are installed. Failures on these tests issue a warning, but testing
# continues.
#
set FailIsOk(SQLITE_ENABLE_ICU) 1
set FailIsOk(SQLITE_ENABLE_ICU_COLLATIONS) 1
file mkdir omittest
foreach sym $CompileOptionsToTest {
if {[info exists startat]} {
if {$startat==$sym} {
unset startat
} else {
puts "Ok"
continue
}
}
}
# This proc processes the command line options passed to this script.
# Currently the only option supported is "-makefile", default
# "../Makefile.linux-gcc". Set the ::MAKEFILE variable to the value of this
# option.
#
proc process_options {argv} {
set ::MAKEBIN make ;# Default value
if {$::tcl_platform(platform)=="windows"} {
set ::MAKEFILE ./Makefile ;# Default value on Windows
if {[info exists MacOnly($sym)] && $tcl_platform(os)!="Darwin"} {
continue
}
set logfile "omittest/$sym.log"
if {[info exists More($sym)]} {
append opts "OPT_FEATURE_FLAGS=-D$sym $More($sym)"
} else {
set ::MAKEFILE ./Makefile.linux-gcc ;# Default value
set opts OPT_FEATURE_FLAGS=-D$sym
}
set ::SKIP_RUN 1 ;# Default to attempt test
set ::TARGET testfixture ;# Default thing to build
for {set i 0} {$i < [llength $argv]} {incr i} {
switch -regexp -- [lindex $argv $i] {
-{1,2}makefile {
incr i
set ::MAKEFILE [lindex $argv $i]
}
-{1,2}nmake {
set ::MAKEBIN nmake
set ::MAKEFILE ./Makefile.msc
}
-{1,2}target {
incr i
set ::TARGET [lindex $argv $i]
}
-{1,2}skip_run {
set ::SKIP_RUN 1
}
-{1,2}run {
set ::SKIP_RUN 0
}
-{1,2}help {
puts $::USAGE_MESSAGE
exit
}
-.* {
puts stderr "Unknown option: [lindex $argv i]"
puts stderr $::USAGE_MESSAGE
exit 1
}
default {
if {[info exists ::SYMBOL]} {
puts stderr [string trim $::USAGE_MESSAGE]
exit -1
}
set ::SYMBOL [lindex $argv $i]
}
}
set ::MAKEFILE [file normalize $::MAKEFILE]
}
}
# Main routine.
#
proc main {argv} {
# List of SQLITE_OMIT_XXX symbols supported by SQLite.
set ::OMIT_SYMBOLS [list \
SQLITE_OMIT_ALTERTABLE \
SQLITE_OMIT_ANALYZE \
SQLITE_OMIT_ATTACH \
SQLITE_OMIT_AUTHORIZATION \
SQLITE_OMIT_AUTOINCREMENT \
SQLITE_OMIT_AUTOINIT \
SQLITE_OMIT_AUTOMATIC_INDEX \
SQLITE_OMIT_AUTORESET \
SQLITE_OMIT_AUTOVACUUM \
SQLITE_OMIT_AUXILIARY_SAFETY_CHECKS \
SQLITE_OMIT_BETWEEN_OPTIMIZATION \
SQLITE_OMIT_BLOB_LITERAL \
SQLITE_OMIT_CASE_SENSITIVE_LIKE_PRAGMA \
SQLITE_OMIT_CAST \
SQLITE_OMIT_CHECK \
SQLITE_OMIT_COMPILEOPTION_DIAGS \
SQLITE_OMIT_COMPLETE \
SQLITE_OMIT_COMPOUND_SELECT \
SQLITE_OMIT_CONFLICT_CLAUSE \
SQLITE_OMIT_CTE \
SQLITE_OMIT_DATETIME_FUNCS \
SQLITE_OMIT_DECLTYPE \
SQLITE_OMIT_DEPRECATED \
SQLITE_OMIT_DESERIALIZE \
SQLITE_OMIT_DISKIO \
SQLITE_OMIT_EXPLAIN \
SQLITE_OMIT_FLAG_PRAGMAS \
SQLITE_OMIT_FLOATING_POINT \
SQLITE_OMIT_FOREIGN_KEY \
SQLITE_OMIT_GENERATED_COLUMNS \
SQLITE_OMIT_GET_TABLE \
SQLITE_OMIT_HEX_INTEGER \
SQLITE_OMIT_INCRBLOB \
SQLITE_OMIT_INTEGRITY_CHECK \
SQLITE_OMIT_INTROSPECTION_PRAGMAS \
SQLITE_OMIT_JSON \
SQLITE_OMIT_LIKE_OPTIMIZATION \
SQLITE_OMIT_LOAD_EXTENSION \
SQLITE_OMIT_LOCALTIME \
SQLITE_OMIT_LOOKASIDE \
SQLITE_OMIT_MEMORYDB \
SQLITE_OMIT_OR_OPTIMIZATION \
SQLITE_OMIT_PAGER_PRAGMAS \
SQLITE_OMIT_PARSER_TRACE \
SQLITE_OMIT_POPEN \
SQLITE_OMIT_PRAGMA \
SQLITE_OMIT_PROGRESS_CALLBACK \
SQLITE_OMIT_QUICKBALANCE \
SQLITE_OMIT_RANDOMNESS \
SQLITE_OMIT_REINDEX \
SQLITE_OMIT_SCHEMA_PRAGMAS \
SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS \
SQLITE_OMIT_SHARED_CACHE \
SQLITE_OMIT_SHUTDOWN_DIRECTORIES \
SQLITE_OMIT_SUBQUERY \
SQLITE_OMIT_TCL_VARIABLE \
SQLITE_OMIT_TEMPDB \
SQLITE_OMIT_TEST_CONTROL \
SQLITE_OMIT_TRACE \
SQLITE_OMIT_TRIGGER \
SQLITE_OMIT_TRUNCATE_OPTIMIZATION \
SQLITE_OMIT_TWOSIZE_LOOKASIDE \
SQLITE_OMIT_UPSERT \
SQLITE_OMIT_UTF \
SQLITE_OMIT_VACUUM \
SQLITE_OMIT_VIEW \
SQLITE_OMIT_VIRTUALTABLE \
SQLITE_OMIT_WAL \
SQLITE_OMIT_WINDOWFUNC \
SQLITE_OMIT_WSD \
SQLITE_OMIT_XFER_OPT \
]
set ::ENABLE_SYMBOLS [list \
SQLITE_ALLOW_ROWID_IN_VIEW \
SQLITE_DISABLE_DIRSYNC \
SQLITE_DISABLE_FTS \
SQLITE_DISABLE_INTRINSIC \
SQLITE_DISABLE_LFS \
SQLITE_DISABLE_PAGECACHE_OVERFLOW_STATS \
SQLITE_DISABLE_SKIPAHEAD_DISTINCT \
SQLITE_ENABLE_API_ARMOR \
SQLITE_ENABLE_ATOMIC_WRITE \
SQLITE_ENABLE_BATCH_ATOMIC_WRITE \
SQLITE_ENABLE_BYTECODE_VTAB \
SQLITE_ENABLE_CEROD \
SQLITE_ENABLE_COLUMN_METADATA \
SQLITE_ENABLE_COLUMN_USED_MASK \
SQLITE_ENABLE_COMMENTS \
SQLITE_ENABLE_CORRUPT_PGNO \
SQLITE_ENABLE_COSTMULT \
SQLITE_ENABLE_CURSOR_HINTS \
SQLITE_ENABLE_DBPAGE_VTAB \
SQLITE_ENABLE_DBSTAT_VTAB \
SQLITE_ENABLE_EXPENSIVE_ASSERT \
SQLITE_ENABLE_EXPLAIN_COMMENTS \
SQLITE_ENABLE_FTS \
SQLITE_ENABLE_GEOPOLY \
SQLITE_ENABLE_HIDDEN_COLUMNS \
SQLITE_ENABLE_ICU \
SQLITE_ENABLE_ICU_COLLATIONS \
SQLITE_ENABLE_INTERNAL_FUNCTIONS \
SQLITE_ENABLE_IOTRACE \
SQLITE_ENABLE_LOAD_EXTENSION \
SQLITE_ENABLE_LOCKING_STYLE \
SQLITE_ENABLE_MATH_FUNCTIONS \
SQLITE_ENABLE_MEMORY_MANAGEMENT \
SQLITE_ENABLE_MEMSYS \
SQLITE_ENABLE_MODULE_COMMENTS \
SQLITE_ENABLE_MULTIPLEX \
SQLITE_ENABLE_MULTITHREADED_CHECKS \
SQLITE_ENABLE_NORMALIZE \
SQLITE_ENABLE_NULL_TRIM \
SQLITE_ENABLE_OFFSET_SQL_FUNC \
SQLITE_ENABLE_OVERSIZE_CELL_CHECK \
SQLITE_ENABLE_PREUPDATE_HOOK \
SQLITE_ENABLE_QPSG \
SQLITE_ENABLE_RBU \
SQLITE_ENABLE_RTREE \
SQLITE_ENABLE_SELECTTRACE \
SQLITE_ENABLE_SESSION \
SQLITE_ENABLE_SETLK_TIMEOUT \
SQLITE_ENABLE_SNAPSHOT \
SQLITE_ENABLE_SORTER_MMAP\
SQLITE_ENABLE_SORTER_REFERENCE \
SQLITE_ENABLE_SORTER_REFERENCES \
SQLITE_ENABLE_SQLLOG\
SQLITE_ENABLE_STAT \
SQLITE_ENABLE_STMT_SCANSTATUS \
SQLITE_ENABLE_STMTVTAB \
SQLITE_ENABLE_TREETRACE \
SQLITE_ENABLE_UNKNOWN_FUNCTION \
SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION \
SQLITE_ENABLE_UNLOCK_NOTIFY \
SQLITE_ENABLE_UPDATE_DELETE_LIMIT \
SQLITE_ENABLE_URI_00_ERROR \
SQLITE_ENABLE_VFSTRACE \
SQLITE_ENABLE_WHERETRACE \
SQLITE_ENABLE_ZIPVFS \
]
# Process any command line options.
process_options $argv
if {[info exists ::SYMBOL] } {
set sym $::SYMBOL
if {[lsearch $::OMIT_SYMBOLS $sym]<0 && [lsearch $::ENABLE_SYMBOLS $sym]<0} {
puts stderr "No such symbol: $sym"
exit -1
}
set dirname "test_[regsub -nocase {^x*SQLITE_} $sym {}]"
run_quick_test $dirname $sym
} else {
# First try a test with all OMIT symbols except SQLITE_OMIT_FLOATING_POINT
# and SQLITE_OMIT_PRAGMA defined. The former doesn't work (causes segfaults)
# and the latter is currently incompatible with the test suite (this should
# be fixed, but it will be a lot of work).
set allsyms [list]
foreach s $::OMIT_SYMBOLS {
if {$s!="SQLITE_OMIT_FLOATING_POINT" && $s!="SQLITE_OMIT_PRAGMA"} {
lappend allsyms $s
}
}
run_quick_test test_OMIT_EVERYTHING $allsyms
# Now try one quick.test with each of the OMIT symbols defined. Included
# are the OMIT_FLOATING_POINT and OMIT_PRAGMA symbols, even though we
# know they will fail. It's good to be reminded of this from time to time.
foreach sym $::OMIT_SYMBOLS {
set dirname "test_[regsub -nocase {^x*SQLITE_} $sym {}]"
run_quick_test $dirname $sym
}
# Try the ENABLE/DISABLE symbols one at a time.
# We don't do them all at once since some are conflicting.
foreach sym $::ENABLE_SYMBOLS {
set dirname "test_[regsub -nocase {^x*SQLITE_} $sym {}]"
run_quick_test $dirname $sym
puts "make tidy sqlite3.lo $opts"
if {[catch {exec make tidy sqlite3.lo $opts >& $logfile}]} {
puts "BUILD FAILED: see $logfile for details"
if {[info exists FailIsOk($sym)]} {
set Failure($sym) 1
} else {
puts "Note: After fixes, continue the test using:\n"
puts " [info nameofexe] $argv0 --start $sym\n"
exit 1
}
}
}
main $argv
if {[llength [array names Failure]]>0} {
puts "BUILD FAILED on the following:"
foreach sym [array names Failure] {
puts " * $sym"
}
}
+1 -1
View File
@@ -26,7 +26,7 @@
** the entire block.
**
** For blocks of more than 16 bytes, the signature is a hex dump of the
** first 8 bytes followed by a 64-bit has of the entire block.
** first 8 bytes followed by a 64-bit hash of the entire block.
*/
static void vlogSignature(unsigned char *p, int n, char *zCksum){
unsigned int s0 = 0, s1 = 0;
+1846
View File
File diff suppressed because it is too large Load Diff