Compare commits

..

420 Commits

Author SHA1 Message Date
drh 4fe1ac8fe1 Simplifications to the row-value IN operator logic. Do not let the query
planner accept a WhereLoop for a row-value IN operator that uses the same
index column more than once.

FossilOrigin-Name: d2adf61f21a3ce901a2b08199ad0de191e88ef16e097c5f7a75c95ad958eff12
2025-07-07 15:40:53 +00:00
drh 4aacd1ef8e Back out the fix at [ba7d5bad32ad6aac] because it does not always work and because
it causes a performance regression.  Add new test cases for row-value lookups of
indexes that contain redundant columns, three of which are currently failing.  This
branch is seeking an improved solution to the redundant index column problem for
row-value lookups.

FossilOrigin-Name: ad8ddcefab5cc526b1cd77731e00939c672e61ca83350d28961b67635d20da03
2025-07-07 10:54:00 +00:00
drh 0840460689 Fix parser error introduced by [325e547a2195571e]. See
[forum:/forumpost/095dbfc06e5b1f7e|forum post 095dbfc06e5].

FossilOrigin-Name: 4eefab44941fc6e17742fa49c8734e7f00a2177d82bc572e596228add53aad39
2025-07-07 02:18:27 +00:00
stephan 27408ab9c9 Add 'reconfigure' target to Makefile.in to re-run the configure script with the same flags it was generated with.
FossilOrigin-Name: c60907e77b32824aaaf024d299cdaf161b5f64fc927ffe5d5455eeb5754e6b01
2025-07-04 18:32:18 +00:00
stephan d9eae6b75a Propagate the -ldl and -lpthread flags, if needed, into sqlite3.pc, per request in [forum:44a58c807353162f | forum post 44a58c807353162f].
FossilOrigin-Name: 64f5f14322349b47451b8cac03bf8cd6f1ae45a8822e7f1ddee3d0b265047501
2025-07-04 17:20:37 +00:00
drh e33ea17d24 Fix harmless compiler warnings.
FossilOrigin-Name: 13af4acebe09b047756c22b800136cffaba532e7fcaa448a4edf4fedb94e9bbc
2025-07-04 12:25:24 +00:00
drh a12e92d2f7 Remove an ALWAYS() added by [960a8e6fc91f4] that turns out to be false
in some cases of malformed SQL.

FossilOrigin-Name: cc8171461bf35f584888a24b844c8b79ad30155b19b61161e9f3abc276e8aae5
2025-07-04 11:48:11 +00:00
dan bd05edd98f Fix a few cases where LIMIT clauses that were part of scalar sub-queries on virtual tables were not being passed to xBestIndex methods correctly.
FossilOrigin-Name: 960a8e6fc91f47add3a089dc6cef013109deadf809994c5149ad3bdfb3884de0
2025-07-03 16:05:41 +00:00
drh a24a397b8b Improvements to sqlite3_vtab_rhs_value() logging in the
ext/misc/vtablog.c extension.

FossilOrigin-Name: 25131ee84f53dab1191e02c19cefd256aed2828c7edea325fcc0ba3b0a668583
2025-07-03 15:50:18 +00:00
dan 0e6e05d4d5 Make the value of an explicit LIMIT clause on a scalar sub-query available to xBestIndex for simple "LIMIT 0" and "LIMIT 1" queries.
FossilOrigin-Name: 33b6a63caafccc61b3193714911cd8b5dd9b7f1798054b8c7845b23688d531f2
2025-07-03 15:32:27 +00:00
dan c525e6e817 Make handling of LIMIT clauses in correlated sub-queries on virtual tables more efficient.
FossilOrigin-Name: 7214cb2a5b35190a06a1040cd4c54f325d347f8d8e36a07fd76c0a421e266522
2025-07-03 14:28:47 +00:00
drh 1ff6f19d8b Enhancements to the xBestIndex output from the ext/misc/vtablog.c
extension.

FossilOrigin-Name: 8b31acc0b18f38eb4af6efebd1ea25cd65a146651101579aee20afd9ec6dc2de
2025-07-03 14:10:03 +00:00
drh bfb4993364 Fix an uninitialized variable added yesterday by [d27d34fb746280e7].
This problem was discovered overnight by 
[https://github.com/google/oss-fuzz|OSSFuzz].

FossilOrigin-Name: 6db4703f1178fc808f3a75c355fb6638fb12c88f6e1ce7f579e200ced8089114
2025-07-03 11:52:17 +00:00
drh 6245e5a46b Improve the bytecode for joins such that it exits earlier if it determines
that no output is possible.

FossilOrigin-Name: 2d2b61cba44a756a3a41ef5c95bbb0c0b7111f4b679c578fec9bd0b214cca367
2025-07-02 11:47:54 +00:00
drh caf0473652 Ensure that Expr.op2 values for TK_AGG_FUNCTION nodes are adjusted when
query flattening.

FossilOrigin-Name: d27d34fb746280e7e81335db4e195914b15403ef0da7b2955550553dd78fbe9a
2025-07-02 02:03:43 +00:00
drh 2427ce16d9 Improved comments on bytecode used to implement aggregate queries, to aid
in debugging.

FossilOrigin-Name: a1a8b85cdba64a17dcdcd4e6b42b872957cec2dc05b0ac34dfcd82f59344034b
2025-07-01 23:17:36 +00:00
drh 46bfcc1a21 Improved byte-code comments for the short-circuit optimization of
[0083d5169a46104a], to aid in debugging.

FossilOrigin-Name: 113f9d10e347eeaa893ff8b47a461009e0b12589374b93cf3e0bddd19c702dea
2025-07-01 20:32:45 +00:00
drh 5e71497404 Cache and reuse virtual table cursors in the bytecode engine.
FossilOrigin-Name: 2d187d4232d750cb1840f1d89c8aed65962cb0883c1d7f91c554b451e475c514
2025-07-01 17:36:55 +00:00
dan 526399b0fd Avoid an assert() failure in fts5 that may occur when processing corrupt records.
FossilOrigin-Name: 8afd6ca85724a69970181042d6aac53742ea2b76ded5966b2541c3afe1121fb9
2025-07-01 16:21:47 +00:00
drh e1910ed1d2 Merge trunk fixes into the empty-table-optimizations branch.
FossilOrigin-Name: 63306e447efb3ac17e789a331ed3bb65459eb8b79d66e9c185ba3bd852f34ce3
2025-07-01 15:13:37 +00:00
drh d82c6a2cf7 When attempting to optimize "expr AND false" to "false" and
"expr IN ()" to "false", take care not to delete aggregate functions
in the "expr" as doing so can change the meaning of the query.
See [forum:/forumpost/f4878de3e7dd4764|forum thread f4878de3e7].

FossilOrigin-Name: 77397bd67d918db57d5ac545d6d963194806fdabcdaa8f822b6b09e4cfe8b715
2025-07-01 12:43:13 +00:00
drh 3d21dcc924 More aggressive optimization of addrHalt for RIGHT JOIN.
FossilOrigin-Name: 5e51d1c0dfcafef9e71c99de3f626dee157c935724b84c6e0c630299a880446f
2025-06-30 21:07:08 +00:00
drh ba56f7020d Compute WhereLevel.addrBrk and .addrHalt early so that those labels can be
used to abort loops early.  Use this to improve performance on two more
of the cases described by [forum:/forumpost/52651713ac|forum post 52651713ac].

FossilOrigin-Name: 6fc0b9ac23be6840542982de4bb282ebca1db8b5ab3baefdde95a997c1506e81
2025-06-30 20:19:19 +00:00
drh 99f1aa03fb Strive to skip the evaluation of scalar subqueries that are part of a
larger expression if the result from the scalar subquery does not change the
result of the overall expression.

FossilOrigin-Name: 0083d5169a46104a25355bdd9d5a2f4027b049191ebda571dd228477ec217296
2025-06-30 16:41:40 +00:00
drh 280559b446 For all binary operators, try to avoid computing subquery operands if the
other operand is NULL.

FossilOrigin-Name: d86eb16283c4b573c506d4faa422d5d9aeb6abc279d8e6a8e2104737162d417f
2025-06-30 12:14:47 +00:00
drh e2e81e6983 Slightly smaller and faster version of the previous check-in.
FossilOrigin-Name: f6e6fd02f4ad49c390a2d3c9626d57f9b2fff1f67eb361b30074cc1f5121810e
2025-06-30 11:04:55 +00:00
stephan b8c81790b2 Minor API doc typo fixes from brickviking.
FossilOrigin-Name: b48d95191662e09659b5b55ae65cd462c9e1700c4f92dd9d40b59548f0797c02
2025-06-30 11:00:59 +00:00
drh e24f20a4f5 Factor out the code that tries to avoid evaluating subquery operands if the
other operand is NULL into a subroutine, so that it can be more easily reused
by other parts of the code generator.

FossilOrigin-Name: 3c6c71bcea16443b82234414137dfa1b59e2ee8fe5097906c738fc1228fec4e6
2025-06-30 10:30:47 +00:00
stephan f0991c416b Minor API doc typo fixes from brickviking.
FossilOrigin-Name: c7cf9dcb69ce558ba6b81b2787f92ed7383e37f08b199faeb14f7adb4e494532
2025-06-29 07:32:20 +00:00
drh 311d73efc2 Improve the bytecode generated for comparisons so that if one operand is
a subquery and the other operand evaluates to NULL, the subquery operand
is not even computed.  This fixes 5 of the 12 slow queries described
in [forum:/forumpost/52651713ac|forum post 52651713ac].

FossilOrigin-Name: f147bc04776ac0056412f69dfc518016c0d5b4e9d964664e3d88f595fb29dbe0
2025-06-28 17:59:15 +00:00
drh c52e9d97d4 Raise an error right away if the number of aggregate terms in a query
exceeds the maximum number of columns.

FossilOrigin-Name: 5508b56fd24016c13981ec280ecdd833007c9d8dd595edb295b984c2b487b5c8
2025-06-27 19:02:21 +00:00
stephan fbf1c0526e API doc typo fixes and closing DD element tags from brickviking.
FossilOrigin-Name: c9ddd15b0197e6e5c5a74581d94cf986523514ffdb28c66ba18de9a22aec97e9
2025-06-27 12:46:50 +00:00
drh e77e589a35 Work around an apparent GCC UBSAN bug. See
[forum:/forumpost/1d7c25d4a2d6f5e2|forum thread 1d7c25d4a2d] for details.

FossilOrigin-Name: 23056532e51abcff486e38a3319545e6663b4a855abe1bc443e2cd7e0473748c
2025-06-26 18:57:20 +00:00
stephan 981022b7ff Minor API doc fixes sent off-list from brickviking.
FossilOrigin-Name: cb4d05633a0c9cdf146f3108e1b4b10754cd79d72a425d8cc9cd21836037a01b
2025-06-25 20:42:40 +00:00
drh a67c71224f Similar fix to the previous check-in, but this time for
sqlite3_preupdate_new().

FossilOrigin-Name: 9aaff764d508cbd9823f23cdf0c510255721bc5c09be481ebc60bd8902ceb8c5
2025-06-24 18:27:59 +00:00
drh 66cd200ede Range check the column index on the sqlite3_preupdate_old() interface
and return SQLITE_MISUSE if too large.
[forum:/forumpost/b617e497287235d0|Forum post b617e49728].

FossilOrigin-Name: 6a5701e6c7be25cba93e55438f950966e1dacb32eb2b23a8acc8ac53da6f0a85
2025-06-24 15:58:32 +00:00
stephan 513fff88c4 API doc typo fixes and one rephrasing improvement from brickviking.
FossilOrigin-Name: 85e8060c4701a601d4bc8a639acd268ee4f2736193820d55ecd9b8abf864132f
2025-06-24 07:38:52 +00:00
dan fe182f74b2 Improve some of the error messages emitted by fts5 when it encounters corruption.
FossilOrigin-Name: 48044a6b57c0a16cb75139c103ad88ca4ab64d74f70a3dee0d8b817fbfbec3c6
2025-06-23 19:38:22 +00:00
drh b1560be826 Fix an SQL typo introduced by the previous check-in.
FossilOrigin-Name: 72a81d247bc74a21d077d311969ac585d0f26bffbd210ec60f03c38bf138790e
2025-06-23 19:00:30 +00:00
drh 28789029ee Escape the "_" character in LIKE patterns in the CLI.
[forum:/forumpost/6a89702f5d|Forum post 6a89702f5d].

FossilOrigin-Name: cf61cd359e666c66b6bba4407a653c799f7f07e1f5ee6b837ad467029c461a6a
2025-06-23 16:51:33 +00:00
drh f453e8d84e Fix a harmless compiler warning injected by [c978aed3b6f82b3d].
FossilOrigin-Name: f46500247b3a2f8b4a2f0f032cc4066af9cb3918e38a09c59db0a1da5747a25c
2025-06-23 13:42:59 +00:00
drh 4c1c400d64 Improved "statement aborts at ..." log-file messages that identify the
trigger that caused the abort.

FossilOrigin-Name: 7691264fe37300c880d612c91cf093327841fbe85fb7ec67e777e911d2cfc9ee
2025-06-23 13:28:13 +00:00
stephan 87c807c6dd Add the --disable-rpath configure script flag to address [forum:13cac3b56516f849 | forum post 13cac3b56516f849].
FossilOrigin-Name: a59d9bb25e518f5d79f654615b92f6c50cfb704b5abee0f820912644b89366c5
2025-06-22 22:48:11 +00:00
stephan b5aa9593ac API doc typo fixes from brickviking.
FossilOrigin-Name: 18e07f8f53693d0dace3c4025a572c1a10582290a338aa7f0913c83842a69b05
2025-06-22 12:04:47 +00:00
stephan 5806a922ba Minor JS test cleanups prompted by a linter.
FossilOrigin-Name: 764235a3d15fda55af85ebe3b5885fa27336cc0e979f1be2f6770b66a84bbe87
2025-06-21 16:33:05 +00:00
stephan 427d2cd57d Remove some duplicated JS tests.
FossilOrigin-Name: d1cb9ed79d806f667c22f5ba9861451d4d0765aa3072e085831045cf3a39f8b4
2025-06-21 16:18:23 +00:00
stephan db37e6097c Reduce the maximum --size flag for JS kvvfs speedtest1 from 4 to 2, as --size 3 and 4 are overflowing the kvvfs storage limits.
FossilOrigin-Name: b77b3adc828ce543e880e230701edd5e0ccb681e4c3c724ea8ad5ecbd69c73a6
2025-06-21 16:02:20 +00:00
stephan 6fcb7f22a1 Give oo1.Stmt.get() similar treatment to [8c187140a60b]. This is an internal change only - the API is unaffected.
FossilOrigin-Name: f5a7abc0a447273de40dacc463d267d26d4b62be56ee15baf05825791c2a7a6e
2025-06-21 15:58:20 +00:00
stephan 2f7f948fa7 Extend the SEE-via-kvvfs tests to include all three key types.
FossilOrigin-Name: fc001aa5ee978795c2ff670bea64db0b69b6bde98653769d9cede8825a28e698
2025-06-21 15:38:59 +00:00
stephan 0cdde5b44f Rework how JS's oo1.DB.exec() flags its Stmt objects to make certain Stmt APIs illegal (i.e. throwing) if called while that Stmt is being step()ped by DB.exec() (which can happen via client-provided per-result-row callbacks). This is an internal change only - the API is unaffected. Remove some unrelated dead code.
FossilOrigin-Name: 8c187140a60b62dc3b6066b8615766d52b7a29a5de992cbb6d312dbb225a980b
2025-06-21 14:38:53 +00:00
stephan a0c6de56ba Numerous small doc typo from BrickViking.
FossilOrigin-Name: 3aab4415de615c178205936372c625bb571bad1016c3d2e7bb2a45932356f3d6
2025-06-21 06:07:13 +00:00
drh b68d63158a Enhance sqlite3BtreeSetPageSize() so that it detects early if no changes
are needed and exists with SQLITE_OK.

FossilOrigin-Name: c978aed3b6f82b3d9d2e0ca0283c611351bca5e5496e86a9d5d0731ebcd27c84
2025-06-20 13:12:55 +00:00
drh 59de42763f Fix an out-of-order local variable declaration in ext/misc/fileio.c.
FossilOrigin-Name: a88bb75288a06492a04ab1278e8a2101a74f4ba712d328b4c73e86ac01cb946d
2025-06-19 20:19:12 +00:00
drh 37794b4ad0 Improve the accuracy of sqlite3BtreeRowCountEst().
FossilOrigin-Name: e553fb538ec1527457e2927edf9127dccf268a8a3b5918d4fb0d066ad9676094
2025-06-19 20:00:37 +00:00
drh 397b82cf0f Generalize the indexCellCompare() so that works on any index page, not just
the current page that a cursor is pointing to.

FossilOrigin-Name: b305a7f5db183d8e0e5d62ca3c9c6260ad94bb954f7342bd3caabcd8308a21f5
2025-06-19 19:33:06 +00:00
stephan 92d1bec584 A slight doc rephrasing for clarity, suggested in the forum.
FossilOrigin-Name: 0d6084a398edb013fcfb613eff8d75e2f86cbb5e3c8049328ede89e75db93cb3
2025-06-19 12:35:30 +00:00
stephan a5c484b432 Doc typo fixes from [forum:0bce273669 | forum post 0bce273669].
FossilOrigin-Name: 8f97e3f00d24b26fe87a9d3396ad855277a1a369f6f89e9c77dc9af4d203bdf1
2025-06-19 10:46:39 +00:00
stephan 64159096b8 Expose the column metadata APIs to WASM (which does not require a non-default sqlite3.c build, contrary to my prior mistaken claims). This adds only 424 bytes to sqlite3.wasm and 660 bytes to sqlite3.js.
FossilOrigin-Name: 3cf983816ccd167d93cb39c7a16b6db4b4f7ef2a64f4181d3bc4530cd0bd3b67
2025-06-19 10:25:50 +00:00
drh ab9c91ae82 Extend the pedantic enforcement of type to VIRTUAL columns.
FossilOrigin-Name: b734c74e55acb26eb61b60937bef870f4b55b2e2e7560a22362f5f31ba2fcd03
2025-06-18 19:04:28 +00:00
drh bcf25e7129 Enforce judgmental typing on STORED generated columns for STRICT
tables.  [forum:/forumpost/6caf195248a849e4|Forum post 6caf195248].

FossilOrigin-Name: 5e9279bff0482806f86657ae05ca3e916708d138bc3c3ceb3fbf454818649d44
2025-06-18 16:17:00 +00:00
stephan 2be0a700ff Export the column-metadata APIs to WASM. Doing so requires a non-default build of sqlite3.c, so this is a proof-of-concept branch saved just in case SQLITE_ENABLE_COLUMN_METADATA ever becomes the default for sqlite3.c.
FossilOrigin-Name: 59db3f639d1073678805dea26a4686eddfb238f055aa90bd429fc7fd33241502
2025-06-18 15:37:04 +00:00
stephan 3a26f72e20 Add the --enable-column-metadata flag to the configure script (off by default). It's only available in the canonical build, not the autoconf build, because it changes how sqlite3.c gets generated.
FossilOrigin-Name: 986b601db11a041d280eb61004723604bf4b6fd573b9832c97e3a9da9ea16e9a
2025-06-18 15:22:50 +00:00
stephan d961d49971 Eliminate configure/build discrepancies in how 'make tclextension-...' works vs other makefile-side handling of the extension, conforming to the former.
FossilOrigin-Name: 7ca545fd3b460fcf92e117baef42655eb6e78ebb5bdc6302f8f1b5b8446c0a06
2025-06-18 14:17:18 +00:00
drh 9a9140ba59 Change the definition of SQLITE_DYNAMIC to a function that has exactly
the same type as sqlite3_destructor_type, in an effort to work around
possible legacy compiler bugs.

FossilOrigin-Name: 83553edf78c35d171a0ddf1a51306e963d715e56d95b8159b561b729cfb27843
2025-06-18 14:14:46 +00:00
stephan 12bd8ea09a Add the --tclConfig.sh FILE flag to buildtclext.tcl to eliminate the discrepancy between the configure-time-detected tclConfig.sh and the one auto-detected by the tclextension family of makefile targets. Add the tclextension-all target to run all of the various tclextension-... targets in their natural order to facilitate testing changes like this one. Update the --help text to note that --with-tclsh should only be used if there's a specific need, and that --with-tcl is generall preferred. This is in response to [https://github.com/termux/termux-packages/issues/23268 | Termux ticket 23268].
FossilOrigin-Name: 928976abcb11f9d5abe1f7631002592c4af7bf83ecadba5b0763866d039c2270
2025-06-18 11:11:30 +00:00
stephan 1e9baaf743 tea: remove the vsatisfies 8.6- enforcement from the extension because at least one platform with tcl 8.6 is inexplicably failing it. [forum:fde857fb8101a4be | Forum post fde857fb8101a4be]
FossilOrigin-Name: 7331e32a76a8a41cc1bd1c84069219c9929e0e0f941c1d9e308cbbb7959373c5
2025-06-17 20:50:51 +00:00
drh df8aa3745a Avoid writing frames with no checksums into the wal file if a
savepoint is rolled back after dirty pages have already been
spilled into the wal file.

FossilOrigin-Name: 5973f9b9aa828ec9274b02a124b95f452c58235eaafffbdda1c32b4ae2d5616d
2025-06-17 19:10:33 +00:00
drh 110055cd6c Fix a corner-case for [9441fff52cc4e19c].
FossilOrigin-Name: 336a59eb3afd80ce048de472368df6dfc32934ee783859d37663ed8f5cf169a5
2025-06-17 18:57:07 +00:00
dan 79a746b1f2 Update walcksum.test so that it works with SQLITE_DEFAULT_AUTOVACUUM=1 builds.
FossilOrigin-Name: 0da16f6c625bff9f2ca5624afa6dce6b5a157f44c1d56b25b92946c13217ab02
2025-06-17 18:17:09 +00:00
stephan 9ebf9d358b Extend [b5c6cb13cff5] to use a wildcard on darwin* because some OSes report a version number in the suffix. [forum:0c4bbc2962dfb06e | Forum post 0c4bbc2962dfb06e].
FossilOrigin-Name: d960bd6f9256410ebc98125b0567380457e39bc8fe768fcd9ea05c6de1994df6
2025-06-17 17:15:12 +00:00
stephan e68aa0e44b Minor proj.tcl portability fixes and cleanups suggested in [forum:7b218c3c9f|forum post 7b218c3c9f]. Tested on Linux, Msys, Cygwin, and Haiku.
FossilOrigin-Name: b5c6cb13cff53f4ba1e0e6a0d61389252bd004d9099727e7a9304217e3f81d80
2025-06-17 14:56:30 +00:00
stephan 6e1c2f0483 proj.tcl portability fixes and cleanups suggested in [forum:7b218c3c9f|forum post 7b218c3c9f]. Branching so that it can be tested on msys/cygwin/haiku before committing to it.
FossilOrigin-Name: 89552e9137b7ebba9600443720e936e8dc4f7ab021d2ac3f0bb01b74071e130c
2025-06-17 14:37:31 +00:00
dan 1ea6a53762 Avoid writing frames with no checksums into the wal file if a savepoint is rolled back after dirty pages have already been spilled into the wal file. Possible fix for [forum:/forumpost/b490f726db | forum post b490f726db].
FossilOrigin-Name: 3a3269fe8e925a522d5df9f011220a842fb15a9f56e785884e32d2e15abda5bb
2025-06-17 11:36:39 +00:00
drh 86d9c2d9f3 Fix an issue going back to version 3.39.0 with transitive IS constraints
in queries that make use of RIGHT JOIN.  Problem reported by
[forum:/forumpost/68f29a2005|forum post 68f29a2005].

FossilOrigin-Name: 9441fff52cc4e19c44df1a77ffe474f409d519b270c7166ce17f99e6ea48fc1e
2025-06-16 17:36:11 +00:00
drh d3a13f7d25 Improved debugging output for the transitive constraint optimization.
FossilOrigin-Name: 94b53c20e9bc8687c44272419aa7a93076eebdeae9a4f50b95b96a49993f9c0d
2025-06-16 16:07:14 +00:00
drh 6ed5aa4b9b Make the show-%p-az-zero hack of the previous check-in configurable at
run-time using the 0x100000 bit of either .treetrace or .wheretrace.
As before, this is all a no-op except for debugging builds.

FossilOrigin-Name: a29627d7e7f8344d9a099cc133bda85250b02dc5ee5f358ba59691e0816b5b2d
2025-06-16 15:34:26 +00:00
drh 67f708298f Add an "#if 0" that can be changed to "1" to cause all %p output to render
as 0, thus making comparisons of .treetrace and .wheretrace output easier.

FossilOrigin-Name: 65e2704c0bc329f3dd248548a2d4edb7d3ace8ceaf0b82b8618b9b1b764884cd
2025-06-16 13:51:09 +00:00
dan 792d1d1b6d Have sqlite3_setlk_timeout() take the database handle mutex. This fixes an assert() failure that could occur if sqlite3_setlk_timeout() were called on a threadsafe handle.
FossilOrigin-Name: a95d126e1330e1b83f42b51f97c4c216622cf38062f3b5d72ccb76313187e850
2025-06-12 07:35:38 +00:00
dan 6a5e74cbf0 Fix a problem with UPDATEs on fts5 tables that contain blob values.
FossilOrigin-Name: badf3014bd1620fd3d4b8013f641fd820b249649fb93cc75b7b8df9dfd6f32a6
2025-06-11 15:03:53 +00:00
drh 23e59b34e9 Fix the concat_ws() SQL function so that it includes empty strings in the
concatenation.  [forum:/forumpost/52503ac21d|Forum post 52503ac21d].

FossilOrigin-Name: 80a78987da484d435a8242c05c48d546d430920df713b24a9d9d9fff7ba1113d
2025-06-11 00:01:42 +00:00
drh a09a4fbac9 Improved selection of the divisor when subdividing nested Bitvec objects.
This fixes a potential stack overflow that can occur when the database size
is within 60 pages of the maximum allowed by the file format.

FossilOrigin-Name: f7ab764ed9df6d7a4a96cb0933d291f00174f33fed3d9951785078fe225adcb7
2025-06-10 19:52:21 +00:00
drh 6a23ff5a07 Minor corrections to the new Bitvec testing logic.
FossilOrigin-Name: 77b79ca1277419b91589aff2c601d4abdd7107d48019a58f7f7c85d96c2a538e
2025-06-10 18:26:09 +00:00
drh 5706b316c3 Enhancements to sqlite3BitvecBuiltinTest() that allow testing code to
create very large Bitvec objects that do not use the linear array cross-check.

FossilOrigin-Name: c5680672cae23f65637eebf66f3bb983a2864be03ea70378832034f3c89ef728
2025-06-10 17:22:53 +00:00
drh 90ba0d4995 Improved diagnostics for Bitvec: Add the sqlite3ShowBitvec() routine that
can be called from a debugger (only available with SQLITE_DEBUG).  Add new
output opcodes for sqlite3BitvecBuiltinTest().

FossilOrigin-Name: dea1e37fa67ada6efc1533b449d9eb22338d9e58eec8f89b48c38319c212c8f4
2025-06-10 16:02:29 +00:00
drh f091f423ad Adjustments to ext/misc/fileio.c in an attempt to get it to build using mingw.
FossilOrigin-Name: 96b14a3f1193de8f30e9fa704f87558dab8027a218868d32e47688cd5df497b7
2025-06-09 22:38:34 +00:00
drh 4c323ba4be Remove unnecessary whitespace and otherwise improve comments in the
wherecode.c module.  No coding changes.

FossilOrigin-Name: 2eb4e9bf0f2df50324a62fb272a92bbd931b8b4e4b35bac0c05b676c97b61339
2025-06-06 23:10:18 +00:00
drh 368c549044 Update the "msort" function in Lemon so that it works with lists of any
length, and also so that the sort is stable.  This patch was motivated by
[forum:/forumpost/63750d717c9ed961|forum post 63750d717c] but was
independently developed, then tested by temporarily setting LISTSIZE to 2.

FossilOrigin-Name: aba5c3135edf7de2798ad808fa0ff176fdba3f4a9b101f1f4210b441cba8e75d
2025-06-06 23:02:03 +00:00
drh b1929b7117 Remove the clunky test_windirent.h and test_windirent.c files from src/
and replace them with a much cleaner and more compact ext/misc/windirent.h.

FossilOrigin-Name: acc978df52ec41ffdb5c27764f30d53efa1f25a314b7d98983dc0d211a36b570
2025-06-05 20:12:41 +00:00
drh 6facd9566d Enhance the FSDIR virtual table with a new "level" column. The query planner
knows how to optimize to avoid search deeper than the maximum requested level.

FossilOrigin-Name: 1ddc0f9e79c33957961bc1443ccb74d756a02cbd20850052079782e76aef2706
2025-06-05 18:28:54 +00:00
stephan 26370358b6 tea build: add an info-exists check after a 'scan' call, as scan does not create its target vars on error. Problem reported at [forum:fde857fb8101a4be | forum post fde857fb8101a4be] and triggers when the 'vsatisfies' test for the host's Tcl version fails (so the build would fail anyway, but will fail more informatively with this fix).
FossilOrigin-Name: 4f21874d5d20aef2e2d67a59e4fa03d98aa6514b16e4d956acfc817142cfbdb6
2025-06-04 18:34:20 +00:00
stephan a29b138692 Apply the duplicate 'export default' workaround to the (untested and unsupported) node-specific build rules in mkwasmbuilds.c to resolve a problem reported off-list by Thomas Steiner.
FossilOrigin-Name: 2f8a1b79533879e4975b405c46fea496ba8bffbef065e7dd0ad29fd4aa8f8f92
2025-06-03 18:10:59 +00:00
drh 1d151e6d25 Enhance sqlite3_rsync so that it works even if the replica database is
initially malformed.

FossilOrigin-Name: ea1754f7d8a770477a1b19b606b27724fdc0b733e51fef32c1ef834f972c3cc5
2025-06-03 10:49:51 +00:00
drh df724c893a Fix an off-by-one error in sqlite3_rsync, reported in
[forum:/forumpost/b6d78f60fc|forum post b6d78f60fc].

FossilOrigin-Name: 27d9e8e79b921c4a86916556f3bf56b94684a7e3d40166c0fdaaf750d4011de0
2025-06-03 10:28:47 +00:00
drh 140748f949 Fix harmless compiler warning introduced by the setlk-snapshot-fix merge.
FossilOrigin-Name: c1f20f89d9eb3e1dd1018c0e0efe5d3043a592f078e235ad04b960334c7186c2
2025-06-03 10:18:54 +00:00
drh 2bd9f69d40 Fix JSONB edit so that when it is trying to reduce the size of an element
it understands 0xf0 (8-byte) sizes.

FossilOrigin-Name: 5b3de6e8ab6b228bf6c0e0c31b50ca29d8b7852b460eaaca6c6ecf5a3c083cab
2025-06-02 23:34:42 +00:00
drh 333b07b18d Increase the version number to 3.51.0
FossilOrigin-Name: ed69d4432712603bea2161e0ca0c99e59480fb000e1cbf1aa1401d924544e351
2025-06-02 18:58:42 +00:00
dan 9269b212bf Fixes to ensure SQLITE_ENABLE_SETLK_TIMEOUT builds use a blocking lock and do not call xSleep() when (a) opening a snapshot transaction, and (b) when blocked by another process running recovery.
FossilOrigin-Name: 7f9c0cdd0630a41db359b188b226a1ad6a3bae1663c27169acfe25edc7fb171b
2025-06-02 18:48:36 +00:00
dan 69ce758efa Fix os_win.c so that SQLITE_ENABLE_SETLK_TIMEOUT=2 builds work on windows.
FossilOrigin-Name: 8efb95e0d4670b9c5dbd8cf34512334f47951a8dff8fdadc8645f75076acd91f
2025-06-02 18:37:32 +00:00
drh 342ef63e63 Improve the accuracy of affinity and collating sequence analysis for
NATURAL JOINs to the left of RIGHT JOINs where source tables are views
or subqueries.  Initial problem report in
[forum:/forumpost/829306db47|forum post 829306db47].

FossilOrigin-Name: f184d1d236e47962658a4639d9533f67a525b74cfe0f06c93e9b85fdcd02a15f
2025-06-02 18:34:17 +00:00
dan cfee69fbe4 Updates to new test cases to run with SQLITE_ENABLE_SETLK_TIMEOUT=2 builds.
FossilOrigin-Name: c6d3e3542fdf6a3428d3a2ec20c699c169ed53341dc782d81f7fe5944f769748
2025-06-02 18:09:46 +00:00
dan eb9a145711 Merge trunk changes into this branch.
FossilOrigin-Name: 7d27451804e525190f8e67da75aaeb3bf2de677021f7566c6681398e60a88c72
2025-06-02 17:44:10 +00:00
stephan d84bbac8be Slight modernization of the TEA README.txt.
FossilOrigin-Name: bf7be67e3fb7b75fc281997f7bf9aa69eaf4da6bdf2fefe359b12d25ec95f512
2025-06-02 15:17:59 +00:00
stephan a3fcd7c79e TEA: remove the stale man page and references to the MSC makefiles from the README.txt. Based on discussion at [forum:87e6660191a472c5 | forum post 87e6660191a472c5]. A couple of weeks ago we internally discussed pulling in the MSC makefiles from the 3.49 tree but they are stale and possibly unused, so opted against it for the time being.
FossilOrigin-Name: c9888a409565e6c8891a3dafa56962df364fb729a61df2701dc0bb282e36fb75
2025-06-02 15:10:41 +00:00
drh 8658a8df59 Remove an unnecessary parameter from sqlite3VdbeRecordUnpack(). Improved
comments and assert()s on KeyInfo.

FossilOrigin-Name: 387f4c4d98b8fb83f6ae406e4143dabda7766e8752b7f6ca104655e51330c978
2025-06-02 13:54:33 +00:00
drh 7590bfd7fc Fix stale comments related to KeyInfo. Add new assert()s associated with
memory management of KeyInfo.

FossilOrigin-Name: abd805bc76f14ede7359b029908179b7ca57e929c5918acae1403ef73ae0bd47
2025-06-02 09:49:07 +00:00
drh d4c224b833 Fix an off-by-one error in the size computation of a vdbe-sorter.
[forum:/forumpost/c1cc8b057a|Forum post c1cc8b057a].
Problem introduced by checkin [d4307a0d43f42e96].

FossilOrigin-Name: 8b7a7fcf62e5c2742c243808fa482472954f2b4aae0bc7ae513bc07065c93737
2025-06-01 21:38:35 +00:00
drh f18bf8997b Fix VACUUM so that it works even when ATTACH_WRITE is disabled.
FossilOrigin-Name: 42494f85acb303919d3f1f2202f8b95fbd657652da4b8dc00451c10ea6c496e0
2025-06-01 16:10:25 +00:00
drh c0190101d1 Enhance "box" and "column" mode formatting in the CLI to better deal with
double-wide characters.

FossilOrigin-Name: b0de22ed0abf2ea5d269f191c884d7b2be167a2ed27018c25aaa0ea238cd621a
2025-05-31 20:51:42 +00:00
dan 977b0f8813 Update a few test scripts so that they run on windows.
FossilOrigin-Name: 14a18f4e3a3f35e636262a253364ab1e8054ed38c0c7fd482633522cbcf5ffc4
2025-05-31 19:55:07 +00:00
drh 0d3e5ca28e New makefile target "xdevtest" works like "releasetest" except that it
omits the "verify-source" dependency so that it can be run with uncommitted
changes in the source tree.

FossilOrigin-Name: 1afb1ac3e9f0a122f1374799c09b60a0dd5443434d4567d94385096ada91bf12
2025-05-31 18:26:37 +00:00
dan 51e3f855b8 Fix an affinity problem caused by a USING or NATURAL JOIN on the LHS of a FULL JOIN. [forum:/forumpost/5028c785b6|Forum post 5028c785b6].
FossilOrigin-Name: 8d393ca07fe09f48d77adb517e2e4baaa58a9251422de62a0504999205d3ea1d
2025-05-31 18:16:21 +00:00
drh 5248693924 Relax query flattener constraint (3b) and thereby allow flattening the RHS of
a LEFT JOIN even if the RHS contains a virtual table.  This was previously
disallowed by [9dbae1df75219e2a] as a performance optimization.  It
turns out that the constraint causes performance issues, and we do not have
a record of any performance issue that it solves.

FossilOrigin-Name: 1ddaa92057e550ea281d45d9860eafe69399224725548a93dd91c47a34e52152
2025-05-31 16:17:14 +00:00
dan 420233e375 Fix assert() statements in os_unix.c and os_win.c. Allow walsetlk_recover.test to run in non-SQLITE_ENABLE_SNAPSHOT builds.
FossilOrigin-Name: 9f521ecda2b8d2f383cc84e308b3a4adfcf1bd6339eb834c8fa76c8704c861b7
2025-05-31 15:10:41 +00:00
stephan 1ff4233f90 Move a mis-located makefile comment block.
FossilOrigin-Name: 7d884386bec11f47c2c18002dd8c573c9b5cb6f7cdf2307a96cccead05b6abf2
2025-05-31 11:08:06 +00:00
stephan 10206572b6 tcl extension: UDFs may now 'break' to return an SQL NULL. Add the (eval -asdict) flag to use a dict, instead of an array, for the eval row data.
FossilOrigin-Name: 413a626b5c7902c1810142536c36e4ea8ee7c616ea82dfe1114199f9319091f7
2025-05-31 11:02:06 +00:00
stephan b504aab848 Add some missing UNUSED_PARAMETER() annotations to squelch downstream build warnings when using -Wextra -pedantic.
FossilOrigin-Name: a98a2f49355ec39c56e571c70d377675b1bd99a6d43cf9217b0eb1e081895d8e
2025-05-31 09:44:00 +00:00
drh d930d7ef14 Follow-up to the previous: The same optimization suppression needs to
happen if the left-hand side is coming from a LEFT JOIN.

FossilOrigin-Name: cf5b37b3a39013d8ca9de92da2289346caf52b56daff59e19b140cc586a3421f
2025-05-30 22:58:09 +00:00
dan ded1959120 If blocking locks are enabled, avoid using the busy handler when blocked by another process running recovery.
FossilOrigin-Name: a35236757ab57c4c9b34e47c5dbc10d8f1220f8152955f5303cf9c3902ee169b
2025-05-30 20:52:18 +00:00
drh dd16539e71 When synthesizing an ON constraint from a USING or NATURAL, if the left-hand
side is coming from a RIGHT JOIN, be sure to set the EP_CanBeNull flag so that
the optimizer knows to check for NULL even if the column has a NOT NULL
constraint.  Fix for the problem reported by
[forum:/forumpost/4fc70203b61c7e12|forum post 4fc70203b61]

FossilOrigin-Name: 60adc78a22956429d34ccc4e2c193c5994c11c3b3cff7901d47fad7d92dba935
2025-05-30 19:55:46 +00:00
dan 88ed38ca6d Avoid invoking the busy-handler if a blocking lock times out while attempting to open a snapshot transaction.
FossilOrigin-Name: fe11f85fd3283bb7002f43bd8b796e9e7b67f6d1a92eb676be06b46d1458fc1d
2025-05-30 18:23:03 +00:00
stephan f42ceb9075 Configure-related fixes and additions, most notably integration of self-tests for proj.tcl's APIs. Teaish make-install fixes based on the discussion in [forum:87e6660191a472c5 | forum thread 87e6660191a472c5].
FossilOrigin-Name: 2e486f8fd011d28fdd7e59ff34f7f04374019932eb160a8c4de56a5ce01e5782
2025-05-30 16:08:31 +00:00
stephan 7ac10ec8b5 Random typo fixes in JNI docs.
FossilOrigin-Name: f63608a3847469b130e029cc569fe6f03a9053352ec43c10d69849cbab4f61c5
2025-05-30 15:46:52 +00:00
drh 8ae57fab64 Use a more robust backup definition for offsetof().
FossilOrigin-Name: 22441955e03df07903b98832a60c05c53721cd67c667f6c83d5e97fcc62735ee
2025-05-30 15:43:04 +00:00
dan b65326f51a Add "include <stddef.h>" to fts5 and rtree to ensure that they use the system version of the offsetof() macro when it is available, as the built-in version triggers ubsan errors with clang.
FossilOrigin-Name: 838deb7f3423df84061a043928ed34e1d74e2e7d57ef1a9519bb32fea82e4352
2025-05-30 11:14:11 +00:00
stephan 0148820fd7 Squelch an interesting but harmless struct initialization warning emitted after an emsdk update. Fix JS breakage introduced by changes in Emscripten 4.0.7: manually export the HEAPxyz symbols which used to be exposed by default.
FossilOrigin-Name: 10d0897cc9a5998fe1344cfbb242a78b59012e29aa3b1993895dfac26721b053
2025-05-30 10:18:09 +00:00
stephan d2b230a488 Fix the missing -lm link flag for the sqlite3 shell when building the autoconf bundle with --disable-static-shell, as reported in [forum:5adf1c932a | forum post 5adf1c932a].
FossilOrigin-Name: f6318c4a6b5a133657741c066ef2c76a71880dbc98cfff1fdd632637daf002dc
2025-05-29 20:29:13 +00:00
drh f429845a60 Extend the fix for ticket [623eff57e76d45f6] so that it covers RIGHT JOIN
in addition to LEFT JOIN.  Problem reported by 
[forum:/forumpost/7dee41d32506c4ae|forum post 2025-05-29T15:10:14Z].

FossilOrigin-Name: 29b1e1b97619d03a97ef562a5707929e241d019179b4ff1d0bc2a8c008441431
2025-05-29 18:44:41 +00:00
drh b163f66de0 Fix a goofy hash function in Lemon. No changes to SQLite itself.
FossilOrigin-Name: d6cbabe23d3919d5bde6a83421cdae92125caec09d5c39a648d0305878c6a1dc
2025-05-29 17:46:34 +00:00
drh 3f52361352 Version 3.50.0
FossilOrigin-Name: dfc790f998f450d9c35e3ba1c8c89c17466cb559f87b0239e4aab9d34e28f742
2025-05-29 14:26:00 +00:00
drh b3c1884b65 Do not use a partial index unless the WHERE clause uses one or more columns
from the table being indexed.  This resolves the issue reported by
[forum:/forumpost/a8704b30f3|forum post 2025-05-28T13:03:40Z]. Test cases
are in TH3.

FossilOrigin-Name: f037ca064daeb81cb386da2a372d8e2d2dce55a3a13bc7bea4968ca51bf2843a
2025-05-28 16:56:23 +00:00
drh b3bcf489a4 Do not use a partial index if the truth of the WHERE clause does not depend
on at least one column from the table being indexed.

FossilOrigin-Name: cbe2a392e45d40778570656d2ef2db43e58ad6453bd9d4b936fecfd963e22736
2025-05-28 14:59:42 +00:00
drh f08f71a21d Slight change to tool/split-sqlite3c.tcl to make it compatible with jimsh
FossilOrigin-Name: fe670ddda933007386eb10facf4048ee88671f74b1fd41dfc3120beb717b8c9e
2025-05-26 23:20:23 +00:00
drh f96d44e5de Fix a bug in the speedtest.tcl testing script that was introduced by
[7e9845433ff26bdc]

FossilOrigin-Name: e4ffa86aa6ca82a42933281f6cbfca7bad702797eb8d6e684a1992e68dc1cfb7
2025-05-26 17:29:13 +00:00
stephan 209894c2f5 In the TEA build, enable USE_TCL_STUBS on Mac platforms.
FossilOrigin-Name: 0b5415151c9bf558378f83b1a60df3d3760f1aa311895af04e1fb79a8fb29e79
2025-05-26 16:59:49 +00:00
dan 93394ebc27 On OpenBSD, do not test fuzzcheck with ubsan as part of "make devtest".
FossilOrigin-Name: a3dabd599c3d3143b67258b307d352968e5f5d4ea0456940d16ae678de8c95eb
2025-05-26 16:17:06 +00:00
drh 8f06aed1df Avoid calls to sprintf() in Lemon, since OpenBSD hates sprintf().
FossilOrigin-Name: ed17858ddf833b6b9c2164f31ee9138a998d28ec1564d09e20deb102eefedbc8
2025-05-26 15:36:43 +00:00
stephan 3f01048954 When detecting TCLLIBDIR, skip over //zipfs paths, as the (file isdirectory) command will actually return true for those, but they're useless for installation purposes. This resolves the tea build's inability to install on stock openbsd.
FossilOrigin-Name: 5b29724a3287c9a910f303faf056d0706b66c3e6ba23f9746c11d775c631f374
2025-05-26 15:20:57 +00:00
stephan 45fa2347fe tclsqlite.c doc typo fix.
FossilOrigin-Name: de0dfac1e5ca9d2661674c20664095386f60c77378311507fcba08111df52b38
2025-05-26 07:15:20 +00:00
drh a01b7adb13 Change json_group_object() so that it ignores entries where the label
is NULL.  [forum:/forumpost/e5bd251fb5|Forum post e5bd251fb5].

FossilOrigin-Name: 28215d131cd970a2756338579fb6b6091ab155be8f419505cae8ac918956165c
2025-05-24 20:20:20 +00:00
stephan c5031b578b vtablog.c doc fixes reported in [forum:416d1e37b2|forum post 416d1e37b2].
FossilOrigin-Name: 5d25f62bcd2d754134f608162778b49b0e71c29bd5a6f2461a07caca3d76c7de
2025-05-24 16:01:50 +00:00
drh 81a2f7ba8f Amend the previous: Set SQLITE_JSON_MAX_DEPTH to 500 on *all* builds
of fuzzcheck.

FossilOrigin-Name: c266e38c5b61f47b920027aad418b641ab32cb8a3360dbcfd9f9f29b14fd5375
2025-05-24 01:34:41 +00:00
drh 85f37eba16 Limit JSON recursion depth to 500 when running ASAN in fuzzcheck, to prevent
stack overflow on ARM64.

FossilOrigin-Name: 5e96e177a040b46aa55492037ce5dc71ab49d66b45659d739f2ee6c3042f16ef
2025-05-23 20:50:49 +00:00
drh c1ea1a6d4d Add the --osmalloc option to the test/speedtest.tcl testing script.
Adjust ./configure so that it does not check for malloc_usable_size().

FossilOrigin-Name: 7e9845433ff26bdc5fe8654281d584394b77e3b206d09669b4468e0271c6eb37
2025-05-23 14:52:23 +00:00
dan 96e16194b8 Fix a problem with using streaming iterators with sqlite3changegroup_add_change().
FossilOrigin-Name: 3dbde727146d28c316df47c7b5116be7f2476a0a0c893207c2a4ca3ab285cb5e
2025-05-22 18:04:48 +00:00
drh 4a0b7a332f Clarify some malloc size computations to simplify the proof that they
are safe.  Remove some code associated with cygwin that is marked "#if 0".

FossilOrigin-Name: ba8184d132a935aa1980fbfb61ff308b93d433d559db4968f9014f7653ac9c6e
2025-05-19 14:50:36 +00:00
drh 79c792d5d9 Make the new sqlite3_setlk_timeout() interface accessible to loadable
extensions.

FossilOrigin-Name: 8819b7285b71932327f47d29fa575cfb338e2fccd3f7c2023faf0575bfdb0079
2025-05-19 14:04:48 +00:00
drh 890de76cf5 Remove stray tab characters from source files.
FossilOrigin-Name: 298ff5a1dc5dbccaf6acd91731044f478a5ce522745332801708ceee996b01e6
2025-05-19 12:46:08 +00:00
drh a58208a214 Fix a harmless comment typo
FossilOrigin-Name: c4d25acec3c1e28e5a4664a74c263cc0d00e118a6db4b26b51cb0d42d0f2b26f
2025-05-19 12:34:11 +00:00
drh acf95a3217 Adjust the tool/warnings.sh script so that it works on the latest versions
of clang on Mac.

FossilOrigin-Name: 05a3dd9a179193d00968329152c8ffe6532f0cbdad7d19b47af32aebc0cd0d9e
2025-05-19 11:08:30 +00:00
stephan 953e450e8e Latest teaish pieces, most significantly for tcl portability fixes. Move autoconf/teaish/autosetup/... to autosetup/teaish/. to simplify maintenance and deployment via the autoconf bundle.
FossilOrigin-Name: 381d3e82e831bedee56108fb585880d802c4d7d50b0804d909a33ff15a3be185
2025-05-17 11:06:02 +00:00
stephan c953cb6b3b Minor tcl doc update.
FossilOrigin-Name: 43259e8c3fab13b4597cdd1c670df00ec756a6fefdeb7d4ba2e0644e4ad47113
2025-05-17 10:35:11 +00:00
stephan 9bb2548e3e Rename feature-tests.tcl to feature.tcl. Haiku tcl portability fixes.
FossilOrigin-Name: 15bd9e581a6d6ebe281b091adc04dca4d1c7fa9bbb582bcbab8c401b4f976753
2025-05-17 10:32:48 +00:00
stephan 1e24694b59 Latest upstream teaish pieces for minor fixes. Restructure this copy of teaish to simplify maintenance and the autoconf bundle build.
FossilOrigin-Name: 2b8d9b75ec5fe96cb5d06a3464fd4eb9a53018b7b548fedcd6cdbc46cdb55bdc
2025-05-17 07:02:06 +00:00
drh 972a0f5e8d Improved version of the previous check-in.
FossilOrigin-Name: 036c97e36cb36a2ac765a8e8539433dcb63f69155d4c24857f84faa44eed6eb5
2025-05-16 18:19:11 +00:00
drh cd64392301 Fix the optimization of check-in [663f5dd32d9db832] that strives to avoid
duplicate compuations in the GROUP BY clause so that it works even if the
GROUP BY term is a subquery on the RHS of a LEFT JOIN.  Problem found
by dbsqlfuzz.  Test cases in TH3.

FossilOrigin-Name: 955a026996b93e530ca5b566689cc646b31d3b9b5a5837897a58452d70f6d942
2025-05-16 17:30:20 +00:00
drh cecf833325 Add the --enablefk option to the "changeset apply" command of the
changeset program.

FossilOrigin-Name: e98d46d436f8d251ae0da5ee85fd856aca3b57cd48d1be31fa6ca88fe72cad00
2025-05-15 18:50:19 +00:00
drh c638017280 Enhance the "changeset" utility program with new command-line options for
the "changeset apply" command.

FossilOrigin-Name: 428daca4f1b3e1a33b7e2f5acf114fa6136d46555e9947e2e88ea107bfec5e4f
2025-05-15 17:33:32 +00:00
drh 4165fd8a86 Rework the showHelp() function in the CLI implementation so that its
purpose and operation are well described by the header commit.  Omit
the use of enums that cause issues for MSVC 2025.

FossilOrigin-Name: 336ceeccc6f85bd78f4a26648af7edf9056d569a767b4120f125a02b2090a349
2025-05-15 11:20:54 +00:00
drh 691b44a1b3 Back out the "low-quality index" query planner hack of check-in
[bcac937526d9a6ef].  Subsequent query planner enhancements for dealing
with star-queries make that change unnecessary and the change was recently
found to cause a performance regression in an unrelated query.
Also fix a typo in a debugging message.

FossilOrigin-Name: e7dcf25efae364b7cdf9eb8265803c816c8b8557e4a7684da428badc6ffb3875
2025-05-14 16:40:05 +00:00
drh c02ac7b9d7 Fix trunk fork.
FossilOrigin-Name: 53644c42c5ee40e905a72bb014515e5e30265577d543eeca09139800822b5b42
2025-05-13 19:06:11 +00:00
stephan 186fd30436 Adjust the strftime() test in test/date4.test to remove flags not supported in musl libc if that environment is detected.
FossilOrigin-Name: fc254c1eb784c79a371bf961945a18a680982cdcd3fdcd7e6bb481712fe21cf8
2025-05-13 18:58:56 +00:00
drh 494830ca8e First cut at enhancing the fsdir virtual table so that it works with
unicode characters on Windows.

FossilOrigin-Name: c9e04dadfdf6c860631ce5603693add565ff2033aa25af5736302af7045fc91e
2025-05-13 16:58:36 +00:00
drh 0df6c5b9a7 Omit the unused readdir_r() routine from test_windirent.c
FossilOrigin-Name: f9a216e3ad1b3bc9be350aad5ef3dc8b3534d3ee67d160bfedda81a61295320c
2025-05-13 15:09:13 +00:00
stephan 0a0777d845 Session extension doc typo fix reported in [forum:75e9408acb|forum post 75e9408acb].
FossilOrigin-Name: b96cfff52b4f364388f168198e999ae2407c4afbc7b020f8bb350ab103ffb55c
2025-05-12 19:12:50 +00:00
drh a0b34dcfc0 Fix a coding mistake in vfstrace.
FossilOrigin-Name: f0054cc0bce4ed735796da1ea68b7773a582042bdd60fdae4e1af4c592104d15
2025-05-12 11:48:39 +00:00
drh eb55814c62 Remove a redundant typedef from the sqlite3_rsync.c source file.
FossilOrigin-Name: b4c37c6bcc644e21a29955e31151ea22a07627e524ce913afd3d2d6eeb7e0bb6
2025-05-11 10:48:10 +00:00
drh 94e22bc077 Provide the SQLITE_BUG_COMPATIBLE_20250510 compile-time option that restores
the JSON5 bug fixed in the previous check-in, in case some applications need
it for legacy compatibility.

FossilOrigin-Name: 491cf31904fdbc9567b838d1ba27901e75f8ea3a117043017d08354bb09f9711
2025-05-10 17:09:53 +00:00
drh 844b457950 Add enforcement of the obscure JSON5 syntax rule that the &#92;0 escape
sequence must not be followed by a digit.
[forum:/forumpost/c061e87faf7d1c55|Forum post c061e87faf].

FossilOrigin-Name: 83c7477f2b9b0d6cb54cf6b14bf3c8ef4807e4bddc7986d275cf6717da8606b7
2025-05-10 15:53:17 +00:00
drh 733aff3be8 Fix PRAGMA trusted_schema=OFF and similar so that it restricts the kinds
of functions in CHECK constraints that the documentation says it does.  It
was letting through some function that it ought not have.  This is a
defect in [5720924cb07766cd].  See
[forum:/forumpost/3fa9d44c0b381342|forum thread 2025-05-08T08:50Z].
Additional test cases will be added separately.

FossilOrigin-Name: 25920beebf71ebc9a1bb9f56932280c9e03390f26fe9da2258f950979b238ce6
2025-05-08 16:18:18 +00:00
stephan cc28137e08 Internal doc typo fix. No code changes.
FossilOrigin-Name: ac2aa39f7e3ae7ac921fac6566186939a1282f80ced5b3e3d5006a77ecf583ff
2025-05-08 13:51:55 +00:00
drh f087b6ace3 Fix a harmless warning about and oversize shift operation on malformed JSONB
inputs.  [https://issues.oss-fuzz.com/issues/415850463|OSSFuzz 415850463].

FossilOrigin-Name: cf8b55b3b6f0b73158e21731a206d5a8d8d9892989d91171a11c6dbbee34b338
2025-05-07 17:13:30 +00:00
dan f67058367b Add test cases for the NOT NULL/IS NULL optimization in CHECK constraints fix.
FossilOrigin-Name: 6eb2939a6093c0796910645172d80c53055559dd57c012f1dc815d89fbf84447
2025-05-06 17:56:32 +00:00
drh 288f356854 Fix a bug in the NOT NULL/IS NULL optimization of check-in [cb94350185f555c3]
that can cause invalid data to be used for a column if that column has a
CHECK constraint that includes the NOT NULL or IS NULL operator.
Problem discovered by the 
[https://issues.chromium.org/issues/415397143|Chromium fuzzer].  Never
seen in the wild, as far as anybody knows.

FossilOrigin-Name: 2adaee9aa90f280a406007695fbc4a314806584c93d6b62b46c031492b31ec27
2025-05-06 17:53:27 +00:00
drh ad39fa81af Fix the sqlite3VdbeTypeofColumn() function so that it works correctly
even when SQLITE_DEBUG is defined.

FossilOrigin-Name: 1d5021533ed688d7a815ce75b338c72f577c14554027f88a21419935a9e68239
2025-05-06 16:28:44 +00:00
drh 3b51a1ac01 Fix console-I/O on Windows for DEBUG=3 builds. Broken by
[925e97e6f4238f02].

FossilOrigin-Name: ccef4f7058928943be9204b2e53baaf791021e78e538396ba9f2a1d76323e8cf
2025-05-06 15:39:39 +00:00
drh d7324103b1 Enhance sqlite3_rsync so that if the first attempt to invoke a copy
of itself on the remote system using ssh fails, try again after
augmenting the PATH.  This enables sqlite3_rsync to work without the
--exe option when the remote system is a Mac.

FossilOrigin-Name: 38d4c94d8c7802101ef3bfb411002f9497fdbbbd2b4d3514cef5b76ffd66f75b
2025-05-03 15:17:21 +00:00
drh 37b76bac18 Fix a harmless redundant variable declaration in sqlite3_rsync.
FossilOrigin-Name: f8f15eff6ae50d569ed13a3b18f33eaa43453c0cb80b6007df38e880b62f45d0
2025-05-03 10:55:47 +00:00
drh e618674714 Addition summary results output when using -vvv on sqlite3_rsync.
FossilOrigin-Name: c702999cfac37fdcae64d261408e58d1f49fee65434fe346db6a2a6c7f8ac54e
2025-05-03 10:49:39 +00:00
drh d7b83224bb Promote the --protocol option to sqlite3_rsync from being an undocumented
debug option to being a supported and user-visible option.  This is 
sometimes needed to work around bugs in prior versions running on the
remote.

FossilOrigin-Name: 4855e04e44e8fce2d6e37dd468eb6e9f4565c36cbc964156e65ac0449d7c212f
2025-05-03 10:35:32 +00:00
drh f4d435dc0d Enhance sqlite3_rsync (in a backwards-compatible way) so that it has the
ability to send hashes for blocks of pages in addition to individual pages.
By judicious use of this capability, network bandwidth requirement to sync two
similar databases is reduced.

FossilOrigin-Name: e5d87aaa8fe1e8c8cb63813d26851183e77809a3d36e4c16c37f88b4b4724d6d
2025-05-03 08:17:46 +00:00
drh e2826db73a Improvements to protocol negotiation.
FossilOrigin-Name: 4f5a06e42010c3e047429f736ffb8e2e89a1eb599277c176945b57710f6713ca
2025-05-03 07:00:51 +00:00
drh 5f4d013732 Clean up command-line parsing. Add the undocumented
-protocol option for debugging.

FossilOrigin-Name: 2a52b174e6e91cd7cfca0b20b39cdd231f377c7bc073f4223574556b94b16aa5
2025-05-02 23:50:30 +00:00
drh bef9565485 Now appears to be working. More testing needed. Refinement of the
version-2 algorithm needed.

FossilOrigin-Name: cb035181d9fb5909696b8ec8f9c3eeb7a7dfb4b50e82e1d3f2d5ad150afcc0ff
2025-05-02 22:25:40 +00:00
drh f124ddf36a Bug fixes. Added new debugging features to better visualize the
protocol.

FossilOrigin-Name: c70330668690e7c3c55ae34137d5b2c91871432004b82b2b23a89fc3f1322a62
2025-05-02 18:32:46 +00:00
drh fbafaa5619 This is the start of an experiment in getting sqlite3_rsync to use less
bandwidth when the two databases are very similar, by sending hashes
over blocks of pages initially, rather than over individual pages, then
requesting more detail when hashes do not match.

FossilOrigin-Name: 266b4b8f0104bd4b1cff87ed78b0223006bf661a9650294a2b330d50c7ee8a0c
2025-05-02 17:39:21 +00:00
drh 5db695197b Do not allow sqlite3_rsync to convert the replica from WAL-mode into
DELETE-mode, as that can disrupt existing clients on the replica side.
DELETE-mode to WAL-mode conversions are allowed, however.  See
[forum:/forumpost/6b575b66156673ee|forum thread 6b575b66156].

FossilOrigin-Name: 660a035b6ce6684d429b882133e032181cc1664f4efadf1bc0e4ae27d45071c4
2025-05-02 11:18:09 +00:00
drh 2bd983a974 Enhance sqlite3_rsync so that, by default, it will sync non-WAL-mode
database files.  Add a new command-line option --wal-only that restricts
the sync to WAL-mode databases only (the former default).  Improve
command-line option parsing so that only a single "-" is required before
each option.

FossilOrigin-Name: 4b53603fe468c0c28b818762917e41bdd870de6d4cc143688f1cdea3136c81a4
2025-05-01 18:07:27 +00:00
drh 391f70c527 Allow sqlite3_rsync to work on non-WAL-mode databases, as long as the
--wal-only flag is not used.

FossilOrigin-Name: e4126dcd1eba4f040a7c07102d34692287b74b41a3437a3b9d15c4f8c9d4e6fd
2025-05-01 16:07:52 +00:00
drh f23a61258b Fix a harmless problem in the CLI in which SQL errors that occur during
the ".schema" command are properly ignored, yes still appear in the ".log"
output. [forum:/forumpost/42fe6520b803be51|Forum post 42fe6520b8]

FossilOrigin-Name: 20abf1ec107f942e4527901685d61283c9c2fe7bcefad63dbf5c6cbf050da849
2025-04-30 14:37:00 +00:00
drh 88ed1806a4 Fix an issue in Bloom filters on RHS subsqueries to IN operators.
See [forum:/forumpost/792a09cb3df9e69f|forum post 792a09cb3d] for
a description of the problem.  Also improve comments related
to [baa83b460c677c21] which was origin of the problem.

FossilOrigin-Name: cdef486e212fe4b26605065d9cff08f608cb80df48ee64e4be63637769bdfacc
2025-04-30 12:48:20 +00:00
stephan a20c09c477 Upstream teaish for a tcl portability fix on Haiku and a much nicer impl of proj-tclConfig-sh-to-autosetup.
FossilOrigin-Name: ca0d30a43b3dfb95dd6b491f592031a053b0b5e95361ffe01ec8bd56d5e2d110
2025-04-29 17:30:51 +00:00
drh 5a9a2d8526 Remove the run-fuzzcheck makefile targets, since testrunner now
accomplishes that for us, and does a better job of it.

FossilOrigin-Name: 3ffd867ed31cd0779aa92b5e8b71592a8e7224977f9da8e5d6793a78bbb80070
2025-04-29 16:30:58 +00:00
drh 2ba946b341 Add the "--fuzzdb FILENAME" to testrunner.tcl as an alternative to setting
the FUZZDB environment variable (as that can be awkward to do on Windows).
Further improvements to the testrunner.tcl documentation.

FossilOrigin-Name: 6fb84156a262ff89d1a2d1df6fbfac4c1a43fb55b9d15205508662e2c9b0894f
2025-04-29 14:23:21 +00:00
drh 873fc5dff2 Update testrunner.tcl documentation. Fix typo in testrunner.tcl output.
FossilOrigin-Name: ba8800b4ba0a690c89d9fb96bb9a0d8789d04160ff9c47ea9afb2b403bec7f0b
2025-04-29 11:35:51 +00:00
drh c171d7624e Improved --explain display of FUZZDB test plans in testrunner.tcl.
FossilOrigin-Name: 42bdd7262ec4f8163263e0535c2cc35b526754d77e1f3ccf5b73b0f44d470d9c
2025-04-29 10:41:16 +00:00
drh ece7709f18 Do not run FUZZDB on either Windows-Memdebug or Windows-Win32Heap.
FossilOrigin-Name: 10d8401d59136dda7051af0da398b06a18031560f2734f4fa347d339765d2089
2025-04-29 10:29:35 +00:00
drh 8a68ab963e Make testrunner.tcl more restrictive about which configurations run
fuzzcheck-asan and fuzzcheck-ubsan.

FossilOrigin-Name: 785599394dde0fb36ae2e07d611f9523a05a0817dbd8c416582b3b682dbfa4ff
2025-04-29 01:37:31 +00:00
drh 246dc92354 Testrunner.tcl now runs fuzzcheck-asan and fuzzcheck-ubsan tests.
FossilOrigin-Name: 3d8f3a255843c063157265702b76d40c38c774d29d658eea2d77efac92ac8789
2025-04-28 19:15:46 +00:00
drh d4cc3a42e2 If the FUZZDB environment variable is set when running testrunner.tcl and
that env-var points to a fuzzcheck database, then suppliment the fuzzcheck
tests with that extra database.

FossilOrigin-Name: c08530dd6a71cb547d164e2313657c917f280e7988211bf199c8776e78a4e2a6
2025-04-28 17:56:23 +00:00
drh 1365bcffbf Enhance testrunner.tcl so that it does not build testfixture unnecessarily -
if the pattern does not match any TCL test.

FossilOrigin-Name: 896d767f1cba64bda7b91b0daebd60ebe4457a58d762da443bf61cf5b39ad2d9
2025-04-28 16:28:00 +00:00
drh 7fec7c96c4 Fix testrunner.tcl so that it honors pattern matches in non-testfixture
tests, such as fuzzcheck and sessionfuzz.

FossilOrigin-Name: 81857474fe90f50b760c22d61a6ad477642dabe1052390cd1614dcec8adb1376
2025-04-28 16:17:17 +00:00
drh 738443c523 Remove a stray blank line from the test/testrunner.tcl script.
FossilOrigin-Name: 7d6005b0d17d86d72757f3578872e82fd12f61ac9160a0277e397df09f6338a9
2025-04-28 15:00:28 +00:00
drh 9112717180 Remove long-obsolete performance testing scripts from the tools/ folder.
The test/speedtest.tcl script is what should be used these days.  This
is just cruft clean-up.

FossilOrigin-Name: 956af8c294ae5b826a5b645922df07dad360290d19bf2b6a7f74d0a783a3e692
2025-04-28 13:32:46 +00:00
stephan 886f674198 tea: pull in upstream teaish. Consolidate the build definition from the upstream build and this one to ease maintenace. Improve compatibility with historical TEA usage of --with-tcl=... (it insists on a /lib suffix for that path).
FossilOrigin-Name: 0ea5993dd8549056d73f3d5447e0a810495ece23a75be8add78fba6842125d85
2025-04-28 09:25:19 +00:00
stephan c26cde3bfd proj.tcl: correct the auto-reconfigure rules to include any X=Y passed to configure. Improve handling of quoted CFLAGS.
FossilOrigin-Name: 7a2f4f319c90b768c6acc96671a3173c0ef0493180f3c4d5443f1ca03d92f6b4
2025-04-27 06:01:26 +00:00
stephan c49c7dad89 autoconf/tea: the default value of --threadsafe=X is now based on a pkgconfig query using the target tclsh, which is much more reliable than grepping Tcl's linker flags. Doc touchups.
FossilOrigin-Name: 4aeec30443b282f10353cdb9415fdce436287280f0f5d5d6b9917da831744898
2025-04-27 04:21:27 +00:00
drh 0f0450eda3 Fix an off-by-one error in an assert(), discovered by oss-fuzz. This is a
harmless error in as much as assert()s are disabled in production builds, and
because the off-by-one only occurs on nonsensical CREATE INDEX statements.

FossilOrigin-Name: 3e627d66ebdef8dfe41bd12a0474d1afca9f50051771774679d25bd1833e69ae
2025-04-25 12:39:32 +00:00
stephan ef90c4209c Teaish internal API tweaks and ensure that -encoding utf-8 is used when source'ing test scripts.
FossilOrigin-Name: f878f578f8fac95a939e3eabe8b64d5627d2ccd98de1e28081b9bca42ffee027
2025-04-25 11:27:13 +00:00
stephan d3b39b18d0 Upstream teaish fixes and improvements.
FossilOrigin-Name: 235ea2c0e1823fe4324c3890069a9131ebb6de14e55eb56c0e9f42a7e491a699
2025-04-23 14:54:13 +00:00
drh 37f22ff75e Fix a problem in the fts5matchinfo.test file that prevented it from
working on Mac.

FossilOrigin-Name: 5a411c609ba0ee17b1ce5bd0b40b9ded92d76f35933f92b2e02a58a3f169c715
2025-04-22 18:45:40 +00:00
stephan 024818be2b Latest upstream jimtcl to fix rare segfault cases.
FossilOrigin-Name: b6c5516940851bd17706435148253325d1b912a44ae138d2b8ca33e5167418c7
2025-04-22 09:29:53 +00:00
stephan 204d787644 Generic cleanups and fixes in the teaish build.
FossilOrigin-Name: 734823a5a8e073b511ebc3f37df3542c1bb734b9b1e1bd50ca3e9df12c4bb89e
2025-04-22 01:01:19 +00:00
drh d2fd099570 Remove an extra conditional that was inserted earlier today and which
is unreachable.

FossilOrigin-Name: 5ea56af2d27611c5a8ea275316d21a02e70032f93243549ae776e9a89edc6229
2025-04-21 23:44:55 +00:00
drh 81cde80f7b Further improvements to the decision of whether or not a BLOB input
is JSONB.

FossilOrigin-Name: 6538813cb89f6109727481e29633e2e98f98e0257c58695e3b53e8ce237d9195
2025-04-21 20:58:49 +00:00
drh cbe4a26e02 Do a better job of providing bug compatibility with SQLite 3.44.0. See
[forum:/forumpost/07e206fcd6|forum thread 07e206fcd6] for background.

FossilOrigin-Name: 614d061b32c3bdf4825323d6f8e8a98624e4eeeb96dd442d8e365527122ed3bc
2025-04-21 19:53:12 +00:00
dan c4e7cf68ce Update to comments in sqlite3session.h.
FossilOrigin-Name: ea9acb5573f4d71a314e4467d30477a1d01c8db648985750a42b3c047f404c9c
2025-04-19 20:08:04 +00:00
drh f857482ed1 Add an appropriate _declspec to the declaration of the sqlite3_dbdata_init()
function in the recovery extension.

FossilOrigin-Name: 00313d15270b36fce44f7784c97ddc42517e23c209c1ccc4d814ef06b11528c0
2025-04-18 14:47:56 +00:00
stephan 31e08190ab Upstream teaish, which simplifies how extension metadata are initialized and shrinks proj.tcl by 4k.
FossilOrigin-Name: c72c00d34d70b36f847af19a2382299746448b5dd94a616f6b567389c5694c17
2025-04-17 19:41:37 +00:00
drh 10744c61ad When logging errors using sqlite3_log() and the error text includes the
text of an SQL statement, but the SQL statement text at the end so that if
the error message buffer overflows it is the SQL statement text that gets
truncated, not the statement of the problem.

FossilOrigin-Name: de0968226effb79f9d25539da7882fa5475e4ff2410870b45a63a6545deb5979
2025-04-17 19:01:54 +00:00
drh 56747d1840 Increase the size of the output buffer for sqlite3_log().
FossilOrigin-Name: a64e8491c9863f890daa9f5d8f678728dc0d00bc1f3c238b50214ec545450fcf
2025-04-17 17:46:28 +00:00
stephan 680a9584c6 Add docs explaining how to test the teaish build.
FossilOrigin-Name: b53619ddb74fa250f03564d04e732248b4161d4d10d6f02268b7c95382d110ff
2025-04-16 22:25:02 +00:00
stephan c264a0fd95 Latest upstream teaish. Most notably it adds the ability for the extension to specify a minimum Tcl version, and this build now enforces a minimum Tcl of 8.6.
FossilOrigin-Name: c86315e538f4d75161faa72673927cde8be080c983f04a98491d1add14615038
2025-04-16 21:53:01 +00:00
stephan 259532c0ad Update doc/tcl-extension-testing.md for Unix systems, consolidating the Tcl 8.x and 9.x sections.
FossilOrigin-Name: c4c5dcb79c57f6e38cfe9b68b00e60e42d03ef30aeaefc5bf9dafed994849e1d
2025-04-16 17:47:16 +00:00
drh 6fe2a9a8f1 Attempt to provide EBCDIC translations to the tables in the JSON
implementation.  The SQLite developers do not have access to any
computers using EBCDIC and so have no way to test this patch, and
cannot vouch for its accuracy.

FossilOrigin-Name: 84e698f38429c142caaa66ac086410f2035691b2ad39ad2fc4e0ebc31dd58a5b
2025-04-16 17:36:26 +00:00
stephan cd83a85e05 Change the target libdir name in the teaish build to match historical tea builds.
FossilOrigin-Name: 8ae437301ed0cf71ef0e07be07917d9702221d27bdc98491209d8f28c7a500e2
2025-04-16 15:40:40 +00:00
stephan b70d450426 A portability fix for proj.tcl: some Tcl builds do not like (array set x $someArray). Also better --mandir handling on Haiku (where the former problem was found).7
FossilOrigin-Name: 849534499d9b2056c0eabef7f3e65f79f58e8a6fefb3f7603de44774da7166b5
2025-04-16 14:21:48 +00:00
stephan b1cc4aeb61 Latest upstream teaish for fixes and improvements.
FossilOrigin-Name: 8f9148b33e01aa7963140704ef16e4304799e5842fa60e55373ccdabe8e3616d
2025-04-16 12:48:27 +00:00
drh 0243ca8245 Correctly handle the case of a multi-column UNIQUE constraint that contains
the ROWID as one of it columns, and then the columns of that UNIQUE are
used in a row-value IN operator as a WHERE clause constraint.  Reported by
[forum:/forumpost/b9647a113b465950|forum post b9647a113b].  Problem
introduced by [723f1be3d4a905a6], part of ticket [da78413751863].

FossilOrigin-Name: d22475b81c4e26ccc50f3b5626d43b32f7a2de34e5a764539554665bdda735d5
2025-04-15 21:59:38 +00:00
drh 8488789d74 Fix a minor typo in a code comment.
FossilOrigin-Name: 158e8c4fd7bdfc1cd4c0135abecd0d00994cd4027cf74ce6e5cf73d76475ae95
2025-04-15 19:53:36 +00:00
stephan 850289bf1e Cleanups and refactoring in proj.tcl and teaish.
FossilOrigin-Name: 6b7ca8176e8c1b5e99e177c3daaba47b0674fa2f82d91754e7a8f66460ca8419
2025-04-15 15:20:30 +00:00
dan 136afcfcc1 Avoid a potential integer overflow in non-default builds of the fts3 matchinfo() function.
FossilOrigin-Name: aecc0100cef3ea83feed558dbe34dd6313721fa54052ee1ed529741cec8cacda
2025-04-15 11:06:37 +00:00
stephan 56da8772bd Further cleanups and code consolidation between teaish.tcl and sqlite-config.tcl parts.
FossilOrigin-Name: 07e9ceee51380ee25e580178fa82030be5d2b65d4f4b4dc86c94b21f7f04f291
2025-04-15 02:02:36 +00:00
stephan dc2d79f80f Slight simplifications in the teaish build.
FossilOrigin-Name: 6b2d0e09e4806b5731764192782ec7e1ad595c529202a684d23bcfe2fae559d7
2025-04-15 00:47:31 +00:00
stephan 5950eb8aa7 Update teaish to the latest upstream copy. Move some of its utility code into proj.tcl for reuse in the top-level configure bits.
FossilOrigin-Name: 921c5ea76925be911222ac5f2887b8a967ff47b1aa43e196231e6168a3f9cb88
2025-04-14 23:52:11 +00:00
drh 483e1181c5 Improved estimate on the number of output rows in a recursive common table expression
that uses the UNION operator.  Follow-up to [f911f1c4977fbcae] and it's output row
estimate changes associated with DISTINCT queries.

FossilOrigin-Name: 92513f6bce7ecc778e78af3a77bc66ff65585fffa2e3138f8acb9e617121eeb0
2025-04-14 19:43:30 +00:00
stephan c801f8954e JNI: part 3 (of 3) of typos and Java style tweaks suggested in [forum:99ac7961d82f57f3|forum post 99ac7961d82f57f3]. Tested with jdk v8 and v21.
FossilOrigin-Name: 914d4c9d6c26536ca14be80eee6c54af4311eac6bf88b327738075275f4b77da
2025-04-14 13:31:18 +00:00
stephan d01239f379 JNI: part 2 of typos and Java style tweaks suggested in [forum:99ac7961d82f57f3|forum post 99ac7961d82f57f3].
FossilOrigin-Name: 5e6e9aee5b43e6ae98e78293a0da30e82ad18c3c9c03fc6298240233ddadb2a2
2025-04-14 12:09:24 +00:00
stephan 6cabff0c22 JNI: part 1 of typos and Java style tweaks suggested in [forum:99ac7961d82f57f3|forum post 99ac7961d82f57f3].
FossilOrigin-Name: ab00af4e48501b0413650df31147866a805c34b7ecf506d1e208bc3ae6c2ef28
2025-04-14 11:31:10 +00:00
stephan 6964b2f737 Doc/help text tweaks in autoconf/tea.
FossilOrigin-Name: d6889f6b9aa70bc90f71883b3e7ba359162477afe5048dacb7dfa11733ad1e5a
2025-04-14 10:20:41 +00:00
stephan a572bbfc7c Minor cleanups and fixes in the autoconf/tea pieces.
FossilOrigin-Name: 4d6536bd0ad333854309e825feaca26fdd13ac4458c7ccfbe77fc76cc5a968bc
2025-04-14 10:18:40 +00:00
stephan a5198b2e13 Latest upstream teaish, which restructures the teaish files a bit.
FossilOrigin-Name: 4f54f7d07d31938f271bc5d04a40cb1f7b5e6ea48e78ad06b7cc65483533f54e
2025-04-13 16:22:58 +00:00
stephan 6b4dcad514 tea build: use autosetup's file-normalize instead of Tcl's (file normalize) because the latter throws on cygwin for names like '.' and './'. Update a doc URL.
FossilOrigin-Name: 0fe77341a0f1e869a909623cdd07b03355b90d302b4f8a875e520befab88ce35
2025-04-12 21:47:18 +00:00
stephan 337f703c54 Port autoconf/tea from the autotools to autosetup.
FossilOrigin-Name: 691708642bf1cac562274a6df427d7c631aa4401dfbe98711963cf89203fb104
2025-04-12 21:24:10 +00:00
stephan 837dc09bce Move the post-configure dot-in-file validation from sqlite-config.tcl to proj.tcl for reuse in the tea port and other downstream trees.
FossilOrigin-Name: 0bac496d5c92c979295e702efc01803f6985b54d3d8ca30dce077c9776f7dcf2
2025-04-12 19:26:18 +00:00
stephan 6b0429676e Doc typo fix.
FossilOrigin-Name: 10b917040b167de6aba6ee434b4e982580e690bbfe80521e34236b29d8e00b7d
2025-04-12 18:37:53 +00:00
stephan 807186f1d3 Eliminate a duplicate -lz flag in the teaish build.
FossilOrigin-Name: 5efb372c9b0d46625cb17aa3e48ead0da2483ca9d04d1507c9d728763f1ee959
2025-04-12 10:33:12 +00:00
stephan a69b2b2973 Add missing teaish.test.tcl.
FossilOrigin-Name: 3946a3ad9cd2d03b6940621066a8e5be0bd6fade88cbf6cb2823425a90eba9c9
2025-04-12 03:20:42 +00:00
stephan 22a85a418e Add missing exports of various LDFLAGS and CFLAGS for the teaish build.
FossilOrigin-Name: 7462b1c66e8b3799ba1d73a1b815993e1c511ac0b7263e747ca0186d263ad001
2025-04-12 03:08:13 +00:00
stephan 71b7e44869 Correct out-of-tree build for autoconf/tea.
FossilOrigin-Name: 955b516618a34eac69da25fc7405015701a72f3cb918fca0cda7d316f6c3db9a
2025-04-12 02:44:02 +00:00
stephan 19b0701087 Initial port of the TEA build (autoconf/tea) from autotools to autosetup.
FossilOrigin-Name: 95227341cf290ca6f20b5ff7e707a28b59f87784947425c3fd1d8e5e7eb878a4
2025-04-12 02:30:04 +00:00
dan 0aa95099f5 Fix a memory leak in sqlite3session_diff().
FossilOrigin-Name: a6cbc5db1c4973ea236874bd9c24cd86dc48fbc7a10e424896c0407c7c32ce6a
2025-04-10 20:52:47 +00:00
drh a863bafba7 Improved detection of run-time errors (ex: OOM errors) in speedtest1.
FossilOrigin-Name: 0e5e0e2f558a417d57c01a2d62cb2117d2adf6ddbc62e6a0208ae23f19b05347
2025-04-10 19:54:56 +00:00
drh f95e964b6b Provide new command-line options --hard-heap-limit and --soft-heap-limit
for speedtest1.

FossilOrigin-Name: 578e9fedeaaacd152ae1988920e6c9a0c43f664e2f9461c0994ba427ae1688e7
2025-04-10 19:39:34 +00:00
drh e4856e86cd Be sure that speedtest1 reports any errors that it encounters while
running the speed tests.

FossilOrigin-Name: 8c8b1a99bc888a5db637900aa3c8ef1b8c748c527580c825a25df1008afcf9e0
2025-04-10 19:03:42 +00:00
dan 7b1afecf53 Fix a comment in sessionD.test.
FossilOrigin-Name: 3516354ee57b683c134de206f5321f064f9cb627aa12ba6fde98e59a9093c50c
2025-04-10 17:25:57 +00:00
dan da00cc101c Improve the error messages returned by sqlite3session_diff().
FossilOrigin-Name: a3217cdb75fd305705856f6504f8816c2b6b0a10907725cb74d025a5c4e369b8
2025-04-10 16:48:04 +00:00
dan 08122e96fe Fix an obscure problem allowing the propagate-constants optimization to improperly substitute a column of a sub-query with NONE affinity. [forum:/forumpost/0109bca824|Forum post 2025-04-08T14:18:45Z].
FossilOrigin-Name: 979f384a93d25e24f760469681618101feaab873738e1b52a7d4b818f7c527d9
2025-04-10 15:01:58 +00:00
dan 2d1c71abeb Fix an obscure problem allowing the propagate-constants optimization to improperly substitute a column of a sub-query with NONE affinity.
FossilOrigin-Name: d82725dcaec7437f37fc15dfb492b51a4f9dbbbcaea04e387d9471b7d291cde2
2025-04-10 14:53:32 +00:00
drh 8a6f89c845 Remove unnecessary "www." prefixes on domain names in URLs.
FossilOrigin-Name: 20acd630b91609725794ce84f9eda01d5f3c898407f0948264830851d25ccaa6
2025-04-10 10:18:07 +00:00
stephan 509d899a2d Doc updates in proj.tcl. Improve configure check for whether fdatasync or nanosleep require -lrt. Remove references to 'tcl-config' build mode from sqlite-config.tcl, as that build is now implemented without a depency on sqlite-config.tcl because the TEA build's needs are considerably more modest.
FossilOrigin-Name: 394bef54411c81fd8ca3aafc13ec2a774e9ff56c7282d90b8425cc8f383aa74c
2025-04-09 13:32:15 +00:00
drh fda6e50ac8 Remove an incorrect ALWAYS() macro. [forum:/forumpost/23875495059357a2|Forum post 2025-04-08T19:16:42Z].
FossilOrigin-Name: 062cca9c63ef6d7b9a525df69391e9b032284703aeb45a18c728305dd5957c43
2025-04-08 20:00:33 +00:00
dan de93449908 Have sqlite3session_diff() automatically attach tables to session objects, as it has always been documented to do.
FossilOrigin-Name: 99827144f112303e27a829c990b1858d227bd7369095100a435c367637985fad
2025-04-08 17:18:01 +00:00
dan 6864f78fdf Have sqlite3session_diff() automatically attach tables to session objects, as it has always been documented to do.
FossilOrigin-Name: ec1641858ec48d96f5a2ddce4575ebd40a18932d69831fdb4eafc9acf508f216
2025-04-08 15:58:19 +00:00
stephan f72c2fd19e During the post-configure validation of @VAR@ references, ignore commented-out references in files which seem (based on their name) to be makefiles, as it's sometimes handy to comment-out such vars during development of a configure script and its corresponding makefile(s).
FossilOrigin-Name: 25d936b7b27d33b18bdac245bb193f7fbeaa9a7e7c320e47bdd433e6b371aef9
2025-04-07 18:29:57 +00:00
stephan d2b9cc099d Rename proj-current-proc-name to proj-current-scope and have it distinguish between global scope and an invalid scope level.
FossilOrigin-Name: 1c7e5b6cab0f8c8d8ae4a1503ea04f2c65943b0788f3996c015fc163ae979a66
2025-04-07 02:16:26 +00:00
stephan 7d83ed04b1 Make it legal to call proj-fatal from the global scope.
FossilOrigin-Name: f1cf373b73f0e97767d6f3c9dd78ce04360eae1ed22f74bea4aeb922f3ca5b5b
2025-04-07 02:08:55 +00:00
drh 29c7c8b913 Fix a harmless code typo introduced by [b57e3c3db00a6bc6] and reported by
[forum:/forumpost/09957d8b2a|forum post 09957d8b2a].

FossilOrigin-Name: f3a6cdb89b13bc173cfce9526f836600469b0242fe62b8f92f8747896d7d47bb
2025-04-06 10:22:26 +00:00
stephan 8aaf23a15e Extend proj-dot-ins-append to provide a way to use it for the special-case emcc.sh.in handling.
FossilOrigin-Name: 0e98bbddc7b5e39310a8bf345521d05fdbcc906e279c23aa24cf30489ceeeff8
2025-04-05 09:17:13 +00:00
stephan bc969569a2 Add a note that SQLite's copy of proj.tcl can be considered the "canonical copy" for practical purposes. We now have at least 3 copies of it floating around in other trees.
FossilOrigin-Name: 77d2c8e9ef9627c87c05beaf5615958628bd47c393c030ff6fcca607ba43e71f
2025-04-05 08:48:19 +00:00
stephan 4d411659c4 Move the automatic reconfigure tcl code from sqlite-config.tcl to proj.tcl so that the TEA bits can reuse it.
FossilOrigin-Name: 52839db2fcdf37631d13c05165ecb551a89c05bd6836f62d62f8f0b7bbe6c6cd
2025-04-05 07:12:41 +00:00
stephan 7cf1b29065 Refactor proj-make-from-dot-in and friends to be more useful and remove some annoying limitations.
FossilOrigin-Name: 501ff84e1263e2b026b0ca5f043bcc912ea935229b625b113b7402955df20dd3
2025-04-05 02:59:37 +00:00
stephan 86527e84e6 Rename makefile var libtclsqlite3.SO to libtclsqlite3.DLL for consistency.
FossilOrigin-Name: 6fb364c853be84c8d1f20497a2cae6e8f06a1d10ae364e3b011cadeaa3e0244b
2025-04-04 23:12:32 +00:00
stephan d09fc81939 Correct a makefile var name type in the configure script, introduced in [4947c1c782].
FossilOrigin-Name: 84d77c5fe84d99d4af695a4da424b7dfc65f2343624e201736b7d673b2a8f179
2025-04-04 22:59:32 +00:00
stephan 205d9960cb Add more vars to the tclConfig.sh-to-tcl exporter, for use in the TEA build.
FossilOrigin-Name: b0e1e49c7a4af526143214ce7dee97ef0da5e7baa85728fc667b1f7607693ab7
2025-04-04 22:14:18 +00:00
stephan 31076c5f26 Account for the Mac-specific -instal_name linker flag, which is apparently needed for linking some third-party code. See [forum:5651662b8875ec0a|forum post 5651662b8875ec0a].
FossilOrigin-Name: 4947c1c78298253a51939adf6cf70ee233075db6d60cd7a183a4162c926e667c
2025-04-04 20:50:00 +00:00
stephan 24fe85b99a Adapt the --all flag to apply to a different set of features, and default to enabled, for the tcl-extension build.
FossilOrigin-Name: b229c8f65acf41b57afacfde712c3a8040d3bd5139bd5e30d450669658185ddd
2025-04-04 16:17:02 +00:00
stephan 91db54f07a Improve --all flag handling so that combinations of (--all --disable-FEATURE) and (--disable-all --FEATURE) work more intuitively. Add missing handling of the --fts3 flag (it was accepted but ignored before). Add TCL_LIBS to the set of vars exported via tclConfig.sh for use in the tea build.
FossilOrigin-Name: 26ef0ff4bfbb4425baa26fa5c8420f5da0603c38ef651104e566c7dc85bfaa3a
2025-04-04 15:41:19 +00:00
jan.nijtmans 82d05b7b54 The win32lock and win32longpath tests don't work on Cygwin
FossilOrigin-Name: 32ef3f26e7fb34dfdb23617a19bb9baa2e4c3dca564a88850b58a0fbe6446cf8
2025-04-04 13:23:03 +00:00
stephan 283d0ee4c6 Minor configure-internal cleanups to support the autosetup port of the TEA build.
FossilOrigin-Name: 244c2b75c10c68bc0499d60b707a925836a4b9d490813785587522109fc11fe2
2025-04-04 13:08:43 +00:00
stephan 29b496a2d5 Minor configure script internal doc edits. No functional changes.
FossilOrigin-Name: 357563bc7c01a744d4038ed3ccc475260b819e98cf90a4270764f79c73d2497e
2025-04-04 03:26:20 +00:00
stephan 16aa90bba4 Make the --static-cli-shell flag available in the autoconf build mode.
FossilOrigin-Name: b78a474ecba6cae4f0e867a515c214fbfe229808145df1870315328d4e13d462
2025-04-04 03:16:47 +00:00
stephan 99ef94e3ac On HaikuOS, if --prefix is not explicitly provided then default it to /boot/home/config/non-packaged, based on an off-list discussion with HaikuOS user BrickViking.
FossilOrigin-Name: c4a558291175378f76d126b12417c6c1d8e6060c0ec1267a97d3cd11b4804439
2025-04-04 02:40:08 +00:00
stephan 2a5694910a Add the --static-cli-shell configure flag to the canonical build, which works like --static-tclsqlite3 but applies to the CLI shell (statically linking it, which only works if all requisite libs are available in static form). It is not called --static-shell because that flag has a completely different legacy meaning in the autoconf build and this flight might eventually be added to that build, so would collide there.
FossilOrigin-Name: fd2c1638ecc38617f5de0380ad23f233d1159be0712ae2ca4cae5c99e841f1b1
2025-04-03 13:24:38 +00:00
stephan 2636632cae Add the --static-tclsqlite3 configure flag (canonical build only) to build tclsqlite3 as a static binary. This will only work on systems which have static versions of all requisite libraries.
FossilOrigin-Name: 61836324369e3213841295911aed4f8439a4b2b0f24820c2cf45bb68a0e2cd04
2025-04-03 00:46:34 +00:00
stephan 20f534708a Minor cleanups to the --static-tclsqlite3 support.
FossilOrigin-Name: 06f1143870280d335daf4e7027fe8771e34415aa1234fe72c0c450c347b8146c
2025-04-03 00:40:33 +00:00
stephan 0993fc62f2 Add experimental --static-tclsqlite3 configure flag to build tclsqlite3 statically, which only works if static libtcl/etc. are available. Currently intended for docker builds via Alpine Linux.
FossilOrigin-Name: bef3c8b1b9fd188ee9f941f93bac4567795fea51cee0830abf1ebc1999e1604f
2025-04-02 23:34:35 +00:00
drh 69da86bf93 Fix harmless compiler warnings in the memstat.c extension. No changes to
the core.

FossilOrigin-Name: 9e903953ba986df98435da40e94fdb645f6f72279552cba63ef50cec1fe3b486
2025-04-02 12:41:16 +00:00
stephan 34a55f872c Remove some stray debug output from proj.tcl.
FossilOrigin-Name: 5fc7150a2045a19966570b86843f180c2f8ff1f4688616ac161f071de0e765ec
2025-04-02 11:21:09 +00:00
drh 2b918dbb01 Increase the size of a variable in FTS3 to help static analyzers
see that there are no integer overflow problems.

FossilOrigin-Name: a921a4682fba23e1e223c2e3ecebd22ec59321552bcc563c29ce501bfe70fa4e
2025-04-02 10:42:47 +00:00
drh 2cbc485ea3 The json-blob-overwrite optimization seeks to prevent unnecessary I/O and
data movement when making small changes to the middle of a large JSONB.

FossilOrigin-Name: 4a3d7b04216fff605629902b7de08fd45eb0a89e7e1b0bb7c5ba82cddbc030cc
2025-04-01 16:32:31 +00:00
drh 76076d442a Fix a typo accidently added to the prior check-in.
FossilOrigin-Name: fb2f283038f9329b6f791d92d6f943269f24f1a0efd5859165b63f517ed52ddb
2025-04-01 16:26:51 +00:00
drh 3a7042e0e2 This is an experimental optimization that attempts to keep a JSONB value
the same size (same number of bytes) after doing a replace of an elements
with a slightly smaller element, by denormalizing the size field.  This
can perhaps avoid unnecessary page updates and memmove() operations when
making small changes in the middle of a large JSONB value.

FossilOrigin-Name: b5de9584b7f49586c5387d8a74af5e41dba50f1817a54257bf9da00deb695f72
2025-04-01 15:17:01 +00:00
drh 4d9384cba3 Fix a harmless typo in a code comment.
FossilOrigin-Name: dd251377bd1a8e95a4a0179c50595f290b08ea93659f4906f88f5a9dff534aa1
2025-03-31 23:18:06 +00:00
stephan 0a0367f387 Ensure that the compilation of extensions get the same CFLAGS as the core lib. Move the feature flags enabled by --dev out of TARGET_DEBUG and into OPT_FEATURE_FLAGS (for consistency). Rename the make-internal gcov-related flags to be more descriptive. At the end of the configure script, if SQLITE_DEBUG is active then emit a note reminding the builder that performance will suffer.
FossilOrigin-Name: e64c6a3856b839e4e8c0a1cb1713b0d2f1d3cb9b915dd215b0d3cb229502d539
2025-03-31 13:08:29 +00:00
stephan 227df626e9 Ensure that extension sources also inherit the debugging-related flags from --debug or --dev.
FossilOrigin-Name: 3e96b772a46638bc25e036de053d620ded3350871ee10e06fd6fe51429934b0d
2025-03-31 10:54:09 +00:00
stephan 8620b42245 Correct the ordering of the configure script's handling of the --dev and --debug flags so that --dev's forcing of --debug get picked up early enough.
FossilOrigin-Name: e48189ed33fa9d02b23c18255c7b4c6cab2a6d4b62f7c1edbb0a58ab329735fc
2025-03-31 10:29:06 +00:00
drh 084e61f5cb The --dev option on ./configure implies --debug and adds -DSQLITE_DEBUG.
FossilOrigin-Name: 67dbd9ff0f1e69e429cf3afaf19b84e8e95fc75035ac90cd0ae78d0d002980f8
2025-03-31 09:53:20 +00:00
stephan 39d14d4856 Minor shell-internal doc addition. No functional changes.
FossilOrigin-Name: 01b99c8a2819469568f369479c097cc8e3ed1f2478958460755b283dc7d11706
2025-03-29 11:50:25 +00:00
stephan 2d49219b1c Correct two tests in shell1.test which were broken by the addition of new output in [0f11087b8475].
FossilOrigin-Name: 909dd0a02a967baef46c3efdca42a0ab4e15003e34ce7e9af82fce5f17213d7b
2025-03-28 16:31:54 +00:00
stephan cd1cbd641c CLI shell: make (.output off) an alias for (.output /dev/null) or (.output nul), depending on the platform. Discussed in [forum:633979ce307f1cc6|forum post 633979ce307f1cc6].
FossilOrigin-Name: 0f11087b84753576425823e10a7eeff45af02f3c0135dee72dec5019c8127500
2025-03-28 15:36:49 +00:00
stephan 13a9fb0d21 Configure/make doc tweaks. No functional changes.
FossilOrigin-Name: dbcc03bd7a727f4643f18a814bb9fd9071c0355f98dd064286240f2af361ee7f
2025-03-28 14:32:01 +00:00
drh 257e026de9 Merge cygwin and tclsqlite fixes into trunk.
FossilOrigin-Name: 121f4d97f9a855131859d342bc2ade5f8c34ba7732029ae156d02cec7cb6dd85
2025-03-27 23:29:25 +00:00
stephan 5ee946f907 Add an explicit db close to fix a file-is-opened failure in session1.test in cygwin.
FossilOrigin-Name: c6e4e1cf2b70d2e603ea3faabd9cb5fbd9f5497672574283ace8c62984dfbb97
2025-03-27 18:42:51 +00:00
drh 460e4cb686 Rearrange #includes in FTS3 to avoid a harmless compiler warning.
FossilOrigin-Name: c5206cee83a4f1e59bfceda35cdfa528f9b4611eaf306da863ae83e9f93cdeb7
2025-03-27 18:22:11 +00:00
jan.nijtmans 1f3207a52a Fix for forum-post [/forum/forumpost/b5fde3596c|b5fde3596c]. Also fix encoding issue for non-ASCII characters.
Also includes a fix from Stephan Beal, about a missing <stdint.h> include.

FossilOrigin-Name: e60198001e12f85a5d6504ce72226dfceb8666fe5ec649237fa23ae20e8aa32d
2025-03-27 17:30:49 +00:00
jan.nijtmans d07045119d shell1.test: == => eq
FossilOrigin-Name: 99fdd19193056259d84768f46519328c300976b102f1b1e0b815720df01b28d0
2025-03-27 17:25:38 +00:00
jan.nijtmans 1588d3de37 More ==/!= => eq/ne fixes
FossilOrigin-Name: 2aa6c4fa6c9c47c7a8548ac3493bfb9ed4e4dec1b6dc4f3599a0373086b3e917
2025-03-27 14:37:07 +00:00
jan.nijtmans 87b90921b6 In Tcl, always use eq/ne for comparing strings, not ==/!=
FossilOrigin-Name: f96a5346e3e890adfdc94a682688c2c15893e50fbaf2a26e5ef39cda8b331ee4
2025-03-27 14:32:57 +00:00
jan.nijtmans eb2644024a Merge trunk. Some additional test-fixes for Cygwin
FossilOrigin-Name: b36adadfa202fb8951149561471c3e01085d31e1837c99806f308f234cd24a8e
2025-03-27 14:13:12 +00:00
drh 7b3477c776 Fix an off-by-one bug in the ".dbtotxt" command from the shell that results
in incorrect output.

FossilOrigin-Name: 2345094e879c5538bfea005785ce0848e6d565a49bcb48b323c258d00ccbe9b8
2025-03-27 10:59:18 +00:00
drh 87ceb6ba9e Reduce the delay caused by anti-virus retries in Windows when attempting to
open a database file with insufficient permission.

FossilOrigin-Name: d25c8a6222d4e3f20c137b1490572ad491d9c404ff12947d5867c3e00fcb615c
2025-03-26 22:23:22 +00:00
drh a6f6fa8675 On winOpen(), redo the read-only test on every retry attempt. Just
don't retry the winAccess() call.

FossilOrigin-Name: ccdd67ad9a508530ccfcec582410768c24bca4eb8b05939577fb99a50dd44b15
2025-03-26 17:05:29 +00:00
drh 4a6de7ff7c Further attempted improvements at fast-fail for an inaccessible
database file.

FossilOrigin-Name: cdeb21a312d4f1a9e3009a0baf0af33857c172f7bc22bca047dcd46a03e9c964
2025-03-26 15:51:05 +00:00
drh 517a0e04d1 Attempt to reduce the amount of retry time when trying to open
an inaccessible database file on Windows.  See
[forum:/forumpost/e7991420f54dca50|forum thread e7991420f5]

FossilOrigin-Name: 986e45912cde7cb8e6db8ba7a9364aef7187a23032be64ef6cd573163f56676d
2025-03-26 14:45:15 +00:00
stephan 22d502e33a Merge trunk into cygwin-fixes branch. Add .fossil-settings/binary-glob to squelch warnings about *.db files on Cygwin.
FossilOrigin-Name: a8328b921c5504eceacade417e16e713999eff63978caf3418fd79501590b1cb
2025-03-26 00:02:15 +00:00
stephan 6de1c9d559 Configure script internal cleanups. Factor out the superfluous proj-lshift_ and use lassign instead. Add -ro flag to proj-file-write.
FossilOrigin-Name: 1f98fc07fdf06d699ffbf1521b0b5e937a582017e4325bd994b488e06becbecc
2025-03-25 01:32:16 +00:00
drh b0c3118cad Clarify and reduce redundancy in an assert() in walChecksumBytes().
FossilOrigin-Name: 3c53abf5e6df446d569040042363265737aa10fc8aaa20b31c587100c557c5e7
2025-03-24 23:08:40 +00:00
dan e6e453def6 Test that the sqlite3changeset_apply() function is properly appling indirect changes.
FossilOrigin-Name: 1dadea3a79c3edd110b0b32b07287744300958fed31f2da11901a42b16f86669
2025-03-24 19:58:13 +00:00
dan 1b906dd920 Add test cases to session1.test.
FossilOrigin-Name: dda9d7cf319e74de7703bda1eb77e3e7aa7459d6fa1508cc1d62cdfc7985c368
2025-03-24 11:13:18 +00:00
stephan 49a015092e Correct a --force flag which should be -force in a TCL file delete call. Some TCL versions (like the one on my system) accepts either but others don't. Problem reported in [forum:c02224d862|forum post c02224d862].
FossilOrigin-Name: 172f4e4772d90f4737eddb43d97a566a6e3b92702c61e23391e43134737cc838
2025-03-23 23:04:48 +00:00
stephan f58b2c46d0 Remove tool/tclConfigShToAutoDef.sh, as that functionality was moved into autosetup/proj.tcl so that it can be reused in, e.g., autoconf/tea.
FossilOrigin-Name: c9c5a15d4d8141aae68d6643869f74879ae053cb86538b805058099af2cec16b
2025-03-23 22:49:00 +00:00
stephan 8d80ca2d1c Internal configure refactoring to support an ongoing conversion of ./autoconf/tea to autosetup.
FossilOrigin-Name: e1d483e342670092c3579f2f0975e49a0c74516ae34103a63b4cde156bf5e92b
2025-03-23 21:38:28 +00:00
drh 75484481c7 Fix the generate_series() enhancement from check-in [d50b784807333c54]
so that it works even if the number that "value" is being compared against
is a non-integer floating point number.  Bug reported by
[forum:/forumpost/0d5d63257e3ff4f6|forum post 0d5d63257].

FossilOrigin-Name: c113e31b818d16770bec1edc980f6833dfb27c4d74178e66a778fbb5671c3a13
2025-03-22 22:55:33 +00:00
stephan 3f911b12e6 Replace use of autosetup/lib/*.auto for sqlite-custom-... features to avoid the possibility of multiple files being loaded (in an unpredictable order) for that purpose. Instead look for autosetup/sqlite-custom.tcl and source it if it exists. The intent is that sqlite-custom.tcl only ever be added in vendor-specific branches and never in the trunk.
FossilOrigin-Name: f3c0071284fbe1c0a8c3fe73792a79f9df6be983e5c9bd1a7e2fe71ba7b2d400
2025-03-22 19:07:54 +00:00
stephan bf698fd69d In the post-configure validation, ensure than no more than one autosetup/lib/*.auto file is found, for reasons explained in the validation's error message.
FossilOrigin-Name: 50bbd69a684988a1df4c9c7616b76ae62bc4eb755cde18616de58aa0880fd4a7
2025-03-22 18:41:48 +00:00
stephan 0fce9c935f Slight corrections to the new docs in autosetup/README.md.
FossilOrigin-Name: 55029e41e03d9b61b8a53f86d7f69afe71459846f3a1a1723f6934e0d37ca77f
2025-03-22 17:56:20 +00:00
stephan 77dc2d8fb1 Document the new configuration customization approach and extend it to enable sqlite-custom-flags to return an empty string to denote that it does not require any new flags (it may still customize flag default values in such cases).
FossilOrigin-Name: b0c7800b0106e90cb7bf7e5d9f48d21f9b058eff6e42339a1621d713ab2dd03c
2025-03-22 17:28:29 +00:00
stephan d9535334c6 Teach mkautoconfamal.sh to avoid copying autosetup/local.tcl and autosetup/*.auto except for autosetup/lib/CURRENT-BRANCH-NAME.auto (if any), the intent being to use lib/CURRENT-BRANCH-NAME.auto for branch-specific configuration customizations.
FossilOrigin-Name: dfe24f13c446de5fdd736ed52fec0fca4637b4151ba008de7a598a2fc9398816
2025-03-22 17:00:32 +00:00
stephan 515b51f635 Add a mechanism to the configure script to allow certain client-specific builds to extend or override the configure options without having to edit sqlite-config.tcl, the goal being to reduce merge conflicts in those builds when updating sqlite-config.tcl from the canonical copy.
FossilOrigin-Name: bafab4ee5545c6cf6eafc5e352a7f25dfcbc7e58d4cc9064d05658c39de2af0d
2025-03-22 16:14:34 +00:00
stephan d877b56688 Configure script internal cleanups and re-orgs. No functional changes.
FossilOrigin-Name: f619e40fb05d3e09dca2ad9d9bbf38c66b4b93dd3d4e7c2071db28e671ee6a9c
2025-03-22 12:43:22 +00:00
stephan 51aef0e4da In the autoconf bundle, do not strip binaries during installation, for parity with the canonical build and the legacy build. Discussed in [forum:9a67df63eda9925c|forum post 9a67df63eda9925c]. A potential TODO here is to add a configure flag which either enables or disables stripping.
FossilOrigin-Name: 6d2e57bd34c562a9cd618c178c3f92b869bf5420907057b8d2438b16a7f91d46
2025-03-22 12:15:13 +00:00
stephan 28b7bfc30f Slightly simplify proj-current-proc-name.
FossilOrigin-Name: 6a0ca9f2360d29272d7be97fe9f516c3ac88864f3e729ba65da1ef6211908775
2025-03-21 22:14:30 +00:00
stephan e02fade10b Fix a multi-arg expr call in proj-current-proc-name (must be single-arg for portability).
FossilOrigin-Name: 914768f3f5d63a891e1cd578afc676960376fc28ee0fa452fcd32cec0ea5cdaf
2025-03-21 21:13:44 +00:00
drh 7f4efdcb65 Teach the CLI that VT100-escape codes that do things like change font
colors have zero-width for the purpose of laying out the columns of a
table.

FossilOrigin-Name: 2d0a8a6c38981552748ff5fc2eeba86590e0f116abac260a7fc9318de0a0dbda
2025-03-21 18:15:13 +00:00
stephan 11d5bea210 Flesh out the new proc-debug and its infrastructure a bit.
FossilOrigin-Name: ba7f1ff0d7d1d3fb79fc298d99fd27b65f639fb1691a1a9cdc9c006b8ff41212
2025-03-21 16:49:32 +00:00
stephan eb6997fbac Proxy configure's msg-debug with proc-debug, which works the same except that it prepends the name of the calling proc to the debug message. No functional changes.
FossilOrigin-Name: f0298c773d3490ad3a5b53d2ceeff1bd90e1a7bb5deeba2d24f681ec1bc10510
2025-03-21 16:06:16 +00:00
stephan 315de605af Teach the configure script to be able find a default installation of libreadline on Haiku OS.
FossilOrigin-Name: 260e9884118172ef76457a34042ace301f20abab4ced172f6b6135010c446a68
2025-03-20 13:41:08 +00:00
drh 4c13878ac2 Fix a problem in the sqlite_dbpage() table-valued function when it is
trying to truncate a file in locking-mode=EXCLUSIVE and the file was
obtained via sqlite3_deserialize().  Problem found by dbsqlfuzz.

FossilOrigin-Name: 346cf9794c6ce82ac32f7ccabc67240309306626709951593720abd198b103e3
2025-03-20 11:47:39 +00:00
stephan 339f9a33b4 Correct part of [505d9e49f7] and [7126a51ed8] to get sessioninvert tests working on cygwin.
FossilOrigin-Name: 83c34decbe336c76062e6b1bfe4c2e8f786841a4b6efa001747e786e872c8c71
2025-03-19 15:21:21 +00:00
stephan 18b250e9c9 Correct part of [04075517] which changed the implicit return value of a test function.
FossilOrigin-Name: 505d9e49f7af619eda9e46e7ed19c4446c64628233528e1ab3f70264e1640ace
2025-03-19 14:57:32 +00:00
stephan f715576a6c Add some explicit db close calls to work around a process-reaping timing problem on cygwin builds.
FossilOrigin-Name: 7126a51ed8a1b90b7f4cf3f1c13f7a1d560ff7a3ae73897ce8d9194df40356ed
2025-03-19 14:52:39 +00:00
stephan 52e2a79304 Test script patches from Jan Nijtmans: always use -DUSE_TCL_STUBS in buildtclext.tcl and improvements in how TRG is populated in testrunner.tcl.
FossilOrigin-Name: aa192203aa1aa188866fe00a5d40dc7b7c72b4f38b06da8708ed0a6c8b8638a6
2025-03-19 13:49:34 +00:00
stephan 21aeeb06fe Merge trunk into the cygwin-fixes branch for the shell test improvements on Windows. An MSC build's make test now has zero failures.
FossilOrigin-Name: 2de4efe10c2591192edca3833fc9e2fae10ebc925fb556f5b53ad483b491b5b3
2025-03-19 13:13:12 +00:00
stephan 178edbaa2f Avoid running test cases involving ANSI control characters or Unicode on Windows in a slave interpreter, as that combination does not work.
FossilOrigin-Name: c7fd71c77f1716c9c85d0f41a07ebd7c96f2e9d5e4c1392fefa1fb53f3cbb746
2025-03-19 11:53:46 +00:00
stephan 6e059d9dac Merge trunk into the cygwin-fixes branch.
FossilOrigin-Name: 34eadd374b3c0a8c9e1f5f4a1c60fda8f16b1c56213b8c4047f96390c676b695
2025-03-19 10:14:46 +00:00
drh 8db881d055 Change the generate_series() table-valued function so that its rowid is just an
alias for its value.  This allows it to be used as the RHS operand of a
RIGHT JOIN.  This fixes the issue raised by
[forum:/forumpost/1e17219c88|forum post 1e17219c88].

FossilOrigin-Name: 77db4d85e70fbf358ae2321c2601966666bdb4d971d7c113ce30a3e541458ee8
2025-03-18 20:15:16 +00:00
dan 31fd886576 Fix a problem that could occur when the RHS of an IN operator was a compound SELECT featuring an ORDER BY on a subquery that was flattened into one of the component SELECTs introduced by [baa83b460c677c21]. Forum post [/forumpost/1e17219c88].
FossilOrigin-Name: 7101ccd5331e36fd1a539f540e79ce0ce159be76ec422e1d9436eec6f3908c6e
2025-03-18 19:21:04 +00:00
stephan e435547beb Internal doc touchups in ext/wasm/mkwasmbuilds.c. No functional changes.
FossilOrigin-Name: 47d34260e74912eeae704bff7c4314b893af86ee66dd96a1bc6f450d3e290702
2025-03-18 13:52:53 +00:00
stephan ccda0f008a Very slight simplification of the run-fuzzcheck rules.
FossilOrigin-Name: c858a39fad30c46aec6a1f81b2d4e56c18ecf7f5cb6d2fe4a32c4b3bb1a6ed64
2025-03-18 12:31:09 +00:00
stephan a49265b717 General updates to autosetup/README.md.
FossilOrigin-Name: be8ad5cf579662c54b7e7bc492d8ca03b1f9032c5dad9a6b20590ca1ac00840b
2025-03-18 11:36:15 +00:00
stephan 17df9cd909 Update the docs in tool/mkccode.tcl to reflect that it's more generic than it was when the docs were written. Change the shebang line to use /bin/env tclsh instead of a hard-coded tclsh path.
FossilOrigin-Name: 9300f7f42dfd143f77fd51aa9e080099540854d36b6997ab1a16be7d77f78d8e
2025-03-18 10:28:56 +00:00
drh 7b99cd6063 Prevent integer overflow when parsing NEAR queries in FTS5.
FossilOrigin-Name: 1a5283d7dab210badb8a33eac29f44dc8c1c210ffb5ef84f43e348170aa406a6
2025-03-17 15:13:47 +00:00
stephan 1774ec3ad0 Add support for the --with-wasi-sdk configure flag to the autoconf build.
FossilOrigin-Name: 44880fa3f0748604ef50b942c28390e041138759efea1d076dfcaa1da48970cb
2025-03-17 14:59:55 +00:00
stephan d176ef5881 Fix a long-standing filename digest computation bug in the OPFS SAHPool VFS which caused all VFS-stored filenames to have a digest value of 0. See [/forumpost/042d53c928382021] and for full details.
FossilOrigin-Name: 493cbe74504e8eb1ca8f2edf49fdab6bebc7fe36ffab06932a4b8c5a4eea86cd
2025-03-16 14:05:42 +00:00
stephan ab68965794 Add --asan-fsanitize=... configure flag to the canonical build to optionally set -fsantize flags for the fuzzcheck-asan tool. Teach proj-check-fsanitiz to fail for flags which the compiler emits any warning for, for reasons described in its comments.
FossilOrigin-Name: 013730e9b92af39cb7fd2871df9b4bc81b8990f918892bd79370704421672da0
2025-03-16 13:09:21 +00:00
stephan 539442300c Configure-internal doc cleanups. No functional changes.
FossilOrigin-Name: be3a2e631100b711996b9524a54fc604966513a62d83fc916270a6226da7adab
2025-03-16 12:27:21 +00:00
stephan bafddb17d7 Consolidate some much-duplicated run-fuzzcheck recipe code in main.mk.
FossilOrigin-Name: c0d9b9fad3a2f23941927f1be2abded3bde2f2b04f7a5f3cc0a54a978020ebaa
2025-03-16 11:24:32 +00:00
drh fc293f7c0e Rework the run-fuzzcheck makefile target so that it better exploit parallelism.
Test case "<tt>make -j16 run-fuzzcheck FUZZDB=20250222.db</tt>"
went from 596 seconds down to 107 seconds.

FossilOrigin-Name: 18bda13e197e4b4ec7464b3e70012f71edc05f73d8b14bb48bad452f81c7e185
2025-03-16 00:13:29 +00:00
drh 42db4d043e Enhance the fuzzcheck testing tool with new command-line options:
--brief, and --slice M N.

FossilOrigin-Name: e64132723db0c4f2b9a58932a93beb1671e42006eebc1aeaa8f320e717043051
2025-03-15 23:42:32 +00:00
drh 6e5d59e8ef Make use of the C99 flexible array feature, when available, so that
the -fsanitize=bounds-strict option can be used, when available.
[forum:/forumpost/311dbf9a1cadfae6|Forum thread 311dbf9a1c].

FossilOrigin-Name: d4307a0d43f42e96ec06ad2c1d8d0f5c8ecae759bae8231b1998633089809f49
2025-03-15 19:55:19 +00:00
drh b7b060401e Work around compilers that do not understand flexible arrays, in the
recovery extension and in the fuzzcheck test module.

FossilOrigin-Name: f101c46cf83e532fd33034abccba496bf395ef10c161af003211614d6581d5eb
2025-03-15 19:00:46 +00:00
drh 7bd72d4abf Fix alignment problems on Linux with -m32 and on Mac PPC.
FossilOrigin-Name: 8a91aeca60548d5cd19add128cf65b9c3815c9103b1ef8ff6bc02711b6d709de
2025-03-15 18:26:27 +00:00
dan f212fb3362 Speed up parsing of very long fts3 query expressions.
FossilOrigin-Name: 2dd5b6895a3b23c2b9cbf0c1c1e802faf8f2b41ef60819eea25d609755266e64
2025-03-15 16:58:39 +00:00
stephan 9f8a238fb5 Configure-internal build cleanups (no functional changes). Add EXTRA_SRC to the deps of sqlite3.c.
FossilOrigin-Name: 8afb8bbce8654d6f76207fb136e79dc52b6724a71eae82a4c098690a68eb75a1
2025-03-15 15:19:42 +00:00
stephan 8c0e922721 -fsanitize is a CFLAG, not LDFLAG, so rename some vars accordingly and simplify the feature check to not run the linker.
FossilOrigin-Name: 44f2c64ec16f4720dc538be30410863c4138ea4ce41c94521bd7980535261735
2025-03-15 13:50:07 +00:00
stephan f792cda1a1 For fuzzcheck-asan, dynamically determine the list of -fsanitize flags to use based on configure-time feature tests.
FossilOrigin-Name: b70f9cc81516e57e73960bed4b4d2abdcf3dab0ad4a400ca1aed49365c25231e
2025-03-15 13:36:01 +00:00
drh d389fd3699 Omit the -fsanitize=bounds-strict for now, as that is still not widely
implemented.  In particular, it does not work on Macs.

FossilOrigin-Name: 3e1c2ac7817e73ea736a39bb0c0ec8212ceedbc89b265b4caf1b53871d27d7c0
2025-03-15 13:11:24 +00:00
drh 0a4f10e6e2 Use flexible arrays in the recovery extension and in the fuzzcheck test program.
Adjust the unix makefile to use -fsanitize=bounds-strict when building
fuzzcheck-asan.

FossilOrigin-Name: 6ea6a6b211fed1a14d7bec1ab1790dec09e2a00423860498a60b760c4a4561fa
2025-03-15 13:04:16 +00:00
drh bd0e3ed522 Use flexible arrays whereever appropriate in FTS5.
FossilOrigin-Name: 16dfc415b6e98a2acae79a24bb0afd401e60efc27cbdd1603a426fd33e17d427
2025-03-15 12:22:39 +00:00
drh 17abe9e251 Convert the Fts5Sorter.aIdx field to a flexible array.
FossilOrigin-Name: 28ac776a23da2753265a7fe2ee2ebb09964815fc9058e69c08275fc217842edc
2025-03-15 00:11:22 +00:00
drh 502b7a236e Turn Fts5Colset.aiCol into a flexible array.
FossilOrigin-Name: 0c4d9c74741794468adc444908f6024f016738aa2852d3a646f2c28d079d9446
2025-03-14 23:57:53 +00:00
drh 126541f8ac In FTS3, rename the MatchinfoBuffer.aMatchinfo field to aMI, to avoid confusing
it with MatchInfo.aMatchinfo.  Make aMI a flexiable array.

FossilOrigin-Name: bb00b973980d259ca85af84c054501cae78b3a9d33ccffa54d7034235dd8d50d
2025-03-14 23:20:12 +00:00
drh dbd455a0fd Fix one of two flexible arrays in FTS3.
FossilOrigin-Name: ddfa87c17906ecf7fd5639a87bbfa9a87d17ab688159acd2fd80cc5b6f25f09b
2025-03-14 21:15:11 +00:00
drh 01ef1dfc1f Use flexible arrays for RTREE.
FossilOrigin-Name: 2b41776179c726586e3ff836edcf235938cf02f7c5e33c1d6954b84d4061b8d5
2025-03-14 20:19:49 +00:00
drh b6e8f65ffe KeyInfo is now an indeterminate size, so we cannot declare a variable of that
type, only a pointer to an instance of that type.

FossilOrigin-Name: 37b687dc2d3b9dc82ed09a9c5b2c00e576b1eebe358a20d18a3da190347b644e
2025-03-14 19:07:11 +00:00
drh cebf06c798 Make use of the flexible-array feature of C99, when available, to try to
pacify -fsanitize=strict-bounds.  This check-in fixes the core. There is
more yet to do in FTS3, RTREE, and in FTS5.

FossilOrigin-Name: 6fd6b32d06bd6a705e5140cd613af823b8183a6f6a9ceeeedfcf5e8b50821d68
2025-03-14 18:10:02 +00:00
stephan dae87df198 Fix an internal doc typo reported in [forum:e25e581f917|forum post e25e581f917].
FossilOrigin-Name: fa6f6ccdffc50024624306900efd2538c7415d8bdd0f02835b2e9c05adab3cf1
2025-03-14 12:37:36 +00:00
stephan 5390f95f07 Minor doc corrections for the sahpool-digest fix and merge in current trunk.
FossilOrigin-Name: 500f2e6ec74b4c0e4ac0365ba4e0d81ed6df8dd09dc0f8af65d294c3453f8865
2025-03-14 11:14:52 +00:00
stephan 1560045c32 Cherrypick the [2b582c0097e33] doc addition, which was initially committed to the wrong branch.
FossilOrigin-Name: f786de8d1873cd27b1bf83273a1e100e9d481144674888ccf65974e003a3caad
2025-03-14 09:34:09 +00:00
drh 99e8490705 Fix the generate_series extension for the case where the termination value
is not an even multiple of the step from the start value and there is also
a value=NNN constraint in the WHERE clause.
[forum:/info/bf2dc8e909983511|Forum post bf2dc8e9]

FossilOrigin-Name: 75e72e3b0d0d689d39e00a01dc361dd6ce2649e68d200bf501ddcf04063041b2
2025-03-13 18:51:18 +00:00
drh 62d9d70edd The --echo flag on the CLI also echos dot-commands provided on the command-line.
FossilOrigin-Name: 6ec0c03b954cf705da076d035a1cc2e784233ae28857385379e44a59af6c5ec4
2025-03-12 15:17:13 +00:00
stephan ff3c451428 Document that sqlite_update_hook() can unset the current hook by passing a NULL callback, to address [forum:652aef4747|forum post 652aef4747].
FossilOrigin-Name: 2b582c0097e3374beb280dfa6b03e0dacb9911da1bceb0dce0468e6b7291e74f
2025-03-12 11:41:12 +00:00
drh 72b5c6db35 Avoid running test cases involving ANSI control characters or Unicode
on Windows in a slave interpreter, as that combination does not work.

FossilOrigin-Name: f6745a7355c62ee64c08e23b795f437dd74add903b55e1255c1d03f9a811170d
2025-03-11 15:46:23 +00:00
drh a7829ecbdd The substitute "puts" command used by the Windows implementation of
sqlite3_analyzer must invoke fflush() after each line of output.  Otherwise
the output can be truncated when redirected into a file.

FossilOrigin-Name: ba058ce90a2ba9ebc4d8fb289108c04f80fa85da01c0b8bd58855681836ba83d
2025-03-11 12:19:27 +00:00
stephan 1fc7844d40 Teach testrunner.tcl to distinguish Cygwin from Windows. This gets it running but then all downstream tests fail, at least in part because of the build target name discrepancies between the platform which requires .exe and those which do not.
FossilOrigin-Name: 2861788e479aea12354f2d34d8e6a2706d193642674ef1f4f852f24c877e0140
2025-03-11 11:24:52 +00:00
drh 642479d1cd Ensure that the TEMP database has been initialized at the beginning of
a call to sqlite3_open_blob() for the TEMP database.  Fix for the issue
reported by [forum:/forumpost/0a556d619b|forum post 0a556d619b].

FossilOrigin-Name: 2cfccdbe08b7b14a6b255f7157ac20d0807327adefcb33fcffeeed14c7603fe1
2025-03-10 22:31:55 +00:00
stephan e0fa42053f Merge trunk into the cygwin-fixes branch.
FossilOrigin-Name: f3d14433f24f89558e72a9085c950bc72440e9933d6b4ff59d6e603d25e39422
2025-03-10 17:35:00 +00:00
stephan 09eba154b2 Add an explicit db close to test/walsetlk.test to work around an unjustified test failure on Windows when the walsetlk tests are run in the same invocation of testfixture.exe in Windows.
FossilOrigin-Name: f418de109335cd7cb29d2b587540c163bbaaa7129c662c2908ef67492139b2d7
2025-03-10 17:28:43 +00:00
stephan b37f8b9714 Patch an unnecessary size_t-to-int conversion which warns on some compilers.
FossilOrigin-Name: 8681dfdb59d3258663ec176daafd7a52446a207db21fbd1a4d151508092dcbc5
2025-03-10 15:35:43 +00:00
stephan 4cd6c0b81b Ensure that the 'clean' target for Makefile.msc cleans up the testdir dir, analog to how the canonical makefile works, as stale files there have been leading to test failures.
FossilOrigin-Name: a591c018558af70e0ddfdd2d4d61905f030bac01df19ac9b204aed09d44517be
2025-03-10 15:27:17 +00:00
stephan 42e5ceb093 Reimplement pathname conversion on Cygwin. MSC test passes/failures are on par with trunk and 'make test' running on cygwin is down to a single failure.
FossilOrigin-Name: 57a4de09149663ac001848773c9dffe53e30f9263e4dacc792a0267401147d25
2025-03-10 15:15:13 +00:00
stephan 05ba11fc95 Tweak [6f24da264cf8d] so that it has no side-effects on autoconf/Makefile.msc.
FossilOrigin-Name: d3d322f122e88ea7d7f086f1c7d3ba8ab5ba7c2899d6d1e18b0b593001f01dcf
2025-03-10 14:10:46 +00:00
drh eed4e1d2df Disable the [d1ba200234f40b84|count-of-view optimization] if any subquery
is DISTINCT, as the optimization does not work in that case.
Bug reported by [forum/forumpost/a860f5fb2e|forum post a860f5fb2e].

FossilOrigin-Name: d7013b63932b2f5750572ae6bdd259a2b6e6548c20fb9a5559edd22d2f2fc6cb
2025-03-10 10:32:31 +00:00
stephan 49a5da1138 Add tf.bat target to Makefile.msc to facilitate running of individual test scripts via testfixture.exe.
FossilOrigin-Name: 6f24da264cf8d4c9fef706e6ab89e8c002ac4abfb79516f65ff4eb806f864959
2025-03-10 09:54:01 +00:00
stephan 065c0a6120 Test app/script patches from Jan Nijtmans for cygwin. Add/replace many more sentinel arguments for TCL variadic functions which specifically need a NULL trailing argument. With this, 'make test' on cygwin runs to completion for me, with 134 of 329227 tests failing. MSC build fails the same 13 tests which fail for me in trunk.
FossilOrigin-Name: 84d8fcfca19cd183d05a702d0eb1742bfae462d3383a3db72741a48cefac1058
2025-03-08 06:53:06 +00:00
stephan 7b9407af90 os_win.c patches for Cygwin (described in the cygwin-fixes branch wiki page). Makefile.msc's test target on trunk fails the same 13 tests as this branch.
FossilOrigin-Name: 655c60d1926adb552d37441bf9857263eae92e3806a8524e8443b81fdfd8c258
2025-03-07 06:54:04 +00:00
stephan 908c0301d1 Merge trunk into the cygwin-fixes branch (which was inadvertently branched too early).
FossilOrigin-Name: a7863b2e2fbea0ea11c494016b99921f70aae09607868aa65af988cbd173b31a
2025-03-06 14:40:45 +00:00
stephan 8199c8d7a7 Cygwin-centric test script tweaks from Jan Nijtmans.
FossilOrigin-Name: 9868615b7d41179672dde2eafff878d50cf9d647c7050ccf5103e385fd182fc2
2025-03-06 13:49:27 +00:00
stephan b6503f1444 Cygwin-centric fixes from Jan Nijtmans.
FossilOrigin-Name: 205979813c7300debb5f1ba270583ef2f08e069d6d01865b5910702889a5c1ed
2025-03-06 13:38:07 +00:00
stephan d75acb8312 Back out the most significant part of [5c28a17253e2f], as Cygwin is a hybrid. With SQLITE_OS_UNIX it will use POSIX locking, which will misinteract with apps using Windows-style locking.
FossilOrigin-Name: 44adf8f38761a0d756c047f93fc76fc1d0aba8cc209970e3ba13e7040dd14b13
2025-03-06 09:29:15 +00:00
stephan 47991d973a Various typo fixes reported by Daniel Dumitriu. No functional changes.
FossilOrigin-Name: 37e6ec777445d8ef81acecbb66f86ae78f2ae67ef0bfd3fbd089da51fff35cc9
2025-03-06 09:08:38 +00:00
stephan ba6510a399 Additional 'array index is signed char' warning cleanups for the shell and its embedded extensions, analog to [44bd44532d].
FossilOrigin-Name: f31042595b8f8a378db9778c9a8223b07ec02cf2f528581ba43bf72b5b03c964
2025-03-06 07:48:45 +00:00
stephan 894cda4db7 Fix a tcl typo in the previous checkin which triggers an error on one machine but not another.
FossilOrigin-Name: 646c2821ad434058db7760e699d21a47c7feb5976199cbe4b58d54c902720cbf
2025-03-06 07:09:50 +00:00
stephan 2d960e943b Have the configure script report cygwin as SQLITE_OS_UNIX instead of SQLITE_OS_WIN, per off-list discussion with Jan Nijtmans.
FossilOrigin-Name: 5c28a17253e2fe56d7fd97cc43345b3fd8bd59fccea3fb1547ed87f7902f76f5
2025-03-06 06:25:45 +00:00
dan fc9b5d2a95 Have the recover module add "PRAGMA foreign_keys = off" to SQL output. Have the shell tool add ".dbconfig defensive off".
FossilOrigin-Name: dcfe3d3292851aa48a085a2c68623b049e2786c8dc7154ccc78508443973b5a1
2025-03-05 19:39:02 +00:00
drh bee4fb401e Always ignore comments in the schema of a database, even if
SQLITE_DBCONFIG_ENABLE_COMMENTS is turned off.

FossilOrigin-Name: 373ae3f4de526c636c35db03d6b5c84526d6f144c1c3bebcbb257e52f563a203
2025-03-05 18:18:17 +00:00
dan c27c61586f Update the recovery extension so that it works with encrypted databases.
FossilOrigin-Name: b0b66f21159b47e1950ca63a01f92fe4f621efb9a2962b310d65fa7ebdbb43b3
2025-03-05 17:26:56 +00:00
drh 427e0076a9 Use AtomicRead() and AtomicWrite() to access the pcache1_g.bUnderPressure
global, to forestall unnecessary angst from thread analyzers.

FossilOrigin-Name: 41ec85637a7fac710a3986ee78ed25a96d331a03653069bae4d9f826cc6f944a
2025-03-05 17:12:42 +00:00
drh 9f19ea83e7 Improvement output for ".schema --indent" in the CLI when the schema contains
partial indexes with long and complicated WHERE clauses.

FossilOrigin-Name: defd7187ff8c4388f8b5467ed168462ec48215a1f4263bc4128b8e4d89a0bb2a
2025-03-05 16:35:51 +00:00
stephan bf09cbe2ca Minor configure script cleanups which started out as cygwin-specific fixes but ended up just being minor platform-agnostic cleanups.
FossilOrigin-Name: 2cda90410ac62843fa3cf5a9592b2b25564cf9d829e107c85854e8167d4fe46d
2025-03-04 21:37:40 +00:00
stephan 4b60c1b49c Roll back part of [6d87a8efe]: the check for tclsh90.exe (as opposed to tclsh9.0.exe) is incorrect on these platforms (it's an msvc build). Also remove an unused function added in that checkin.
FossilOrigin-Name: dc84976a7c0d0028b7c576d54e18d1b8e1fc2376bc7b0504f1c86e82c1f7c814
2025-03-04 21:31:18 +00:00
stephan e34ad2b0b3 tclsqlite3 patch from Christian Werner: replace FILE handles with TCL channels for the db copy command.
FossilOrigin-Name: ea1f7f8de4abb80fe41a115c9f601ff27cd728493640c6d47d868913feec28dc
2025-03-04 21:25:18 +00:00
stephan 0ca5b1e39d Teach autosetup how to find tclsh v9.0 on cygwin.
FossilOrigin-Name: 6d87a8efe5611102eac150e5dc1e9d9602318ab8b96046b29c66602e7c3d12fa
2025-03-04 19:38:38 +00:00
stephan f5965e9d51 Makefile doc updates. Remove a couple extraneous targets. No functional changes.
FossilOrigin-Name: 5a3e22999f8da075f7ca3e039f10386fb85295a2457c9495d2c48b7137a84296
2025-03-04 07:29:28 +00:00
stephan 3ce81095f9 Minor doc typo fixes via [forum:65bd941da8|forum post 65bd941da8].
FossilOrigin-Name: 6f6a03e93cf58eaee79603de0b28ad34c872fb4b4b7d9c4e7fe35c698b27618a
2025-03-04 06:29:03 +00:00
stephan 5b27bfac44 Document the EXTRA_SRC makefile var and add --amalgamation-extra-src=list to the canonical-build configure script as the formal way to pass that at configure-time.
FossilOrigin-Name: 44de0ec29a86f91a227132f7af8898108d555463b754b299eace0ee8475bad57
2025-03-04 05:16:10 +00:00
stephan 69eaadbee3 Merge trunk into the sahpool-digest branch.
FossilOrigin-Name: fc1eeb7d1f2880907b0fe71a8c572dd7cd74a5d65ec0177332976ad2f8c2b216
2025-02-26 03:32:52 +00:00
stephan d2f7dfa619 More work on the sahpool digest fix. New/fixed versions can read legacy (no digest) files but the reverse is only possible in limited circumstances (when files originated from a legacy version). The burning question is whether the real fix would be to remove this digest check altogether, as it only applies in a very limited context, and the fact that it was broken for some 18 months unnoticed suggests that its value might not be worth the CPU cycles.
FossilOrigin-Name: 0df62b776c68bebb0e187b353b6f29b0a41a29f0a1c8d6728fa6b9f7ce0d13f7
2025-02-26 03:03:08 +00:00
stephan c97abeac0b Add a test app to assist in validating the SAHPool digest calculation fix.
FossilOrigin-Name: a1e304b8020025cc73a658bd8c7697d59b4f3ad96cac0a3e36553a3207d13dc6
2025-02-03 17:21:54 +00:00
stephan 40ce00b546 Initial work on a fix for the SAHPool VFS's effectively-no-op digest calculation, as reported in [https://github.com/sqlite/sqlite-wasm/issues/97|ticket #97 of the downstream npm subproject]. This requires more testing alongside databases created before this version to ensure that it's backwards-compatible.
FossilOrigin-Name: 9234c33f92d92bfddc6211c9c587f1072e70837c0ffe1416ef7d84d59bacd364
2025-02-03 16:26:30 +00:00
412 changed files with 14713 additions and 18127 deletions
+1
View File
@@ -0,0 +1 @@
*.db
+24 -19
View File
@@ -122,10 +122,13 @@ LDFLAGS.rt = @LDFLAGS_RT@
CFLAGS.icu = @CFLAGS_ICU@
LDFLAGS.libsqlite3.soname = @LDFLAGS_LIBSQLITE3_SONAME@
# soname: see https://sqlite.org/src/forumpost/5a3b44f510df8ded
LDFLAGS.libsqlite3.os-specific = @LDFLAGS_MAC_CVERSION@ @LDFLAGS_OUT_IMPLIB@
LDFLAGS.libsqlite3.os-specific = \
@LDFLAGS_MAC_CVERSION@ @LDFLAGS_MAC_INSTALL_NAME@ @LDFLAGS_OUT_IMPLIB@
# os-specific: see
# - https://sqlite.org/forum/forumpost/9dfd5b8fd525a5d7
# - https://sqlite.org/forum/forumpost/0c7fc097b2
# - https://sqlite.org/forum/forumpost/5651662b8875ec0a
libsqlite3.DLL.basename = @SQLITE_DLL_BASENAME@
# DLL.basename: see https://sqlite.org/forum/forumpost/828fdfe904
libsqlite3.out.implib = @SQLITE_OUT_IMPLIB@
@@ -135,16 +138,13 @@ ENABLE_LIB_STATIC = @ENABLE_LIB_STATIC@
HAVE_WASI_SDK = @HAVE_WASI_SDK@
libsqlite3.DLL.install-rules = @SQLITE_DLL_INSTALL_RULES@
T.cc.sqlite = $(T.cc) @TARGET_DEBUG@
# -fsanitize flags for the fuzzcheck-asap app
CFLAGS.fuzzcheck-asan.fsanitize = @CFLAGS_ASAN_FSANITIZE@
#
# Define -D_HAVE_SQLITE_CONFIG_H so that the code knows it
# can include the generated sqlite_cfg.h.
# Intended to either be empty or be set to -g -DSQLITE_DEBUG=1.
#
# main.mk will fill out T.cc.sqlite with additional flags common to
# all builds.
#
T.cc.sqlite += -D_HAVE_SQLITE_CONFIG_H -DBUILD_sqlite
T.cc.TARGET_DEBUG = @TARGET_DEBUG@
#
# $(JIMSH) and $(CFLAGS.jimsh) are documented in main.mk. $(JIMSH)
@@ -213,6 +213,13 @@ TCL_CONFIG_SH = @TCL_CONFIG_SH@
#TCL_STUB_LIB_SPEC = @TCL_STUB_LIB_SPEC@
#TCL_EXEC_PREFIX = @TCL_EXEC_PREFIX@
#TCL_VERSION = @TCL_VERSION@
TCL_MAJOR_VERSION = @TCL_MAJOR_VERSION@
# ^^^ main.mk optionally uses this for determining the Tcl extension's
# DLL name.
TCL_EXT_DLL_BASENAME = @TCL_EXT_DLL_BASENAME@
# ^^^ base name of the Tcl extension DLL. It varies by platform and
# Tcl version.
#
# $(TCLLIBDIR) = where to install the tcl plugin. If this is empty, it
# is calculated at make-time by the targets which need it but we
@@ -243,8 +250,8 @@ TSTRNNR_OPTS = @TSTRNNR_OPTS@
CFLAGS.gcov1 = -DSQLITE_COVERAGE_TEST=1 -fprofile-arcs -ftest-coverage
LDFLAGS.gcov1 = -lgcov
USE_GCOV = @USE_GCOV@
T.compile.extras = $(CFLAGS.gcov$(USE_GCOV))
T.link.extras = $(LDFLAGS.gcov$(USE_GCOV))
T.compile.gcov = $(CFLAGS.gcov$(USE_GCOV))
T.link.gcov = $(LDFLAGS.gcov$(USE_GCOV))
#
# Vars with the AS_ prefix are specifically related to AutoSetup.
@@ -257,10 +264,15 @@ AS_AUTO_DEF = $(TOP)/auto.def
# invoked with to produce this makefile.
#
AS_AUTORECONFIG = @SQLITE_AUTORECONFIG@
.PHONY: reconfigure
reconfigure:
$(AS_AUTORECONFIG)
USE_AMALGAMATION ?= @USE_AMALGAMATION@
LINK_TOOLS_DYNAMICALLY ?= @LINK_TOOLS_DYNAMICALLY@
AMALGAMATION_GEN_FLAGS ?= --linemacros=@AMALGAMATION_LINE_MACROS@
EXTRA_SRC ?= @AMALGAMATION_EXTRA_SRC@
STATIC_TCLSQLITE3 = @STATIC_TCLSQLITE3@
STATIC_CLI_SHELL = @STATIC_CLI_SHELL@
#
# CFLAGS for sqlite3$(T.exe)
@@ -322,13 +334,7 @@ misspell: ./custom.rws has_tclsh84
# perform cleanup known to be relevant to (only) the autosetup-driven
# build.
#
#clean-autosetup:
# -if [ -f ext/wasm/GNUmakefile ]; then \
# gmake --no-print-directory --ignore-errors -C ext/wasm clean; \
# fi >/dev/null 2>&1; true
#clean: clean-autosetup
distclean-autosetup: clean
distclean-autosetup:
rm -f sqlite_cfg.h config.log config.status config.defines.* Makefile sqlite3.pc
rm -f $(TOP)/tool/emcc.sh
rm -f libsqlite3*$(T.dll)
@@ -342,5 +348,4 @@ distclean: distclean-autosetup
version-info$(T.exe): $(TOP)/tool/version-info.c Makefile sqlite3.h
$(T.link) $(ST_OPT) -o $@ $(TOP)/tool/version-info.c
IS_CROSS_COMPILING = @IS_CROSS_COMPILING@
include $(TOP)/main.mk
+20 -13
View File
@@ -884,7 +884,7 @@ RCC = $(RCC) -DSQLITE_ENABLE_API_ARMOR=1
!ENDIF
!IF $(DEBUG)>2
TCC = $(TCC) -DSQLITE_DEBUG=1
TCC = $(TCC) -DSQLITE_DEBUG=1 -DSQLITE_USE_W32_FOR_CONSOLE_IO
RCC = $(RCC) -DSQLITE_DEBUG=1
!IF $(DYNAMIC_SHELL)==0
TCC = $(TCC) -DSQLITE_ENABLE_WHERETRACE -DSQLITE_ENABLE_SELECTTRACE
@@ -1616,7 +1616,6 @@ TESTSRC = \
$(TOP)\src\test_quota.c \
$(TOP)\src\test_rtree.c \
$(TOP)\src\test_schema.c \
$(TOP)\src\test_schemapool.c \
$(TOP)\src\test_superlock.c \
$(TOP)\src\test_syscall.c \
$(TOP)\src\test_tclsh.c \
@@ -1624,7 +1623,6 @@ TESTSRC = \
$(TOP)\src\test_thread.c \
$(TOP)\src\test_vdbecov.c \
$(TOP)\src\test_vfs.c \
$(TOP)\src\test_windirent.c \
$(TOP)\src\test_window.c \
$(TOP)\src\test_wsd.c \
$(TOP)\ext\fts3\fts3_term.c \
@@ -1973,10 +1971,6 @@ fuzzcheck.exe: $(FUZZCHECK_SRC) $(SQLITE3C) $(SQLITE3H)
fuzzcheck-asan.exe: $(FUZZCHECK_SRC) $(SQLITE3C) $(SQLITE3H)
$(LTLINK) $(NO_WARN) /fsanitize=address $(FUZZCHECK_OPTS) $(FUZZCHECK_SRC) $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
run-fuzzcheck: fuzzcheck.exe fuzzcheck-asan.exe
fuzzcheck --spinner $(FUZZDB)
fuzzcheck-asan --spinner $(FUZZDB)
ossshell.exe: $(OSSSHELL_SRC) $(SQLITE3C) $(SQLITE3H)
$(LTLINK) $(NO_WARN) $(FUZZCHECK_OPTS) $(OSSSHELL_SRC) $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
@@ -2400,12 +2394,11 @@ SHELL_DEP = \
$(TOP)\ext\misc\sqlite3_stdio.h \
$(TOP)\ext\misc\uint.c \
$(TOP)\ext\misc\vfstrace.c \
$(TOP)\ext\misc\windirent.h \
$(TOP)\ext\misc\zipfile.c \
$(TOP)\ext\recover\dbdata.c \
$(TOP)\ext\recover\sqlite3recover.c \
$(TOP)\ext\recover\sqlite3recover.h \
$(TOP)\src\test_windirent.c \
$(TOP)\src\test_windirent.h
$(TOP)\ext\recover\sqlite3recover.h
# If use of zlib is enabled, add the "zipfile.c" source file.
#
@@ -2590,10 +2583,15 @@ sqlite_tcl.h:
testfixture.exe: $(TESTFIXTURE_SRC) $(TESTFIXTURE_DEP) $(SQLITE3H) $(LIBRESOBJS) $(HDR) $(SQLITE_TCL_DEP)
$(LTLINK) -DSQLITE_NO_SYNC=1 $(TESTFIXTURE_FLAGS) \
-DBUILD_sqlite -I$(TCLINCDIR) \
-DBUILD_sqlite -I$(TCLINCDIR) -I$(TOP)\ext\misc \
$(TESTFIXTURE_SRC) \
/link $(LDFLAGS) $(LTLINKOPTS) $(TCLLIBPATHS) $(LTLIBPATHS) $(LIBRESOBJS) $(TCLLIBS) $(LTLIBS) $(TLIBS)
# A small helper for manually running individual tests
tf.bat: testfixture.exe Makefile.msc
echo @set PATH=$(LIBTCLPATH);%PATH% > $@
echo .\testfixture.exe %* >> $@
extensiontest: testfixture.exe testloadext.dll
@set PATH=$(LIBTCLPATH);$(PATH)
.\testfixture.exe $(TOP)\test\loadext.test $(TESTOPTS)
@@ -2674,7 +2672,14 @@ srctree-check: $(TOP)\tool\srctree-check.tcl
# Testing for a release
#
releasetest:
releasetest: verify-source
$(TCLSH_CMD) $(TOP)\test\testrunner.tcl release
# xdevtest is like releasetest, except that it skips the
# dependency on verify-source so that xdevtest can be run from
# a modified source tree.
#
xdevtest:
$(TCLSH_CMD) $(TOP)\test\testrunner.tcl release
@@ -2845,7 +2850,9 @@ clean:
del /Q lsm.dll lsmtest.exe 2>NUL
del /Q atrc.exe changesetfuzz.exe dbtotxt.exe index_usage.exe 2>NUL
del /Q testloadext.dll 2>NUL
del /Q testfixture.exe test.db 2>NUL
del /Q testfixture.exe test.db tf.bat 2>NUL
del /Q /S testdir 2>/NUL
-rmdir /Q /S testdir 2>NUL
del /Q LogEst.exe fts3view.exe rollback-test.exe showdb.exe dbdump.exe 2>NUL
del /Q changeset.exe 2>NUL
del /Q showjournal.exe showstat4.exe showwal.exe speedtest1.exe 2>NUL
+12 -12
View File
@@ -57,18 +57,18 @@ If you do not want to use Fossil, you can download tarballs or ZIP
archives or [SQLite archives](https://sqlite.org/cli.html#sqlar) as follows:
* Latest trunk check-in as
[Tarball](https://www.sqlite.org/src/tarball/sqlite.tar.gz),
[ZIP-archive](https://www.sqlite.org/src/zip/sqlite.zip), or
[SQLite-archive](https://www.sqlite.org/src/sqlar/sqlite.sqlar).
[Tarball](https://sqlite.org/src/tarball/sqlite.tar.gz),
[ZIP-archive](https://sqlite.org/src/zip/sqlite.zip), or
[SQLite-archive](https://sqlite.org/src/sqlar/sqlite.sqlar).
* Latest release as
[Tarball](https://www.sqlite.org/src/tarball/sqlite.tar.gz?r=release),
[ZIP-archive](https://www.sqlite.org/src/zip/sqlite.zip?r=release), or
[SQLite-archive](https://www.sqlite.org/src/sqlar/sqlite.sqlar?r=release).
[Tarball](https://sqlite.org/src/tarball/sqlite.tar.gz?r=release),
[ZIP-archive](https://sqlite.org/src/zip/sqlite.zip?r=release), or
[SQLite-archive](https://sqlite.org/src/sqlar/sqlite.sqlar?r=release).
* For other check-ins, substitute an appropriate branch name or
tag or hash prefix in place of "release" in the URLs of the previous
bullet. Or browse the [timeline](https://www.sqlite.org/src/timeline)
bullet. Or browse the [timeline](https://sqlite.org/src/timeline)
to locate the check-in desired, click on its information page link,
then click on the "Tarball" or "ZIP Archive" links on the information
page.
@@ -308,14 +308,14 @@ individual source file exceeds 32K lines in length.
## How It All Fits Together
SQLite is modular in design.
See the [architectural description](https://www.sqlite.org/arch.html)
See the [architectural description](https://sqlite.org/arch.html)
for details. Other documents that are useful in
helping to understand how SQLite works include the
[file format](https://www.sqlite.org/fileformat2.html) description,
the [virtual machine](https://www.sqlite.org/opcode.html) that runs
[file format](https://sqlite.org/fileformat2.html) description,
the [virtual machine](https://sqlite.org/opcode.html) that runs
prepared statements, the description of
[how transactions work](https://www.sqlite.org/atomiccommit.html), and
the [overview of the query planner](https://www.sqlite.org/optoverview.html).
[how transactions work](https://sqlite.org/atomiccommit.html), and
the [overview of the query planner](https://sqlite.org/optoverview.html).
Decades of effort have gone into optimizing SQLite, both
for small size and high performance. And optimizations tend to result in
+1 -1
View File
@@ -1 +1 @@
3.50.0
3.51.0
+19 -3
View File
@@ -12,7 +12,6 @@
#
# JimTCL: https://jim.tcl.tk
#
use sqlite-config
sqlite-configure canonical {
proj-if-opt-truthy dev {
@@ -25,8 +24,9 @@ sqlite-configure canonical {
# -------------^^^^^^^ intentionally using [get-env] instead of
# [proj-get-env] here because [sqlite-setup-default-cflags] uses
# [proj-get-env] and we want this to supercede that.
sqlite-munge-cflags
sqlite-munge-cflags; # straighten out -DSQLITE_ENABLE/OMIT flags
}
sqlite-handle-debug ;# must come after --dev flag check
sqlite-check-common-bins ;# must come before [sqlite-handle-wasi-sdk]
sqlite-handle-wasi-sdk ;# must run relatively early, as it changes the environment
sqlite-check-common-system-deps
@@ -41,8 +41,24 @@ sqlite-configure canonical {
proj-define-for-opt linemacros AMALGAMATION_LINE_MACROS \
"Use #line macros in the amalgamation:"
define AMALGAMATION_EXTRA_SRC \
[join [opt-val amalgamation-extra-src ""] " "]
define LINK_TOOLS_DYNAMICALLY [proj-opt-was-provided dynlink-tools]
if {[set fsan [join [opt-val asan-fsanitize] ","]] in {auto ""}} {
set fsan address,bounds-strict
}
define CFLAGS_ASAN_FSANITIZE [proj-check-fsanitize [split $fsan ", "]]
sqlite-handle-tcl
sqlite-handle-emsdk
}
proj-if-opt-truthy static-shells {
proj-opt-set static-tclsqlite3 1
proj-opt-set static-cli-shell 1
}
proj-define-for-opt static-tclsqlite3 STATIC_TCLSQLITE3 "Statically link tclsqlite3?"
proj-define-for-opt static-cli-shell STATIC_CLI_SHELL "Statically link CLI shell?"
}; # sqlite-configure
+31 -16
View File
@@ -50,6 +50,7 @@ CC = @CC@
ENABLE_LIB_SHARED = @ENABLE_LIB_SHARED@
ENABLE_LIB_STATIC = @ENABLE_LIB_STATIC@
HAVE_WASI_SDK = @HAVE_WASI_SDK@
CFLAGS = @CFLAGS@ @CPPFLAGS@
#
@@ -71,11 +72,8 @@ LDFLAGS.rt = @LDFLAGS_RT@
LDFLAGS.icu = @LDFLAGS_ICU@
CFLAGS.icu = @CFLAGS_ICU@
# When cross-compiling, we need to avoid the -s flag because it only
# works on the build host's platform.
INSTALL.strip.1 = $(INSTALL)
INSTALL.strip.0 = $(INSTALL) -s
INSTALL.strip = $(INSTALL.strip.@IS_CROSS_COMPILING@)
# INSTALL reminder: we specifically do not strip binaries,
# as discussed in https://sqlite.org/forum/forumpost/9a67df63eda9925c.
INSTALL.noexec = $(INSTALL) -m 0644
install-dir.bin = $(DESTDIR)$(bindir)
@@ -127,10 +125,8 @@ OPT_FEATURE_FLAGS = @OPT_FEATURE_FLAGS@
LDFLAGS.libsqlite3.soname = @LDFLAGS_LIBSQLITE3_SONAME@
# soname: see https://sqlite.org/src/forumpost/5a3b44f510df8ded
LDFLAGS.libsqlite3.os-specific = @LDFLAGS_MAC_CVERSION@ @LDFLAGS_OUT_IMPLIB@
# os-specific: see
# - https://sqlite.org/forum/forumpost/9dfd5b8fd525a5d7
# - https://sqlite.org/forum/forumpost/0c7fc097b2
LDFLAGS.libsqlite3.os-specific = \
@LDFLAGS_MAC_CVERSION@ @LDFLAGS_MAC_INSTALL_NAME@ @LDFLAGS_OUT_IMPLIB@
LDFLAGS.libsqlite3 = \
$(LDFLAGS.rpath) $(LDFLAGS.pthread) \
@@ -195,6 +191,8 @@ install-dll-unix-generic: install-dll-out-implib
install-dll-msys: install-dll-out-implib $(install-dir.bin)
$(INSTALL) $(libsqlite3.DLL) "$(install-dir.bin)"
# ----------------------------------------------^^^ yes, bin
# Each of {msys,mingw,cygwin} uses a different name for the DLL, but
# that is already accounted for via $(libsqlite3.DLL).
install-dll-mingw: install-dll-msys
install-dll-cygwin: install-dll-msys
@@ -220,27 +218,43 @@ install-lib-0 install-lib-:
install-lib: install-lib-$(ENABLE_LIB_STATIC)
install: install-lib
#
# Flags to link the shell app either directly against sqlite3.c
# (ENABLE_STATIC_SHELL==1) or libsqlite3.so (ENABLE_STATIC_SHELL==0).
#
ENABLE_STATIC_SHELL = @ENABLE_STATIC_SHELL@
sqlite3-shell-link-flags.1 = $(TOP)/sqlite3.c $(LDFLAGS.libsqlite3)
sqlite3-shell-link-flags.0 = -L. -lsqlite3 $(LDFLAGS.zlib)
sqlite3-shell-link-flags.0 = -L. -lsqlite3 $(LDFLAGS.zlib) $(LDFLAGS.math)
sqlite3-shell-deps.1 = $(TOP)/sqlite3.c
sqlite3-shell-deps.0 = $(libsqlite3.DLL)
#
# STATIC_CLI_SHELL = 1 to statically link sqlite3$(T.exe), else
# 0. Requires static versions of all requisite libraries. Primarily
# intended for use with static-friendly environments like Alpine
# Linux.
#
STATIC_CLI_SHELL = @STATIC_CLI_SHELL@
#
# sqlite3-shell-static.flags.N = N is $(STATIC_CLI_SHELL)
#
sqlite3-shell-static.flags.1 = -static
sqlite3-shell-static.flags.0 =
sqlite3$(T.exe): $(TOP)/shell.c $(sqlite3-shell-deps.$(ENABLE_STATIC_SHELL))
$(CC) -o $@ \
$(TOP)/shell.c $(sqlite3-shell-link-flags.$(ENABLE_STATIC_SHELL)) \
$(sqlite3-shell-static.flags.$(STATIC_CLI_SHELL)) \
-I. $(OPT_FEATURE_FLAGS) $(SHELL_OPT) \
$(CFLAGS) $(CFLAGS.readline) $(CFLAGS.icu) \
$(LDFLAGS) $(LDFLAGS.readline)
all: sqlite3$(T.exe)
sqlite3$(T.exe)-1:
sqlite3$(T.exe)-0: sqlite3$(T.exe)
all: sqlite3$(T.exe)-$(HAVE_WASI_SDK)
install-shell: sqlite3$(T.exe) $(install-dir.bin)
$(INSTALL.strip) sqlite3$(T.exe) "$(install-dir.bin)"
install: install-shell
install-shell-0: sqlite3$(T.exe) $(install-dir.bin)
$(INSTALL) sqlite3$(T.exe) "$(install-dir.bin)"
install-shell-1:
install: install-shell-$(HAVE_WASI_SDK)
install-headers: $(TOP)/sqlite3.h $(install-dir.include)
$(INSTALL.noexec) $(TOP)/sqlite3.h $(TOP)/sqlite3ext.h "$(install-dir.include)"
@@ -269,15 +283,16 @@ DIST_FILES := \
sqlite3.rc sqlite3rc.h Replace.cs \
sqlite3.pc.in sqlite3.1
#
# Maintenance note: dist_name must be sqlite-$(PACKAGE_VERSION) so
# that tool/mkautoconfamal.sh knows how to find it.
#
dist_name = sqlite-$(PACKAGE_VERSION)
dist_tarball = $(dist_name).tar.gz
dist:
rm -fr $(dist_name)
mkdir -p $(dist_name)
cp -rp $(DIST_FILES) $(dist_name)/.
rm -f $(dist_name)/tea/configure.ac.in
tar czf $(dist_tarball) $(dist_name)
rm -fr $(dist_name)
ls -l $(dist_tarball)
+1 -1
View File
@@ -724,7 +724,7 @@ RCC = $(RCC) -DSQLITE_ENABLE_API_ARMOR=1
!ENDIF
!IF $(DEBUG)>2
TCC = $(TCC) -DSQLITE_DEBUG=1
TCC = $(TCC) -DSQLITE_DEBUG=1 -DSQLITE_USE_W32_FOR_CONSOLE_IO
RCC = $(RCC) -DSQLITE_DEBUG=1
!IF $(DYNAMIC_SHELL)==0
TCC = $(TCC) -DSQLITE_ENABLE_WHERETRACE -DSQLITE_ENABLE_SELECTTRACE
+1 -1
View File
@@ -90,7 +90,7 @@ Other preprocessor defines
Additionally, preprocessor defines may be specified by using the OPTS macro
on the NMAKE command line. However, not all possible preprocessor defines
may be specified in this manner as some require the amalgamation to be built
with them enabled (see http://www.sqlite.org/compile.html). For example, the
with them enabled (see http://sqlite.org/compile.html). For example, the
following will work:
"OPTS=-DSQLITE_ENABLE_STAT4=1 -DSQLITE_OMIT_JSON=1"
+16 -1
View File
@@ -5,6 +5,21 @@
# "autoconf" bundle of the SQLite project.
use sqlite-config
sqlite-configure autoconf {
sqlite-check-common-bins
sqlite-handle-debug
sqlite-check-common-bins ;# must come before [sqlite-handle-wasi-sdk]
sqlite-handle-wasi-sdk ;# must run relatively early, as it changes the environment
sqlite-check-common-system-deps
proj-define-for-opt static-shell ENABLE_STATIC_SHELL \
"Link library statically into the CLI shell?"
proj-define-for-opt static-cli-shell STATIC_CLI_SHELL "Statically link CLI shell?"
if {![opt-bool static-shell] && [opt-bool static-cli-shell]} {
proj-fatal "--disable-static-shell and --static-cli-shell are mutualy exclusive"
}
if {![opt-bool shared] && ![opt-bool static-shell]} {
proj-opt-set shared 1
proj-indented-notice {
NOTICE: ignoring --disable-shared because --disable-static-shell
was specified.
}
}
}
+540 -445
View File
File diff suppressed because it is too large Load Diff
+53 -37
View File
@@ -1,9 +1,30 @@
This is the SQLite extension for Tcl using the Tcl Extension
Architecture (TEA).
This is the SQLite extension for Tcl using something akin to
the Tcl Extension Architecture (TEA). To build it:
----------------------- A BETTER WAY ---------------------------
./configure ...flags...
A better way to build the TCL extension for SQLite is to use the
e.g.:
./configure --with-tcl=/path/to/tcl/install/root
or:
./configure --with-tclsh=/path/to/tcl/install/root
Run ./configure --help for the full list of flags.
The configuration process will fail if tclConfig.sh cannot be found.
The makefile will only honor CFLAGS and CPPFLAGS passed to the
configure script, not those directly passed to the makefile.
Then:
make test install
----------------------- THE PREFERRED WAY ---------------------------
The preferred way to build the TCL extension for SQLite is to use the
canonical source code tarball. For Unix:
./configure --with-tclsh=$(TCLSH)
@@ -20,24 +41,32 @@ step-by-step instructions at the links below for more information:
https://sqlite.org/src/doc/trunk/doc/compile-for-unix.md
https://sqlite.org/src/doc/trunk/doc/compile-for-windows.md
The whole point of the amalgamation-autoconf tarball (in which this
README.txt file is embedded) is to provide a means of compiling
SQLite that does not require first installing TCL and/or "tclsh".
The canonical Makefile in the SQLite source tree provides more
capabilities (such as the the ability to run test cases to ensure
that the build worked) and is better maintained. The only
downside of the canonical Makefile is that it requires a TCL
installation. But if you are wanting to build the TCL extension for
SQLite, then presumably you already have a TCL installation. So why
not just use the more-capable and better-maintained canoncal Makefile?
And info about the extension's Tcl interface can be found at:
This TEA builder is derived from code found at
https://sqlite.org/tclsqlite.html
The whole point of the amalgamation-autoconf tarball (in which this
README.txt file is embedded) is to provide a means of compiling SQLite
that does not require first installing TCL and/or "tclsh". The
canonical Makefile in the SQLite source tree provides more
capabilities (such as the the ability to run test cases to ensure that
the build worked) and is better maintained. The only downside of the
canonical Makefile is that it requires a TCL installation. But if you
are wanting to build the TCL extension for SQLite, then presumably you
already have a TCL installation. So why not just use the more-capable
and better-maintained canoncal Makefile?
As of version 3.50.0, this build process uses "teaish":
https://fossil.wanderinghorse.net/r/teaish
which is conceptually derived from the pre-3.50 toolchain, TEA:
http://core.tcl-lang.org/tclconfig
http://core.tcl-lang.org/sampleextension
The SQLite developers do not understand how it works. It seems to
work for us. It might also work for you. But we cannot promise that.
It to works for us. It might also work for you. But we cannot
promise that.
If you want to use this TEA builder and it works for you, that's fine.
But if you have trouble, the first thing you should do is go back
@@ -49,30 +78,17 @@ to using the canonical Makefile in the SQLite source tree.
UNIX BUILD
==========
Building under most UNIX systems is easy, just run the configure script
and then run make. For more information about the build process, see
the tcl/unix/README file in the Tcl src dist. The following minimal
example will install the extension in the /opt/tcl directory.
Building under most UNIX systems is easy, just run the configure
script and then run make. For example:
$ cd sqlite-*-tea
$ ./configure --prefix=/opt/tcl
$ make
$ ./configure --with-tcl=/path/to/tcl/install/root
$ make test
$ make install
WINDOWS BUILD
=============
The recommended method to build extensions under windows is to use the
Msys + Mingw build process. This provides a Unix-style build while
generating native Windows binaries. Using the Msys + Mingw build tools
means that you can use the same configure script as per the Unix build
to create a Makefile. See the tcl/win/README file for the URL of
the Msys + Mingw download.
If you have VC++ then you may wish to use the files in the win
subdirectory and build the extension using just VC++. These files have
been designed to be as generic as possible but will require some
additional maintenance by the project developer to synchronise with
the TEA configure.in and Makefile.in files. Instructions for using the
VC++ makefile are written in the first part of the Makefile.vc
file.
On Windows this build is known to work on Cygwin and some Msys2
environments. We do not currently support Microsoft makefiles for
native Windows builds.
+50
View File
@@ -0,0 +1,50 @@
# -*- tcl -*-
#
# Unless this file is named _teaish.tester.tcl.in, you are probably
# looking at an automatically generated/filtered copy and should
# probably not edit it.
#
# This is the wrapper script invoked by teaish's "make test" recipe.
# It gets passed 3 args:
#
# $1 = the DLL name, or "" if the extension has no DLL
#
# $2 = the "load prefix" for Tcl's [load] or empty if $1 is empty
#
# $3 = the /path/to/teaish/tester.tcl (test utility code)
#
@if TEAISH_VSATISFIES_CODE
@TEAISH_VSATISFIES_CODE@
@endif
if {[llength [lindex $::argv 0]] > 0} {
load [file normalize [lindex $::argv 0]] [lindex $::argv 1];
# ----^^^^^^^ needed on Haiku when argv 0 is just a filename, else
# load cannot find the file.
}
set ::argv [lassign $argv - -]
source -encoding utf-8 [lindex $::argv 0]; # teaish/tester.tcl
@if TEAISH_PKGINIT_TCL
apply {{file} {
set dir [file dirname $::argv0]
source -encoding utf-8 $file
}} [join {@TEAISH_PKGINIT_TCL@}]
@endif
@if TEAISH_TM_TCL
apply {{file} {
set dir [file dirname $::argv0]
source -encoding utf-8 $file
}} [join {@TEAISH_TM_TCL@}]
@endif
@if TEAISH_TEST_TCL
apply {{file} {
# Populate state for [tester.tcl::teaish-build-flag*]
array set ::teaish__BuildFlags @TEAISH__DEFINES_MAP@
set dir [file normalize [file dirname $file]]
#test-fail "Just testing"
source -encoding utf-8 $file
}} [join {@TEAISH_TEST_TCL@}]
@else # TEAISH_TEST_TCL
# No $TEAISH_TEST_TCL provided, so here's a default test which simply
# loads the extension.
puts {Extension @TEAISH_NAME@ @TEAISH_VERSION@ successfully loaded from @TEAISH_TESTER_TCL@}
@endif
-9
View File
@@ -1,9 +0,0 @@
#
# Include the TEA standard macro set
#
builtin(include,tclconfig/tcl.m4)
#
# Add here whatever m4 macros you want to define for your package
#
+8
View File
@@ -0,0 +1,8 @@
#/do/not/tclsh
# ^^^ help out editors which guess this file's content type.
#
# Main configure script entry point for the TEA(ish) framework. All
# extension-specific customization goes in teaish.tcl.in or
# teaish.tcl.
use teaish/core
teaish-configure-core
Vendored Executable
+7
View File
@@ -0,0 +1,7 @@
#!/bin/sh
dir0="`dirname "$0"`"
dirA="$dir0/../autosetup"
# This is the case ^^^^^^^^^^^^ in the SQLite "autoconf" bundle.
WRAPPER="$0"; export WRAPPER; exec "`"$dirA/autosetup-find-tclsh"`" \
"$dirA/autosetup" --teaish-extension-dir="$dir0" \
"$@"
-227
View File
@@ -1,227 +0,0 @@
#!/bin/bash -norc
dnl This file is an input file used by the GNU "autoconf" program to
dnl generate the file "configure", which is run during Tcl installation
dnl to configure the system for the local environment.
#-----------------------------------------------------------------------
# Sample configure.ac for Tcl Extensions. The only places you should
# need to modify this file are marked by the string __CHANGE__
#-----------------------------------------------------------------------
#-----------------------------------------------------------------------
# __CHANGE__
# Set your package name and version numbers here.
#
# This initializes the environment with PACKAGE_NAME and PACKAGE_VERSION
# set as provided. These will also be added as -D defs in your Makefile
# so you can encode the package version directly into the source files.
# This will also define a special symbol for Windows (BUILD_<PACKAGE_NAME>
# so that we create the export library with the dll.
#-----------------------------------------------------------------------
AC_INIT([sqlite],[@VERSION@])
#--------------------------------------------------------------------
# Call TEA_INIT as the first TEA_ macro to set up initial vars.
# This will define a ${TEA_PLATFORM} variable == "unix" or "windows"
# as well as PKG_LIB_FILE and PKG_STUB_LIB_FILE.
#--------------------------------------------------------------------
TEA_INIT()
AC_CONFIG_AUX_DIR(tclconfig)
#--------------------------------------------------------------------
# Load the tclConfig.sh file
#--------------------------------------------------------------------
TEA_PATH_TCLCONFIG
TEA_LOAD_TCLCONFIG
#--------------------------------------------------------------------
# Load the tkConfig.sh file if necessary (Tk extension)
#--------------------------------------------------------------------
#TEA_PATH_TKCONFIG
#TEA_LOAD_TKCONFIG
#-----------------------------------------------------------------------
# Handle the --prefix=... option by defaulting to what Tcl gave.
# Must be called after TEA_LOAD_TCLCONFIG and before TEA_SETUP_COMPILER.
#-----------------------------------------------------------------------
TEA_PREFIX
#-----------------------------------------------------------------------
# Standard compiler checks.
# This sets up CC by using the CC env var, or looks for gcc otherwise.
# This also calls AC_PROG_CC and a few others to create the basic setup
# necessary to compile executables.
#-----------------------------------------------------------------------
TEA_SETUP_COMPILER
#-----------------------------------------------------------------------
# __CHANGE__
# Specify the C source files to compile in TEA_ADD_SOURCES,
# public headers that need to be installed in TEA_ADD_HEADERS,
# stub library C source files to compile in TEA_ADD_STUB_SOURCES,
# and runtime Tcl library files in TEA_ADD_TCL_SOURCES.
# This defines PKG(_STUB)_SOURCES, PKG(_STUB)_OBJECTS, PKG_HEADERS
# and PKG_TCL_SOURCES.
#-----------------------------------------------------------------------
TEA_ADD_SOURCES([tclsqlite3.c])
TEA_ADD_HEADERS([])
TEA_ADD_INCLUDES([])
TEA_ADD_LIBS([])
TEA_ADD_CFLAGS([-DSQLITE_ENABLE_FTS3=1])
TEA_ADD_CFLAGS([-DSQLITE_ENABLE_FTS4=1])
TEA_ADD_CFLAGS([-DSQLITE_ENABLE_FTS5=1])
TEA_ADD_CFLAGS([-DSQLITE_3_SUFFIX_ONLY=1])
TEA_ADD_CFLAGS([-DSQLITE_ENABLE_RTREE=1])
TEA_ADD_CFLAGS([-DSQLITE_ENABLE_GEOPOLY=1])
TEA_ADD_CFLAGS([-DSQLITE_ENABLE_MATH_FUNCTIONS=1])
TEA_ADD_CFLAGS([-DSQLITE_ENABLE_DESERIALIZE=1])
TEA_ADD_CFLAGS([-DSQLITE_ENABLE_DBPAGE_VTAB=1])
TEA_ADD_CFLAGS([-DSQLITE_ENABLE_BYTECODE_VTAB=1])
TEA_ADD_CFLAGS([-DSQLITE_ENABLE_DBSTAT_VTAB=1])
TEA_ADD_STUB_SOURCES([])
TEA_ADD_TCL_SOURCES([])
#--------------------------------------------------------------------
# The --with-system-sqlite causes the TCL bindings to SQLite to use
# the system shared library for SQLite rather than statically linking
# against its own private copy. This is dangerous and leads to
# undesirable dependences and is not recommended.
# Patchs from rmax.
#--------------------------------------------------------------------
AC_ARG_WITH([system-sqlite],
[AS_HELP_STRING([--with-system-sqlite],
[use a system-supplied libsqlite3 instead of the bundled one])],
[], [with_system_sqlite=no])
if test x$with_system_sqlite != xno; then
AC_CHECK_HEADER([sqlite3.h],
[AC_CHECK_LIB([sqlite3],[sqlite3_initialize],
[AC_DEFINE(USE_SYSTEM_SQLITE)
LIBS="$LIBS -lsqlite3"])])
fi
#--------------------------------------------------------------------
# __CHANGE__
#
# You can add more files to clean if your extension creates any extra
# files by extending CLEANFILES.
# Add pkgIndex.tcl if it is generated in the Makefile instead of ./configure
# and change Makefile.in to move it from CONFIG_CLEAN_FILES to BINARIES var.
#
# A few miscellaneous platform-specific items:
# TEA_ADD_* any platform specific compiler/build info here.
#--------------------------------------------------------------------
#CLEANFILES="$CLEANFILES pkgIndex.tcl"
if test "${TEA_PLATFORM}" = "windows" ; then
# Ensure no empty if clauses
:
#TEA_ADD_SOURCES([win/winFile.c])
#TEA_ADD_INCLUDES([-I\"$(${CYGPATH} ${srcdir}/win)\"])
else
# Ensure no empty else clauses
:
#TEA_ADD_SOURCES([unix/unixFile.c])
#TEA_ADD_LIBS([-lsuperfly])
fi
#--------------------------------------------------------------------
# __CHANGE__
# Choose which headers you need. Extension authors should try very
# hard to only rely on the Tcl public header files. Internal headers
# contain private data structures and are subject to change without
# notice.
# This MUST be called after TEA_LOAD_TCLCONFIG / TEA_LOAD_TKCONFIG
#--------------------------------------------------------------------
TEA_PUBLIC_TCL_HEADERS
#TEA_PRIVATE_TCL_HEADERS
#TEA_PUBLIC_TK_HEADERS
#TEA_PRIVATE_TK_HEADERS
#TEA_PATH_X
#--------------------------------------------------------------------
# Check whether --enable-threads or --disable-threads was given.
# This auto-enables if Tcl was compiled threaded.
#--------------------------------------------------------------------
TEA_ENABLE_THREADS
if test "${TCL_THREADS}" = "1" ; then
AC_DEFINE(SQLITE_THREADSAFE, 1, [Trigger sqlite threadsafe build])
# Not automatically added by Tcl because its assumed Tcl links to them,
# but it may not if it isn't really a threaded build.
TEA_ADD_LIBS([$THREADS_LIBS])
else
AC_DEFINE(SQLITE_THREADSAFE, 0, [Trigger sqlite non-threadsafe build])
fi
#--------------------------------------------------------------------
# The statement below defines a collection of symbols related to
# building as a shared library instead of a static library.
#--------------------------------------------------------------------
TEA_ENABLE_SHARED
#--------------------------------------------------------------------
# This macro figures out what flags to use with the compiler/linker
# when building shared/static debug/optimized objects. This information
# can be taken from the tclConfig.sh file, but this figures it all out.
#--------------------------------------------------------------------
TEA_CONFIG_CFLAGS
#--------------------------------------------------------------------
# Set the default compiler switches based on the --enable-symbols option.
#--------------------------------------------------------------------
TEA_ENABLE_SYMBOLS
#--------------------------------------------------------------------
# This macro generates a line to use when building a library. It
# depends on values set by the TEA_ENABLE_SHARED, TEA_ENABLE_SYMBOLS,
# and TEA_LOAD_TCLCONFIG macros above.
#--------------------------------------------------------------------
TEA_MAKE_LIB
#--------------------------------------------------------------------
# Determine the name of the tclsh and/or wish executables in the
# Tcl and Tk build directories or the location they were installed
# into. These paths are used to support running test cases only,
# the Makefile should not be making use of these paths to generate
# a pkgIndex.tcl file or anything else at extension build time.
#--------------------------------------------------------------------
TEA_PROG_TCLSH
#TEA_PROG_WISH
#--------------------------------------------------------------------
# Setup a *Config.sh.in configuration file.
#--------------------------------------------------------------------
#TEA_EXPORT_CONFIG([sample])
#AC_SUBST(SAMPLE_VAR)
#--------------------------------------------------------------------
# Specify files to substitute AC variables in. You may alternatively
# have a special pkgIndex.tcl.in or other files which require
# substituting the AC variables in. Include these here.
#--------------------------------------------------------------------
AC_CONFIG_FILES([Makefile pkgIndex.tcl])
#AC_CONFIG_FILES([sampleConfig.sh])
#--------------------------------------------------------------------
# Finally, substitute all of the various values into the files
# specified with AC_CONFIG_FILES.
#--------------------------------------------------------------------
AC_OUTPUT
-15
View File
@@ -1,15 +0,0 @@
.TH sqlite3 n 4.1 "Tcl-Extensions"
.HS sqlite3 tcl
.BS
.SH NAME
sqlite3 \- an interface to the SQLite3 database engine
.SH SYNOPSIS
\fBsqlite3\fI command_name ?filename?\fR
.br
.SH DESCRIPTION
SQLite3 is a self-contains, zero-configuration, transactional SQL database
engine. This extension provides an easy to use interface for accessing
SQLite database files from Tcl.
.PP
For full documentation see \fIhttp://www.sqlite.org/\fR and
in particular \fIhttp://www.sqlite.org/tclsqlite.html\fR.
+35 -5
View File
@@ -1,10 +1,40 @@
# -*- tcl -*-
# Tcl package index file, version 1.1
# Tcl package index file
#
# Unless this file is named pkgIndex.tcl.in, you are probably looking
# at an automatically generated/filtered copy and should probably not
# edit it.
#
# Adapted from https://core.tcl-lang.org/tcltls
@if TEAISH_VSATISFIES_CODE
@TEAISH_VSATISFIES_CODE@
@endif
if {[package vsatisfies [package provide Tcl] 9.0-]} {
package ifneeded sqlite3 @PACKAGE_VERSION@ \
[list load [file join $dir @PKG_LIB_FILE9@] Sqlite3]
package ifneeded {@TEAISH_PKGNAME@} {@TEAISH_VERSION@} [list apply {{dir} {
@if TEAISH_ENABLE_DLL
load [file join $dir {@TEAISH_DLL9@}] @TEAISH_LOAD_PREFIX@
@endif
@if TEAISH_PKGINIT_TCL_TAIL
set initScript [file join $dir {@TEAISH_PKGINIT_TCL_TAIL@}]
if {[file exists $initScript]} {
source -encoding utf-8 $initScript
}
@endif
}} $dir]
} else {
package ifneeded sqlite3 @PACKAGE_VERSION@ \
[list load [file join $dir @PKG_LIB_FILE8@] Sqlite3]
package ifneeded {@TEAISH_PKGNAME@} {@TEAISH_VERSION@} [list apply {{dir} {
@if TEAISH_ENABLE_DLL
if {[string tolower [file extension {@TEAISH_DLL8@}]] in [list .dll .dylib .so]} {
load [file join $dir {@TEAISH_DLL8@}] @TEAISH_LOAD_PREFIX@
} else {
load {} @TEAISH_LOAD_PREFIX@
}
@endif
@if TEAISH_PKGINIT_TCL_TAIL
set initScript [file join $dir {@TEAISH_PKGINIT_TCL_TAIL@}]
if {[file exists $initScript]} {
source -encoding utf-8 $initScript
}
@endif
}} $dir]
}
-541
View File
@@ -1,541 +0,0 @@
#!/bin/sh
# install - install a program, script, or datafile
scriptversion=2020-11-14.01; # UTC
# This originates from X11R5 (mit/util/scripts/install.sh), which was
# later released in X11R6 (xc/config/util/install.sh) with the
# following copyright and license.
#
# Copyright (C) 1994 X Consortium
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to
# deal in the Software without restriction, including without limitation the
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
# sell copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
# Except as contained in this notice, the name of the X Consortium shall not
# be used in advertising or otherwise to promote the sale, use or other deal-
# ings in this Software without prior written authorization from the X Consor-
# tium.
#
#
# FSF changes to this file are in the public domain.
#
# Calling this script install-sh is preferred over install.sh, to prevent
# 'make' implicit rules from creating a file called install from it
# when there is no Makefile.
#
# This script is compatible with the BSD install script, but was written
# from scratch.
tab=' '
nl='
'
IFS=" $tab$nl"
# Set DOITPROG to "echo" to test this script.
doit=${DOITPROG-}
doit_exec=${doit:-exec}
# Put in absolute file names if you don't have them in your path;
# or use environment vars.
chgrpprog=${CHGRPPROG-chgrp}
chmodprog=${CHMODPROG-chmod}
chownprog=${CHOWNPROG-chown}
cmpprog=${CMPPROG-cmp}
cpprog=${CPPROG-cp}
mkdirprog=${MKDIRPROG-mkdir}
mvprog=${MVPROG-mv}
rmprog=${RMPROG-rm}
stripprog=${STRIPPROG-strip}
posix_mkdir=
# Desired mode of installed file.
mode=0755
# Create dirs (including intermediate dirs) using mode 755.
# This is like GNU 'install' as of coreutils 8.32 (2020).
mkdir_umask=22
backupsuffix=
chgrpcmd=
chmodcmd=$chmodprog
chowncmd=
mvcmd=$mvprog
rmcmd="$rmprog -f"
stripcmd=
src=
dst=
dir_arg=
dst_arg=
copy_on_change=false
is_target_a_directory=possibly
usage="\
Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
or: $0 [OPTION]... SRCFILES... DIRECTORY
or: $0 [OPTION]... -t DIRECTORY SRCFILES...
or: $0 [OPTION]... -d DIRECTORIES...
In the 1st form, copy SRCFILE to DSTFILE.
In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
In the 4th, create DIRECTORIES.
Options:
--help display this help and exit.
--version display version info and exit.
-c (ignored)
-C install only if different (preserve data modification time)
-d create directories instead of installing files.
-g GROUP $chgrpprog installed files to GROUP.
-m MODE $chmodprog installed files to MODE.
-o USER $chownprog installed files to USER.
-p pass -p to $cpprog.
-s $stripprog installed files.
-S SUFFIX attempt to back up existing files, with suffix SUFFIX.
-t DIRECTORY install into DIRECTORY.
-T report an error if DSTFILE is a directory.
Environment variables override the default commands:
CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
RMPROG STRIPPROG
By default, rm is invoked with -f; when overridden with RMPROG,
it's up to you to specify -f if you want it.
If -S is not specified, no backups are attempted.
Email bug reports to bug-automake@gnu.org.
Automake home page: https://www.gnu.org/software/automake/
"
while test $# -ne 0; do
case $1 in
-c) ;;
-C) copy_on_change=true;;
-d) dir_arg=true;;
-g) chgrpcmd="$chgrpprog $2"
shift;;
--help) echo "$usage"; exit $?;;
-m) mode=$2
case $mode in
*' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*)
echo "$0: invalid mode: $mode" >&2
exit 1;;
esac
shift;;
-o) chowncmd="$chownprog $2"
shift;;
-p) cpprog="$cpprog -p";;
-s) stripcmd=$stripprog;;
-S) backupsuffix="$2"
shift;;
-t)
is_target_a_directory=always
dst_arg=$2
# Protect names problematic for 'test' and other utilities.
case $dst_arg in
-* | [=\(\)!]) dst_arg=./$dst_arg;;
esac
shift;;
-T) is_target_a_directory=never;;
--version) echo "$0 $scriptversion"; exit $?;;
--) shift
break;;
-*) echo "$0: invalid option: $1" >&2
exit 1;;
*) break;;
esac
shift
done
# We allow the use of options -d and -T together, by making -d
# take the precedence; this is for compatibility with GNU install.
if test -n "$dir_arg"; then
if test -n "$dst_arg"; then
echo "$0: target directory not allowed when installing a directory." >&2
exit 1
fi
fi
if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
# When -d is used, all remaining arguments are directories to create.
# When -t is used, the destination is already specified.
# Otherwise, the last argument is the destination. Remove it from $@.
for arg
do
if test -n "$dst_arg"; then
# $@ is not empty: it contains at least $arg.
set fnord "$@" "$dst_arg"
shift # fnord
fi
shift # arg
dst_arg=$arg
# Protect names problematic for 'test' and other utilities.
case $dst_arg in
-* | [=\(\)!]) dst_arg=./$dst_arg;;
esac
done
fi
if test $# -eq 0; then
if test -z "$dir_arg"; then
echo "$0: no input file specified." >&2
exit 1
fi
# It's OK to call 'install-sh -d' without argument.
# This can happen when creating conditional directories.
exit 0
fi
if test -z "$dir_arg"; then
if test $# -gt 1 || test "$is_target_a_directory" = always; then
if test ! -d "$dst_arg"; then
echo "$0: $dst_arg: Is not a directory." >&2
exit 1
fi
fi
fi
if test -z "$dir_arg"; then
do_exit='(exit $ret); exit $ret'
trap "ret=129; $do_exit" 1
trap "ret=130; $do_exit" 2
trap "ret=141; $do_exit" 13
trap "ret=143; $do_exit" 15
# Set umask so as not to create temps with too-generous modes.
# However, 'strip' requires both read and write access to temps.
case $mode in
# Optimize common cases.
*644) cp_umask=133;;
*755) cp_umask=22;;
*[0-7])
if test -z "$stripcmd"; then
u_plus_rw=
else
u_plus_rw='% 200'
fi
cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
*)
if test -z "$stripcmd"; then
u_plus_rw=
else
u_plus_rw=,u+rw
fi
cp_umask=$mode$u_plus_rw;;
esac
fi
for src
do
# Protect names problematic for 'test' and other utilities.
case $src in
-* | [=\(\)!]) src=./$src;;
esac
if test -n "$dir_arg"; then
dst=$src
dstdir=$dst
test -d "$dstdir"
dstdir_status=$?
# Don't chown directories that already exist.
if test $dstdir_status = 0; then
chowncmd=""
fi
else
# Waiting for this to be detected by the "$cpprog $src $dsttmp" command
# might cause directories to be created, which would be especially bad
# if $src (and thus $dsttmp) contains '*'.
if test ! -f "$src" && test ! -d "$src"; then
echo "$0: $src does not exist." >&2
exit 1
fi
if test -z "$dst_arg"; then
echo "$0: no destination specified." >&2
exit 1
fi
dst=$dst_arg
# If destination is a directory, append the input filename.
if test -d "$dst"; then
if test "$is_target_a_directory" = never; then
echo "$0: $dst_arg: Is a directory" >&2
exit 1
fi
dstdir=$dst
dstbase=`basename "$src"`
case $dst in
*/) dst=$dst$dstbase;;
*) dst=$dst/$dstbase;;
esac
dstdir_status=0
else
dstdir=`dirname "$dst"`
test -d "$dstdir"
dstdir_status=$?
fi
fi
case $dstdir in
*/) dstdirslash=$dstdir;;
*) dstdirslash=$dstdir/;;
esac
obsolete_mkdir_used=false
if test $dstdir_status != 0; then
case $posix_mkdir in
'')
# With -d, create the new directory with the user-specified mode.
# Otherwise, rely on $mkdir_umask.
if test -n "$dir_arg"; then
mkdir_mode=-m$mode
else
mkdir_mode=
fi
posix_mkdir=false
# The $RANDOM variable is not portable (e.g., dash). Use it
# here however when possible just to lower collision chance.
tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
trap '
ret=$?
rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null
exit $ret
' 0
# Because "mkdir -p" follows existing symlinks and we likely work
# directly in world-writeable /tmp, make sure that the '$tmpdir'
# directory is successfully created first before we actually test
# 'mkdir -p'.
if (umask $mkdir_umask &&
$mkdirprog $mkdir_mode "$tmpdir" &&
exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1
then
if test -z "$dir_arg" || {
# Check for POSIX incompatibilities with -m.
# HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
# other-writable bit of parent directory when it shouldn't.
# FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
test_tmpdir="$tmpdir/a"
ls_ld_tmpdir=`ls -ld "$test_tmpdir"`
case $ls_ld_tmpdir in
d????-?r-*) different_mode=700;;
d????-?--*) different_mode=755;;
*) false;;
esac &&
$mkdirprog -m$different_mode -p -- "$test_tmpdir" && {
ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"`
test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
}
}
then posix_mkdir=:
fi
rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir"
else
# Remove any dirs left behind by ancient mkdir implementations.
rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null
fi
trap '' 0;;
esac
if
$posix_mkdir && (
umask $mkdir_umask &&
$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
)
then :
else
# mkdir does not conform to POSIX,
# or it failed possibly due to a race condition. Create the
# directory the slow way, step by step, checking for races as we go.
case $dstdir in
/*) prefix='/';;
[-=\(\)!]*) prefix='./';;
*) prefix='';;
esac
oIFS=$IFS
IFS=/
set -f
set fnord $dstdir
shift
set +f
IFS=$oIFS
prefixes=
for d
do
test X"$d" = X && continue
prefix=$prefix$d
if test -d "$prefix"; then
prefixes=
else
if $posix_mkdir; then
(umask $mkdir_umask &&
$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
# Don't fail if two instances are running concurrently.
test -d "$prefix" || exit 1
else
case $prefix in
*\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
*) qprefix=$prefix;;
esac
prefixes="$prefixes '$qprefix'"
fi
fi
prefix=$prefix/
done
if test -n "$prefixes"; then
# Don't fail if two instances are running concurrently.
(umask $mkdir_umask &&
eval "\$doit_exec \$mkdirprog $prefixes") ||
test -d "$dstdir" || exit 1
obsolete_mkdir_used=true
fi
fi
fi
if test -n "$dir_arg"; then
{ test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
{ test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
{ test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
else
# Make a couple of temp file names in the proper directory.
dsttmp=${dstdirslash}_inst.$$_
rmtmp=${dstdirslash}_rm.$$_
# Trap to clean up those temp files at exit.
trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
# Copy the file name to the temp name.
(umask $cp_umask &&
{ test -z "$stripcmd" || {
# Create $dsttmp read-write so that cp doesn't create it read-only,
# which would cause strip to fail.
if test -z "$doit"; then
: >"$dsttmp" # No need to fork-exec 'touch'.
else
$doit touch "$dsttmp"
fi
}
} &&
$doit_exec $cpprog "$src" "$dsttmp") &&
# and set any options; do chmod last to preserve setuid bits.
#
# If any of these fail, we abort the whole thing. If we want to
# ignore errors from any of these, just make sure not to ignore
# errors from the above "$doit $cpprog $src $dsttmp" command.
#
{ test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
{ test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
{ test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
{ test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
# If -C, don't bother to copy if it wouldn't change the file.
if $copy_on_change &&
old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` &&
new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` &&
set -f &&
set X $old && old=:$2:$4:$5:$6 &&
set X $new && new=:$2:$4:$5:$6 &&
set +f &&
test "$old" = "$new" &&
$cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
then
rm -f "$dsttmp"
else
# If $backupsuffix is set, and the file being installed
# already exists, attempt a backup. Don't worry if it fails,
# e.g., if mv doesn't support -f.
if test -n "$backupsuffix" && test -f "$dst"; then
$doit $mvcmd -f "$dst" "$dst$backupsuffix" 2>/dev/null
fi
# Rename the file to the real destination.
$doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
# The rename failed, perhaps because mv can't rename something else
# to itself, or perhaps because mv is so ancient that it does not
# support -f.
{
# Now remove or move aside any old file at destination location.
# We try this two ways since rm can't unlink itself on some
# systems and the destination file might be busy for other
# reasons. In this case, the final cleanup might fail but the new
# file should still install successfully.
{
test ! -f "$dst" ||
$doit $rmcmd "$dst" 2>/dev/null ||
{ $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
{ $doit $rmcmd "$rmtmp" 2>/dev/null; :; }
} ||
{ echo "$0: cannot unlink or rename $dst" >&2
(exit 1); exit 1
}
} &&
# Now rename the file to the real destination.
$doit $mvcmd "$dsttmp" "$dst"
}
fi || exit 1
trap '' 0
fi
done
# Local variables:
# eval: (add-hook 'before-save-hook 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-time-zone: "UTC0"
# time-stamp-end: "; # UTC"
# End:
File diff suppressed because it is too large Load Diff
+569
View File
@@ -0,0 +1,569 @@
# Teaish configure script for the SQLite Tcl extension
#
# State for disparate config-time pieces.
#
array set sqlite__Config [proj-strip-hash-comments {
#
# The list of feature --flags which the --all flag implies. This
# requires special handling in a few places.
#
all-flag-enables {fts3 fts4 fts5 rtree geopoly}
# >0 if building in the canonical tree. -1=undetermined
is-canonical -1
}]
#
# Set up the package info for teaish...
#
apply {{dir} {
# Figure out the version number...
set version ""
if {[file exists $dir/../VERSION]} {
# The canonical SQLite TEA(ish) build
set version [proj-file-content -trim $dir/../VERSION]
set ::sqlite__Config(is-canonical) 1
set distname sqlite-tcl
} elseif {[file exists $dir/generic/tclsqlite3.c]} {
# The copy from the teaish tree, used as a dev/test bed before
# updating SQLite's tree.
set ::sqlite__Config(is-canonical) 0
set fd [open $dir/generic/tclsqlite3.c rb]
while {[gets $fd line] >=0} {
if {[regexp {^#define[ ]+SQLITE_VERSION[ ]+"(3.+)"} \
$line - version]} {
set distname sqlite-teaish
break
}
}
close $fd
}
if {"" eq $version} {
proj-fatal "Cannot determine the SQLite version number"
}
proj-assert {$::sqlite__Config(is-canonical) > -1}
proj-assert {[string match 3.*.* $version]} \
"Unexpected SQLite version: $version"
set pragmas {}
if {$::sqlite__Config(is-canonical)} {
# Disable "make dist" in the canonical tree. That tree is
# generated from several pieces and creating/testing working
# "dist" rules for that sub-build currently feels unnecessary. The
# copy in the teaish tree, though, should be able to "make dist".
lappend pragmas no-dist
} else {
lappend pragmas full-dist
}
teaish-pkginfo-set -vars {
-name sqlite
-name.pkg sqlite3
-version $version
-name.dist $distname
-libDir sqlite$version
-pragmas $pragmas
-src generic/tclsqlite3.c
}
# We should also have:
# -vsatisfies 8.6-
# But at least one platform is failing this vsatisfies check
# for no apparent reason:
# https://sqlite.org/forum/forumpost/fde857fb8101a4be
}} [teaish-get -dir]
#
# Must return either an empty string or a list in the form accepted by
# autosetup's [options] function.
#
proc teaish-options {} {
# These flags and defaults mostly derive from the historical TEA
# build. Some, like ICU, are taken from the canonical SQLite tree.
return [subst -nocommands -nobackslashes {
with-system-sqlite=0
=> {Use the system-level SQLite instead of the copy in this tree.
Also requires use of --override-sqlite-version so that the build
knows what version number to associate with the system-level SQLite.}
override-sqlite-version:VERSION
=> {For use with --with-system-sqlite to set the version number.}
threadsafe=1 => {Disable mutexing}
with-tempstore:=no => {Use an in-RAM database for temporary tables: never,no,yes,always}
load-extension=0 => {Enable loading of external extensions}
math=1 => {Disable math functions}
json=1 => {Disable JSON functions}
fts3 => {Enable the FTS3 extension}
fts4 => {Enable the FTS4 extension}
fts5 => {Enable the FTS5 extension}
update-limit => {Enable the UPDATE/DELETE LIMIT clause}
geopoly => {Enable the GEOPOLY extension}
rtree => {Enable the RTREE extension}
session => {Enable the SESSION extension}
all=1 => {Disable $::sqlite__Config(all-flag-enables)}
with-icu-ldflags:LDFLAGS
=> {Enable SQLITE_ENABLE_ICU and add the given linker flags for the
ICU libraries. e.g. on Ubuntu systems, try '-licui18n -licuuc -licudata'.}
with-icu-cflags:CFLAGS
=> {Apply extra CFLAGS/CPPFLAGS necessary for building with ICU.
e.g. -I/usr/local/include}
with-icu-config:=auto
=> {Enable SQLITE_ENABLE_ICU. Value must be one of: auto, pkg-config,
/path/to/icu-config}
icu-collations=0
=> {Enable SQLITE_ENABLE_ICU_COLLATIONS. Requires --with-icu-ldflags=...
or --with-icu-config}
}]
}
#
# Gets called by tea-configure-core. Must perform any configuration
# work needed for this extension.
#
proc teaish-configure {} {
use teaish/feature
if {[proj-opt-was-provided override-sqlite-version]} {
teaish-pkginfo-set -version [opt-val override-sqlite-version]
proj-warn "overriding sqlite version number:" [teaish-pkginfo-get -version]
} elseif {[proj-opt-was-provided with-system-sqlite]
&& [opt-val with-system-sqlite] ne "0"} {
proj-fatal "when using --with-system-sqlite also use" \
"--override-sqlite-version to specify a library version number."
}
define CFLAGS [proj-get-env CFLAGS {-O2}]
sqlite-munge-cflags
#
# Add feature flags from legacy configure.ac which are not covered by
# --flags.
#
sqlite-add-feature-flag {
-DSQLITE_3_SUFFIX_ONLY=1
-DSQLITE_ENABLE_DESERIALIZE=1
-DSQLITE_ENABLE_DBPAGE_VTAB=1
-DSQLITE_ENABLE_BYTECODE_VTAB=1
-DSQLITE_ENABLE_DBSTAT_VTAB=1
}
if {[opt-bool with-system-sqlite]} {
msg-result "Using system-level sqlite3."
teaish-cflags-add -DUSE_SYSTEM_SQLITE
teaish-ldflags-add -lsqlite3
} elseif {$::sqlite__Config(is-canonical)} {
teaish-cflags-add -I[teaish-get -dir]/..
}
teaish-check-librt
teaish-check-libz
sqlite-handle-threadsafe
sqlite-handle-tempstore
sqlite-handle-load-extension
sqlite-handle-math
sqlite-handle-icu
sqlite-handle-common-feature-flags; # must be late in the process
}; # teaish-configure
define OPT_FEATURE_FLAGS {} ; # -DSQLITE_OMIT/ENABLE flags.
#
# Adds $args, if not empty, to OPT_FEATURE_FLAGS. This is intended only for holding
# -DSQLITE_ENABLE/OMIT/... flags, but that is not enforced here.
proc sqlite-add-feature-flag {args} {
if {"" ne $args} {
define-append OPT_FEATURE_FLAGS {*}$args
}
}
#
# Check for log(3) in libm and die with an error if it is not
# found. $featureName should be the feature name which requires that
# function (it's used only in error messages). defines LDFLAGS_MATH to
# the required linker flags (which may be empty even if the math APIs
# are found, depending on the OS).
proc sqlite-affirm-have-math {featureName} {
if {"" eq [get-define LDFLAGS_MATH ""]} {
if {![msg-quiet proj-check-function-in-lib log m]} {
user-error "Missing math APIs for $featureName"
}
set lfl [get-define lib_log ""]
undefine lib_log
if {"" ne $lfl} {
user-notice "Forcing requirement of $lfl for $featureName"
}
define LDFLAGS_MATH $lfl
teaish-ldflags-prepend $lfl
}
}
#
# Handle various SQLITE_ENABLE/OMIT_... feature flags.
proc sqlite-handle-common-feature-flags {} {
msg-result "Feature flags..."
if {![opt-bool all]} {
# Special handling for --disable-all
foreach flag $::sqlite__Config(all-flag-enables) {
if {![proj-opt-was-provided $flag]} {
proj-opt-set $flag 0
}
}
}
foreach {boolFlag featureFlag ifSetEvalThis} [proj-strip-hash-comments {
all {} {
# The 'all' option must be first in this list. This impl makes
# an effort to only apply flags which the user did not already
# apply, so that combinations like (--all --disable-geopoly)
# will indeed disable geopoly. There are corner cases where
# flags which depend on each other will behave in non-intuitive
# ways:
#
# --all --disable-rtree
#
# Will NOT disable geopoly, though geopoly depends on rtree.
# The --geopoly flag, though, will automatically re-enable
# --rtree, so --disable-rtree won't actually disable anything in
# that case.
foreach k $::sqlite__Config(all-flag-enables) {
if {![proj-opt-was-provided $k]} {
proj-opt-set $k 1
}
}
}
fts3 -DSQLITE_ENABLE_FTS3 {sqlite-affirm-have-math fts3}
fts4 -DSQLITE_ENABLE_FTS4 {sqlite-affirm-have-math fts4}
fts5 -DSQLITE_ENABLE_FTS5 {sqlite-affirm-have-math fts5}
geopoly -DSQLITE_ENABLE_GEOPOLY {proj-opt-set rtree}
rtree -DSQLITE_ENABLE_RTREE {}
session {-DSQLITE_ENABLE_SESSION -DSQLITE_ENABLE_PREUPDATE_HOOK} {}
update-limit -DSQLITE_ENABLE_UPDATE_DELETE_LIMIT {}
scanstatus -DSQLITE_ENABLE_STMT_SCANSTATUS {}
}] {
if {$boolFlag ni $::autosetup(options)} {
# Skip flags which are in the canonical build but not
# the autoconf bundle.
continue
}
proj-if-opt-truthy $boolFlag {
sqlite-add-feature-flag $featureFlag
if {0 != [eval $ifSetEvalThis] && "all" ne $boolFlag} {
msg-result " + $boolFlag"
}
} {
if {"all" ne $boolFlag} {
msg-result " - $boolFlag"
}
}
}
#
# Invert the above loop's logic for some SQLITE_OMIT_... cases. If
# config option $boolFlag is false, [sqlite-add-feature-flag
# $featureFlag], where $featureFlag is intended to be
# -DSQLITE_OMIT_...
foreach {boolFlag featureFlag} {
json -DSQLITE_OMIT_JSON
} {
if {[proj-opt-truthy $boolFlag]} {
msg-result " + $boolFlag"
} else {
sqlite-add-feature-flag $featureFlag
msg-result " - $boolFlag"
}
}
##
# Remove duplicates from the final feature flag sets and show them
# to the user.
set oFF [get-define OPT_FEATURE_FLAGS]
if {"" ne $oFF} {
define OPT_FEATURE_FLAGS [lsort -unique $oFF]
msg-result "Library feature flags: [get-define OPT_FEATURE_FLAGS]"
}
if {[lsearch [get-define TARGET_DEBUG ""] -DSQLITE_DEBUG=1] > -1} {
msg-result "Note: this is a debug build, so performance will suffer."
}
teaish-cflags-add -define OPT_FEATURE_FLAGS
}; # sqlite-handle-common-feature-flags
#
# If --enable-threadsafe is set, this adds -DSQLITE_THREADSAFE=1 to
# OPT_FEATURE_FLAGS and sets LDFLAGS_PTHREAD to the linker flags
# needed for linking pthread (possibly an empty string). If
# --enable-threadsafe is not set, adds -DSQLITE_THREADSAFE=0 to
# OPT_FEATURE_FLAGS and sets LDFLAGS_PTHREAD to an empty string.
#
# It prepends the flags to the global LDFLAGS.
proc sqlite-handle-threadsafe {} {
msg-checking "Support threadsafe operation? "
define LDFLAGS_PTHREAD ""
set enable 0
if {[proj-opt-was-provided threadsafe]} {
proj-if-opt-truthy threadsafe {
if {[proj-check-function-in-lib pthread_create pthread]
&& [proj-check-function-in-lib pthread_mutexattr_init pthread]} {
incr enable
set ldf [get-define lib_pthread_create]
define LDFLAGS_PTHREAD $ldf
teaish-ldflags-prepend $ldf
undefine lib_pthread_create
undefine lib_pthread_mutexattr_init
} else {
user-error "Missing required pthread libraries. Use --disable-threadsafe to disable this check."
}
# Recall that LDFLAGS_PTHREAD might be empty even if pthreads if
# found because it's in -lc on some platforms.
} {
msg-result "Disabled using --disable-threadsafe"
}
} else {
#
# If user does not specify --[disable-]threadsafe then select a
# default based on whether it looks like Tcl has threading
# support.
#
catch {
scan [exec echo {puts [tcl::pkgconfig get threaded]} | [get-define TCLSH_CMD]] \
%d enable
}
if {$enable} {
set flagName "--threadsafe"
set lblAbled "enabled"
msg-result yes
} else {
set flagName "--disable-threadsafe"
set lblAbled "disabled"
msg-result no
}
msg-result "Defaulting to ${flagName} because Tcl has threading ${lblAbled}."
# ^^^ We (probably) don't need to link against -lpthread in the
# is-enabled case. We might in the case of static linking. Unsure.
}
sqlite-add-feature-flag -DSQLITE_THREADSAFE=${enable}
return $enable
}
#
# Handles the --enable-load-extension flag. Returns 1 if the support
# is enabled, else 0. If support for that feature is not found, a
# fatal error is triggered if --enable-load-extension is explicitly
# provided, else a loud warning is instead emitted. If
# --disable-load-extension is used, no check is performed.
#
# Makes the following environment changes:
#
# - defines LDFLAGS_DLOPEN to any linker flags needed for this
# feature. It may legally be empty on some systems where dlopen()
# is in libc.
#
# - If the feature is not available, adds
# -DSQLITE_OMIT_LOAD_EXTENSION=1 to the feature flags list.
proc sqlite-handle-load-extension {} {
define LDFLAGS_DLOPEN ""
set found 0
proj-if-opt-truthy load-extension {
set found [proj-check-function-in-lib dlopen dl]
if {$found} {
set ldf [get-define lib_dlopen]
define LDFLAGS_DLOPEN $ldf
teaish-ldflags-prepend $ldf
undefine lib_dlopen
} else {
if {[proj-opt-was-provided load-extension]} {
# Explicit --enable-load-extension: fail if not found
proj-indented-notice -error {
--enable-load-extension was provided but dlopen()
not found. Use --disable-load-extension to bypass this
check.
}
} else {
# It was implicitly enabled: warn if not found
proj-indented-notice {
WARNING: dlopen() not found, so loadable module support will
be disabled. Use --disable-load-extension to bypass this
check.
}
}
}
}
if {$found} {
msg-result "Loadable extension support enabled."
} else {
msg-result "Disabling loadable extension support. Use --enable-load-extension to enable them."
sqlite-add-feature-flag -DSQLITE_OMIT_LOAD_EXTENSION=1
}
return $found
}
#
# ICU - International Components for Unicode
#
# Handles these flags:
#
# --with-icu-ldflags=LDFLAGS
# --with-icu-cflags=CFLAGS
# --with-icu-config[=auto | pkg-config | /path/to/icu-config]
# --enable-icu-collations
#
# --with-icu-config values:
#
# - auto: use the first one of (pkg-config, icu-config) found on the
# system.
# - pkg-config: use only pkg-config to determine flags
# - /path/to/icu-config: use that to determine flags
#
# If --with-icu-config is used as neither pkg-config nor icu-config
# are found, fail fatally.
#
# If both --with-icu-ldflags and --with-icu-config are provided, they
# are cumulative. If neither are provided, icu-collations is not
# honored and a warning is emitted if it is provided.
#
# Design note: though we could automatically enable ICU if the
# icu-config binary or (pkg-config icu-io) are found, we specifically
# do not. ICU is always an opt-in feature.
proc sqlite-handle-icu {} {
define LDFLAGS_LIBICU [join [opt-val with-icu-ldflags ""]]
define CFLAGS_LIBICU [join [opt-val with-icu-cflags ""]]
if {[proj-opt-was-provided with-icu-config]} {
msg-result "Checking for ICU support..."
set icuConfigBin [opt-val with-icu-config]
set tryIcuConfigBin 1; # set to 0 if we end up using pkg-config
if {$icuConfigBin in {auto pkg-config}} {
uplevel 3 { use pkg-config }
if {[pkg-config-init 0] && [pkg-config icu-io]} {
# Maintenance reminder: historical docs say to use both of
# (icu-io, icu-uc). icu-uc lacks a required lib and icu-io has
# all of them on tested OSes.
set tryIcuConfigBin 0
define LDFLAGS_LIBICU [get-define PKG_ICU_IO_LDFLAGS]
define-append LDFLAGS_LIBICU [get-define PKG_ICU_IO_LIBS]
define CFLAGS_LIBICU [get-define PKG_ICU_IO_CFLAGS]
} elseif {"pkg-config" eq $icuConfigBin} {
proj-fatal "pkg-config cannot find package icu-io"
} else {
proj-assert {"auto" eq $icuConfigBin}
}
}
if {$tryIcuConfigBin} {
if {"auto" eq $icuConfigBin} {
set icuConfigBin [proj-first-bin-of \
/usr/local/bin/icu-config \
/usr/bin/icu-config]
if {"" eq $icuConfigBin} {
proj-indented-notice -error {
--with-icu-config=auto cannot find (pkg-config icu-io) or icu-config binary.
On Ubuntu-like systems try:
--with-icu-ldflags='-licui18n -licuuc -licudata'
}
}
}
if {[file-isexec $icuConfigBin]} {
set x [exec $icuConfigBin --ldflags]
if {"" eq $x} {
proj-indented-notice -error \
[subst {
$icuConfigBin --ldflags returned no data.
On Ubuntu-like systems try:
--with-icu-ldflags='-licui18n -licuuc -licudata'
}]
}
define-append LDFLAGS_LIBICU $x
set x [exec $icuConfigBin --cppflags]
define-append CFLAGS_LIBICU $x
} else {
proj-fatal "--with-icu-config=$icuConfigBin does not refer to an executable"
}
}
}
set ldflags [define LDFLAGS_LIBICU [string trim [get-define LDFLAGS_LIBICU]]]
set cflags [define CFLAGS_LIBICU [string trim [get-define CFLAGS_LIBICU]]]
if {"" ne $ldflags} {
sqlite-add-feature-flag -DSQLITE_ENABLE_ICU
msg-result "Enabling ICU support with flags: $ldflags $cflags"
if {[opt-bool icu-collations]} {
msg-result "Enabling ICU collations."
sqlite-add-feature-flag -DSQLITE_ENABLE_ICU_COLLATIONS
}
teaish-ldflags-prepend $ldflags
teaish-cflags-add $cflags
} elseif {[opt-bool icu-collations]} {
proj-warn "ignoring --enable-icu-collations because neither --with-icu-ldflags nor --with-icu-config provided any linker flags"
} else {
msg-result "ICU support is disabled."
}
}; # sqlite-handle-icu
#
# Handles the --with-tempstore flag.
#
# The test fixture likes to set SQLITE_TEMP_STORE on its own, so do
# not set that feature flag unless it was explicitly provided to the
# configure script.
proc sqlite-handle-tempstore {} {
if {[proj-opt-was-provided with-tempstore]} {
set ts [opt-val with-tempstore no]
set tsn 1
msg-checking "Use an in-RAM database for temporary tables? "
switch -exact -- $ts {
never { set tsn 0 }
no { set tsn 1 }
yes { set tsn 2 }
always { set tsn 3 }
default {
user-error "Invalid --with-tempstore value '$ts'. Use one of: never, no, yes, always"
}
}
msg-result $ts
sqlite-add-feature-flag -DSQLITE_TEMP_STORE=$tsn
}
}
#
# Handles the --enable-math flag.
proc sqlite-handle-math {} {
proj-if-opt-truthy math {
if {![proj-check-function-in-lib ceil m]} {
user-error "Cannot find libm functions. Use --disable-math to bypass this."
}
set lfl [get-define lib_ceil]
undefine lib_ceil
define LDFLAGS_MATH $lfl
teaish-ldflags-prepend $lfl
sqlite-add-feature-flag -DSQLITE_ENABLE_MATH_FUNCTIONS
msg-result "Enabling math SQL functions"
} {
define LDFLAGS_MATH ""
msg-result "Disabling math SQL functions"
}
}
#
# Move -DSQLITE_OMIT... and -DSQLITE_ENABLE... flags from CFLAGS and
# CPPFLAGS to OPT_FEATURE_FLAGS and remove them from BUILD_CFLAGS.
proc sqlite-munge-cflags {} {
# Move CFLAGS and CPPFLAGS entries matching -DSQLITE_OMIT* and
# -DSQLITE_ENABLE* to OPT_FEATURE_FLAGS. This behavior is derived
# from the pre-3.48 build.
#
# If any configure flags for features are in conflict with
# CFLAGS/CPPFLAGS-specified feature flags, all bets are off. There
# are no guarantees about which one will take precedence.
foreach flagDef {CFLAGS CPPFLAGS} {
set tmp ""
foreach cf [get-define $flagDef ""] {
switch -glob -- $cf {
-DSQLITE_OMIT* -
-DSQLITE_ENABLE* {
sqlite-add-feature-flag $cf
}
default {
lappend tmp $cf
}
}
}
define $flagDef $tmp
}
}
+14
View File
@@ -0,0 +1,14 @@
test-expect 1.0-open {
sqlite3 db :memory:
} {}
test-assert 1.1-version-3.x {
[string match 3.* [db eval {select sqlite_version()}]]
}
test-expect 1.2-select {
db eval {select 'hi, world',1,2,3}
} {{hi, world} 1 2 3}
test-expect 99.0-db-close {db close} {}
-61
View File
@@ -1,61 +0,0 @@
#------------------------------------------------------------- -*- makefile -*-
#
# Sample makefile for building Tcl extensions.
#
# Basic build, test and install
# nmake /s /nologo /f makefile.vc INSTALLDIR=c:\path\to\tcl
# nmake /s /nologo /f makefile.vc INSTALLDIR=c:\path\to\tcl test
# nmake /s /nologo /f makefile.vc INSTALLDIR=c:\path\to\tcl install
#
# For other build options (debug, static etc.)
# See TIP 477 (https://core.tcl.tk/tips/doc/trunk/tip/477.md) for
# detailed documentation.
#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#
#------------------------------------------------------------------------------
# PROJECT is sqlite, not sqlite3 to match TEA AC_INIT definition.
# This makes the generated DLL name also consistent between the two
# except for the "t" suffix which is the convention for nmake builds.
PROJECT = sqlite
PRJ_PACKAGE_TCLNAME = sqlite3
!include "rules-ext.vc"
PRJ_OBJS = $(TMP_DIR)\tclsqlite3.obj
# Preprocessor macros specific to sqlite3.
PRJ_DEFINES = -I"$(ROOT)\.." -D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE \
-DSQLITE_ENABLE_DBPAGE_VTAB=1 -DSQLITE_ENABLE_DBSTAT_VTAB=1 \
-DSQLITE_ENABLE_FTS3_PARENTHESIS=1 -DSQLITE_ENABLE_FTS4=1 \
-DSQLITE_ENABLE_FTS5=1 -DSQLITE_ENABLE_COLUMN_METADATA=1 \
-DSQLITE_ENABLE_JSON1=1 -DSQLITE_LIKE_DOESNT_MATCH_BLOBS=1 \
-DSQLITE_3_SUFFIX_ONLY=1 -DSQLITE_ENABLE_RTREE=1 \
-DSQLITE_UNTESTABLE=1 -DSQLITE_OMIT_LOOKASIDE=1 \
-DSQLITE_SECURE_DELETE=1 -DSQLITE_SOUNDEX=1 -DSQLITE_ENABLE_GEOPOLY=1 \
-DSQLITE_ENABLE_UPDATE_DELETE_LIMIT=1 \
-DSQLITE_ENABLE_MATH_FUNCTIONS=1 -DDSQLITE_USE_ALLOCA=1 \
-DSQLITE_ENABLE_STAT4=1 -DSQLITE_OMIT_DEPRECATED=1 \
-DSQLITE_WIN32_GETVERSIONEX=0 -DSQLITE_WIN32_NO_ANSI=1
PRJ_DEFINES = $(PRJ_DEFINES) -I$(TMP_DIR)
# Standard targets to build, install, test etc.
!include "$(_RULESDIR)\targets.vc"
# The built-in pkgindex does no suffice for our extension as
# the PROJECT name (sqlite) is not same as init function name (Sqlite3)
pkgindex:
@echo if {[package vsatisfies [package provide Tcl] 9.0-]} { > $(OUT_DIR)\pkgIndex.tcl
@echo package ifneeded $(PRJ_PACKAGE_TCLNAME) $(DOTVERSION) \
[list load [file join $$dir $(PRJLIBNAME9)] [string totitle $(PRJ_PACKAGE_TCLNAME)]] >> $(OUT_DIR)\pkgIndex.tcl
@echo } else { >> $(OUT_DIR)\pkgIndex.tcl
@echo package ifneeded $(PRJ_PACKAGE_TCLNAME) $(DOTVERSION) \
[list load [file join $$dir $(PRJLIBNAME8)] [string totitle $(PRJ_PACKAGE_TCLNAME)]] >> $(OUT_DIR)\pkgIndex.tcl
@echo } >> $(OUT_DIR)\pkgIndex.tcl
# Install the manpage though on Windows, doubt it does much good
install: default-install-docs-n
# Explicit dependency rules
-815
View File
@@ -1,815 +0,0 @@
/*
* ----------------------------------------------------------------------------
* nmakehlp.c --
*
* This is used to fix limitations within nmake and the environment.
*
* Copyright (c) 2002 by David Gravereaux.
* Copyright (c) 2006 by Pat Thoyts
*
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
* ----------------------------------------------------------------------------
*/
#define _CRT_SECURE_NO_DEPRECATE
#include <windows.h>
#ifdef _MSC_VER
#pragma comment (lib, "user32.lib")
#pragma comment (lib, "kernel32.lib")
#endif
#include <stdio.h>
#include <math.h>
/*
* This library is required for x64 builds with _some_ versions of MSVC
*/
#if defined(_M_IA64) || defined(_M_AMD64)
#if _MSC_VER >= 1400 && _MSC_VER < 1500
#pragma comment(lib, "bufferoverflowU")
#endif
#endif
/* ISO hack for dumb VC++ */
#ifdef _MSC_VER
#define snprintf _snprintf
#endif
/* protos */
static int CheckForCompilerFeature(const char *option);
static int CheckForLinkerFeature(char **options, int count);
static int IsIn(const char *string, const char *substring);
static int SubstituteFile(const char *substs, const char *filename);
static int QualifyPath(const char *path);
static int LocateDependency(const char *keyfile);
static const char *GetVersionFromFile(const char *filename, const char *match, int numdots);
static DWORD WINAPI ReadFromPipe(LPVOID args);
/* globals */
#define CHUNK 25
#define STATICBUFFERSIZE 1000
typedef struct {
HANDLE pipe;
char buffer[STATICBUFFERSIZE];
} pipeinfo;
pipeinfo Out = {INVALID_HANDLE_VALUE, ""};
pipeinfo Err = {INVALID_HANDLE_VALUE, ""};
/*
* exitcodes: 0 == no, 1 == yes, 2 == error
*/
int
main(
int argc,
char *argv[])
{
char msg[300];
DWORD dwWritten;
int chars;
const char *s;
/*
* Make sure children (cl.exe and link.exe) are kept quiet.
*/
SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX);
/*
* Make sure the compiler and linker aren't effected by the outside world.
*/
SetEnvironmentVariable("CL", "");
SetEnvironmentVariable("LINK", "");
if (argc > 1 && *argv[1] == '-') {
switch (*(argv[1]+1)) {
case 'c':
if (argc != 3) {
chars = snprintf(msg, sizeof(msg) - 1,
"usage: %s -c <compiler option>\n"
"Tests for whether cl.exe supports an option\n"
"exitcodes: 0 == no, 1 == yes, 2 == error\n", argv[0]);
WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,
&dwWritten, NULL);
return 2;
}
return CheckForCompilerFeature(argv[2]);
case 'l':
if (argc < 3) {
chars = snprintf(msg, sizeof(msg) - 1,
"usage: %s -l <linker option> ?<mandatory option> ...?\n"
"Tests for whether link.exe supports an option\n"
"exitcodes: 0 == no, 1 == yes, 2 == error\n", argv[0]);
WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,
&dwWritten, NULL);
return 2;
}
return CheckForLinkerFeature(&argv[2], argc-2);
case 'f':
if (argc == 2) {
chars = snprintf(msg, sizeof(msg) - 1,
"usage: %s -f <string> <substring>\n"
"Find a substring within another\n"
"exitcodes: 0 == no, 1 == yes, 2 == error\n", argv[0]);
WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,
&dwWritten, NULL);
return 2;
} else if (argc == 3) {
/*
* If the string is blank, there is no match.
*/
return 0;
} else {
return IsIn(argv[2], argv[3]);
}
case 's':
if (argc == 2) {
chars = snprintf(msg, sizeof(msg) - 1,
"usage: %s -s <substitutions file> <file>\n"
"Perform a set of string map type substutitions on a file\n"
"exitcodes: 0\n",
argv[0]);
WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,
&dwWritten, NULL);
return 2;
}
return SubstituteFile(argv[2], argv[3]);
case 'V':
if (argc != 4) {
chars = snprintf(msg, sizeof(msg) - 1,
"usage: %s -V filename matchstring\n"
"Extract a version from a file:\n"
"eg: pkgIndex.tcl \"package ifneeded http\"",
argv[0]);
WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,
&dwWritten, NULL);
return 0;
}
s = GetVersionFromFile(argv[2], argv[3], *(argv[1]+2) - '0');
if (s && *s) {
printf("%s\n", s);
return 0;
} else
return 1; /* Version not found. Return non-0 exit code */
case 'Q':
if (argc != 3) {
chars = snprintf(msg, sizeof(msg) - 1,
"usage: %s -Q path\n"
"Emit the fully qualified path\n"
"exitcodes: 0 == no, 1 == yes, 2 == error\n", argv[0]);
WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,
&dwWritten, NULL);
return 2;
}
return QualifyPath(argv[2]);
case 'L':
if (argc != 3) {
chars = snprintf(msg, sizeof(msg) - 1,
"usage: %s -L keypath\n"
"Emit the fully qualified path of directory containing keypath\n"
"exitcodes: 0 == success, 1 == not found, 2 == error\n", argv[0]);
WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,
&dwWritten, NULL);
return 2;
}
return LocateDependency(argv[2]);
}
}
chars = snprintf(msg, sizeof(msg) - 1,
"usage: %s -c|-f|-l|-Q|-s|-V ...\n"
"This is a little helper app to equalize shell differences between WinNT and\n"
"Win9x and get nmake.exe to accomplish its job.\n",
argv[0]);
WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars, &dwWritten, NULL);
return 2;
}
static int
CheckForCompilerFeature(
const char *option)
{
STARTUPINFO si;
PROCESS_INFORMATION pi;
SECURITY_ATTRIBUTES sa;
DWORD threadID;
char msg[300];
BOOL ok;
HANDLE hProcess, h, pipeThreads[2];
char cmdline[100];
hProcess = GetCurrentProcess();
ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));
ZeroMemory(&si, sizeof(STARTUPINFO));
si.cb = sizeof(STARTUPINFO);
si.dwFlags = STARTF_USESTDHANDLES;
si.hStdInput = INVALID_HANDLE_VALUE;
ZeroMemory(&sa, sizeof(SECURITY_ATTRIBUTES));
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.lpSecurityDescriptor = NULL;
sa.bInheritHandle = FALSE;
/*
* Create a non-inheritible pipe.
*/
CreatePipe(&Out.pipe, &h, &sa, 0);
/*
* Dupe the write side, make it inheritible, and close the original.
*/
DuplicateHandle(hProcess, h, hProcess, &si.hStdOutput, 0, TRUE,
DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE);
/*
* Same as above, but for the error side.
*/
CreatePipe(&Err.pipe, &h, &sa, 0);
DuplicateHandle(hProcess, h, hProcess, &si.hStdError, 0, TRUE,
DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE);
/*
* Base command line.
*/
lstrcpy(cmdline, "cl.exe -nologo -c -TC -Zs -X -Fp.\\_junk.pch ");
/*
* Append our option for testing
*/
lstrcat(cmdline, option);
/*
* Filename to compile, which exists, but is nothing and empty.
*/
lstrcat(cmdline, " .\\nul");
ok = CreateProcess(
NULL, /* Module name. */
cmdline, /* Command line. */
NULL, /* Process handle not inheritable. */
NULL, /* Thread handle not inheritable. */
TRUE, /* yes, inherit handles. */
DETACHED_PROCESS, /* No console for you. */
NULL, /* Use parent's environment block. */
NULL, /* Use parent's starting directory. */
&si, /* Pointer to STARTUPINFO structure. */
&pi); /* Pointer to PROCESS_INFORMATION structure. */
if (!ok) {
DWORD err = GetLastError();
int chars = snprintf(msg, sizeof(msg) - 1,
"Tried to launch: \"%s\", but got error [%u]: ", cmdline, err);
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS|
FORMAT_MESSAGE_MAX_WIDTH_MASK, 0L, err, 0, (LPSTR)&msg[chars],
(300-chars), 0);
WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, lstrlen(msg), &err,NULL);
return 2;
}
/*
* Close our references to the write handles that have now been inherited.
*/
CloseHandle(si.hStdOutput);
CloseHandle(si.hStdError);
WaitForInputIdle(pi.hProcess, 5000);
CloseHandle(pi.hThread);
/*
* Start the pipe reader threads.
*/
pipeThreads[0] = CreateThread(NULL, 0, ReadFromPipe, &Out, 0, &threadID);
pipeThreads[1] = CreateThread(NULL, 0, ReadFromPipe, &Err, 0, &threadID);
/*
* Block waiting for the process to end.
*/
WaitForSingleObject(pi.hProcess, INFINITE);
CloseHandle(pi.hProcess);
/*
* Wait for our pipe to get done reading, should it be a little slow.
*/
WaitForMultipleObjects(2, pipeThreads, TRUE, 500);
CloseHandle(pipeThreads[0]);
CloseHandle(pipeThreads[1]);
/*
* Look for the commandline warning code in both streams.
* - in MSVC 6 & 7 we get D4002, in MSVC 8 we get D9002.
*/
return !(strstr(Out.buffer, "D4002") != NULL
|| strstr(Err.buffer, "D4002") != NULL
|| strstr(Out.buffer, "D9002") != NULL
|| strstr(Err.buffer, "D9002") != NULL
|| strstr(Out.buffer, "D2021") != NULL
|| strstr(Err.buffer, "D2021") != NULL);
}
static int
CheckForLinkerFeature(
char **options,
int count)
{
STARTUPINFO si;
PROCESS_INFORMATION pi;
SECURITY_ATTRIBUTES sa;
DWORD threadID;
char msg[300];
BOOL ok;
HANDLE hProcess, h, pipeThreads[2];
int i;
char cmdline[255];
hProcess = GetCurrentProcess();
ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));
ZeroMemory(&si, sizeof(STARTUPINFO));
si.cb = sizeof(STARTUPINFO);
si.dwFlags = STARTF_USESTDHANDLES;
si.hStdInput = INVALID_HANDLE_VALUE;
ZeroMemory(&sa, sizeof(SECURITY_ATTRIBUTES));
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.lpSecurityDescriptor = NULL;
sa.bInheritHandle = TRUE;
/*
* Create a non-inheritible pipe.
*/
CreatePipe(&Out.pipe, &h, &sa, 0);
/*
* Dupe the write side, make it inheritible, and close the original.
*/
DuplicateHandle(hProcess, h, hProcess, &si.hStdOutput, 0, TRUE,
DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE);
/*
* Same as above, but for the error side.
*/
CreatePipe(&Err.pipe, &h, &sa, 0);
DuplicateHandle(hProcess, h, hProcess, &si.hStdError, 0, TRUE,
DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE);
/*
* Base command line.
*/
lstrcpy(cmdline, "link.exe -nologo ");
/*
* Append our option for testing.
*/
for (i = 0; i < count; i++) {
lstrcat(cmdline, " \"");
lstrcat(cmdline, options[i]);
lstrcat(cmdline, "\"");
}
ok = CreateProcess(
NULL, /* Module name. */
cmdline, /* Command line. */
NULL, /* Process handle not inheritable. */
NULL, /* Thread handle not inheritable. */
TRUE, /* yes, inherit handles. */
DETACHED_PROCESS, /* No console for you. */
NULL, /* Use parent's environment block. */
NULL, /* Use parent's starting directory. */
&si, /* Pointer to STARTUPINFO structure. */
&pi); /* Pointer to PROCESS_INFORMATION structure. */
if (!ok) {
DWORD err = GetLastError();
int chars = snprintf(msg, sizeof(msg) - 1,
"Tried to launch: \"%s\", but got error [%u]: ", cmdline, err);
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS|
FORMAT_MESSAGE_MAX_WIDTH_MASK, 0L, err, 0, (LPSTR)&msg[chars],
(300-chars), 0);
WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, lstrlen(msg), &err,NULL);
return 2;
}
/*
* Close our references to the write handles that have now been inherited.
*/
CloseHandle(si.hStdOutput);
CloseHandle(si.hStdError);
WaitForInputIdle(pi.hProcess, 5000);
CloseHandle(pi.hThread);
/*
* Start the pipe reader threads.
*/
pipeThreads[0] = CreateThread(NULL, 0, ReadFromPipe, &Out, 0, &threadID);
pipeThreads[1] = CreateThread(NULL, 0, ReadFromPipe, &Err, 0, &threadID);
/*
* Block waiting for the process to end.
*/
WaitForSingleObject(pi.hProcess, INFINITE);
CloseHandle(pi.hProcess);
/*
* Wait for our pipe to get done reading, should it be a little slow.
*/
WaitForMultipleObjects(2, pipeThreads, TRUE, 500);
CloseHandle(pipeThreads[0]);
CloseHandle(pipeThreads[1]);
/*
* Look for the commandline warning code in the stderr stream.
*/
return !(strstr(Out.buffer, "LNK1117") != NULL ||
strstr(Err.buffer, "LNK1117") != NULL ||
strstr(Out.buffer, "LNK4044") != NULL ||
strstr(Err.buffer, "LNK4044") != NULL ||
strstr(Out.buffer, "LNK4224") != NULL ||
strstr(Err.buffer, "LNK4224") != NULL);
}
static DWORD WINAPI
ReadFromPipe(
LPVOID args)
{
pipeinfo *pi = (pipeinfo *) args;
char *lastBuf = pi->buffer;
DWORD dwRead;
BOOL ok;
again:
if (lastBuf - pi->buffer + CHUNK > STATICBUFFERSIZE) {
CloseHandle(pi->pipe);
return (DWORD)-1;
}
ok = ReadFile(pi->pipe, lastBuf, CHUNK, &dwRead, 0L);
if (!ok || dwRead == 0) {
CloseHandle(pi->pipe);
return 0;
}
lastBuf += dwRead;
goto again;
return 0; /* makes the compiler happy */
}
static int
IsIn(
const char *string,
const char *substring)
{
return (strstr(string, substring) != NULL);
}
/*
* GetVersionFromFile --
* Looks for a match string in a file and then returns the version
* following the match where a version is anything acceptable to
* package provide or package ifneeded.
*/
static const char *
GetVersionFromFile(
const char *filename,
const char *match,
int numdots)
{
static char szBuffer[100];
char *szResult = NULL;
FILE *fp = fopen(filename, "rt");
if (fp != NULL) {
/*
* Read data until we see our match string.
*/
while (fgets(szBuffer, sizeof(szBuffer), fp) != NULL) {
LPSTR p, q;
p = strstr(szBuffer, match);
if (p != NULL) {
/*
* Skip to first digit after the match.
*/
p += strlen(match);
while (*p && !isdigit((unsigned char)*p)) {
++p;
}
/*
* Find ending whitespace.
*/
q = p;
while (*q && (strchr("0123456789.ab", *q)) && (((!strchr(".ab", *q)
&& !strchr("ab", q[-1])) || --numdots))) {
++q;
}
*q = 0;
szResult = p;
break;
}
}
fclose(fp);
}
return szResult;
}
/*
* List helpers for the SubstituteFile function
*/
typedef struct list_item_t {
struct list_item_t *nextPtr;
char * key;
char * value;
} list_item_t;
/* insert a list item into the list (list may be null) */
static list_item_t *
list_insert(list_item_t **listPtrPtr, const char *key, const char *value)
{
list_item_t *itemPtr = (list_item_t *)malloc(sizeof(list_item_t));
if (itemPtr) {
itemPtr->key = strdup(key);
itemPtr->value = strdup(value);
itemPtr->nextPtr = NULL;
while(*listPtrPtr) {
listPtrPtr = &(*listPtrPtr)->nextPtr;
}
*listPtrPtr = itemPtr;
}
return itemPtr;
}
static void
list_free(list_item_t **listPtrPtr)
{
list_item_t *tmpPtr, *listPtr = *listPtrPtr;
while (listPtr) {
tmpPtr = listPtr;
listPtr = listPtr->nextPtr;
free(tmpPtr->key);
free(tmpPtr->value);
free(tmpPtr);
}
}
/*
* SubstituteFile --
* As windows doesn't provide anything useful like sed and it's unreliable
* to use the tclsh you are building against (consider x-platform builds -
* eg compiling AMD64 target from IX86) we provide a simple substitution
* option here to handle autoconf style substitutions.
* The substitution file is whitespace and line delimited. The file should
* consist of lines matching the regular expression:
* \s*\S+\s+\S*$
*
* Usage is something like:
* nmakehlp -S << $** > $@
* @PACKAGE_NAME@ $(PACKAGE_NAME)
* @PACKAGE_VERSION@ $(PACKAGE_VERSION)
* <<
*/
static int
SubstituteFile(
const char *substitutions,
const char *filename)
{
static char szBuffer[1024], szCopy[1024];
list_item_t *substPtr = NULL;
FILE *fp, *sp;
fp = fopen(filename, "rt");
if (fp != NULL) {
/*
* Build a list of substutitions from the first filename
*/
sp = fopen(substitutions, "rt");
if (sp != NULL) {
while (fgets(szBuffer, sizeof(szBuffer), sp) != NULL) {
unsigned char *ks, *ke, *vs, *ve;
ks = (unsigned char*)szBuffer;
while (ks && *ks && isspace(*ks)) ++ks;
ke = ks;
while (ke && *ke && !isspace(*ke)) ++ke;
vs = ke;
while (vs && *vs && isspace(*vs)) ++vs;
ve = vs;
while (ve && *ve && !(*ve == '\r' || *ve == '\n')) ++ve;
*ke = 0, *ve = 0;
list_insert(&substPtr, (char*)ks, (char*)vs);
}
fclose(sp);
}
/* debug: dump the list */
#ifndef NDEBUG
{
int n = 0;
list_item_t *p = NULL;
for (p = substPtr; p != NULL; p = p->nextPtr, ++n) {
fprintf(stderr, "% 3d '%s' => '%s'\n", n, p->key, p->value);
}
}
#endif
/*
* Run the substitutions over each line of the input
*/
while (fgets(szBuffer, sizeof(szBuffer), fp) != NULL) {
list_item_t *p = NULL;
for (p = substPtr; p != NULL; p = p->nextPtr) {
char *m = strstr(szBuffer, p->key);
if (m) {
char *cp, *op, *sp;
cp = szCopy;
op = szBuffer;
while (op != m) *cp++ = *op++;
sp = p->value;
while (sp && *sp) *cp++ = *sp++;
op += strlen(p->key);
while (*op) *cp++ = *op++;
*cp = 0;
memcpy(szBuffer, szCopy, sizeof(szCopy));
}
}
printf("%s", szBuffer);
}
list_free(&substPtr);
}
fclose(fp);
return 0;
}
BOOL FileExists(LPCTSTR szPath)
{
#ifndef INVALID_FILE_ATTRIBUTES
#define INVALID_FILE_ATTRIBUTES ((DWORD)-1)
#endif
DWORD pathAttr = GetFileAttributes(szPath);
return (pathAttr != INVALID_FILE_ATTRIBUTES &&
!(pathAttr & FILE_ATTRIBUTE_DIRECTORY));
}
/*
* QualifyPath --
*
* This composes the current working directory with a provided path
* and returns the fully qualified and normalized path.
* Mostly needed to setup paths for testing.
*/
static int
QualifyPath(
const char *szPath)
{
char szCwd[MAX_PATH + 1];
GetFullPathName(szPath, sizeof(szCwd)-1, szCwd, NULL);
printf("%s\n", szCwd);
return 0;
}
/*
* Implements LocateDependency for a single directory. See that command
* for an explanation.
* Returns 0 if found after printing the directory.
* Returns 1 if not found but no errors.
* Returns 2 on any kind of error
* Basically, these are used as exit codes for the process.
*/
static int LocateDependencyHelper(const char *dir, const char *keypath)
{
HANDLE hSearch;
char path[MAX_PATH+1];
size_t dirlen;
int keylen, ret;
WIN32_FIND_DATA finfo;
if (dir == NULL || keypath == NULL)
return 2; /* Have no real error reporting mechanism into nmake */
dirlen = strlen(dir);
if ((dirlen + 3) > sizeof(path))
return 2;
strncpy(path, dir, dirlen);
strncpy(path+dirlen, "\\*", 3); /* Including terminating \0 */
keylen = strlen(keypath);
#if 0 /* This function is not available in Visual C++ 6 */
/*
* Use numerics 0 -> FindExInfoStandard,
* 1 -> FindExSearchLimitToDirectories,
* as these are not defined in Visual C++ 6
*/
hSearch = FindFirstFileEx(path, 0, &finfo, 1, NULL, 0);
#else
hSearch = FindFirstFile(path, &finfo);
#endif
if (hSearch == INVALID_HANDLE_VALUE)
return 1; /* Not found */
/* Loop through all subdirs checking if the keypath is under there */
ret = 1; /* Assume not found */
do {
int sublen;
/*
* We need to check it is a directory despite the
* FindExSearchLimitToDirectories in the above call. See SDK docs
*/
if ((finfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0)
continue;
sublen = strlen(finfo.cFileName);
if ((dirlen+1+sublen+1+keylen+1) > sizeof(path))
continue; /* Path does not fit, assume not matched */
strncpy(path+dirlen+1, finfo.cFileName, sublen);
path[dirlen+1+sublen] = '\\';
strncpy(path+dirlen+1+sublen+1, keypath, keylen+1);
if (FileExists(path)) {
/* Found a match, print to stdout */
path[dirlen+1+sublen] = '\0';
QualifyPath(path);
ret = 0;
break;
}
} while (FindNextFile(hSearch, &finfo));
FindClose(hSearch);
return ret;
}
/*
* LocateDependency --
*
* Locates a dependency for a package.
* keypath - a relative path within the package directory
* that is used to confirm it is the correct directory.
* The search path for the package directory is currently only
* the parent and grandparent of the current working directory.
* If found, the command prints
* name_DIRPATH=<full path of located directory>
* and returns 0. If not found, does not print anything and returns 1.
*/
static int LocateDependency(const char *keypath)
{
size_t i;
int ret;
static const char *paths[] = {"..", "..\\..", "..\\..\\.."};
for (i = 0; i < (sizeof(paths)/sizeof(paths[0])); ++i) {
ret = LocateDependencyHelper(paths[i], keypath);
if (ret == 0)
return ret;
}
return ret;
}
/*
* Local variables:
* mode: c
* c-basic-offset: 4
* fill-column: 78
* indent-tabs-mode: t
* tab-width: 8
* End:
*/
-123
View File
@@ -1,123 +0,0 @@
# This file should only be included in makefiles for Tcl extensions,
# NOT in the makefile for Tcl itself.
!ifndef _RULES_EXT_VC
# We need to run from the directory the parent makefile is located in.
# nmake does not tell us what makefile was used to invoke it so parent
# makefile has to set the MAKEFILEVC macro or we just make a guess and
# warn if we think that is not the case.
!if "$(MAKEFILEVC)" == ""
!if exist("$(PROJECT).vc")
MAKEFILEVC = $(PROJECT).vc
!elseif exist("makefile.vc")
MAKEFILEVC = makefile.vc
!endif
!endif # "$(MAKEFILEVC)" == ""
!if !exist("$(MAKEFILEVC)")
MSG = ^
You must run nmake from the directory containing the project makefile.^
If you are doing that and getting this message, set the MAKEFILEVC^
macro to the name of the project makefile.
!message WARNING: $(MSG)
!endif
!if "$(PROJECT)" == "tcl"
!error The rules-ext.vc file is not intended for Tcl itself.
!endif
# We extract version numbers using the nmakehlp program. For now use
# the local copy of nmakehlp. Once we locate Tcl, we will use that
# one if it is newer.
!if "$(MACHINE)" == "IX86" || "$(MACHINE)" == "$(NATIVE_ARCH)"
!if [$(CC) -nologo -DNDEBUG "nmakehlp.c" -link -subsystem:console > nul]
!endif
!else
!if [copy x86_64-w64-mingw32-nmakehlp.exe nmakehlp.exe >NUL]
!endif
!endif
# First locate the Tcl directory that we are working with.
!if "$(TCLDIR)" != ""
_RULESDIR = $(TCLDIR:/=\)
!else
# If an installation path is specified, that is also the Tcl directory.
# Also Tk never builds against an installed Tcl, it needs Tcl sources
!if defined(INSTALLDIR) && "$(PROJECT)" != "tk"
_RULESDIR=$(INSTALLDIR:/=\)
!else
# Locate Tcl sources
!if [echo _RULESDIR = \> nmakehlp.out] \
|| [nmakehlp -L generic\tcl.h >> nmakehlp.out]
_RULESDIR = ..\..\tcl
!else
!include nmakehlp.out
!endif
!endif # defined(INSTALLDIR)....
!endif # ifndef TCLDIR
# Now look for the targets.vc file under the Tcl root. Note we check this
# file and not rules.vc because the latter also exists on older systems.
!if exist("$(_RULESDIR)\lib\nmake\targets.vc") # Building against installed Tcl
_RULESDIR = $(_RULESDIR)\lib\nmake
!elseif exist("$(_RULESDIR)\win\targets.vc") # Building against Tcl sources
_RULESDIR = $(_RULESDIR)\win
!else
# If we have not located Tcl's targets file, most likely we are compiling
# against an older version of Tcl and so must use our own support files.
_RULESDIR = .
!endif
!if "$(_RULESDIR)" != "."
# Potentially using Tcl's support files. If this extension has its own
# nmake support files, need to compare the versions and pick newer.
!if exist("rules.vc") # The extension has its own copy
!if [echo TCL_RULES_MAJOR = \> versions.vc] \
&& [nmakehlp -V "$(_RULESDIR)\rules.vc" RULES_VERSION_MAJOR >> versions.vc]
!endif
!if [echo TCL_RULES_MINOR = \>> versions.vc] \
&& [nmakehlp -V "$(_RULESDIR)\rules.vc" RULES_VERSION_MINOR >> versions.vc]
!endif
!if [echo OUR_RULES_MAJOR = \>> versions.vc] \
&& [nmakehlp -V "rules.vc" RULES_VERSION_MAJOR >> versions.vc]
!endif
!if [echo OUR_RULES_MINOR = \>> versions.vc] \
&& [nmakehlp -V "rules.vc" RULES_VERSION_MINOR >> versions.vc]
!endif
!include versions.vc
# We have a newer version of the support files, use them
!if ($(TCL_RULES_MAJOR) != $(OUR_RULES_MAJOR)) || ($(TCL_RULES_MINOR) < $(OUR_RULES_MINOR))
_RULESDIR = .
!endif
!endif # if exist("rules.vc")
!endif # if $(_RULESDIR) != "."
# Let rules.vc know what copy of nmakehlp.c to use.
NMAKEHLPC = $(_RULESDIR)\nmakehlp.c
# Get rid of our internal defines before calling rules.vc
!undef TCL_RULES_MAJOR
!undef TCL_RULES_MINOR
!undef OUR_RULES_MAJOR
!undef OUR_RULES_MINOR
!if exist("$(_RULESDIR)\rules.vc")
!message *** Using $(_RULESDIR)\rules.vc
!include "$(_RULESDIR)\rules.vc"
!else
!error *** Could not locate rules.vc in $(_RULESDIR)
!endif
!endif # _RULES_EXT_VC
File diff suppressed because it is too large Load Diff
-98
View File
@@ -1,98 +0,0 @@
#------------------------------------------------------------- -*- makefile -*-
# targets.vc --
#
# Part of the nmake based build system for Tcl and its extensions.
# This file defines some standard targets for the convenience of extensions
# and can be optionally included by the extension makefile.
# See TIP 477 (https://core.tcl-lang.org/tips/doc/main/tip/477.md) for docs.
$(PROJECT): setup pkgindex $(PRJLIB)
!ifdef PRJ_STUBOBJS
$(PROJECT): $(PRJSTUBLIB)
$(PRJSTUBLIB): $(PRJ_STUBOBJS)
$(LIBCMD) $**
$(PRJ_STUBOBJS):
$(CCSTUBSCMD) %s
!endif # PRJ_STUBOBJS
!ifdef PRJ_MANIFEST
$(PROJECT): $(PRJLIB).manifest
$(PRJLIB).manifest: $(PRJ_MANIFEST)
@nmakehlp -s << $** >$@
@MACHINE@ $(MACHINE:IX86=X86)
<<
!endif
!if "$(PROJECT)" != "tcl" && "$(PROJECT)" != "tk"
$(PRJLIB): $(PRJ_OBJS) $(RESFILE)
!if $(STATIC_BUILD)
$(LIBCMD) $**
!else
$(DLLCMD) $**
$(_VC_MANIFEST_EMBED_DLL)
!endif
-@del $*.exp
!endif
!if "$(PRJ_HEADERS)" != "" && "$(PRJ_OBJS)" != ""
$(PRJ_OBJS): $(PRJ_HEADERS)
!endif
# If parent makefile has defined stub objects, add their installation
# to the default install
!if "$(PRJ_STUBOBJS)" != ""
default-install: default-install-stubs
!endif
# Unlike the other default targets, these cannot be in rules.vc because
# the executed command depends on existence of macro PRJ_HEADERS_PUBLIC
# that the parent makefile will not define until after including rules-ext.vc
!if "$(PRJ_HEADERS_PUBLIC)" != ""
default-install: default-install-headers
default-install-headers:
@echo Installing headers to '$(INCLUDE_INSTALL_DIR)'
@for %f in ($(PRJ_HEADERS_PUBLIC)) do @$(COPY) %f "$(INCLUDE_INSTALL_DIR)"
!endif
!if "$(DISABLE_STANDARD_TARGETS)" == ""
DISABLE_STANDARD_TARGETS = 0
!endif
!if "$(DISABLE_TARGET_setup)" == ""
DISABLE_TARGET_setup = 0
!endif
!if "$(DISABLE_TARGET_install)" == ""
DISABLE_TARGET_install = 0
!endif
!if "$(DISABLE_TARGET_clean)" == ""
DISABLE_TARGET_clean = 0
!endif
!if "$(DISABLE_TARGET_test)" == ""
DISABLE_TARGET_test = 0
!endif
!if "$(DISABLE_TARGET_shell)" == ""
DISABLE_TARGET_shell = 0
!endif
!if !$(DISABLE_STANDARD_TARGETS)
!if !$(DISABLE_TARGET_setup)
setup: default-setup
!endif
!if !$(DISABLE_TARGET_install)
install: default-install
!endif
!if !$(DISABLE_TARGET_clean)
clean: default-clean
realclean: hose
hose: default-hose
distclean: realclean default-distclean
!endif
!if !$(DISABLE_TARGET_test)
test: default-test
!endif
!if !$(DISABLE_TARGET_shell)
shell: default-shell
!endif
!endif # DISABLE_STANDARD_TARGETS
+117 -44
View File
@@ -14,7 +14,9 @@ build infrastructure. It is not an [Autosetup][] reference.
- Symbolic Names of Feature Flags
- Do Not Update Global Shared State
- [Updating Autosetup](#updating)
- [Patching Autosetup for Project-local changes](#patching)
- ***[Patching Autosetup for Project-local changes](#patching)***
- [Branch-specific Customization](#branch-customization)
------------------------------------------------------------------------
@@ -42,12 +44,13 @@ following files:
(e.g. Fossil), and personal projects of SQLite's developers. It is
essentially an amalgamation of a decade's worth of autosetup-related
utility code.
- [auto.def][]: the primary driver for the `./configure` process.
When we talk about "the configure script," we're referring to
this file.
- [sqlite-config.tcl][]: utility code which is too project-specific
for `proj.tcl`. We split this out of `auto.def` so that it can be
used by both `auto.def` and...
- [auto.def][]: the primary driver for the `./configure` process.
When we talk about "the configure script," we're technically
referring to this file, though it actually contains very little
of the TCL code.
- [autoconf/auto.def][]: the main driver script for the "autoconf"
bundle's configure script. It is essentially a slightly trimmed-down
version of the main `auto.def` file. The `autoconf` dir was ported
@@ -61,11 +64,11 @@ Autosetup API Tips
This section briefly covers only APIs which are frequently useful in
day-to-day maintenance and might not be immediately recognized as such
obvious from a casual perusal of the relevant TCL files. The complete
docs of those with `proj-` prefix can be found in [proj.tcl][] and
those with an `sqlite-` prefix are in [sqlite-config.tcl][]. The
others are scattered around [the TCL files in
./autosetup](/dir/autosetup).
from a casual perusal of the relevant TCL files. The complete docs of
those with `proj-` prefix can be found in [proj.tcl][] and those with
an `sqlite-` prefix are in [sqlite-config.tcl][]. The others are part
of Autosetup's core packages and are scattered around [the TCL files
in ./autosetup](/dir/autosetup).
In (mostly) alphabetical order:
@@ -83,19 +86,14 @@ In (mostly) alphabetical order:
Works like `get-env` but will, if that function finds no match,
look for a file named `./.env-$VAR` and, if found, return its
trimmed contents. This can be used, e.g., to set a developer's
local preferences for the default `CFLAGS`.
- **`define-for-opt flag defineName ?checkingMsg? ?yesVal=1? ?noVal=0?`**\
`[define $defineName]` to either `$yesVal` or `$noVal`, depending on
whether `--$flag` is truthy or not. `$checkingMsg` is a
human-readable description of the check being made, e.g. "enable foo?"
If no `checkingMsg` is provided, the operation is silent.\
Potential TODO: change the final two args to `-yes` and `-no`
flags. They're rarely needed, though: search [auto.def][] for
`TSTRNNR_OPTS` for an example of where they are used.
local preferences for the default `CFLAGS`.\
Tip: adding `-O0` to `.env-CFLAGS` reduces rebuild times
considerably at the cost of performance in `make devtest` and the
like.
- **`proj-fatal msg`**\
Emits `$msg` to stderr and exits with non-zero.
Emits `$msg` to stderr and exits with non-zero. Its differences from
autosetup's `user-error` are purely cosmetic.
- **`proj-if-opt-truthy flag thenScript ?elseScript?`**\
Evals `thenScript` if the given `--flag` is truthy, else it
@@ -117,7 +115,10 @@ In (mostly) alphabetical order:
else 0. This distinction can be used to determine, e.g., whether
`--with-readline` was provided or whether we're searching for
readline by default. In the former case, failure to find it should
be treated as fatal, where in the latter case it's not.
be treated as fatal, where in the latter case it's not.\
Unlike most functions which deal with `--flags`, this one does not
validate that `$FLAG` is a registered flag so will not fail fatally
if `$FLAG` is not registered as an Autosetup option.
- **`proj-val-truthy value`**\
Returns 1 if `$value` is "truthy," See `proj-opt-truthy` for the definition
@@ -139,6 +140,15 @@ In (mostly) alphabetical order:
The shell-specific counterpart of `sqlite-add-feature-flag` which
only adds the given flag(s) to the CLI-shell-specific CFLAGS.
- **`sqlite-configure BUILD-NAME {script}`**\
This is where all configure `--flags` are defined for all known
build modes ("canonical" or "autoconf"). After processing all flags,
this function runs `$script`, which contains the build-mode-specific
configuration bits, and then runs any finalization bits which are
common to all build modes. The `auto.def` files are intended to contain
exactly two commands:
`use sqlite-config; sqlite-configure BUILD-NAME {script}`
- **`user-notice msg`**\
Queues `$msg` to be sent to stderr, but does not emit it until
either `show-notices` is called or the next time autosetup would
@@ -152,13 +162,18 @@ In (mostly) alphabetical order:
Ensuring TCL Compatibility
========================================================================
It is important that any TCL files used by the configure process
remain compatible with both [JimTCL][] and the canonical TCL. Though
JimTCL has outstanding compatibility with canonical TCL, it does have
a few corners with incompatibilities, e.g. regular expressions. If a
script runs in JimTCL without using any JimTCL-specific features, then
it's a certainty that it will run in canonical TCL as well. The
opposite, however, is not _always_ the case.
One of the significant benefits of using Autosetup is that (A) this
project uses many TCL scripts in the build process and (B) Autosetup
comes with a TCL interpreter named [JimTCL][].
It is important that any TCL files used by the configure process and
makefiles remain compatible with both [JimTCL][] and the canonical
TCL. Though JimTCL has outstanding compatibility with canonical TCL,
it does have a few corners with incompatibilities, e.g. regular
expressions. If a script runs in JimTCL without using any
JimTCL-specific features, then it's a certainty that it will run in
canonical TCL as well. The opposite, however, is not _always_ the
case.
When [`./configure`](/file/configure) is run, it goes through a
bootstrapping process to find a suitable TCL with which to run the
@@ -187,14 +202,17 @@ compatibility across TCL implementations:
before looking for a system-level `tclsh`. Be aware, though, that
`make distclean` will remove that file.
**Note that `jimsh0` is distinctly different from the `jimsh`** which
gets built for code-generation purposes. The latter requires
**Note that `./jimsh0` is distinctly different from the `./jimsh`**
which gets built for code-generation purposes. The latter requires
non-default build flags to enable features which are
platform-dependent, most notably to make its `[file normalize]` work.
This means, for example, that the configure script and its utility
APIs must not use `[file normalize]`, but autosetup provides a
TCL-only implementation of `[file-normalize]` (note the dash) for
portable use in the configure script.
portable use in the configure script. Contrariwise, code-generation
scripts invoked via `make` may use `[file normalize]`, as they'll use
`./jimsh` or `tclsh` instead of `./jimsh0`.
Known TCL Incompatibilities
------------------------------------------------------------------------
@@ -221,6 +239,7 @@ A summary of known incompatibilities in JimTCL
- `regsub` does not support the `\y` flag. A workaround is demonstrated
in [](/info/c2e5dd791cce3ec4).
<a name="conventions"></a>
Design Conventions
========================================================================
@@ -247,8 +266,9 @@ dots are not permitted.
The `X.y` convention is used in the makefiles primarily because the
person who did the initial port finds that considerably easier on the
eyes and fingers. In practice, the `X_Y` form of such exports is used
exactly once in [Makefile.in][], where it's translated into into `X.y`
form for consumption by [Makefile.in][] and [main.mk][]. For example:
exactly once in [Makefile.in][], where it's translated from `@X_Y@`
into into `X.y` form for consumption by [Makefile.in][] and
[main.mk][]. For example:
>
```
@@ -265,9 +285,9 @@ of taste, for which there is no accounting.)
Do Not Update Global Shared State
------------------------------------------------------------------------
In both the legacy Autotools-driven build and in common Autosetup
usage, feature tests performed by the configure script may amend
global flags such as `LIBS`, `LDFLAGS`, and `CFLAGS`[^as-cflags]. That's
In both the legacy Autotools-driven build and common Autosetup usage,
feature tests performed by the configure script may amend global flags
such as `LIBS`, `LDFLAGS`, and `CFLAGS`[^as-cflags]. That's
appropriate for a makefile which builds a single deliverable, but less
so for makefiles which produce multiple deliverables. Drawbacks of
that approach include:
@@ -275,8 +295,8 @@ that approach include:
- It's unlikely that every single deliverable will require the same
core set of those flags.
- It can be difficult to determine the origin of any given change to
that global state because those changes are hidden behind voodoo performed
outside the immediate visibility of the configure script's
that global state because those changes are hidden behind voodoo
performed outside the immediate visibility of the configure script's
maintainer.
- It can force the maintainers of the configure script to place tests
in a specific order so that the resulting flags get applied at
@@ -357,17 +377,70 @@ Patching Autosetup for Project-local Changes
Autosetup reserves the flag name **`--debug`** for its own purposes,
and its own special handling of `--enable-...` flags makes `--debug`
an alias for `--enable-debug`. As we have a long history of using
`--enable-debug` for this project's own purposes, we patch autosetup
to use the name `--autosetup-debug` in place of `--debug`. That
requires (as of this writing) four small edits in
[](/file/autosetup/autosetup), as demonstrated in [check-in
3296c8d3](/info/3296c8d3).
an alias for `--enable-debug`. As this project has a long history of
using `--enable-debug`, we patch autosetup to use the name
`--autosetup-debug` in place of `--debug`. That requires (as of this
writing) four small edits in [](/file/autosetup/autosetup), as
demonstrated in [check-in 3296c8d3](/info/3296c8d3).
If autosetup is upgraded and this patch is _not_ applied the invoking
`./configure` will fail loudly because of the declaration of the
`debug` flag in `auto.def` - duplicated flags are not permitted.
<a name="branch-customization"></a>
Branch-specific Customization
========================================================================
Certain vendor-specific branches require slight configure script
customization. Rather than editing `sqlite-config.tcl` for this,
which frequently leads to merge conflicts, the following approach
is recommended:
In the vendor-specific branch, create a file named
`autosetup/sqlite-custom.tcl`.
That file should contain the following content...
If flag customization is required, add:
>
```
proc sqlite-custom-flags {} {
# If any existing --flags require different default values
# then call:
options-defaults {
flag-name new-default-value
...
}
# ^^^ That will replace the default value but will not update
# the --help text, which may lead to some confusion:
# https://github.com/msteveb/autosetup/issues/77
return {
{*} {
new-flag-name => {Help text}
...
}
}; #see below
}
```
That function must return either an empty string or a list in the form
used internally by `sqlite-config.tcl:sqlite-configure`.
Next, define:
>
```
proc sqlite-custom-handle-flags {} {
... do any custom flag handling here ...
}
```
That function, if defined, will be called relatively late in the
configure process, before any filtered files are generated but after
all other significant processing.
[Autosetup]: https://msteveb.github.io/autosetup/
[auto.def]: /file/auto.def
+25 -12
View File
@@ -9132,7 +9132,7 @@ int Jim_StringEqObj(Jim_Obj *aObjPtr, Jim_Obj *bObjPtr)
const char *sA = Jim_GetString(aObjPtr, &Alen);
const char *sB = Jim_GetString(bObjPtr, &Blen);
return Alen == Blen && memcmp(sA, sB, Alen) == 0;
return Alen == Blen && *sA == *sB && memcmp(sA, sB, Alen) == 0;
}
}
@@ -10242,7 +10242,7 @@ static int JimCommandsHT_KeyCompare(void *privdata, const void *key1, const void
int len1, len2;
const char *str1 = Jim_GetStringNoQualifier((Jim_Obj *)key1, &len1);
const char *str2 = Jim_GetStringNoQualifier((Jim_Obj *)key2, &len2);
return len1 == len2 && memcmp(str1, str2, len1) == 0;
return len1 == len2 && *str1 == *str2 && memcmp(str1, str2, len1) == 0;
}
static void JimCommandsHT_ValDestructor(void *interp, void *val)
@@ -13864,6 +13864,13 @@ static int JimExprOpNumUnary(Jim_Interp *interp, struct JimExprNode *node)
case JIM_EXPROP_NOT:
wC = !bA;
break;
case JIM_EXPROP_UNARYPLUS:
case JIM_EXPROP_UNARYMINUS:
rc = JIM_ERR;
Jim_SetResultFormatted(interp,
"can't use non-numeric string as operand of \"%s\"",
node->type == JIM_EXPROP_UNARYPLUS ? "+" : "-");
break;
default:
abort();
}
@@ -19868,16 +19875,22 @@ wrongargs:
}
else if (errorCodeObj) {
int len = Jim_ListLength(interp, argv[idx + 1]);
int i;
ret = JIM_OK;
if (len > Jim_ListLength(interp, errorCodeObj)) {
for (i = 0; i < len; i++) {
Jim_Obj *matchObj = Jim_ListGetIndex(interp, argv[idx + 1], i);
Jim_Obj *objPtr = Jim_ListGetIndex(interp, errorCodeObj, i);
if (Jim_StringCompareObj(interp, matchObj, objPtr, 0) != 0) {
ret = -1;
break;
ret = -1;
}
else {
int i;
ret = JIM_OK;
for (i = 0; i < len; i++) {
Jim_Obj *matchObj = Jim_ListGetIndex(interp, argv[idx + 1], i);
Jim_Obj *objPtr = Jim_ListGetIndex(interp, errorCodeObj, i);
if (Jim_StringCompareObj(interp, matchObj, objPtr, 0) != 0) {
ret = -1;
break;
}
}
}
}
@@ -20253,7 +20266,7 @@ static int Jim_DictCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *arg
}
case OPT_SET:
return Jim_SetDictKeysVector(interp, argv[2], argv + 3, argc - 4, argv[argc - 1], JIM_ERRMSG);
return Jim_SetDictKeysVector(interp, argv[2], argv + 3, argc - 4, argv[argc - 1], JIM_ERRMSG | JIM_UNSHARED);
case OPT_EXISTS:{
int rc = Jim_DictKeysVector(interp, argv[2], argv + 3, argc - 3, &objPtr, JIM_NONE);
@@ -20265,7 +20278,7 @@ static int Jim_DictCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *arg
}
case OPT_UNSET:
if (Jim_SetDictKeysVector(interp, argv[2], argv + 3, argc - 3, NULL, JIM_NONE) != JIM_OK) {
if (Jim_SetDictKeysVector(interp, argv[2], argv + 3, argc - 3, NULL, JIM_UNSHARED) != JIM_OK) {
return JIM_ERR;
}
return JIM_OK;
+1346 -178
View File
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+4
View File
@@ -0,0 +1,4 @@
The *.tcl files in this directory are part of the SQLite's "autoconf"
bundle which are specific to the TEA(-ish) build. During the tarball
generation process, they are copied into <TOP>/autoconf/autosetup/teaish
(which itself is created as part of that process).
File diff suppressed because it is too large Load Diff
+214
View File
@@ -0,0 +1,214 @@
########################################################################
# 2025 April 7
#
# 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.
#
########################################################################
# ----- @module feature-tests.tcl -----
# @section TEA-ish collection of feature tests.
#
# Functions in this file with a prefix of teaish__ are
# private/internal APIs. Those with a prefix of teaish- are
# public APIs.
# @teaish-check-libz
#
# Checks for zlib.h and the function deflate in libz. If found,
# prepends -lz to the extension's ldflags and returns 1, else returns
# 0. It also defines LDFLAGS_LIBZ to the libs flag.
#
proc teaish-check-libz {} {
teaish-check-cached "Checking for libz" {
set rc 0
if {[msg-quiet cc-check-includes zlib.h] && [msg-quiet proj-check-function-in-lib deflate z]} {
teaish-ldflags-prepend [define LDFLAGS_LIBZ [get-define lib_deflate]]
undefine lib_deflate
incr rc
}
expr $rc
}
}
# @teaish-check-librt ?funclist?
#
# Checks whether -lrt is needed for any of the given functions. If
# so, appends -lrt via [teaish-ldflags-prepend] and returns 1, else
# returns 0. It also defines LDFLAGS_LIBRT to the libs flag or an
# empty string.
#
# Some systems (ex: SunOS) require -lrt in order to use nanosleep.
#
proc teaish-check-librt {{funclist {fdatasync nanosleep}}} {
teaish-check-cached -nostatus "Checking whether ($funclist) need librt" {
define LDFLAGS_LIBRT ""
foreach func $funclist {
if {[msg-quiet proj-check-function-in-lib $func rt]} {
set ldrt [get-define lib_${func}]
undefine lib_${func}
if {"" ne $ldrt} {
teaish-ldflags-prepend -r [define LDFLAGS_LIBRT $ldrt]
msg-result $ldrt
return 1
} else {
msg-result "no lib needed"
return 1
}
}
}
msg-result "not found"
return 0
}
}
# @teaish-check-stdint
#
# A thin proxy for [cc-with] which checks for <stdint.h> and the
# various fixed-size int types it declares. It defines HAVE_STDINT_T
# to 0 or 1 and (if it's 1) defines HAVE_XYZ_T for each XYZ int type
# to 0 or 1, depending on whether its available.
proc teaish-check-stdint {} {
teaish-check-cached "Checking for stdint.h" {
msg-quiet cc-with {-includes stdint.h} \
{cc-check-types int8_t int16_t int32_t int64_t intptr_t \
uint8_t uint16_t uint32_t uint64_t uintptr_t}
}
}
# @teaish-is-mingw
#
# Returns 1 if building for mingw, else 0.
proc teaish-is-mingw {} {
return [expr {
[string match *mingw* [get-define host]] &&
![file exists /dev/null]
}]
}
# @teaish-check-libdl
#
# Checks for whether dlopen() can be found and whether it requires
# -ldl for linking. If found, returns 1, defines LDFLAGS_DLOPEN to the
# linker flags (if any), and passes those flags to
# teaish-ldflags-prepend. It unconditionally defines HAVE_DLOPEN to 0
# or 1 (the its return result value).
proc teaish-check-dlopen {} {
teaish-check-cached -nostatus "Checking for dlopen()" {
set rc 0
set lfl ""
if {[cc-with {-includes dlfcn.h} {
cctest -link 1 -declare "extern char* dlerror(void);" -code "dlerror();"}]} {
msg-result "-ldl not needed"
incr rc
} elseif {[cc-check-includes dlfcn.h]} {
incr rc
if {[cc-check-function-in-lib dlopen dl]} {
set lfl [get-define lib_dlopen]
undefine lib_dlopen
msg-result " dlopen() needs $lfl"
} else {
msg-result " - dlopen() not found in libdl. Assuming dlopen() is built-in."
}
} else {
msg-result "not found"
}
teaish-ldflags-prepend [define LDFLAGS_DLOPEN $lfl]
define HAVE_DLOPEN $rc
}
}
#
# @teaish-check-libmath
#
# Handles the --enable-math flag. Returns 1 if found, else 0.
# If found, it prepends -lm (if needed) to the linker flags.
proc teaish-check-libmath {} {
teaish-check-cached "Checking for libc math library" {
set lfl ""
set rc 0
if {[msg-quiet proj-check-function-in-lib ceil m]} {
incr rc
set lfl [get-define lib_ceil]
undefine lib_ceil
teaish-ldflags-prepend $lfl
msg-checking "$lfl "
}
define LDFLAGS_LIBMATH $lfl
expr $rc
}
}
# @teaish-import-features ?-flags? feature-names...
#
# For each $name in feature-names... it invokes:
#
# use teaish/feature/$name
#
# to load TEAISH_AUTOSETUP_DIR/feature/$name.tcl
#
# By default, if a proc named teaish-check-${name}-options is defined
# after sourcing a file, it is called and its result is passed to
# proj-append-options. This can be suppressed with the -no-options
# flag.
#
# Flags:
#
# -no-options: disables the automatic running of
# teaish-check-NAME-options,
#
# -run: if the function teaish-check-NAME exists after importing
# then it is called. This flag must not be used when calling this
# function from teaish-options. This trumps both -pre and -post.
#
# -pre: if the function teaish-check-NAME exists after importing
# then it is passed to [teaish-checks-queue -pre].
#
# -post: works like -pre but instead uses[teaish-checks-queue -post].
proc teaish-import-features {args} {
set pk ""
set doOpt 1
proj-parse-simple-flags args flags {
-no-options 0 {set doOpt 0}
-run 0 {expr 1}
-pre 0 {set pk -pre}
-post 0 {set pk -post}
}
#
# TODO: never import the same module more than once. The "use"
# command is smart enough to not do that but we would need to
# remember whether or not any teaish-check-${arg}* procs have been
# called before, and skip them.
#
if {$flags(-run) && "" ne $pk} {
proj-error "Cannot use both -run and $pk" \
" (called from [proj-scope 1])"
}
foreach arg $args {
uplevel "use teaish/feature/$arg"
if {$doOpt} {
set n "teaish-check-${arg}-options"
if {[llength [info proc $n]] > 0} {
if {"" ne [set x [$n]]} {
options-add $x
}
}
}
if {$flags(-run)} {
set n "teaish-check-${arg}"
if {[llength [info proc $n]] > 0} {
uplevel 1 $n
}
} elseif {"" ne $pk} {
set n "teaish-check-${arg}"
if {[llength [info proc $n]] > 0} {
teaish-checks-queue {*}$pk $n
}
}
}
}
+293
View File
@@ -0,0 +1,293 @@
########################################################################
# 2025 April 5
#
# 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.
#
########################################################################
#
# Helper routines for running tests on teaish extensions
#
########################################################################
# ----- @module teaish/tester.tcl -----
#
# @section TEA-ish Testing APIs.
#
# Though these are part of the autosup dir hierarchy, they are not
# intended to be run from autosetup code. Rather, they're for use
# with/via teaish.tester.tcl and target canonical Tcl only, not JimTcl
# (which the autosetup pieces do target).
#
# @test-current-scope ?lvl?
#
# Returns the name of the _calling_ proc from ($lvl + 1) levels up the
# call stack (where the caller's level will be 1 up from _this_
# call). If $lvl would resolve to global scope "global scope" is
# returned and if it would be negative then a string indicating such
# is returned (as opposed to throwing an error).
#
proc test-current-scope {{lvl 0}} {
#uplevel [expr {$lvl + 1}] {lindex [info level 0] 0}
set ilvl [info level]
set offset [expr {$ilvl - $lvl - 1}]
if { $offset < 0} {
return "invalid scope ($offset)"
} elseif { $offset == 0} {
return "global scope"
} else {
return [lindex [info level $offset] 0]
}
}
# @test-msg
#
# Emits all arugments to stdout.
#
proc test-msg {args} {
puts "$args"
}
# @test-warn
#
# Emits all arugments to stderr.
#
proc test-warn {args} {
puts stderr "WARNING: $args"
}
#
# @test-error msg
#
# Triggers a test-failed error with a string describing the calling
# scope and the provided message.
#
proc test-fail {args} {
#puts stderr "ERROR: \[[test-current-scope 1]]: $msg"
#exit 1
error "FAIL: \[[test-current-scope 1]]: $args"
}
array set ::test__Counters {}
array set ::test__Config {
verbose-assert 0 verbose-affirm 0
}
# Internal impl for affirm and assert.
#
# $args = ?-v? script {msg-on-fail ""}
proc test__affert {failMode args} {
if {$failMode} {
set what assert
} else {
set what affirm
}
set verbose $::test__Config(verbose-$what)
if {"-v" eq [lindex $args 0]} {
lassign $args - script msg
if {1 == [llength $args]} {
# If -v is the only arg, toggle default verbose mode
set ::test__Config(verbose-$what) [expr {!$::test__Config(verbose-$what)}]
return
}
incr verbose
} else {
lassign $args script msg
}
incr ::test__Counters($what)
if {![uplevel 1 expr [list $script]]} {
if {"" eq $msg} {
set msg $script
}
set txt [join [list $what # $::test__Counters($what) "failed:" $msg]]
if {$failMode} {
puts stderr $txt
exit 1
} else {
error $txt
}
} elseif {$verbose} {
puts stderr [join [list $what # $::test__Counters($what) "passed:" $script]]
}
}
#
# @affirm ?-v? script ?msg?
#
# Works like a conventional assert method does, but reports failures
# using [error] instead of [exit]. If -v is used, it reports passing
# assertions to stderr. $script is evaluated in the caller's scope as
# an argument to [expr].
#
proc affirm {args} {
tailcall test__affert 0 {*}$args
}
#
# @assert ?-v? script ?msg?
#
# Works like [affirm] but exits on error.
#
proc assert {args} {
tailcall test__affert 1 {*}$args
}
#
# @assert-matches ?-e? pattern ?-e? rhs ?msg?
#
# Equivalent to assert {[string match $pattern $rhs]} except that
# if either of those are prefixed with an -e flag, they are eval'd
# and their results are used.
#
proc assert-matches {args} {
set evalLhs 0
set evalRhs 0
if {"-e" eq [lindex $args 0]} {
incr evalLhs
set args [lassign $args -]
}
set args [lassign $args pattern]
if {"-e" eq [lindex $args 0]} {
incr evalRhs
set args [lassign $args -]
}
set args [lassign $args rhs msg]
if {$evalLhs} {
set pattern [uplevel 1 $pattern]
}
if {$evalRhs} {
set rhs [uplevel 1 $rhs]
}
#puts "***pattern=$pattern\n***rhs=$rhs"
tailcall test__affert 1 \
[join [list \[ string match [list $pattern] [list $rhs] \]]] $msg
# why does this not work? [list \[ string match [list $pattern] [list $rhs] \]] $msg
# "\[string match [list $pattern] [list $rhs]\]"
}
#
# @test-assert testId script ?msg?
#
# Works like [assert] but emits $testId to stdout first.
#
proc test-assert {testId script {msg ""}} {
puts "test $testId"
tailcall test__affert 1 $script $msg
}
#
# @test-expect testId script result
#
# Runs $script in the calling scope and compares its result to
# $result, minus any leading or trailing whitespace. If they differ,
# it triggers an [assert].
#
proc test-expect {testId script result} {
puts "test $testId"
set x [string trim [uplevel 1 $script]]
set result [string trim $result]
tailcall test__affert 0 [list "{$x}" eq "{$result}"] \
"\nEXPECTED: <<$result>>\nGOT: <<$x>>"
}
#
# @test-catch cmd ?...args?
#
# Runs [cmd ...args], repressing any exception except to possibly log
# the failure. Returns 1 if it caught anything, 0 if it didn't.
#
proc test-catch {cmd args} {
if {[catch {
uplevel 1 $cmd {*}$args
} rc xopts]} {
puts "[test-current-scope] ignoring failure of: $cmd [lindex $args 0]: $rc"
return 1
}
return 0
}
#
# @test-catch-matching pattern (script|cmd args...)
#
# Works like test-catch, but it expects its argument(s) to to throw an
# error matching the given string (checked with [string match]). If
# they do not throw, or the error does not match $pattern, this
# function throws, else it returns 1.
#
# If there is no second argument, the $cmd is assumed to be a script,
# and will be eval'd in the caller's scope.
#
# TODO: add -glob and -regex flags to control matching flavor.
#
proc test-catch-matching {pattern cmd args} {
if {[catch {
#puts "**** catch-matching cmd=$cmd args=$args"
if {0 == [llength $args]} {
uplevel 1 $cmd {*}$args
} else {
$cmd {*}$args
}
} rc xopts]} {
if {[string match $pattern $rc]} {
return 1
} else {
error "[test-current-scope] exception does not match {$pattern}: {$rc}"
}
}
error "[test-current-scope] expecting to see an error matching {$pattern}"
}
if {![array exists ::teaish__BuildFlags]} {
array set ::teaish__BuildFlags {}
}
#
# @teaish-build-flag3 flag tgtVar ?dflt?
#
# If the current build has the configure-time flag named $flag set
# then tgtVar is assigned its value and 1 is returned, else tgtVal is
# assigned $dflt and 0 is returned.
#
# Caveat #1: only valid when called in the context of teaish's default
# "make test" recipe, e.g. from teaish.test.tcl. It is not valid from
# a teaish.tcl configure script because (A) the state it relies on
# doesn't fully exist at that point and (B) that level of the API has
# more direct access to the build state. This function requires that
# an external script have populated its internal state, which is
# normally handled via teaish.tester.tcl.in.
#
# Caveat #2: defines in the style of HAVE_FEATURENAME with a value of
# 0 are, by long-standing configure script conventions, treated as
# _undefined_ here.
#
proc teaish-build-flag3 {flag tgtVar {dflt ""}} {
upvar $tgtVar tgt
if {[info exists ::teaish__BuildFlags($flag)]} {
set tgt $::teaish__BuildFlags($flag)
return 1;
} elseif {0==[array size ::teaish__BuildFlags]} {
test-warn \
"\[[test-current-scope]] was called from " \
"[test-current-scope 1] without the build flags imported."
}
set tgt $dflt
return 0
}
#
# @teaish-build-flag flag ?dflt?
#
# Convenience form of teaish-build-flag3 which returns the
# configure-time-defined value of $flag or "" if it's not defined (or
# if it's an empty string).
#
proc teaish-build-flag {flag {dflt ""}} {
set tgt ""
teaish-build-flag3 $flag tgt $dflt
return $tgt
}
+1 -10
View File
@@ -725,10 +725,6 @@ as part of the output file.</p>
<p>There can be multiple <tt>%code</tt> directives. The arguments of
all <tt>%code</tt> directives are concatenated.</p>
<p>If the argument to <tt>%code</tt> is a filename within <tt>&lt;...&gt;</tt>
then the content of the named file is inserted instead of the text of the
argument itself.
<a id='default_destructor'></a>
<h4>4.4.2 The <tt>%default_destructor</tt> directive</h4>
@@ -850,7 +846,7 @@ or more tokens. The alternative meaning is tried if the original token
would have generated a syntax error.</p>
<p>The <tt>%fallback</tt> directive was added to support robust parsing of SQL
syntax in <a href='https://www.sqlite.org/'>SQLite</a>.
syntax in <a href='https://sqlite.org/'>SQLite</a>.
The SQL language contains a large assortment of keywords, each of which
appears as a different token to the language parser. SQL contains so
many keywords that it can be difficult for programmers to keep up with
@@ -924,11 +920,6 @@ For example:</p>
<p>This might be needed, for example, if some of the C actions in the
grammar call functions that are prototyped in unistd.h.</p>
<p>If the argument to <tt>%include</tt> is a filename within
<tt>&lt;...&gt;</tt> then the content of that file is inserted instead
of the text of the argument itself.
<p>Use the <tt><a href="#pcode">%code</a></tt> directive to add code to
the end of the generated parser.</p>
-142
View File
@@ -1,142 +0,0 @@
Shared-Schema Mode Notes
========================
The [reuse-schema](/timeline?r=reuse-schema) branch contains changes
to allow SQLite connections to share schemas
between database connections within the same process in order to save memory.
Schemas may be shared between multiple databases attached to the same or
distinct connection handles.
Compile with -DSQLITE\_ENABLE\_SHARED\_SCHEMA in order to enable the
shared-schema enhancement. Enabling the shared-schema enhancement causes
approximately a 0.1% increase in CPU cycles consumed and about a 3000-byte
increase in the size of the library, even if shared-schema is never used.
Assuming the compile-time requirements are satisfied, the shared-schema
feature is engaged by opening the database connection using the
sqlite3&#95;open&#95;v2() API with the SQLITE&#95;OPEN&#95;SHARED&#95;SCHEMA
flag specified. The main database and any attached databases will then share
an in-memory Schema object with any other database opened within the process
for which:
* the contents of the sqlite&#95;master table, including all object names,
SQL statements and root pages are identical, and
* have the same values for the schema-cookie.
Temp databases (those populated with "CREATE TEMP TABLE" and similar
statements) never share schemas.
Connections opened with the SQLITE&#95;OPEN&#95;SHARED&#95;SCHEMA flag
specified may not modify any database schema except that belonging to the
temp database in anyway. This includes creating or dropping database
objects, vacuuming the database, or running ANALYZE when the
sqlite&#95;stat\[14\] tables do not exist.
For SQLITE&#95;OPEN&#95;SHARED&#95;SCHEMA connections, the
SQLITE&#95;DBSTATUS&#95;SCHEMA&#95;USED sqlite3&#95;db&#95;status() verb
distributes the memory used for a shared schema object evenly between all
database connections that share it.
## The ".shared-schema" Command
The shell tool on this branch contains a special dot-command to help with
managing databases. The ".shared-schema" dot-command can be used to test
whether or not two databases are similar enough to share in-memory schemas,
and to fix minor problems that prevent them from doing so. To test if
two or more database are compatible, one database is opened directly using
the shell tool and the following command issued:
.shared-schema check <database-1> [<database-2>]...
where &lt;database-1&gt; etc. are replaced with the names of database files
on disk. For each database specified on the command line, a single line of
output is produced. If the database can share an in-memory schema with the
main database opened by the shell tool, the output is of the form:
<database> is compatible
Otherwise, if the database cannot share a schema with the main db, the output
is of the form:
<database> is NOT compatible (<reason>)
where &lt;reason&gt; indicates the cause of the incompatibility. &lt;reason&gt;
is always one of the following.
<ul>
<li> <b>objects</b> - the databases contain a different set schema objects
(tables, indexes, views and triggers).
<li> <b>SQL</b> - the databases contain the same set of objects, but the SQL
statements used to create them were not the same.
<li> <b>root pages</b> - the databases contain the same set of objects created
by the same SQL statements, but the root pages are not the same.
<li> <b>order of sqlite&#95;master rows</b> - the databases contain the same
set of objects created by the same SQL statements with the same root pages,
but the order of the rows in the sqlite&#95;master tables are different.
<li> <b>schema cookie</b> - the database schemas are compatible, but the
schema cookie values ("PRAGMA schema&#95;version") are different.
</ul>
The final three problems in the list above can be fixed using the
.shared-schema command. To modify such a database so that it can share a
schema with the main database, the following shell command is used:
.shared-schema fix <database-1> [<database-2>]...
If a database can be modified so that it may share a schema with the main
database opened by the shell tool, output is as follows:
Fixing <database>... <database> is compatible
If a database does not require modification, or cannot be modified such that
it can share a schema with the main database, the output of "fix" is identical
to that of the "check" command.
## Implementation Notes
A single Schema object is never used by more than one database simultaneously,
regardless of whether or not those databases are attached to the same or
different database handles. Instead, a pool of schema objects is maintained
for each unique sqlite&#95;master-contents/schema-cookie combination
opened within the process. Each time database schemas are required by a
connection, for example as part of an sqlite3&#95;prepare\*(),
sqlite3&#95;blob&#95;open() or sqlite3&#95;blob&#95;open() call, it obtains
the minimum number of schemas required from the various schema-pools, returning
them at the end of the call. This means that a single schema-pool only ever
contains more than one copy of the schema if:
* Two threads require schemas from the same pool at the same time, or
* A single sqlite3&#95;prepare\*() call requires schemas for two or more
attached databases that use the same schema-pool.
The size of a schema-pool never shrinks. Each schema pool always maintains
a number of schema objects equal to the highwater mark of schema objects
simultaneously required by clients.
This approach is preferred to allowing multiple databases to use the same
Schema object simultaneously for three reasons:
* The Schema object is not completely read-only. For example, the
Index.zIdxAff string is allocated lazily.
* Throughout the statement compiler, SQLite uses variables like
Table.pSchema and Index.pSchema with the sqlite3SchemaToIndex() routine
in order to determine which attached database a Table or Index object
resides in. This mechanism does not work if the same Schema may be
used by two or more attached databases.
* It may be easier to modify this approach in order to allow
SQLITE&#95;OPEN&#95;SHARED&#95;SCHEMA connections to modify database
schemas, should that be required.
SQLITE&#95;OPEN&#95;SHARED&#95;SCHEMA connections do not store their
virtual-table handles in the Table.pVTable list of each table. This would not
work, as (a) there is no guarantee that a connection will be assigned the same
Schema object each time it requests one from a schema-pool and (b) a single
Schema (and therefore Table) object may correspond to tables in two or more
databases attached to a single connection. Instead, all virtual-table handles
associated with a single database are stored in a linked-list headed at
Db.pVTable.
+107 -51
View File
@@ -35,84 +35,69 @@ perspective on how to compile SQLite on unix-like systems.
### 2.1 Setup
<ol type="1">
<li value="1">
[Fossil](https://fossil-scm.org/) installed.
<li value="1">
[Fossil][] installed.
<li> Check out source code and set environment variables:
<ol type="a">
<li> **TCLSOURCE** &rarr;
The top-level directory of a Fossil check-out of the TCL source tree.
The top-level directory of a [Fossil][] check-out of the
[TCL source tree][tcl-fossil].
<li> **SQLITESOURCE** &rarr;
A Fossil check-out of the SQLite source tree.
<li> **TCLBUILD** &rarr;
<li> **TCLHOME** &rarr;
A directory that does not exist at the start of the test and which
will be deleted at the end of the test, and that will contain the
test builds of the TCL libraries and the SQLite TCL Extensions.
It is the top-most installation directory, i.e. the one provided
to Tcl's `./configure --prefix=/path/to/tcl`.
<li> **TCLVERSION** &rarr;
The `X.Y`-form version of Tcl being used: 8.6, 9.0, 9.1...
</ol>
</ol>
### 2.2 Testing TCL 8.6 on unix
### 2.2 Testing TCL 8.x and 9.x on unix
From a checked-out copy of [the core Tcl tree][tcl-fossil]
<ol type="1">
<li value="3"> `mkdir -p $TCLBUILD/tcl86`
<li> `cd $TCLSOURCE/unix`
<li> `fossil up core-8-6-16` <br>
&uarr; Or some other version of Tcl8.6.
<li value="3">`TCLVERSION=8.6` <br>
&uarr; A version of your choice. This process has been tested with
values of 8.6, 9.0, and 9.1 (as of 2025-04-16). The out-of-life
version 8.5 fails some of `make devtest` for undetermined reasons.
<li>`TCLHOME=$HOME/tcl/$TCLVERSION`
<li>`TCLSOURCE=/path/to/tcl/checkout`
<li>`SQLITESOURCE=/path/to/sqlite/checkout`
<li>`rm -fr $TCLHOME` <br>
&uarr; Ensure that no stale Tcl installation is laying around.
<li> `cd $TCLSOURCE`
<li> `fossil up core-8-6-branch` <br>
&uarr; The branch corresponding to `$TCLVERSION`, e.g.
`core-9-0-branch` or `trunk`.
<li> `fossil clean -x`
<li> `./configure --prefix=$TCLBUILD/tcl86 --disable-shared` <br>
&uarr; The --disable-shared is to avoid the need to set LD_LIBRARY_PATH
<li> `cd unix`
<li> `./configure --prefix=$TCLHOME --disable-shared` <br>
&uarr; The `--disable-shared` is to avoid the need to set `LD_LIBRARY_PATH`
when using this Tcl build.
<li> `make install`
<li> `cd $SQLITESOURCE`
<li> `fossil clean -x`
<li> `./configure --with-tclsh=$TCLBUILD/tcl86/bin/tclsh8.6 --all`
<li> `./configure --with-tcl=$TCLHOME --all`
<li> `make tclextension-install` <br>
&uarr; Verify extension installed at $TCLBUILD/tcl86/lib/tcl8.6/sqlite3.*
&uarr; Verify extension installed at
`$TCLHOME/lib/tcl${TCLVERSION}/sqlite<SQLITE_VERSION>`.
<li> `make tclextension-list` <br>
&uarr; Verify TCL extension correctly installed.
<li> `make tclextension-verify` <br>
&uarr; Verify that the correct version is installed.
<li> `$TCLBUILD/tcl86/bin/tclsh8.6 test/testrunner.tcl release --explain` <br>
<li> `$TCLHOME/bin/tclsh[89].[0-9] test/testrunner.tcl release --explain` <br>
&uarr; Verify thousands of lines of output with no errors. Or
consider running "devtest" without --explain instead of "release".
</ol>
### 2.3 Testing TCL 9.0 on unix
<ol>
<li value="16"> `mkdir -p $TCLBUILD/tcl90`
<li> `fossil up core-9-0-0` <br>
&uarr; Or some other version of Tcl9
<li> `fossil clean -x`
<li> `./configure --prefix=$TCLBUILD/tcl90 --disable-shared` <br>
&uarr; The --disable-shared is to avoid the need to set LD_LIBRARY_PATH
when using this Tcl build.
<li> `make install`
<li> `cp -r ../library $TCLBUILD/tcl90/lib/tcl9.0` <br>
&uarr; The Tcl library is not installed by "make install" for Tcl9.0 unless
you also include the --disable-zipfs to ./configure. But if you do that
then the generated tclsh9.0 is no longer stand-alone. On the other hand,
if you don't install the Tcl library, other programs like testfixture
won't be able to find the Tcl library and hence won't work. This
extra installation step resolves the dilemma.
This step is not required when building Tcl8.6, which lacks support for
zipfs and hence always installs its Tcl library.
<li> `cd $SQLITESOURCE`
<li> `fossil clean -x`
<li> `./configure --with-tclsh=$TCLBUILD/tcl90/bin/tclsh9.0 --all`
<li> `make tclextension-install` <br>
&uarr; Verify extension installed at $TCLBUILD/tcl90/lib/sqlite3.*
<li> `make tclextension-list` <br>
&uarr; Verify TCL extension correctly installed.
<li> `make tclextension-verify`
<li> `$TCLBUILD/tcl90/bin/tclsh9.0 test/testrunner.tcl release --explain` <br>
&uarr; Verify thousands of lines of output with no errors. Or
consider running "devtest" without --explain instead of "release".
</ol>
### 2.4 Cleanup
### 2.3 Cleanup
<ol type="1">
<li value="29"> `rm -rf $TCLBUILD`
<li value="29"> `rm -rf $TCLHOME`
</ol>
<a id="windows"></a>
@@ -123,9 +108,11 @@ perspective on how to compile SQLite on Windows.
### 3.1 Setup for Windows
(These docs are not as up-to-date as the Unix docs, above.)
<ol type="1">
<li value="1">
[Fossil](https://fossil-scm.org/) installed.
<li value="1">
[Fossil][] installed.
<li>
Unix-like command-line tools installed. Example:
[unxutils](https://unxutils.sourceforge.net/)
@@ -206,3 +193,72 @@ perspective on how to compile SQLite on Windows.
<ol type="1">
<li value="35"> `rm -rf %TCLBUILD%`
</ol>
## 4.0 Testing the TEA(ish) Build (unix only)
This part requires following the setup instructions for Unix systems,
at the top of this document.
The former TEA, now TEA(ish), build of this extension uses the same
code as the builds described above but is provided in a form more
convenient for downstream Tcl users.
It lives in `autoconf/tea` and, as part of the `autoconf` bundle,
_cannot be tested directly from the canonical tree_. Instead it has to
be packaged.
### 4.1 Teaish Setup
Follow the same Tcl- and environment-related related setup described
in the first section of this document, up to and including the
installation of Tcl (unless, of course, it was already installed using
those same instructions).
### 4.2 Teaish Testing
<ol>
<li>`cd $SQLITESOURCE`
<li>Run either `make snapshot-tarball` or `make amalgamation-tarball`
&uarr;
Those steps will leave behind a temp dir called `mkpkg_tmp_dir`,
under which the extension is most readily reached. It can optionally
be extracted from the generated tarball, but that tarball was
generated from this dir, and reusing this dir is a time saver
during development.
<li> `cd mkpkg_tmp/tea`
<li> `./configure --with-tcl=$TCLHOME`
<li> `make test install` <br>
&uarr; Should run to completion without any errors.
<li> `make uninstall` <br>
&uarr; Will uninstall the extension. This _can_ be run
in the same invocation as the `install` target, but only
if the `-j#` make flag is _not_ used. If it is, the
install/uninstall steps will race and make a mess of things.
Parallel builds do not help in this build, anyway, as there's
only a single C file to compile.
</ol>
When actively developing and testing the teaish build, which requires
going through the tarball generation, there's a caveat about the
`mkpkg_tmp_dir` dir: it will be deleted every time a tarball is
built, the shell console which is parked in that
directory for testing needs to add `cd $PWD &&` to the start of the
build commands, like:
>
```
[user@host:.../mkpkg_tmp_dir/tea]$ \
cd $PWD && ./configure CFLAGS=-O0 --with-tcl=$TCLHOME \
&& make test install uninstall
```
### 4.3 Teaish Cleanup
<ol type="1">
<li> `rm -rf $TCLHOME`
<li> `cd $SQLITESOURCE; rm -fr mkpkg_tmp_dir; fossil clean -x`
</ol>
[Fossil]: https://fossil-scm.org/home
[tcl-fossil]: https://core.tcl-lang.org/tcl
+68 -20
View File
@@ -15,6 +15,7 @@
<li> 3.1. <a href=#commands_to_run_tests>Commands to Run SQLite Tests</a>
<li> 3.2. <a href=#zipvfs_tests>Running ZipVFS Tests</a>
<li> 3.3. <a href=#source_code_test_failures>Investigating Source Code Test Failures</a>
<li> 3.4. <a href=#fuzzdb>External Fuzzcheck Databases</a>
</ul>
<li> 4. <a href=#testrunner_options>Extra testrunner.tcl Options</a>
<li> 5. <a href=#cpu_cores>Controlling CPU Core Utilization</a>
@@ -23,47 +24,62 @@
<a name=overview></a>
# 1. Overview
testrunner.tcl is a Tcl script used to run multiple SQLite tests using
multiple jobs. It supports the following types of tests:
The testrunner.tcl program is a Tcl script used to run multiple SQLite
tests in parallel, thus reducing testing time on multi-core machines.
It supports the following types of tests:
* Tcl test scripts.
* Fuzzcheck tests, including using an external fuzzcheck database.
* Tests run with `make` commands. Examples:
- `make mdevtest`
- `make devtest`
- `make releasetest`
- `make sdevtest`
- `make testrunner`
testrunner.tcl pipes the output of all tests and builds run into log file
**testrunner.log**, created in the current working directory. Search this
file to find details of errors. Suggested search commands:
The testrunner.tcl program stores output of all tests and builds run in
log file **testrunner.log**, created in the current working directory.
Search this file to find details of errors. Suggested search commands:
* `grep "^!" testrunner.log`
* `grep failed testrunner.log`
testrunner.tcl also populates SQLite database **testrunner.db**. This database
contains details of all tests run, running and to be run. A useful query
might be:
The testrunner.tcl program also populates SQLite database **testrunner.db**.
This database contains details of all tests run, running and to be run.
A useful query might be:
```
SELECT * FROM script WHERE state='failed'
```
You can get a summary of errors in a prior run by invoking commands like
these:
```
tclsh $(TESTDIR)/testrunner.tcl errors
tclsh $(TESTDIR)/testrunner.tcl errors -v
```
Running the command:
```
./testfixture $(TESTDIR)/testrunner.tcl status
tclsh $(TESTDIR)/testrunner.tcl status
```
in the directory containing the testrunner.db database runs various queries
to produce a succinct report on the state of a running testrunner.tcl script.
Running:
A good way to keep and eye on test progress is to run either of the two
following commands:
```
watch ./testfixture $(TESTDIR)/testrunner.tcl status
watch tclsh $(TESTDIR)/testrunner.tcl status
tclsh $(TESTDIR)/testrunner.tcl status -d 2
```
in another terminal is a good way to keep an eye on a long running test.
Both of the commands above accomplish about the same thing, but the second
one has the advantage of not requiring "watch" to be installed on your
system.
Sometimes testrunner.tcl uses the `testfixture` binary that it is run with
to run tests (see "Binary Tests" below). Sometimes it builds testfixture and
@@ -239,9 +255,7 @@ of the specific tests run.
As with <a href=#source code tests>source code tests</a>, one or more patterns
may be appended to any of the above commands (mdevtest, sdevtest or release).
In that case only Tcl tests (no fuzz or other tests) that match the specified
pattern are run. For example, to run the just the Tcl rtree tests in all
builds and configurations supported by "release":
Pattern matching is used for both Tcl tests and fuzz tests.
```
tclsh $TESTDIR/testrunner.tcl release rtree%
@@ -292,6 +306,34 @@ target to build. This may be used either to run a `make` command test directly,
or else to build a testfixture (or testfixture.exe) binary with which to
run a Tcl test script, as <a href=#binary_test_failures>described above</a>.
<a name=fuzzdb></a>
## 3.4 External Fuzzcheck Databases
Testrunner.tcl will also run fuzzcheck against an external (out of tree)
database, for example fuzzcheck databases generated by dbsqlfuzz. To do
this, simply add the "`--fuzzdb` *FILENAME*" command-line option or set
the FUZZDB environment variable to the name of the external
database. For large external databases, testrunner.tcl will automatically use
the "`--slice`" command-line option of fuzzcheck to divide the work up into
multiple jobs, to increase parallelism.
Thus, for example, to run a full releasetest including an external
dbsqlfuzz database, run a command like one of these:
```
tclsh test/testrunner.tcl releasetest --fuzzdb ../fuzz/20250415.db
FUZZDB=../fuzz/20250415.db make releasetest
nmake /f Makefile.msc FUZZDB=../fuzz/20250415.db releasetest
```
The patternlist option to testrunner.tcl will match against fuzzcheck
databases. So if you want to run *only* tests involving the external
database, you can use a command something like this:
```
tclsh test/testrunner.tcl releasetest 20250415 --fuzzdb ../fuzz/20250415.db
```
<a name=testrunner_options></a>
# 4. Extra testrunner.tcl Options
@@ -315,16 +357,22 @@ would normally execute into the testrunner.log file. Example:
tclsh $TESTDIR/testrunner.tcl --dryrun mdevtest"
```
The **--explain** option is similar to --dryrun in that it prevents testrunner.tcl
from building any binaries or running any tests. The difference is that --explain
prints on standard output a human-readable summary of all the builds and tests that
would have been run.
The **--explain** option is similar to --dryrun in that it prevents
testrunner.tcl from building any binaries or running any tests. The
difference is that --explain prints on standard output a human-readable
summary of all the builds and tests that would have been run.
```
# Show what builds and tests would have been run
tclsh $TESTDIR/testrunner.tcl --explain mdevtest
```
The **--status** option uses VT100 escape sequences to display the test
status full-screen. This is similar to running
"`watch test/testrunner status`" in a separate window, just more convenient.
Unfortunately, this option does not work correctly on Windows, due to the
sketchy implementation of VT100 escapes on the Windows console.
<a name=cpu_cores></a>
# 5. Controlling CPU Core Utilization
+1 -1
View File
@@ -1,6 +1,6 @@
## Loadable Extensions
Various [loadable extensions](https://www.sqlite.org/loadext.html) for
Various [loadable extensions](https://sqlite.org/loadext.html) for
SQLite are found in subfolders.
Most subfolders are dedicated to a single loadable extension (for
+1 -1
View File
@@ -28,7 +28,7 @@
static int dbHandleFromObj(Tcl_Interp *interp, Tcl_Obj *pObj, sqlite3 **pDb){
Tcl_CmdInfo info;
if( 0==Tcl_GetCommandInfo(interp, Tcl_GetString(pObj), &info) ){
Tcl_AppendResult(interp, "no such handle: ", Tcl_GetString(pObj), 0);
Tcl_AppendResult(interp, "no such handle: ", Tcl_GetString(pObj), NULL);
return TCL_ERROR;
}
+3 -3
View File
@@ -62,20 +62,20 @@
matches rows that contain both the "engineering" and "consultancy" tokens
in the same column with not more than 10 other words between them. It does
not matter which of the two terms occurs first in the document, only that
they be seperated by only 10 tokens or less. The user may also specify
they be separated by only 10 tokens or less. The user may also specify
a different required proximity by adding "/N" immediately after the NEAR
operator, where N is an integer. For example:
<col> MATCH 'engineering NEAR/5 consultancy'
searches for a row containing an instance of each specified token seperated
searches for a row containing an instance of each specified token separated
by not more than 5 other tokens. More than one NEAR operator can be used
in as sequence. For example this query:
<col> MATCH 'reliable NEAR/2 engineering NEAR/5 consultancy'
searches for a row that contains an instance of the token "reliable"
seperated by not more than two tokens from an instance of "engineering",
separated by not more than two tokens from an instance of "engineering",
which is in turn separated by not more than 5 other tokens from an
instance of the term "consultancy". Phrases enclosed in quotes may
also be used as arguments to the NEAR operator.
-6
View File
@@ -295,12 +295,6 @@
# define SQLITE_CORE 1
#endif
#include <assert.h>
#include <stdlib.h>
#include <stddef.h>
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#include "fts3.h"
#ifndef SQLITE_CORE
+25 -1
View File
@@ -14,6 +14,13 @@
#ifndef _FTSINT_H
#define _FTSINT_H
#include <assert.h>
#include <stdlib.h>
#include <stddef.h>
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#if !defined(NDEBUG) && !defined(SQLITE_DEBUG)
# define NDEBUG 1
#endif
@@ -202,6 +209,19 @@ typedef sqlite3_int64 i64; /* 8-byte signed integer */
#define deliberate_fall_through
/*
** Macros needed to provide flexible arrays in a portable way
*/
#ifndef offsetof
# define offsetof(ST,M) ((size_t)((char*)&((ST*)0)->M - (char*)0))
#endif
#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)
# define FLEXARRAY
#else
# define FLEXARRAY 1
#endif
#endif /* SQLITE_AMALGAMATION */
#ifdef SQLITE_DEBUG
@@ -431,9 +451,13 @@ struct Fts3Phrase {
*/
int nToken; /* Number of tokens in the phrase */
int iColumn; /* Index of column this phrase must match */
Fts3PhraseToken aToken[1]; /* One entry for each token in the phrase */
Fts3PhraseToken aToken[FLEXARRAY]; /* One for each token in the phrase */
};
/* Size (in bytes) of an Fts3Phrase object large enough to hold N tokens */
#define SZ_FTS3PHRASE(N) \
(offsetof(Fts3Phrase,aToken)+(N)*sizeof(Fts3PhraseToken))
/*
** A tree of these objects forms the RHS of a MATCH operator.
**
+38 -14
View File
@@ -161,6 +161,23 @@ int sqlite3Fts3OpenTokenizer(
*/
static int fts3ExprParse(ParseContext *, const char *, int, Fts3Expr **, int *);
/*
** Search buffer z[], size n, for a '"' character. Or, if enable_parenthesis
** is defined, search for '(' and ')' as well. Return the index of the first
** such character in the buffer. If there is no such character, return -1.
*/
static int findBarredChar(const char *z, int n){
int ii;
for(ii=0; ii<n; ii++){
if( (z[ii]=='"')
|| (sqlite3_fts3_enable_parentheses && (z[ii]=='(' || z[ii]==')'))
){
return ii;
}
}
return -1;
}
/*
** Extract the next token from buffer z (length n) using the tokenizer
** and other information (column names etc.) in pParse. Create an Fts3Expr
@@ -185,16 +202,9 @@ static int getNextToken(
int rc;
sqlite3_tokenizer_cursor *pCursor;
Fts3Expr *pRet = 0;
int i = 0;
/* Set variable i to the maximum number of bytes of input to tokenize. */
for(i=0; i<n; i++){
if( sqlite3_fts3_enable_parentheses && (z[i]=='(' || z[i]==')') ) break;
if( z[i]=='"' ) break;
}
*pnConsumed = i;
rc = sqlite3Fts3OpenTokenizer(pTokenizer, pParse->iLangid, z, i, &pCursor);
*pnConsumed = n;
rc = sqlite3Fts3OpenTokenizer(pTokenizer, pParse->iLangid, z, n, &pCursor);
if( rc==SQLITE_OK ){
const char *zToken;
int nToken = 0, iStart = 0, iEnd = 0, iPosition = 0;
@@ -202,7 +212,18 @@ static int getNextToken(
rc = pModule->xNext(pCursor, &zToken, &nToken, &iStart, &iEnd, &iPosition);
if( rc==SQLITE_OK ){
nByte = sizeof(Fts3Expr) + sizeof(Fts3Phrase) + nToken;
/* Check that this tokenization did not gobble up any " characters. Or,
** if enable_parenthesis is true, that it did not gobble up any
** open or close parenthesis characters either. If it did, call
** getNextToken() again, but pass only that part of the input buffer
** up to the first such character. */
int iBarred = findBarredChar(z, iEnd);
if( iBarred>=0 ){
pModule->xClose(pCursor);
return getNextToken(pParse, iCol, z, iBarred, ppExpr, pnConsumed);
}
nByte = sizeof(Fts3Expr) + SZ_FTS3PHRASE(1) + nToken;
pRet = (Fts3Expr *)sqlite3Fts3MallocZero(nByte);
if( !pRet ){
rc = SQLITE_NOMEM;
@@ -212,7 +233,7 @@ static int getNextToken(
pRet->pPhrase->nToken = 1;
pRet->pPhrase->iColumn = iCol;
pRet->pPhrase->aToken[0].n = nToken;
pRet->pPhrase->aToken[0].z = (char *)&pRet->pPhrase[1];
pRet->pPhrase->aToken[0].z = (char*)&pRet->pPhrase->aToken[1];
memcpy(pRet->pPhrase->aToken[0].z, zToken, nToken);
if( iEnd<n && z[iEnd]=='*' ){
@@ -236,7 +257,11 @@ static int getNextToken(
}
*pnConsumed = iEnd;
}else if( i && rc==SQLITE_DONE ){
}else if( n && rc==SQLITE_DONE ){
int iBarred = findBarredChar(z, n);
if( iBarred>=0 ){
*pnConsumed = iBarred;
}
rc = SQLITE_OK;
}
@@ -285,7 +310,7 @@ static int getNextString(
char *zTemp = 0;
i64 nTemp = 0;
const int nSpace = sizeof(Fts3Expr) + sizeof(Fts3Phrase);
const int nSpace = sizeof(Fts3Expr) + SZ_FTS3PHRASE(1);
int nToken = 0;
/* The final Fts3Expr data structure, including the Fts3Phrase,
@@ -1239,7 +1264,6 @@ static void fts3ExprTestCommon(
}
if( rc!=SQLITE_OK && rc!=SQLITE_NOMEM ){
sqlite3Fts3ExprFree(pExpr);
sqlite3_result_error(context, "Error parsing expression", -1);
}else if( rc==SQLITE_NOMEM || !(zBuf = exprToString(pExpr, 0)) ){
sqlite3_result_error_nomem(context);
+18 -14
View File
@@ -108,9 +108,13 @@ struct MatchinfoBuffer {
int nElem;
int bGlobal; /* Set if global data is loaded */
char *zMatchinfo;
u32 aMatchinfo[1];
u32 aMI[FLEXARRAY];
};
/* Size (in bytes) of a MatchinfoBuffer sufficient for N elements */
#define SZ_MATCHINFOBUFFER(N) \
(offsetof(MatchinfoBuffer,aMI)+(((N)+1)/2)*sizeof(u64))
/*
** The snippet() and offsets() functions both return text values. An instance
@@ -135,13 +139,13 @@ struct StrBuffer {
static MatchinfoBuffer *fts3MIBufferNew(size_t nElem, const char *zMatchinfo){
MatchinfoBuffer *pRet;
sqlite3_int64 nByte = sizeof(u32) * (2*(sqlite3_int64)nElem + 1)
+ sizeof(MatchinfoBuffer);
+ SZ_MATCHINFOBUFFER(1);
sqlite3_int64 nStr = strlen(zMatchinfo);
pRet = sqlite3Fts3MallocZero(nByte + nStr+1);
if( pRet ){
pRet->aMatchinfo[0] = (u8*)(&pRet->aMatchinfo[1]) - (u8*)pRet;
pRet->aMatchinfo[1+nElem] = pRet->aMatchinfo[0]
pRet->aMI[0] = (u8*)(&pRet->aMI[1]) - (u8*)pRet;
pRet->aMI[1+nElem] = pRet->aMI[0]
+ sizeof(u32)*((int)nElem+1);
pRet->nElem = (int)nElem;
pRet->zMatchinfo = ((char*)pRet) + nByte;
@@ -155,10 +159,10 @@ static MatchinfoBuffer *fts3MIBufferNew(size_t nElem, const char *zMatchinfo){
static void fts3MIBufferFree(void *p){
MatchinfoBuffer *pBuf = (MatchinfoBuffer*)((u8*)p - ((u32*)p)[-1]);
assert( (u32*)p==&pBuf->aMatchinfo[1]
|| (u32*)p==&pBuf->aMatchinfo[pBuf->nElem+2]
assert( (u32*)p==&pBuf->aMI[1]
|| (u32*)p==&pBuf->aMI[pBuf->nElem+2]
);
if( (u32*)p==&pBuf->aMatchinfo[1] ){
if( (u32*)p==&pBuf->aMI[1] ){
pBuf->aRef[1] = 0;
}else{
pBuf->aRef[2] = 0;
@@ -175,18 +179,18 @@ static void (*fts3MIBufferAlloc(MatchinfoBuffer *p, u32 **paOut))(void*){
if( p->aRef[1]==0 ){
p->aRef[1] = 1;
aOut = &p->aMatchinfo[1];
aOut = &p->aMI[1];
xRet = fts3MIBufferFree;
}
else if( p->aRef[2]==0 ){
p->aRef[2] = 1;
aOut = &p->aMatchinfo[p->nElem+2];
aOut = &p->aMI[p->nElem+2];
xRet = fts3MIBufferFree;
}else{
aOut = (u32*)sqlite3_malloc64(p->nElem * sizeof(u32));
if( aOut ){
xRet = sqlite3_free;
if( p->bGlobal ) memcpy(aOut, &p->aMatchinfo[1], p->nElem*sizeof(u32));
if( p->bGlobal ) memcpy(aOut, &p->aMI[1], p->nElem*sizeof(u32));
}
}
@@ -196,7 +200,7 @@ static void (*fts3MIBufferAlloc(MatchinfoBuffer *p, u32 **paOut))(void*){
static void fts3MIBufferSetGlobal(MatchinfoBuffer *p){
p->bGlobal = 1;
memcpy(&p->aMatchinfo[2+p->nElem], &p->aMatchinfo[1], p->nElem*sizeof(u32));
memcpy(&p->aMI[2+p->nElem], &p->aMI[1], p->nElem*sizeof(u32));
}
/*
@@ -1023,16 +1027,16 @@ static size_t fts3MatchinfoSize(MatchInfo *pInfo, char cArg){
break;
case FTS3_MATCHINFO_LHITS:
nVal = pInfo->nCol * pInfo->nPhrase;
nVal = (size_t)pInfo->nCol * pInfo->nPhrase;
break;
case FTS3_MATCHINFO_LHITS_BM:
nVal = pInfo->nPhrase * ((pInfo->nCol + 31) / 32);
nVal = (size_t)pInfo->nPhrase * ((pInfo->nCol + 31) / 32);
break;
default:
assert( cArg==FTS3_MATCHINFO_HITS );
nVal = pInfo->nCol * pInfo->nPhrase * 3;
nVal = (size_t)pInfo->nCol * pInfo->nPhrase * 3;
break;
}
+3 -3
View File
@@ -219,7 +219,7 @@ static int SQLITE_TCLAPI fts3_near_match_cmd(
rc = Tcl_ListObjGetElements(interp, pPhrase, &nToken, &apToken);
if( rc!=TCL_OK ) goto near_match_out;
if( nToken>NM_MAX_TOKEN ){
Tcl_AppendResult(interp, "Too many tokens in phrase", 0);
Tcl_AppendResult(interp, "Too many tokens in phrase", NULL);
rc = TCL_ERROR;
goto near_match_out;
}
@@ -547,7 +547,7 @@ static int SQLITE_TCLAPI fts3_test_varint_cmd(
if( w!=w2 || nByte!=nByte2 ){
char *zErr = sqlite3_mprintf("error testing %lld", w);
Tcl_ResetResult(interp);
Tcl_AppendResult(interp, zErr, 0);
Tcl_AppendResult(interp, zErr, NULL);
return TCL_ERROR;
}
@@ -557,7 +557,7 @@ static int SQLITE_TCLAPI fts3_test_varint_cmd(
if( (int)w!=i || nByte!=nByte2 ){
char *zErr = sqlite3_mprintf("error testing %lld (32-bit)", w);
Tcl_ResetResult(interp);
Tcl_AppendResult(interp, zErr, 0);
Tcl_AppendResult(interp, zErr, NULL);
return TCL_ERROR;
}
}
+1 -1
View File
@@ -346,7 +346,7 @@ static int fts3tokFilterMethod(
fts3tokResetCursor(pCsr);
if( idxNum==1 ){
const char *zByte = (const char *)sqlite3_value_text(apVal[0]);
int nByte = sqlite3_value_bytes(apVal[0]);
sqlite3_int64 nByte = sqlite3_value_bytes(apVal[0]);
pCsr->zInput = sqlite3_malloc64(nByte+1);
if( pCsr->zInput==0 ){
rc = SQLITE_NOMEM;
+16 -2
View File
@@ -20,6 +20,7 @@ SQLITE_EXTENSION_INIT1
#include <string.h>
#include <assert.h>
#include <stddef.h>
#ifndef SQLITE_AMALGAMATION
@@ -75,6 +76,18 @@ typedef sqlite3_uint64 u64;
# define EIGHT_BYTE_ALIGNMENT(X) ((((uptr)(X) - (uptr)0)&7)==0)
#endif
/*
** Macros needed to provide flexible arrays in a portable way
*/
#ifndef offsetof
# define offsetof(ST,M) ((size_t)((char*)&((ST*)0)->M - (char*)0))
#endif
#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)
# define FLEXARRAY
#else
# define FLEXARRAY 1
#endif
#endif
/* Truncate very long tokens to this many bytes. Hard limit is
@@ -147,10 +160,11 @@ typedef struct Fts5Colset Fts5Colset;
*/
struct Fts5Colset {
int nCol;
int aiCol[1];
int aiCol[FLEXARRAY];
};
/* Size (int bytes) of a complete Fts5Colset object with N columns. */
#define SZ_FTS5COLSET(N) (sizeof(i64)*((N+2)/2))
/**************************************************************************
** Interface to code in fts5_config.c. fts5_config.c contains contains code
+33 -22
View File
@@ -86,9 +86,13 @@ struct Fts5ExprNode {
/* Child nodes. For a NOT node, this array always contains 2 entries. For
** AND or OR nodes, it contains 2 or more entries. */
int nChild; /* Number of child nodes */
Fts5ExprNode *apChild[1]; /* Array of child nodes */
Fts5ExprNode *apChild[FLEXARRAY]; /* Array of child nodes */
};
/* Size (in bytes) of an Fts5ExprNode object that holds up to N children */
#define SZ_FTS5EXPRNODE(N) \
(offsetof(Fts5ExprNode,apChild) + (N)*sizeof(Fts5ExprNode*))
#define Fts5NodeIsString(p) ((p)->eType==FTS5_TERM || (p)->eType==FTS5_STRING)
/*
@@ -119,9 +123,13 @@ struct Fts5ExprPhrase {
Fts5ExprNode *pNode; /* FTS5_STRING node this phrase is part of */
Fts5Buffer poslist; /* Current position list */
int nTerm; /* Number of entries in aTerm[] */
Fts5ExprTerm aTerm[1]; /* Terms that make up this phrase */
Fts5ExprTerm aTerm[FLEXARRAY]; /* Terms that make up this phrase */
};
/* Size (in bytes) of an Fts5ExprPhrase object that holds up to N terms */
#define SZ_FTS5EXPRPHRASE(N) \
(offsetof(Fts5ExprPhrase,aTerm) + (N)*sizeof(Fts5ExprTerm))
/*
** One or more phrases that must appear within a certain token distance of
** each other within each matching document.
@@ -130,9 +138,12 @@ struct Fts5ExprNearset {
int nNear; /* NEAR parameter */
Fts5Colset *pColset; /* Columns to search (NULL -> all columns) */
int nPhrase; /* Number of entries in aPhrase[] array */
Fts5ExprPhrase *apPhrase[1]; /* Array of phrase pointers */
Fts5ExprPhrase *apPhrase[FLEXARRAY]; /* Array of phrase pointers */
};
/* Size (in bytes) of an Fts5ExprNearset object covering up to N phrases */
#define SZ_FTS5EXPRNEARSET(N) \
(offsetof(Fts5ExprNearset,apPhrase)+(N)*sizeof(Fts5ExprPhrase*))
/*
** Parse context.
@@ -292,7 +303,7 @@ int sqlite3Fts5ExprNew(
/* If the LHS of the MATCH expression was a user column, apply the
** implicit column-filter. */
if( sParse.rc==SQLITE_OK && iCol<pConfig->nCol ){
int n = sizeof(Fts5Colset);
int n = SZ_FTS5COLSET(1);
Fts5Colset *pColset = (Fts5Colset*)sqlite3Fts5MallocZero(&sParse.rc, n);
if( pColset ){
pColset->nCol = 1;
@@ -1650,7 +1661,7 @@ Fts5ExprNearset *sqlite3Fts5ParseNearset(
if( pParse->rc==SQLITE_OK ){
if( pNear==0 ){
sqlite3_int64 nByte;
nByte = sizeof(Fts5ExprNearset) + SZALLOC * sizeof(Fts5ExprPhrase*);
nByte = SZ_FTS5EXPRNEARSET(SZALLOC+1);
pRet = sqlite3_malloc64(nByte);
if( pRet==0 ){
pParse->rc = SQLITE_NOMEM;
@@ -1661,7 +1672,7 @@ Fts5ExprNearset *sqlite3Fts5ParseNearset(
int nNew = pNear->nPhrase + SZALLOC;
sqlite3_int64 nByte;
nByte = sizeof(Fts5ExprNearset) + nNew * sizeof(Fts5ExprPhrase*);
nByte = SZ_FTS5EXPRNEARSET(nNew+1);
pRet = (Fts5ExprNearset*)sqlite3_realloc64(pNear, nByte);
if( pRet==0 ){
pParse->rc = SQLITE_NOMEM;
@@ -1752,12 +1763,12 @@ static int fts5ParseTokenize(
int nNew = SZALLOC + (pPhrase ? pPhrase->nTerm : 0);
pNew = (Fts5ExprPhrase*)sqlite3_realloc64(pPhrase,
sizeof(Fts5ExprPhrase) + sizeof(Fts5ExprTerm) * nNew
SZ_FTS5EXPRPHRASE(nNew+1)
);
if( pNew==0 ){
rc = SQLITE_NOMEM;
}else{
if( pPhrase==0 ) memset(pNew, 0, sizeof(Fts5ExprPhrase));
if( pPhrase==0 ) memset(pNew, 0, SZ_FTS5EXPRPHRASE(1));
pCtx->pPhrase = pPhrase = pNew;
pNew->nTerm = nNew - SZALLOC;
}
@@ -1865,7 +1876,7 @@ Fts5ExprPhrase *sqlite3Fts5ParseTerm(
if( sCtx.pPhrase==0 ){
/* This happens when parsing a token or quoted phrase that contains
** no token characters at all. (e.g ... MATCH '""'). */
sCtx.pPhrase = sqlite3Fts5MallocZero(&pParse->rc, sizeof(Fts5ExprPhrase));
sCtx.pPhrase = sqlite3Fts5MallocZero(&pParse->rc, SZ_FTS5EXPRPHRASE(1));
}else if( sCtx.pPhrase->nTerm ){
sCtx.pPhrase->aTerm[sCtx.pPhrase->nTerm-1].bPrefix = (u8)bPrefix;
}
@@ -1900,19 +1911,18 @@ int sqlite3Fts5ExprClonePhrase(
sizeof(Fts5ExprPhrase*));
}
if( rc==SQLITE_OK ){
pNew->pRoot = (Fts5ExprNode*)sqlite3Fts5MallocZero(&rc,
sizeof(Fts5ExprNode));
pNew->pRoot = (Fts5ExprNode*)sqlite3Fts5MallocZero(&rc, SZ_FTS5EXPRNODE(1));
}
if( rc==SQLITE_OK ){
pNew->pRoot->pNear = (Fts5ExprNearset*)sqlite3Fts5MallocZero(&rc,
sizeof(Fts5ExprNearset) + sizeof(Fts5ExprPhrase*));
pNew->pRoot->pNear = (Fts5ExprNearset*)sqlite3Fts5MallocZero(&rc,
SZ_FTS5EXPRNEARSET(2));
}
if( rc==SQLITE_OK && ALWAYS(pOrig!=0) ){
Fts5Colset *pColsetOrig = pOrig->pNode->pNear->pColset;
if( pColsetOrig ){
sqlite3_int64 nByte;
Fts5Colset *pColset;
nByte = sizeof(Fts5Colset) + (pColsetOrig->nCol-1) * sizeof(int);
nByte = SZ_FTS5COLSET(pColsetOrig->nCol);
pColset = (Fts5Colset*)sqlite3Fts5MallocZero(&rc, nByte);
if( pColset ){
memcpy(pColset, pColsetOrig, (size_t)nByte);
@@ -1940,7 +1950,7 @@ int sqlite3Fts5ExprClonePhrase(
}else{
/* This happens when parsing a token or quoted phrase that contains
** no token characters at all. (e.g ... MATCH '""'). */
sCtx.pPhrase = sqlite3Fts5MallocZero(&rc, sizeof(Fts5ExprPhrase));
sCtx.pPhrase = sqlite3Fts5MallocZero(&rc, SZ_FTS5EXPRPHRASE(1));
}
}
@@ -2005,7 +2015,8 @@ void sqlite3Fts5ParseSetDistance(
);
return;
}
nNear = nNear * 10 + (p->p[i] - '0');
if( nNear<214748363 ) nNear = nNear * 10 + (p->p[i] - '0');
/* ^^^^^^^^^^^^^^^--- Prevent integer overflow */
}
}else{
nNear = FTS5_DEFAULT_NEARDIST;
@@ -2034,7 +2045,7 @@ static Fts5Colset *fts5ParseColset(
assert( pParse->rc==SQLITE_OK );
assert( iCol>=0 && iCol<pParse->pConfig->nCol );
pNew = sqlite3_realloc64(p, sizeof(Fts5Colset) + sizeof(int)*nCol);
pNew = sqlite3_realloc64(p, SZ_FTS5COLSET(nCol+1));
if( pNew==0 ){
pParse->rc = SQLITE_NOMEM;
}else{
@@ -2069,7 +2080,7 @@ Fts5Colset *sqlite3Fts5ParseColsetInvert(Fts5Parse *pParse, Fts5Colset *p){
int nCol = pParse->pConfig->nCol;
pRet = (Fts5Colset*)sqlite3Fts5MallocZero(&pParse->rc,
sizeof(Fts5Colset) + sizeof(int)*nCol
SZ_FTS5COLSET(nCol+1)
);
if( pRet ){
int i;
@@ -2130,7 +2141,7 @@ Fts5Colset *sqlite3Fts5ParseColset(
static Fts5Colset *fts5CloneColset(int *pRc, Fts5Colset *pOrig){
Fts5Colset *pRet;
if( pOrig ){
sqlite3_int64 nByte = sizeof(Fts5Colset) + (pOrig->nCol-1) * sizeof(int);
sqlite3_int64 nByte = SZ_FTS5COLSET(pOrig->nCol);
pRet = (Fts5Colset*)sqlite3Fts5MallocZero(pRc, nByte);
if( pRet ){
memcpy(pRet, pOrig, (size_t)nByte);
@@ -2298,7 +2309,7 @@ static Fts5ExprNode *fts5ParsePhraseToAnd(
assert( pNear->nPhrase==1 );
assert( pParse->bPhraseToAnd );
nByte = sizeof(Fts5ExprNode) + nTerm*sizeof(Fts5ExprNode*);
nByte = SZ_FTS5EXPRNODE(nTerm+1);
pRet = (Fts5ExprNode*)sqlite3Fts5MallocZero(&pParse->rc, nByte);
if( pRet ){
pRet->eType = FTS5_AND;
@@ -2308,7 +2319,7 @@ static Fts5ExprNode *fts5ParsePhraseToAnd(
pParse->nPhrase--;
for(ii=0; ii<nTerm; ii++){
Fts5ExprPhrase *pPhrase = (Fts5ExprPhrase*)sqlite3Fts5MallocZero(
&pParse->rc, sizeof(Fts5ExprPhrase)
&pParse->rc, SZ_FTS5EXPRPHRASE(1)
);
if( pPhrase ){
if( parseGrowPhraseArray(pParse) ){
@@ -2377,7 +2388,7 @@ Fts5ExprNode *sqlite3Fts5ParseNode(
if( pRight->eType==eType ) nChild += pRight->nChild-1;
}
nByte = sizeof(Fts5ExprNode) + sizeof(Fts5ExprNode*)*(nChild-1);
nByte = SZ_FTS5EXPRNODE(nChild);
pRet = (Fts5ExprNode*)sqlite3Fts5MallocZero(&pParse->rc, nByte);
if( pRet ){
+139 -76
View File
@@ -422,9 +422,13 @@ struct Fts5Structure {
u64 nOriginCntr; /* Origin value for next top-level segment */
int nSegment; /* Total segments in this structure */
int nLevel; /* Number of levels in this index */
Fts5StructureLevel aLevel[1]; /* Array of nLevel level objects */
Fts5StructureLevel aLevel[FLEXARRAY]; /* Array of nLevel level objects */
};
/* Size (in bytes) of an Fts5Structure object holding up to N levels */
#define SZ_FTS5STRUCTURE(N) \
(offsetof(Fts5Structure,aLevel) + (N)*sizeof(Fts5StructureLevel))
/*
** An object of type Fts5SegWriter is used to write to segments.
*/
@@ -550,15 +554,49 @@ struct Fts5SegIter {
u8 bDel; /* True if the delete flag is set */
};
static int fts5IndexCorruptRowid(Fts5Index *pIdx, i64 iRowid){
pIdx->rc = FTS5_CORRUPT;
sqlite3Fts5ConfigErrmsg(pIdx->pConfig,
"fts5: corruption found reading blob %lld from table \"%s\"",
iRowid, pIdx->pConfig->zName
);
return SQLITE_CORRUPT_VTAB;
}
#define FTS5_CORRUPT_ROWID(pIdx, iRowid) fts5IndexCorruptRowid(pIdx, iRowid)
static int fts5IndexCorruptIter(Fts5Index *pIdx, Fts5SegIter *pIter){
pIdx->rc = FTS5_CORRUPT;
sqlite3Fts5ConfigErrmsg(pIdx->pConfig,
"fts5: corruption on page %d, segment %d, table \"%s\"",
pIter->iLeafPgno, pIter->pSeg->iSegid, pIdx->pConfig->zName
);
return SQLITE_CORRUPT_VTAB;
}
#define FTS5_CORRUPT_ITER(pIdx, pIter) fts5IndexCorruptIter(pIdx, pIter)
static int fts5IndexCorruptIdx(Fts5Index *pIdx){
pIdx->rc = FTS5_CORRUPT;
sqlite3Fts5ConfigErrmsg(pIdx->pConfig,
"fts5: corruption in table \"%s\"", pIdx->pConfig->zName
);
return SQLITE_CORRUPT_VTAB;
}
#define FTS5_CORRUPT_IDX(pIdx) fts5IndexCorruptIdx(pIdx)
/*
** Array of tombstone pages. Reference counted.
*/
struct Fts5TombstoneArray {
int nRef; /* Number of pointers to this object */
int nRef; /* Number of pointers to this object */
int nTombstone;
Fts5Data *apTombstone[1]; /* Array of tombstone pages */
Fts5Data *apTombstone[FLEXARRAY]; /* Array of tombstone pages */
};
/* Size (in bytes) of an Fts5TombstoneArray holding up to N tombstones */
#define SZ_FTS5TOMBSTONEARRAY(N) \
(offsetof(Fts5TombstoneArray,apTombstone)+(N)*sizeof(Fts5Data*))
/*
** Argument is a pointer to an Fts5Data structure that contains a
** leaf page.
@@ -627,9 +665,12 @@ struct Fts5Iter {
i64 iSwitchRowid; /* Firstest rowid of other than aFirst[1] */
Fts5CResult *aFirst; /* Current merge state (see above) */
Fts5SegIter aSeg[1]; /* Array of segment iterators */
Fts5SegIter aSeg[FLEXARRAY]; /* Array of segment iterators */
};
/* Size (in bytes) of an Fts5Iter object holding up to N segment iterators */
#define SZ_FTS5ITER(N) (offsetof(Fts5Iter,aSeg)+(N)*sizeof(Fts5SegIter))
/*
** An instance of the following type is used to iterate through the contents
** of a doclist-index record.
@@ -656,9 +697,13 @@ struct Fts5DlidxLvl {
struct Fts5DlidxIter {
int nLvl;
int iSegid;
Fts5DlidxLvl aLvl[1];
Fts5DlidxLvl aLvl[FLEXARRAY];
};
/* Size (in bytes) of an Fts5DlidxIter object with up to N levels */
#define SZ_FTS5DLIDXITER(N) \
(offsetof(Fts5DlidxIter,aLvl)+(N)*sizeof(Fts5DlidxLvl))
static void fts5PutU16(u8 *aOut, u16 iVal){
aOut[0] = (iVal>>8);
aOut[1] = (iVal&0xFF);
@@ -828,7 +873,7 @@ static Fts5Data *fts5DataRead(Fts5Index *p, i64 iRowid){
** All the reasons those functions might return SQLITE_ERROR - missing
** table, missing row, non-blob/text in block column - indicate
** backing store corruption. */
if( rc==SQLITE_ERROR ) rc = FTS5_CORRUPT;
if( rc==SQLITE_ERROR ) rc = FTS5_CORRUPT_ROWID(p, iRowid);
if( rc==SQLITE_OK ){
u8 *aOut = 0; /* Read blob data into this buffer */
@@ -878,7 +923,7 @@ static Fts5Data *fts5LeafRead(Fts5Index *p, i64 iRowid){
Fts5Data *pRet = fts5DataRead(p, iRowid);
if( pRet ){
if( pRet->nn<4 || pRet->szLeaf>pRet->nn ){
p->rc = FTS5_CORRUPT;
FTS5_CORRUPT_ROWID(p, iRowid);
fts5DataRelease(pRet);
pRet = 0;
}
@@ -1026,7 +1071,7 @@ int sqlite3Fts5StructureTest(Fts5Index *p, void *pStruct){
static void fts5StructureMakeWritable(int *pRc, Fts5Structure **pp){
Fts5Structure *p = *pp;
if( *pRc==SQLITE_OK && p->nRef>1 ){
i64 nByte = sizeof(Fts5Structure)+(p->nLevel-1)*sizeof(Fts5StructureLevel);
i64 nByte = SZ_FTS5STRUCTURE(p->nLevel);
Fts5Structure *pNew;
pNew = (Fts5Structure*)sqlite3Fts5MallocZero(pRc, nByte);
if( pNew ){
@@ -1100,10 +1145,7 @@ static int fts5StructureDecode(
){
return FTS5_CORRUPT;
}
nByte = (
sizeof(Fts5Structure) + /* Main structure */
sizeof(Fts5StructureLevel) * (nLevel-1) /* aLevel[] array */
);
nByte = SZ_FTS5STRUCTURE(nLevel);
pRet = (Fts5Structure*)sqlite3Fts5MallocZero(&rc, nByte);
if( pRet ){
@@ -1183,10 +1225,7 @@ static void fts5StructureAddLevel(int *pRc, Fts5Structure **ppStruct){
if( *pRc==SQLITE_OK ){
Fts5Structure *pStruct = *ppStruct;
int nLevel = pStruct->nLevel;
sqlite3_int64 nByte = (
sizeof(Fts5Structure) + /* Main structure */
sizeof(Fts5StructureLevel) * (nLevel+1) /* aLevel[] array */
);
sqlite3_int64 nByte = SZ_FTS5STRUCTURE(nLevel+2);
pStruct = sqlite3_realloc64(pStruct, nByte);
if( pStruct ){
@@ -1243,8 +1282,14 @@ static Fts5Structure *fts5StructureReadUncached(Fts5Index *p){
/* TODO: Do we need this if the leaf-index is appended? Probably... */
memset(&pData->p[pData->nn], 0, FTS5_DATA_PADDING);
p->rc = fts5StructureDecode(pData->p, pData->nn, &iCookie, &pRet);
if( p->rc==SQLITE_OK && (pConfig->pgsz==0 || pConfig->iCookie!=iCookie) ){
p->rc = sqlite3Fts5ConfigLoad(pConfig, iCookie);
if( p->rc==SQLITE_OK ){
if( (pConfig->pgsz==0 || pConfig->iCookie!=iCookie) ){
p->rc = sqlite3Fts5ConfigLoad(pConfig, iCookie);
}
}else if( p->rc==SQLITE_CORRUPT_VTAB ){
sqlite3Fts5ConfigErrmsg(p->pConfig,
"fts5: corrupt structure record for table \"%s\"", p->pConfig->zName
);
}
fts5DataRelease(pData);
if( p->rc!=SQLITE_OK ){
@@ -1725,7 +1770,7 @@ static Fts5DlidxIter *fts5DlidxIterInit(
int bDone = 0;
for(i=0; p->rc==SQLITE_OK && bDone==0; i++){
sqlite3_int64 nByte = sizeof(Fts5DlidxIter) + i * sizeof(Fts5DlidxLvl);
sqlite3_int64 nByte = SZ_FTS5DLIDXITER(i+1);
Fts5DlidxIter *pNew;
pNew = (Fts5DlidxIter*)sqlite3_realloc64(pIter, nByte);
@@ -1867,7 +1912,7 @@ static void fts5SegIterLoadRowid(Fts5Index *p, Fts5SegIter *pIter){
while( iOff>=pIter->pLeaf->szLeaf ){
fts5SegIterNextPage(p, pIter);
if( pIter->pLeaf==0 ){
if( p->rc==SQLITE_OK ) p->rc = FTS5_CORRUPT;
if( p->rc==SQLITE_OK ) FTS5_CORRUPT_ITER(p, pIter);
return;
}
iOff = 4;
@@ -1899,7 +1944,7 @@ static void fts5SegIterLoadTerm(Fts5Index *p, Fts5SegIter *pIter, int nKeep){
iOff += fts5GetVarint32(&a[iOff], nNew);
if( iOff+nNew>pIter->pLeaf->szLeaf || nKeep>pIter->term.n || nNew==0 ){
p->rc = FTS5_CORRUPT;
FTS5_CORRUPT_ITER(p, pIter);
return;
}
pIter->term.n = nKeep;
@@ -1943,7 +1988,7 @@ static void fts5SegIterSetNext(Fts5Index *p, Fts5SegIter *pIter){
static void fts5SegIterAllocTombstone(Fts5Index *p, Fts5SegIter *pIter){
const int nTomb = pIter->pSeg->nPgTombstone;
if( nTomb>0 ){
int nByte = nTomb * sizeof(Fts5Data*) + sizeof(Fts5TombstoneArray);
int nByte = SZ_FTS5TOMBSTONEARRAY(nTomb+1);
Fts5TombstoneArray *pNew;
pNew = (Fts5TombstoneArray*)sqlite3Fts5MallocZero(&p->rc, nByte);
if( pNew ){
@@ -2094,7 +2139,7 @@ static void fts5SegIterReverseNewPage(Fts5Index *p, Fts5SegIter *pIter){
iRowidOff = fts5LeafFirstRowidOff(pNew);
if( iRowidOff ){
if( iRowidOff>=pNew->szLeaf ){
p->rc = FTS5_CORRUPT;
FTS5_CORRUPT_ITER(p, pIter);
}else{
pIter->pLeaf = pNew;
pIter->iLeafOffset = iRowidOff;
@@ -2328,7 +2373,7 @@ static void fts5SegIterNext(
}
assert_nc( iOff<pLeaf->szLeaf );
if( iOff>pLeaf->szLeaf ){
p->rc = FTS5_CORRUPT;
FTS5_CORRUPT_ITER(p, pIter);
return;
}
}
@@ -2436,18 +2481,20 @@ static void fts5SegIterReverse(Fts5Index *p, Fts5SegIter *pIter){
fts5DataRelease(pIter->pLeaf);
pIter->pLeaf = pLast;
pIter->iLeafPgno = pgnoLast;
iOff = fts5LeafFirstRowidOff(pLast);
if( iOff>pLast->szLeaf ){
p->rc = FTS5_CORRUPT;
return;
}
iOff += fts5GetVarint(&pLast->p[iOff], (u64*)&pIter->iRowid);
pIter->iLeafOffset = iOff;
if( p->rc==SQLITE_OK ){
iOff = fts5LeafFirstRowidOff(pLast);
if( iOff>pLast->szLeaf ){
FTS5_CORRUPT_ITER(p, pIter);
return;
}
iOff += fts5GetVarint(&pLast->p[iOff], (u64*)&pIter->iRowid);
pIter->iLeafOffset = iOff;
if( fts5LeafIsTermless(pLast) ){
pIter->iEndofDoclist = pLast->nn+1;
}else{
pIter->iEndofDoclist = fts5LeafFirstTermOff(pLast);
if( fts5LeafIsTermless(pLast) ){
pIter->iEndofDoclist = pLast->nn+1;
}else{
pIter->iEndofDoclist = fts5LeafFirstTermOff(pLast);
}
}
}
@@ -2517,7 +2564,7 @@ static void fts5LeafSeek(
iPgidx += fts5GetVarint32(&a[iPgidx], iTermOff);
iOff = iTermOff;
if( iOff>n ){
p->rc = FTS5_CORRUPT;
FTS5_CORRUPT_ITER(p, pIter);
return;
}
@@ -2560,7 +2607,7 @@ static void fts5LeafSeek(
iOff = iTermOff;
if( iOff>=n ){
p->rc = FTS5_CORRUPT;
FTS5_CORRUPT_ITER(p, pIter);
return;
}
@@ -2582,7 +2629,7 @@ static void fts5LeafSeek(
iPgidx = (u32)pIter->pLeaf->szLeaf;
iPgidx += fts5GetVarint32(&pIter->pLeaf->p[iPgidx], iOff);
if( iOff<4 || (i64)iOff>=pIter->pLeaf->szLeaf ){
p->rc = FTS5_CORRUPT;
FTS5_CORRUPT_ITER(p, pIter);
return;
}else{
nKeep = 0;
@@ -2597,7 +2644,7 @@ static void fts5LeafSeek(
search_success:
if( (i64)iOff+nNew>n || nNew<1 ){
p->rc = FTS5_CORRUPT;
FTS5_CORRUPT_ITER(p, pIter);
return;
}
pIter->iLeafOffset = iOff + nNew;
@@ -3062,7 +3109,7 @@ static void fts5SegIterGotoPage(
assert( iLeafPgno>pIter->iLeafPgno );
if( iLeafPgno>pIter->pSeg->pgnoLast ){
p->rc = FTS5_CORRUPT;
FTS5_CORRUPT_IDX(p);
}else{
fts5DataRelease(pIter->pNextLeaf);
pIter->pNextLeaf = 0;
@@ -3077,7 +3124,7 @@ static void fts5SegIterGotoPage(
u8 *a = pIter->pLeaf->p;
int n = pIter->pLeaf->szLeaf;
if( iOff<4 || iOff>=n ){
p->rc = FTS5_CORRUPT;
FTS5_CORRUPT_IDX(p);
}else{
iOff += fts5GetVarint(&a[iOff], (u64*)&pIter->iRowid);
pIter->iLeafOffset = iOff;
@@ -3404,8 +3451,7 @@ static Fts5Iter *fts5MultiIterAlloc(
for(nSlot=2; nSlot<nSeg; nSlot=nSlot*2);
pNew = fts5IdxMalloc(p,
sizeof(Fts5Iter) + /* pNew */
sizeof(Fts5SegIter) * (nSlot-1) + /* pNew->aSeg[] */
SZ_FTS5ITER(nSlot) + /* pNew + pNew->aSeg[] */
sizeof(Fts5CResult) * nSlot /* pNew->aFirst[] */
);
if( pNew ){
@@ -3557,7 +3603,7 @@ static void fts5ChunkIterate(
if( nRem<=0 ){
break;
}else if( pSeg->pSeg==0 ){
p->rc = FTS5_CORRUPT;
FTS5_CORRUPT_IDX(p);
return;
}else{
pgno++;
@@ -4660,7 +4706,7 @@ static void fts5TrimSegments(Fts5Index *p, Fts5Iter *pIter){
** a single page has been assigned to more than one segment. In
** this case a prior iteration of this loop may have corrupted the
** segment currently being trimmed. */
p->rc = FTS5_CORRUPT;
FTS5_CORRUPT_ROWID(p, iLeafRowid);
}else{
fts5BufferZero(&buf);
fts5BufferGrow(&p->rc, &buf, pData->nn);
@@ -5127,7 +5173,7 @@ static void fts5SecureDeleteOverflow(
}else if( bDetailNone ){
break;
}else if( iNext>=pLeaf->szLeaf || pLeaf->nn<pLeaf->szLeaf || iNext<4 ){
p->rc = FTS5_CORRUPT;
FTS5_CORRUPT_ROWID(p, iRowid);
break;
}else{
int nShift = iNext - 4;
@@ -5147,7 +5193,7 @@ static void fts5SecureDeleteOverflow(
i1 += fts5GetVarint32(&aPg[i1], iFirst);
if( iFirst<iNext ){
p->rc = FTS5_CORRUPT;
FTS5_CORRUPT_ROWID(p, iRowid);
break;
}
aIdx = sqlite3Fts5MallocZero(&p->rc, (pLeaf->nn-pLeaf->szLeaf)+2);
@@ -5370,14 +5416,14 @@ static void fts5DoSecureDelete(
nSuffix = (nPrefix2 + nSuffix2) - nPrefix;
if( (iKeyOff+nSuffix)>iPgIdx || (iNextOff+nSuffix2)>iPgIdx ){
p->rc = FTS5_CORRUPT;
FTS5_CORRUPT_IDX(p);
}else{
if( iKey!=1 ){
iOff += sqlite3Fts5PutVarint(&aPg[iOff], nPrefix);
}
iOff += sqlite3Fts5PutVarint(&aPg[iOff], nSuffix);
if( nPrefix2>pSeg->term.n ){
p->rc = FTS5_CORRUPT;
FTS5_CORRUPT_IDX(p);
}else if( nPrefix2>nPrefix ){
memcpy(&aPg[iOff], &pSeg->term.p[nPrefix], nPrefix2-nPrefix);
iOff += (nPrefix2-nPrefix);
@@ -5771,7 +5817,7 @@ static Fts5Structure *fts5IndexOptimizeStruct(
Fts5Structure *pStruct
){
Fts5Structure *pNew = 0;
sqlite3_int64 nByte = sizeof(Fts5Structure);
sqlite3_int64 nByte = SZ_FTS5STRUCTURE(1);
int nSeg = pStruct->nSegment;
int i;
@@ -5801,6 +5847,7 @@ static Fts5Structure *fts5IndexOptimizeStruct(
}
nByte += (((i64)pStruct->nLevel)+1) * sizeof(Fts5StructureLevel);
assert( nByte==(i64)SZ_FTS5STRUCTURE(pStruct->nLevel+2) );
pNew = (Fts5Structure*)sqlite3Fts5MallocZero(&p->rc, nByte);
if( pNew ){
@@ -6169,7 +6216,7 @@ static void fts5MergePrefixLists(
}
if( pHead==0 || pHead->pNext==0 ){
p->rc = FTS5_CORRUPT;
FTS5_CORRUPT_IDX(p);
break;
}
@@ -6206,7 +6253,7 @@ static void fts5MergePrefixLists(
assert_nc( tmp.n+nTail<=nTmp );
assert( tmp.n+nTail<=nTmp+nMerge*10 );
if( tmp.n+nTail>nTmp-FTS5_DATA_ZERO_PADDING ){
if( p->rc==SQLITE_OK ) p->rc = FTS5_CORRUPT;
if( p->rc==SQLITE_OK ) FTS5_CORRUPT_IDX(p);
break;
}
fts5BufferSafeAppendVarint(&out, (tmp.n+nTail) * 2);
@@ -6377,9 +6424,13 @@ struct Fts5TokenDataIter {
int nIterAlloc;
Fts5PoslistReader *aPoslistReader;
int *aPoslistToIter;
Fts5Iter *apIter[1];
Fts5Iter *apIter[FLEXARRAY];
};
/* Size in bytes of an Fts5TokenDataIter object holding up to N iterators */
#define SZ_FTS5TOKENDATAITER(N) \
(offsetof(Fts5TokenDataIter,apIter) + (N)*sizeof(Fts5Iter))
/*
** The two input arrays - a1[] and a2[] - are in sorted order. This function
** merges the two arrays together and writes the result to output array
@@ -6642,7 +6693,7 @@ static void fts5SetupPrefixIter(
&& p->pConfig->bPrefixInsttoken
){
s.pTokendata = &s2;
s2.pT = (Fts5TokenDataIter*)fts5IdxMalloc(p, sizeof(*s2.pT));
s2.pT = (Fts5TokenDataIter*)fts5IdxMalloc(p, SZ_FTS5TOKENDATAITER(1));
}
if( p->pConfig->eDetail==FTS5_DETAIL_NONE ){
@@ -6770,15 +6821,17 @@ int sqlite3Fts5IndexRollback(Fts5Index *p){
** and the initial version of the "averages" record (a zero-byte blob).
*/
int sqlite3Fts5IndexReinit(Fts5Index *p){
Fts5Structure s;
Fts5Structure *pTmp;
u8 tmpSpace[SZ_FTS5STRUCTURE(1)];
fts5StructureInvalidate(p);
fts5IndexDiscardData(p);
memset(&s, 0, sizeof(Fts5Structure));
pTmp = (Fts5Structure*)tmpSpace;
memset(pTmp, 0, SZ_FTS5STRUCTURE(1));
if( p->pConfig->bContentlessDelete ){
s.nOriginCntr = 1;
pTmp->nOriginCntr = 1;
}
fts5DataWrite(p, FTS5_AVERAGES_ROWID, (const u8*)"", 0);
fts5StructureWrite(p, &s);
fts5StructureWrite(p, pTmp);
return fts5IndexReturn(p);
}
@@ -6986,7 +7039,7 @@ static Fts5TokenDataIter *fts5AppendTokendataIter(
if( p->rc==SQLITE_OK ){
if( pIn==0 || pIn->nIter==pIn->nIterAlloc ){
int nAlloc = pIn ? pIn->nIterAlloc*2 : 16;
int nByte = nAlloc * sizeof(Fts5Iter*) + sizeof(Fts5TokenDataIter);
int nByte = SZ_FTS5TOKENDATAITER(nAlloc+1);
Fts5TokenDataIter *pNew = (Fts5TokenDataIter*)sqlite3_realloc(pIn, nByte);
if( pNew==0 ){
@@ -7502,7 +7555,8 @@ static int fts5SetupPrefixIterTokendata(
fts5BufferGrow(&p->rc, &token, nToken+1);
assert( token.p!=0 || p->rc!=SQLITE_OK );
ctx.pT = (Fts5TokenDataIter*)sqlite3Fts5MallocZero(&p->rc, sizeof(*ctx.pT));
ctx.pT = (Fts5TokenDataIter*)sqlite3Fts5MallocZero(&p->rc,
SZ_FTS5TOKENDATAITER(1));
if( p->rc==SQLITE_OK ){
@@ -7633,7 +7687,8 @@ int sqlite3Fts5IndexIterWriteTokendata(
if( pIter->nSeg>0 ){
/* This is a prefix term iterator. */
if( pT==0 ){
pT = (Fts5TokenDataIter*)sqlite3Fts5MallocZero(&p->rc, sizeof(*pT));
pT = (Fts5TokenDataIter*)sqlite3Fts5MallocZero(&p->rc,
SZ_FTS5TOKENDATAITER(1));
pIter->pTokenDataIter = pT;
}
if( pT ){
@@ -8327,14 +8382,17 @@ static void fts5IndexIntegrityCheckEmpty(
for(i=iFirst; p->rc==SQLITE_OK && i<=iLast; i++){
Fts5Data *pLeaf = fts5DataRead(p, FTS5_SEGMENT_ROWID(pSeg->iSegid, i));
if( pLeaf ){
if( !fts5LeafIsTermless(pLeaf) ) p->rc = FTS5_CORRUPT;
if( i>=iNoRowid && 0!=fts5LeafFirstRowidOff(pLeaf) ) p->rc = FTS5_CORRUPT;
if( !fts5LeafIsTermless(pLeaf)
|| (i>=iNoRowid && 0!=fts5LeafFirstRowidOff(pLeaf))
){
FTS5_CORRUPT_ROWID(p, FTS5_SEGMENT_ROWID(pSeg->iSegid, i));
}
}
fts5DataRelease(pLeaf);
}
}
static void fts5IntegrityCheckPgidx(Fts5Index *p, Fts5Data *pLeaf){
static void fts5IntegrityCheckPgidx(Fts5Index *p, i64 iRowid, Fts5Data *pLeaf){
i64 iTermOff = 0;
int ii;
@@ -8352,12 +8410,12 @@ static void fts5IntegrityCheckPgidx(Fts5Index *p, Fts5Data *pLeaf){
iOff = iTermOff;
if( iOff>=pLeaf->szLeaf ){
p->rc = FTS5_CORRUPT;
FTS5_CORRUPT_ROWID(p, iRowid);
}else if( iTermOff==nIncr ){
int nByte;
iOff += fts5GetVarint32(&pLeaf->p[iOff], nByte);
if( (iOff+nByte)>pLeaf->szLeaf ){
p->rc = FTS5_CORRUPT;
FTS5_CORRUPT_ROWID(p, iRowid);
}else{
fts5BufferSet(&p->rc, &buf1, nByte, &pLeaf->p[iOff]);
}
@@ -8366,7 +8424,7 @@ static void fts5IntegrityCheckPgidx(Fts5Index *p, Fts5Data *pLeaf){
iOff += fts5GetVarint32(&pLeaf->p[iOff], nKeep);
iOff += fts5GetVarint32(&pLeaf->p[iOff], nByte);
if( nKeep>buf1.n || (iOff+nByte)>pLeaf->szLeaf ){
p->rc = FTS5_CORRUPT;
FTS5_CORRUPT_ROWID(p, iRowid);
}else{
buf1.n = nKeep;
fts5BufferAppendBlob(&p->rc, &buf1, nByte, &pLeaf->p[iOff]);
@@ -8374,7 +8432,7 @@ static void fts5IntegrityCheckPgidx(Fts5Index *p, Fts5Data *pLeaf){
if( p->rc==SQLITE_OK ){
res = fts5BufferCompare(&buf1, &buf2);
if( res<=0 ) p->rc = FTS5_CORRUPT;
if( res<=0 ) FTS5_CORRUPT_ROWID(p, iRowid);
}
}
fts5BufferSet(&p->rc, &buf2, buf1.n, buf1.p);
@@ -8435,7 +8493,7 @@ static void fts5IndexIntegrityCheckSegment(
** entry even if all the terms are removed from it by secure-delete
** operations. */
}else{
p->rc = FTS5_CORRUPT;
FTS5_CORRUPT_ROWID(p, iRow);
}
}else{
@@ -8447,15 +8505,15 @@ static void fts5IndexIntegrityCheckSegment(
iOff = fts5LeafFirstTermOff(pLeaf);
iRowidOff = fts5LeafFirstRowidOff(pLeaf);
if( iRowidOff>=iOff || iOff>=pLeaf->szLeaf ){
p->rc = FTS5_CORRUPT;
FTS5_CORRUPT_ROWID(p, iRow);
}else{
iOff += fts5GetVarint32(&pLeaf->p[iOff], nTerm);
res = fts5Memcmp(&pLeaf->p[iOff], zIdxTerm, MIN(nTerm, nIdxTerm));
if( res==0 ) res = nTerm - nIdxTerm;
if( res<0 ) p->rc = FTS5_CORRUPT;
if( res<0 ) FTS5_CORRUPT_ROWID(p, iRow);
}
fts5IntegrityCheckPgidx(p, pLeaf);
fts5IntegrityCheckPgidx(p, iRow, pLeaf);
}
fts5DataRelease(pLeaf);
if( p->rc ) break;
@@ -8485,7 +8543,7 @@ static void fts5IndexIntegrityCheckSegment(
iKey = FTS5_SEGMENT_ROWID(iSegid, iPg);
pLeaf = fts5DataRead(p, iKey);
if( pLeaf ){
if( fts5LeafFirstRowidOff(pLeaf)!=0 ) p->rc = FTS5_CORRUPT;
if( fts5LeafFirstRowidOff(pLeaf)!=0 ) FTS5_CORRUPT_ROWID(p, iKey);
fts5DataRelease(pLeaf);
}
}
@@ -8500,12 +8558,12 @@ static void fts5IndexIntegrityCheckSegment(
int iRowidOff = fts5LeafFirstRowidOff(pLeaf);
ASSERT_SZLEAF_OK(pLeaf);
if( iRowidOff>=pLeaf->szLeaf ){
p->rc = FTS5_CORRUPT;
FTS5_CORRUPT_ROWID(p, iKey);
}else if( bSecureDelete==0 || iRowidOff>0 ){
i64 iDlRowid = fts5DlidxIterRowid(pDlidx);
fts5GetVarint(&pLeaf->p[iRowidOff], (u64*)&iRowid);
if( iRowid<iDlRowid || (bSecureDelete==0 && iRowid!=iDlRowid) ){
p->rc = FTS5_CORRUPT;
FTS5_CORRUPT_ROWID(p, iKey);
}
}
fts5DataRelease(pLeaf);
@@ -8620,7 +8678,12 @@ int sqlite3Fts5IndexIntegrityCheck(Fts5Index *p, u64 cksum, int bUseCksum){
fts5TestTerm(p, &term, 0, 0, cksum2, &cksum3);
fts5MultiIterFree(pIter);
if( p->rc==SQLITE_OK && bUseCksum && cksum!=cksum2 ) p->rc = FTS5_CORRUPT;
if( p->rc==SQLITE_OK && bUseCksum && cksum!=cksum2 ){
p->rc = FTS5_CORRUPT;
sqlite3Fts5ConfigErrmsg(p->pConfig,
"fts5: checksum mismatch for table \"%s\"", p->pConfig->zName
);
}
fts5StructureRelease(pStruct);
#ifdef SQLITE_DEBUG
+6 -3
View File
@@ -170,9 +170,11 @@ struct Fts5Sorter {
i64 iRowid; /* Current rowid */
const u8 *aPoslist; /* Position lists for current row */
int nIdx; /* Number of entries in aIdx[] */
int aIdx[1]; /* Offsets into aPoslist for current row */
int aIdx[FLEXARRAY]; /* Offsets into aPoslist for current row */
};
/* Size (int bytes) of an Fts5Sorter object with N indexes */
#define SZ_FTS5SORTER(N) (offsetof(Fts5Sorter,nIdx)+((N+2)/2)*sizeof(i64))
/*
** Virtual-table cursor object.
@@ -1050,7 +1052,7 @@ static int fts5CursorFirstSorted(
const char *zRankArgs = pCsr->zRankArgs;
nPhrase = sqlite3Fts5ExprPhraseCount(pCsr->pExpr);
nByte = sizeof(Fts5Sorter) + sizeof(int) * (nPhrase-1);
nByte = SZ_FTS5SORTER(nPhrase);
pSorter = (Fts5Sorter*)sqlite3_malloc64(nByte);
if( pSorter==0 ) return SQLITE_NOMEM;
memset(pSorter, 0, (size_t)nByte);
@@ -3699,8 +3701,9 @@ static int fts5IntegrityMethod(
" FTS5 table %s.%s: %s",
zSchema, zTabname, sqlite3_errstr(rc));
}
}else if( (rc&0xff)==SQLITE_CORRUPT ){
rc = SQLITE_OK;
}
sqlite3Fts5IndexCloseReader(pTab->p.pIndex);
pTab->p.pConfig->pzErrmsg = 0;
+18 -5
View File
@@ -539,6 +539,7 @@ static int fts5StorageDeleteFromIndex(
for(iCol=1; rc==SQLITE_OK && iCol<=pConfig->nCol; iCol++){
if( pConfig->abUnindexed[iCol-1]==0 ){
sqlite3_value *pVal = 0;
sqlite3_value *pFree = 0;
const char *pText = 0;
int nText = 0;
const char *pLoc = 0;
@@ -555,11 +556,22 @@ static int fts5StorageDeleteFromIndex(
if( pConfig->bLocale && sqlite3Fts5IsLocaleValue(pConfig, pVal) ){
rc = sqlite3Fts5DecodeLocaleValue(pVal, &pText, &nText, &pLoc, &nLoc);
}else{
pText = (const char*)sqlite3_value_text(pVal);
nText = sqlite3_value_bytes(pVal);
if( pConfig->bLocale && pSeek ){
pLoc = (const char*)sqlite3_column_text(pSeek, iCol + pConfig->nCol);
nLoc = sqlite3_column_bytes(pSeek, iCol + pConfig->nCol);
if( sqlite3_value_type(pVal)!=SQLITE_TEXT ){
/* Make a copy of the value to work with. This is because the call
** to sqlite3_value_text() below forces the type of the value to
** SQLITE_TEXT, and we may need to use it again later. */
pFree = pVal = sqlite3_value_dup(pVal);
if( pVal==0 ){
rc = SQLITE_NOMEM;
}
}
if( rc==SQLITE_OK ){
pText = (const char*)sqlite3_value_text(pVal);
nText = sqlite3_value_bytes(pVal);
if( pConfig->bLocale && pSeek ){
pLoc = (const char*)sqlite3_column_text(pSeek, iCol+pConfig->nCol);
nLoc = sqlite3_column_bytes(pSeek, iCol + pConfig->nCol);
}
}
}
@@ -575,6 +587,7 @@ static int fts5StorageDeleteFromIndex(
}
sqlite3Fts5ClearLocale(pConfig);
}
sqlite3_value_free(pFree);
}
}
if( rc==SQLITE_OK && p->nTotalRow<1 ){
+1 -1
View File
@@ -14,7 +14,7 @@
** versions of FTS5. It contains the implementation of an FTS5 auxiliary
** function very similar to the FTS4 function matchinfo():
**
** https://www.sqlite.org/fts3.html#matchinfo
** https://sqlite.org/fts3.html#matchinfo
**
** Known differences are that:
**
-1
View File
@@ -778,4 +778,3 @@ void sqlite3Fts5UnicodeAscii(u8 *aArray, u8 *aAscii){
}
aAscii[0] = 0; /* 0x00 is never a token character */
}
+1 -1
View File
@@ -428,7 +428,7 @@ do_execsql_test 15.1 {
}
do_catchsql_test 15.2 {
INSERT INTO t1(t1) VALUES('integrity-check');
} {1 {database disk image is malformed}}
} {1 {fts5: checksum mismatch for table "t1"}}
#-------------------------------------------------------------------------
#
+3 -4
View File
@@ -47,11 +47,10 @@ do_test 1.3 {
DELETE FROM t1_data WHERE rowid = fts5_rowid('segment', $segid, 4);
}
catchsql { INSERT INTO t1(t1) VALUES('integrity-check') }
} {1 {database disk image is malformed}}
} {1 {fts5: corruption found reading blob 137438953476 from table "t1"}}
do_execsql_test 1.3b {
PRAGMA integrity_check(t1);
} {{malformed inverted index for FTS5 table main.t1}}
} {{fts5: corruption found reading blob 137438953476 from table "t1"}}
do_test 1.4 {
db_restore_and_reopen
@@ -61,7 +60,7 @@ do_test 1.4 {
rowid = fts5_rowid('segment', $segid, 4);
}
catchsql { INSERT INTO t1(t1) VALUES('integrity-check') }
} {1 {database disk image is malformed}}
} {1 {fts5: corruption found reading blob 137438953476 from table "t1"}}
db_restore_and_reopen
#db eval {SELECT rowid, fts5_decode(rowid, block) aS r FROM t1_data} {puts $r}
+6 -6
View File
@@ -109,12 +109,12 @@ for {set i [expr $nbyte-2]} {$i>=0} {incr i -1} {
do_catchsql_test 2.$i.2 {
INSERT INTO t1(t1) VALUES('integrity-check');
} {1 {database disk image is malformed}}
} {/1.*fts5: corruption.*/}
do_test 2.$i.3 {
set res [catchsql {SELECT rowid FROM t1 WHERE t1 MATCH 'x*'}]
expr {
$res=="1 {database disk image is malformed}"
[string match {*fts5: corruption*} $res]
|| $res=="0 {$all}"
}
} 1
@@ -160,17 +160,17 @@ foreach {tn hdr} {
close $fd
set res [catchsql {SELECT rowid FROM x3 WHERE x3 MATCH 'x AND a'}]
if {$res == "1 {database disk image is malformed}"} {incr nCorrupt}
if {[string match {*fts5: corruption*} $res]} {incr nCorrupt}
set {} 1
} {1}
if {($tn2 % 10)==0 && $existing != $hdr} {
do_test 3.$tn.$tn2.2 {
catchsql { INSERT INTO x3(x3) VALUES('integrity-check') }
} {1 {database disk image is malformed}}
} {/.*fts5: corruption.*/}
do_execsql_test 3.$tn.$tn2.3 {
PRAGMA integrity_check(x3);
} {{malformed inverted index for FTS5 table main.x3}}
} {/.*fts5: corruption.*/}
}
execsql ROLLBACK
@@ -209,7 +209,7 @@ foreach {tn nCut} {
set res [catchsql {
SELECT rowid FROM x4 WHERE x4 MATCH 'a' ORDER BY 1 DESC
}]
if {$res == "1 {database disk image is malformed}"} {incr nCorrupt}
if {[string match {*fts5: corruption*} $res]} {incr nCorrupt}
set {} 1
} {1}
File diff suppressed because one or more lines are too long
+4 -4
View File
@@ -237,7 +237,7 @@ do_test 1.0 {
do_catchsql_test 1.1 {
SELECT * FROM t1('R*') WHERE (a,b)<=(current_date,0) ORDER BY rowid DESC;
} {1 {database disk image is malformed}}
} {/.*fts5: corrupt.*/}
#-------------------------------------------------------------------------
#
@@ -450,7 +450,7 @@ do_test 2.0 {
do_catchsql_test 2.1 {
SELECT * FROM t1('R*R*R*R*') WHERE (a,b)<=(current_date,0) ORDER BY rowid DESC;
} {1 {database disk image is malformed}}
} {/.*fts5: corrupt.*/}
#-------------------------------------------------------------------------
reset_db
@@ -569,7 +569,7 @@ do_test 3.0 {
do_catchsql_test 3.1 {
UPDATE t1 SET b=quote(zeroblob(200)) WHERE a MATCH 'thra*T';
} {1 {database disk image is malformed}}
} {/.*fts5: corrupt.*/}
#-------------------------------------------------------------------------
reset_db
@@ -878,7 +878,7 @@ do_execsql_test 5.1 {
}
do_catchsql_test 5.4 {
UPDATE t1 SET content=randomblob(500);
} {1 {database disk image is malformed}}
} {/.*fts5: corrupt.*/}
#-------------------------------------------------------------------------
reset_db
+1 -1
View File
@@ -123,6 +123,6 @@ do_execsql_test 2.2 {
do_catchsql_test 2.3 {
DELETE FROM t1 WHERE rowid = 1
} {1 {database disk image is malformed}}
} {/.*fts5: corrupt.*/}
finish_test
+1 -1
View File
@@ -32,7 +32,7 @@ sqlite3 db test.db
do_catchsql_test 1.2 {
SELECT * FROM t1
} {1 {database disk image is malformed}}
} {1 {fts5: corrupt structure record for table "t1"}}
do_catchsql_test 1.3 {
DROP TABLE t1
} {0 {}}
+20
View File
@@ -325,5 +325,25 @@ ifcapable foreignkey {
}
}
#-------------------------------------------------------------------------
reset_db
do_execsql_test 13.0 {
CREATE VIRTUAL TABLE t1 USING fts5(a, b);
INSERT INTO t1 VALUES('abc def', X'123456');
}
faultsim_save_and_close
do_faultsim_test 13 -faults oom* -prep {
faultsim_restore_and_reopen
} -body {
execsql {
UPDATE t1 SET a='def abc'
}
} -test {
faultsim_test_result {0 {}}
}
finish_test
+5 -3
View File
@@ -528,9 +528,12 @@ do_execsql_test 16.0 {
BEGIN EXCLUSIVE;
}
sqlite3 db2 test.db
do_test 16.1 {
catchsql { SELECT * FROM t1 } db2
set rc [catch {
sqlite3 db2 test.db
db2 eval {SELECT * FROM t1}
} errmsg]
lappend rc $errmsg
} {1 {database is locked}}
do_execsql_test 16.2 {
@@ -542,4 +545,3 @@ do_test 16.3 {
} {0 {}}
finish_test
+1 -1
View File
@@ -46,7 +46,7 @@ do_execsql_test 1.5 {
do_catchsql_test 1.6 {
INSERT INTO f1(f1) VALUES('integrity-check');
} {1 {database disk image is malformed}}
} {/.*fts5: corrupt.*/}
do_execsql_test 1.7 {
INSERT INTO f1(f1) VALUES('rebuild');
+30
View File
@@ -28,4 +28,34 @@ do_execsql_test 1.1 {
INSERT INTO sss VALUES('まりや');
}
foreach {tn enc tok} {
1 utf-8 ascii
2 utf-16 ascii
3 utf-8 unicode61
4 utf-16 unicode61
} {
reset_db
do_execsql_test 1.$tn.0 "
PRAGMA encoding = '$enc';
CREATE VIRTUAL TABLE vt2 USING fts5(c0, c1, tokenize=$tok);
"
do_execsql_test 1.$tn.1 {
INSERT INTO vt2(c0, c1) VALUES ('bhal', x'17db');
}
do_execsql_test 1.$tn.2 {
UPDATE vt2 SET c0='bhal';
}
do_execsql_test 1.$tn.3 {
INSERT INTO vt2(vt2) VALUES('integrity-check')
}
do_execsql_test 1.$tn.4 {
SELECT quote(c1) FROM vt2
} {X'17DB'}
}
finish_test
+1 -1
View File
@@ -429,7 +429,7 @@ $(doc.index): $(JAVA_FILES.main) $(MAKEFILE)
.FORCE: doc
doc: $(doc.index)
javadoc: $(doc.index)
# Force rebild of docs
# Force rebuild of docs
redoc:
@rm -f $(doc.index)
@$(MAKE) doc
+4 -4
View File
@@ -133,7 +133,7 @@
** Which sqlite3.c we're using needs to be configurable to enable
** building against a custom copy, e.g. the SEE variant. We have to
** include sqlite3.c, as opposed to sqlite3.h, in order to get access
** to some interal details like SQLITE_MAX_... and friends. This
** to some internal details like SQLITE_MAX_... and friends. This
** increases the rebuild time considerably but we need this in order
** to access some internal functionality and keep the to-Java-exported
** values of SQLITE_MAX_... and SQLITE_LIMIT_... in sync with the C
@@ -5512,7 +5512,7 @@ static inline jobject new_java_fts5_api(JNIEnv * const env, fts5_api *sv){
** Returns a per-JNIEnv global ref to the Fts5ExtensionApi singleton
** instance, or NULL on OOM.
*/
static jobject s3jni_getFts5ExensionApi(JNIEnv * const env){
static jobject s3jni_getFts5ExtensionApi(JNIEnv * const env){
if( !SJG.fts5.jExt ){
S3JniGlobal_mutex_enter;
if( !SJG.fts5.jExt ){
@@ -5578,7 +5578,7 @@ JniDeclFtsApi(jobject,getInstanceForDb)(JniArgsEnvClass,jobject jDb){
JniDeclFtsXA(jobject,getInstance)(JniArgsEnvClass){
return s3jni_getFts5ExensionApi(env);
return s3jni_getFts5ExtensionApi(env);
}
JniDeclFtsXA(jint,xColumnCount)(JniArgsEnvObj,jobject jCtx){
@@ -5641,7 +5641,7 @@ static void s3jni_fts5_extension_function(Fts5ExtensionApi const *pApi,
S3JniDeclLocal_env;
assert(pAux);
jFXA = s3jni_getFts5ExensionApi(env);
jFXA = s3jni_getFts5ExtensionApi(env);
if( !jFXA ) goto error_oom;
jpFts = new_java_Fts5Context(env, pFts);
if( !jpFts ) goto error_oom;
+1 -1
View File
@@ -1342,7 +1342,7 @@ JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1data_1count
* Method: sqlite3_db_config
* Signature: (Lorg/sqlite/jni/capi/sqlite3;IILorg/sqlite/jni/capi/OutputPointer/Int32;)I
*/
JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1db_1config__Lorg_sqlite_jni_capi_sqlite3_2IILorg_sqlite_jni_capi_OutputPointer_Int32_2
JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1db_1config__Lorg_sqlite_jni_capi_sqlite3_2IILorg_sqlite_jni_capi_OutputPointer_00024Int32_2
(JNIEnv *, jclass, jobject, jint, jint, jobject);
/*
@@ -31,11 +31,11 @@ import java.lang.annotation.*;
never pass a null value to the callback for that parameter.</p>
<p>Passing a null, for this annotation's definition of null, for
any parameter marked with this annoation specifically invokes
any parameter marked with this annotation specifically invokes
undefined behavior (see below).</p>
<p>Passing 0 (i.e. C NULL) or a negative value for any long-type
parameter marked with this annoation specifically invokes undefined
parameter marked with this annotation specifically invokes undefined
behavior (see below). Such values are treated as C pointers in the
JNI layer.</p>
@@ -120,7 +120,7 @@ public abstract class AggregateFunction<T> implements SQLFunction {
argument, the context is set to the given initial value. On all other
calls, the 2nd argument is ignored.
@see SQLFunction.PerContextState#getAggregateState
@see AggregateFunction.PerContextState#getAggregateState
*/
protected final ValueHolder<T> getAggregateState(sqlite3_context cx, T initialValue){
return map.getAggregateState(cx, initialValue);
@@ -130,7 +130,7 @@ public abstract class AggregateFunction<T> implements SQLFunction {
To be called from the implementation's xFinal() method to fetch
the final state of the UDF and remove its mapping.
see SQLFunction.PerContextState#takeAggregateState
see AggregateFunction.PerContextState#takeAggregateState
*/
protected final T takeAggregateState(sqlite3_context cx){
return map.takeAggregateState(cx);
+9 -14
View File
@@ -12,14 +12,9 @@
** This file declares the main JNI bindings for the sqlite3 C API.
*/
package org.sqlite.jni.capi;
import java.nio.charset.StandardCharsets;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import org.sqlite.jni.annotation.*;
import java.util.Arrays;
import java.nio.charset.StandardCharsets;
import org.sqlite.jni.annotation.*;
/**
This class contains the entire C-style sqlite3 JNI API binding,
@@ -169,7 +164,7 @@ public final class CApi {
<p>Like the C API, it returns 0 if allocation fails or if
initialize is false and no prior aggregate context was allocated
for cx. If initialize is true then it returns 0 only on
allocation error. In all casses, 0 is considered the sentinel
allocation error. In all cases, 0 is considered the sentinel
"not a key" value.
*/
public static native long sqlite3_aggregate_context(sqlite3_context cx, boolean initialize);
@@ -563,7 +558,7 @@ public final class CApi {
sqlite3_blob_open(db.getNativePointer(), dbName, tableName, columnName,
iRow, flags, out);
return out.take();
};
}
private static native int sqlite3_blob_read(
@NotNull long ptrToBlob, @NotNull byte[] target, int srcOffset
@@ -1298,7 +1293,7 @@ public final class CApi {
final OutputPointer.sqlite3 out = new OutputPointer.sqlite3();
sqlite3_open(filename, out);
return out.take();
};
}
public static native int sqlite3_open_v2(
@Nullable String filename, @NotNull OutputPointer.sqlite3 ppDb,
@@ -1314,7 +1309,7 @@ public final class CApi {
final OutputPointer.sqlite3 out = new OutputPointer.sqlite3();
sqlite3_open_v2(filename, out, flags, zVfs);
return out.take();
};
}
/**
The sqlite3_prepare() family of functions require slightly
@@ -1410,7 +1405,7 @@ public final class CApi {
/**
Works like the canonical sqlite3_prepare_v2() but its "tail"
output paramter is returned as the index offset into the given
output parameter is returned as the index offset into the given
byte array at which SQL parsing stopped.
*/
public static int sqlite3_prepare_v2(
@@ -1462,7 +1457,7 @@ public final class CApi {
/**
Works like the canonical sqlite3_prepare_v2() but its "tail"
output paramter is returned as the index offset into the given
output parameter is returned as the index offset into the given
byte array at which SQL parsing stopped.
*/
public static int sqlite3_prepare_v3(
@@ -1542,7 +1537,7 @@ public final class CApi {
int rc = 0;
final OutputPointer.sqlite3_stmt outStmt = new OutputPointer.sqlite3_stmt();
while( 0==rc && pos<sqlChunk.length ){
sqlite3_stmt stmt = null;
sqlite3_stmt stmt;
if( pos>0 ){
sqlChunk = Arrays.copyOfRange(sqlChunk, pos,
sqlChunk.length);
@@ -13,7 +13,7 @@
*/
package org.sqlite.jni.capi;
/**
This marker interface exists soley for use as a documentation and
This marker interface exists solely for use as a documentation and
class-grouping tool. It should be applied to interfaces or
classes which have a call() method implementing some specific
callback interface on behalf of the C library.
@@ -34,7 +34,7 @@ package org.sqlite.jni.capi;
proxying for, minus the {@code sqlite3_} prefix, plus a {@code
Callback} suffix. e.g. {@code sqlite3_busy_handler()}'s callback is
named {@code BusyHandlerCallback}. Exceptions are made where that
would potentially be ambiguous, e.g. {@link ConfigSqllogCallback}
would potentially be ambiguous, e.g. {@link ConfigSqlLogCallback}
instead of {@code ConfigCallback} because the {@code
sqlite3_config()} interface may need to support more callback types
in the future.
@@ -20,7 +20,7 @@ package org.sqlite.jni.capi;
from the native JNI code is unduly quirky due to a lack of
autoboxing at that level.
<p>The usage is similar for all of thes types:
<p>The usage is similar for all of these types:
<pre>{@code
OutputPointer.sqlite3 out = new OutputPointer.sqlite3();
@@ -55,9 +55,9 @@ public final class OutputPointer {
/** Sets the current value to null. */
public void clear(){value = null;}
/** Returns the current value. */
public final org.sqlite.jni.capi.sqlite3 get(){return value;}
public org.sqlite.jni.capi.sqlite3 get(){return value;}
/** Equivalent to calling get() then clear(). */
public final org.sqlite.jni.capi.sqlite3 take(){
public org.sqlite.jni.capi.sqlite3 take(){
final org.sqlite.jni.capi.sqlite3 v = value;
value = null;
return v;
@@ -76,9 +76,9 @@ public final class OutputPointer {
/** Sets the current value to null. */
public void clear(){value = null;}
/** Returns the current value. */
public final org.sqlite.jni.capi.sqlite3_blob get(){return value;}
public org.sqlite.jni.capi.sqlite3_blob get(){return value;}
/** Equivalent to calling get() then clear(). */
public final org.sqlite.jni.capi.sqlite3_blob take(){
public org.sqlite.jni.capi.sqlite3_blob take(){
final org.sqlite.jni.capi.sqlite3_blob v = value;
value = null;
return v;
@@ -98,9 +98,9 @@ public final class OutputPointer {
/** Sets the current value to null. */
public void clear(){value = null;}
/** Returns the current value. */
public final org.sqlite.jni.capi.sqlite3_stmt get(){return value;}
public org.sqlite.jni.capi.sqlite3_stmt get(){return value;}
/** Equivalent to calling get() then clear(). */
public final org.sqlite.jni.capi.sqlite3_stmt take(){
public org.sqlite.jni.capi.sqlite3_stmt take(){
final org.sqlite.jni.capi.sqlite3_stmt v = value;
value = null;
return v;
@@ -120,9 +120,9 @@ public final class OutputPointer {
/** Sets the current value to null. */
public void clear(){value = null;}
/** Returns the current value. */
public final org.sqlite.jni.capi.sqlite3_value get(){return value;}
public org.sqlite.jni.capi.sqlite3_value get(){return value;}
/** Equivalent to calling get() then clear(). */
public final org.sqlite.jni.capi.sqlite3_value take(){
public org.sqlite.jni.capi.sqlite3_value take(){
final org.sqlite.jni.capi.sqlite3_value v = value;
value = null;
return v;
@@ -144,9 +144,9 @@ public final class OutputPointer {
/** Initializes with the value v. */
public Bool(boolean v){value = v;}
/** Returns the current value. */
public final boolean get(){return value;}
public boolean get(){return value;}
/** Sets the current value to v. */
public final void set(boolean v){value = v;}
public void set(boolean v){value = v;}
}
/**
@@ -164,9 +164,9 @@ public final class OutputPointer {
/** Initializes with the value v. */
public Int32(int v){value = v;}
/** Returns the current value. */
public final int get(){return value;}
public int get(){return value;}
/** Sets the current value to v. */
public final void set(int v){value = v;}
public void set(int v){value = v;}
}
/**
@@ -184,9 +184,9 @@ public final class OutputPointer {
/** Initializes with the value v. */
public Int64(long v){value = v;}
/** Returns the current value. */
public final long get(){return value;}
public long get(){return value;}
/** Sets the current value. */
public final void set(long v){value = v;}
public void set(long v){value = v;}
}
/**
@@ -204,9 +204,9 @@ public final class OutputPointer {
/** Initializes with the value v. */
public String(java.lang.String v){value = v;}
/** Returns the current value. */
public final java.lang.String get(){return value;}
public java.lang.String get(){return value;}
/** Sets the current value. */
public final void set(java.lang.String v){value = v;}
public void set(java.lang.String v){value = v;}
}
/**
@@ -224,9 +224,9 @@ public final class OutputPointer {
/** Initializes with the value v. */
public ByteArray(byte[] v){value = v;}
/** Returns the current value. */
public final byte[] get(){return value;}
public byte[] get(){return value;}
/** Sets the current value. */
public final void set(byte[] v){value = v;}
public void set(byte[] v){value = v;}
}
/**
@@ -246,8 +246,8 @@ public final class OutputPointer {
/** Initializes with the value v. */
public ByteBuffer(java.nio.ByteBuffer v){value = v;}
/** Returns the current value. */
public final java.nio.ByteBuffer get(){return value;}
public java.nio.ByteBuffer get(){return value;}
/** Sets the current value. */
public final void set(java.nio.ByteBuffer v){value = v;}
public void set(java.nio.ByteBuffer v){value = v;}
}
}
@@ -65,7 +65,7 @@ public interface PrepareMultiCallback extends CallbackProxy {
A PrepareMultiCallback impl which steps entirely through a result set,
ignoring all non-error results.
*/
public static final class StepAll implements PrepareMultiCallback {
final class StepAll implements PrepareMultiCallback {
public StepAll(){}
/**
Calls sqlite3_step() on st until it returns something other than
+26 -27
View File
@@ -13,7 +13,6 @@
** SQLTester framework.
*/
package org.sqlite.jni.capi;
import java.util.List;
import java.util.ArrayList;
import java.util.Arrays;
import java.nio.charset.StandardCharsets;
@@ -31,7 +30,7 @@ enum ResultBufferMode {
ESCAPED,
//! Append output as-is
ASIS
};
}
/**
Modes to specify how to emit multi-row output from
@@ -42,7 +41,7 @@ enum ResultRowMode {
ONELINE,
//! Add a newline between each result row.
NEWLINE
};
}
/**
Base exception type for test-related failures.
@@ -278,7 +277,7 @@ public class SQLTester {
}
private StringBuilder clearBuffer(StringBuilder b){
b.setLength(0);;
b.setLength(0);
return b;
}
@@ -334,7 +333,7 @@ public class SQLTester {
return this;
}
sqlite3 setCurrentDb(int n) throws Exception{
sqlite3 setCurrentDb(int n){
affirmDbId(n);
iCurrentDb = n;
return this.aDb[n];
@@ -342,7 +341,7 @@ public class SQLTester {
sqlite3 getCurrentDb(){ return aDb[iCurrentDb]; }
sqlite3 getDbById(int id) throws Exception{
sqlite3 getDbById(int id){
return affirmDbId(id).aDb[id];
}
@@ -363,7 +362,7 @@ public class SQLTester {
}
}
sqlite3 openDb(String name, boolean createIfNeeded) throws DbException {
sqlite3 openDb(String name, boolean createIfNeeded) {
closeDb();
int flags = SQLITE_OPEN_READWRITE;
if( createIfNeeded ) flags |= SQLITE_OPEN_CREATE;
@@ -755,7 +754,7 @@ abstract class Command {
fall in the inclusive range (min,max) then this function throws. Use
a max value of -1 to mean unlimited.
*/
protected final void argcCheck(TestScript ts, String[] argv, int min, int max) throws Exception{
protected final void argcCheck(TestScript ts, String[] argv, int min, int max){
int argc = argv.length-1;
if(argc<min || (max>=0 && argc>max)){
if( min==max ){
@@ -771,16 +770,16 @@ abstract class Command {
/**
Equivalent to argcCheck(argv,argc,argc).
*/
protected final void argcCheck(TestScript ts, String[] argv, int argc) throws Exception{
protected final void argcCheck(TestScript ts, String[] argv, int argc){
argcCheck(ts, argv, argc, argc);
}
}
//! --close command
class CloseDbCommand extends Command {
public void process(SQLTester t, TestScript ts, String[] argv) throws Exception{
public void process(SQLTester t, TestScript ts, String[] argv){
argcCheck(ts,argv,0,1);
Integer id;
int id;
if(argv.length>1){
String arg = argv[1];
if("all".equals(arg)){
@@ -801,7 +800,7 @@ class CloseDbCommand extends Command {
class ColumnNamesCommand extends Command {
public void process(
SQLTester st, TestScript ts, String[] argv
) throws Exception{
){
argcCheck(ts,argv,1);
st.outputColumnNames( Integer.parseInt(argv[1])!=0 );
}
@@ -809,7 +808,7 @@ class ColumnNamesCommand extends Command {
//! --db command
class DbCommand extends Command {
public void process(SQLTester t, TestScript ts, String[] argv) throws Exception{
public void process(SQLTester t, TestScript ts, String[] argv){
argcCheck(ts,argv,1);
t.setCurrentDb( Integer.parseInt(argv[1]) );
}
@@ -821,7 +820,7 @@ class GlobCommand extends Command {
public GlobCommand(){}
protected GlobCommand(boolean negate){ this.negate = negate; }
public void process(SQLTester t, TestScript ts, String[] argv) throws Exception{
public void process(SQLTester t, TestScript ts, String[] argv){
argcCheck(ts,argv,1,-1);
t.incrementTestCounter();
final String sql = t.takeInputBuffer();
@@ -851,7 +850,7 @@ class JsonBlockCommand extends TableResultCommand {
//! --new command
class NewDbCommand extends OpenDbCommand {
public NewDbCommand(){ super(true); }
public void process(SQLTester t, TestScript ts, String[] argv) throws Exception{
public void process(SQLTester t, TestScript ts, String[] argv){
if(argv.length>1){
Util.unlink(argv[1]);
}
@@ -867,7 +866,7 @@ class NoopCommand extends Command {
this.verbose = verbose;
}
public NoopCommand(){}
public void process(SQLTester t, TestScript ts, String[] argv) throws Exception{
public void process(SQLTester t, TestScript ts, String[] argv){
if( this.verbose ){
t.outln("Skipping unhandled command: "+argv[0]);
}
@@ -885,7 +884,7 @@ class NotGlobCommand extends GlobCommand {
class NullCommand extends Command {
public void process(
SQLTester st, TestScript ts, String[] argv
) throws Exception{
){
argcCheck(ts,argv,1);
st.setNullValue( argv[1] );
}
@@ -896,7 +895,7 @@ class OpenDbCommand extends Command {
private boolean createIfNeeded = false;
public OpenDbCommand(){}
protected OpenDbCommand(boolean c){createIfNeeded = c;}
public void process(SQLTester t, TestScript ts, String[] argv) throws Exception{
public void process(SQLTester t, TestScript ts, String[] argv){
argcCheck(ts,argv,1);
t.openDb(argv[1], createIfNeeded);
}
@@ -906,7 +905,7 @@ class OpenDbCommand extends Command {
class PrintCommand extends Command {
public void process(
SQLTester st, TestScript ts, String[] argv
) throws Exception{
){
st.out(ts.getOutputPrefix(),": ");
if( 1==argv.length ){
st.out( st.getInputText() );
@@ -921,7 +920,7 @@ class ResultCommand extends Command {
private final ResultBufferMode bufferMode;
protected ResultCommand(ResultBufferMode bm){ bufferMode = bm; }
public ResultCommand(){ this(ResultBufferMode.ESCAPED); }
public void process(SQLTester t, TestScript ts, String[] argv) throws Exception{
public void process(SQLTester t, TestScript ts, String[] argv){
argcCheck(ts,argv,0,-1);
t.incrementTestCounter();
final String sql = t.takeInputBuffer();
@@ -939,7 +938,7 @@ class ResultCommand extends Command {
//! --run command
class RunCommand extends Command {
public void process(SQLTester t, TestScript ts, String[] argv) throws Exception{
public void process(SQLTester t, TestScript ts, String[] argv){
argcCheck(ts,argv,0,1);
final sqlite3 db = (1==argv.length)
? t.getCurrentDb() : t.getDbById( Integer.parseInt(argv[1]) );
@@ -959,7 +958,7 @@ class TableResultCommand extends Command {
private final boolean jsonMode;
protected TableResultCommand(boolean jsonMode){ this.jsonMode = jsonMode; }
public TableResultCommand(){ this(false); }
public void process(SQLTester t, TestScript ts, String[] argv) throws Exception{
public void process(SQLTester t, TestScript ts, String[] argv){
argcCheck(ts,argv,0);
t.incrementTestCounter();
String body = ts.fetchCommandBody(t);
@@ -1002,7 +1001,7 @@ class TableResultCommand extends Command {
//! --testcase command
class TestCaseCommand extends Command {
public void process(SQLTester t, TestScript ts, String[] argv) throws Exception{
public void process(SQLTester t, TestScript ts, String[] argv){
argcCheck(ts,argv,1);
ts.setTestCaseName(argv[1]);
t.clearResultBuffer();
@@ -1012,7 +1011,7 @@ class TestCaseCommand extends Command {
//! --verbosity command
class VerbosityCommand extends Command {
public void process(SQLTester t, TestScript ts, String[] argv) throws Exception{
public void process(SQLTester t, TestScript ts, String[] argv){
argcCheck(ts,argv,1);
ts.setVerbosity( Integer.parseInt(argv[1]) );
}
@@ -1020,7 +1019,7 @@ class VerbosityCommand extends Command {
class CommandDispatcher {
private static java.util.Map<String,Command> commandMap =
private static final java.util.Map<String,Command> commandMap =
new java.util.HashMap<>();
/**
@@ -1244,7 +1243,7 @@ class TestScript {
}
cur.pos = i;
final String rv = cur.sb.toString();
if( i==cur.src.length && 0==rv.length() ){
if( i==cur.src.length && rv.isEmpty() ){
return null /* EOF */;
}
return rv;
@@ -1364,7 +1363,7 @@ class TestScript {
if( m.find() ){
throw new IncompatibleDirective(this, m.group(1)+": "+m.group(3));
}
if( line.indexOf("\n|")>=0 ){
if( line.contains("\n|") ){
throw new IncompatibleDirective(this, "newline-pipe combination.");
}
return;
@@ -18,11 +18,11 @@ package org.sqlite.jni.capi;
They are populated only via that interface.
*/
public final class TableColumnMetadata {
OutputPointer.Bool pNotNull = new OutputPointer.Bool();
OutputPointer.Bool pPrimaryKey = new OutputPointer.Bool();
OutputPointer.Bool pAutoinc = new OutputPointer.Bool();
OutputPointer.String pzCollSeq = new OutputPointer.String();
OutputPointer.String pzDataType = new OutputPointer.String();
final OutputPointer.Bool pNotNull = new OutputPointer.Bool();
final OutputPointer.Bool pPrimaryKey = new OutputPointer.Bool();
final OutputPointer.Bool pAutoinc = new OutputPointer.Bool();
final OutputPointer.String pzCollSeq = new OutputPointer.String();
final OutputPointer.String pzDataType = new OutputPointer.String();
public TableColumnMetadata(){
}
+10 -11
View File
@@ -19,7 +19,6 @@ import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
/**
An annotation for Tester1 tests which we do not want to run in
@@ -62,13 +61,13 @@ public class Tester1 implements Runnable {
//! List of test*() methods to run.
private static List<java.lang.reflect.Method> testMethods = null;
//! List of exceptions collected by run()
private static List<Exception> listErrors = new ArrayList<>();
private static final List<Exception> listErrors = new ArrayList<>();
private static final class Metrics {
//! Number of times createNewDb() (or equivalent) is invoked.
volatile int dbOpen = 0;
}
private Integer tId;
private final Integer tId;
Tester1(Integer id){
tId = id;
@@ -78,7 +77,7 @@ public class Tester1 implements Runnable {
public static synchronized void outln(){
if( !quietMode ){
System.out.println("");
System.out.println();
}
}
@@ -523,7 +522,7 @@ public class Tester1 implements Runnable {
}
sqlite3_finalize(stmt);
affirm(3 == n);
affirm("w😃rldhell🤩!🤩".equals(sbuf.toString()));
affirm("w😃rldhell🤩!🤩".contentEquals(sbuf));
try( sqlite3_stmt stmt2 = prepare(db, "SELECT ?, ?") ){
rc = sqlite3_bind_text(stmt2, 1, "");
@@ -668,7 +667,7 @@ public class Tester1 implements Runnable {
execSql(db, "CREATE TABLE t(a); INSERT INTO t(a) VALUES('a'),('b'),('c')");
final ValueHolder<Integer> xDestroyCalled = new ValueHolder<>(0);
final CollationCallback myCollation = new CollationCallback() {
private String myState =
private final String myState =
"this is local state. There is much like it, but this is mine.";
@Override
// Reverse-sorts its inputs...
@@ -847,7 +846,7 @@ public class Tester1 implements Runnable {
SQLFunction funcAgg = new AggregateFunction<Integer>(){
@Override public void xStep(sqlite3_context cx, sqlite3_value[] args){
/** Throwing from here should emit loud noise on stdout or stderr
but the exception is supressed because we have no way to inform
but the exception is suppressed because we have no way to inform
sqlite about it from these callbacks. */
//throw new RuntimeException("Throwing from an xStep");
}
@@ -1850,7 +1849,7 @@ public class Tester1 implements Runnable {
"; insert into t(a) values(1),(2),(3);",
"select a from t;"
};
final List<sqlite3_stmt> liStmt = new ArrayList<sqlite3_stmt>();
final List<sqlite3_stmt> liStmt = new ArrayList<>();
final PrepareMultiCallback proxy = new PrepareMultiCallback.StepAll();
final ValueHolder<String> toss = new ValueHolder<>(null);
PrepareMultiCallback m = new PrepareMultiCallback() {
@@ -1984,9 +1983,9 @@ public class Tester1 implements Runnable {
-v: emit some developer-mode info at the end.
*/
public static void main(String[] args) throws Exception {
Integer nThread = 1;
int nThread = 1;
boolean doSomethingForDev = false;
Integer nRepeat = 1;
int nRepeat = 1;
boolean forceFail = false;
boolean sqlLog = false;
boolean configLog = false;
@@ -2048,7 +2047,7 @@ public class Tester1 implements Runnable {
final ConfigLogCallback log = new ConfigLogCallback() {
@Override public void call(int code, String msg){
outln("ConfigLogCallback: ",ResultCode.getEntryForInt(code),": ", msg);
};
}
};
int rc = sqlite3_config( log );
affirm( 0==rc );
@@ -33,5 +33,5 @@ public interface XDestroyCallback {
each individual reference, leading to memory corruption or a
crash via duplicate free().
*/
public void xDestroy();
void xDestroy();
}
@@ -12,7 +12,6 @@
** This file is part of the JNI bindings for the sqlite3 C API.
*/
package org.sqlite.jni.fts5;
import java.nio.charset.StandardCharsets;
import org.sqlite.jni.capi.*;
import org.sqlite.jni.annotation.*;
@@ -24,7 +23,7 @@ public final class Fts5ExtensionApi extends NativePointerHolder<Fts5ExtensionApi
private final int iVersion = 2;
/* Callback type for used by xQueryPhrase(). */
public static interface XQueryPhraseCallback {
public interface XQueryPhraseCallback {
int call(Fts5ExtensionApi fapi, Fts5Context cx);
}
+47 -48
View File
@@ -12,12 +12,11 @@
** This file contains a set of tests for the sqlite3 JNI bindings.
*/
package org.sqlite.jni.fts5;
import java.util.*;
import static org.sqlite.jni.capi.CApi.*;
import static org.sqlite.jni.capi.Tester1.*;
import org.sqlite.jni.capi.*;
import org.sqlite.jni.fts5.*;
import java.util.*;
import java.nio.charset.StandardCharsets;
public class TesterFts5 {
@@ -88,7 +87,7 @@ public class TesterFts5 {
** thrown.
*/
private static String[] sqlite3_exec(sqlite3 db, String sql) {
List<String> aOut = new ArrayList<String>();
List<String> aOut = new ArrayList<>();
/* Iterate through the list of SQL statements. For each, step through
** it and add any results to the aOut[] array. */
@@ -137,14 +136,14 @@ public class TesterFts5 {
** fts5_columncount()
*/
private static void create_test_functions(sqlite3 db){
/*
/*
** A user-defined-function fts5_rowid() that uses xRowid()
*/
fts5_extension_function fts5_rowid = new fts5_extension_function(){
@Override public void call(
Fts5ExtensionApi ext,
Fts5ExtensionApi ext,
Fts5Context fCx,
sqlite3_context pCx,
sqlite3_context pCx,
sqlite3_value argv[]
){
long rowid = ext.xRowid(fCx);
@@ -153,14 +152,14 @@ public class TesterFts5 {
public void xDestroy(){ }
};
/*
** fts5_columncount() - xColumnCount()
/*
** fts5_columncount() - xColumnCount()
*/
fts5_extension_function fts5_columncount = new fts5_extension_function(){
@Override public void call(
Fts5ExtensionApi ext,
Fts5ExtensionApi ext,
Fts5Context fCx,
sqlite3_context pCx,
sqlite3_context pCx,
sqlite3_value argv[]
){
int nCol = ext.xColumnCount(fCx);
@@ -169,14 +168,14 @@ public class TesterFts5 {
public void xDestroy(){ }
};
/*
** fts5_columnsize() - xColumnSize()
/*
** fts5_columnsize() - xColumnSize()
*/
fts5_extension_function fts5_columnsize = new fts5_extension_function(){
@Override public void call(
Fts5ExtensionApi ext,
Fts5ExtensionApi ext,
Fts5Context fCx,
sqlite3_context pCx,
sqlite3_context pCx,
sqlite3_value argv[]
){
if( argv.length!=1 ){
@@ -194,14 +193,14 @@ public class TesterFts5 {
public void xDestroy(){ }
};
/*
** fts5_columntext() - xColumnText()
/*
** fts5_columntext() - xColumnText()
*/
fts5_extension_function fts5_columntext = new fts5_extension_function(){
@Override public void call(
Fts5ExtensionApi ext,
Fts5ExtensionApi ext,
Fts5Context fCx,
sqlite3_context pCx,
sqlite3_context pCx,
sqlite3_value argv[]
){
if( argv.length!=1 ){
@@ -219,14 +218,14 @@ public class TesterFts5 {
public void xDestroy(){ }
};
/*
** fts5_columntotalsize() - xColumnTotalSize()
/*
** fts5_columntotalsize() - xColumnTotalSize()
*/
fts5_extension_function fts5_columntsize = new fts5_extension_function(){
@Override public void call(
Fts5ExtensionApi ext,
Fts5ExtensionApi ext,
Fts5Context fCx,
sqlite3_context pCx,
sqlite3_context pCx,
sqlite3_value argv[]
){
if( argv.length!=1 ){
@@ -251,9 +250,9 @@ public class TesterFts5 {
*/
class fts5_aux implements fts5_extension_function {
@Override public void call(
Fts5ExtensionApi ext,
Fts5ExtensionApi ext,
Fts5Context fCx,
sqlite3_context pCx,
sqlite3_context pCx,
sqlite3_value argv[]
){
if( argv.length>1 ){
@@ -268,13 +267,13 @@ public class TesterFts5 {
if( argv.length==1 ){
String val = sqlite3_value_text16(argv[0]);
if( !val.equals("") ){
if( !val.isEmpty() ){
ext.xSetAuxdata(fCx, val);
}
}
}
public void xDestroy(){ }
};
}
/*
** fts5_inst(<fts>);
@@ -286,9 +285,9 @@ public class TesterFts5 {
*/
fts5_extension_function fts5_inst = new fts5_extension_function(){
@Override public void call(
Fts5ExtensionApi ext,
Fts5ExtensionApi ext,
Fts5Context fCx,
sqlite3_context pCx,
sqlite3_context pCx,
sqlite3_value argv[]
){
if( argv.length!=0 ){
@@ -299,7 +298,7 @@ public class TesterFts5 {
OutputPointer.Int32 piPhrase = new OutputPointer.Int32();
OutputPointer.Int32 piCol = new OutputPointer.Int32();
OutputPointer.Int32 piOff = new OutputPointer.Int32();
String ret = new String();
String ret = "";
int rc = ext.xInstCount(fCx, pnInst);
int nInst = pnInst.get();
@@ -327,9 +326,9 @@ public class TesterFts5 {
*/
fts5_extension_function fts5_pinst = new fts5_extension_function(){
@Override public void call(
Fts5ExtensionApi ext,
Fts5ExtensionApi ext,
Fts5Context fCx,
sqlite3_context pCx,
sqlite3_context pCx,
sqlite3_value argv[]
){
if( argv.length!=0 ){
@@ -338,7 +337,7 @@ public class TesterFts5 {
OutputPointer.Int32 piCol = new OutputPointer.Int32();
OutputPointer.Int32 piOff = new OutputPointer.Int32();
String ret = new String();
String ret = "";
int rc = SQLITE_OK;
int nPhrase = ext.xPhraseCount(fCx);
@@ -350,7 +349,7 @@ public class TesterFts5 {
rc==SQLITE_OK && piCol.get()>=0;
ext.xPhraseNext(fCx, pIter, piCol, piOff)
){
if( !ret.equals("") ) ret += " ";
if( !ret.isEmpty() ) ret += " ";
ret += "{"+ii+" "+piCol.get()+" "+piOff.get()+"}";
}
}
@@ -374,9 +373,9 @@ public class TesterFts5 {
*/
fts5_extension_function fts5_pcolinst = new fts5_extension_function(){
@Override public void call(
Fts5ExtensionApi ext,
Fts5ExtensionApi ext,
Fts5Context fCx,
sqlite3_context pCx,
sqlite3_context pCx,
sqlite3_value argv[]
){
if( argv.length!=0 ){
@@ -384,7 +383,7 @@ public class TesterFts5 {
}
OutputPointer.Int32 piCol = new OutputPointer.Int32();
String ret = new String();
String ret = "";
int rc = SQLITE_OK;
int nPhrase = ext.xPhraseCount(fCx);
@@ -396,7 +395,7 @@ public class TesterFts5 {
rc==SQLITE_OK && piCol.get()>=0;
ext.xPhraseNextColumn(fCx, pIter, piCol)
){
if( !ret.equals("") ) ret += " ";
if( !ret.isEmpty() ) ret += " ";
ret += "{"+ii+" "+piCol.get()+"}";
}
}
@@ -415,9 +414,9 @@ public class TesterFts5 {
*/
fts5_extension_function fts5_rowcount = new fts5_extension_function(){
@Override public void call(
Fts5ExtensionApi ext,
Fts5ExtensionApi ext,
Fts5Context fCx,
sqlite3_context pCx,
sqlite3_context pCx,
sqlite3_value argv[]
){
if( argv.length!=0 ){
@@ -440,9 +439,9 @@ public class TesterFts5 {
*/
fts5_extension_function fts5_phrasesize = new fts5_extension_function(){
@Override public void call(
Fts5ExtensionApi ext,
Fts5ExtensionApi ext,
Fts5Context fCx,
sqlite3_context pCx,
sqlite3_context pCx,
sqlite3_value argv[]
){
if( argv.length!=1 ){
@@ -464,9 +463,9 @@ public class TesterFts5 {
*/
fts5_extension_function fts5_phrasehits = new fts5_extension_function(){
@Override public void call(
Fts5ExtensionApi ext,
Fts5ExtensionApi ext,
Fts5Context fCx,
sqlite3_context pCx,
sqlite3_context pCx,
sqlite3_value argv[]
){
if( argv.length!=1 ){
@@ -503,9 +502,9 @@ public class TesterFts5 {
*/
fts5_extension_function fts5_tokenize = new fts5_extension_function(){
@Override public void call(
Fts5ExtensionApi ext,
Fts5ExtensionApi ext,
Fts5Context fCx,
sqlite3_context pCx,
sqlite3_context pCx,
sqlite3_value argv[]
){
if( argv.length!=1 ){
@@ -515,7 +514,7 @@ public class TesterFts5 {
int rc = SQLITE_OK;
class MyCallback implements XTokenizeCallback {
private List<String> myList = new ArrayList<String>();
private List<String> myList = new ArrayList<>();
public String getval() {
return String.join("+", myList);
@@ -524,7 +523,7 @@ public class TesterFts5 {
@Override
public int call(int tFlags, byte[] txt, int iStart, int iEnd){
try {
String str = new String(txt, "UTF-8");
String str = new String(txt, StandardCharsets.UTF_8);
myList.add(str);
} catch (Exception e) {
}
@@ -39,7 +39,11 @@ public interface fts5_extension_function {
*/
void xDestroy();
public static abstract class Abstract implements fts5_extension_function {
/**
A base implementation of fts5_extension_function() which has a
no-op xDestroy() method.
*/
abstract class Abstract implements fts5_extension_function {
@Override public abstract void call(Fts5ExtensionApi ext, Fts5Context fCx,
sqlite3_context pCx, sqlite3_value argv[]);
@Override public void xDestroy(){}
@@ -4,7 +4,7 @@
The purpose of the Test Script Interpreter is to read and interpret
script files that contain SQL commands and desired results. The
interpreter will check results and report any discrepencies found.
interpreter will check results and report any discrepancies found.
The test script files are ASCII text files. The filename always ends with
".test". Each script is evaluated independently; context does not carry
@@ -160,7 +160,7 @@ the result buffer. This distinction does not matter for the --result
command itself, but it is important for related commands like --glob
and --notglob. Sometimes test cases will contains a bunch of SQL
followed by multiple --glob and/or --notglob statements. All of the
globs should be evaluated agains the result buffer, but the SQL should
globs should be evaluated against the result buffer, but the SQL should
only be run once. This is accomplished by resetting the input buffer
but not the result buffer.
@@ -12,10 +12,6 @@
** This file is part of the wrapper1 interface for sqlite3.
*/
package org.sqlite.jni.wrapper1;
import org.sqlite.jni.capi.CApi;
import org.sqlite.jni.annotation.*;
import org.sqlite.jni.capi.sqlite3_context;
import org.sqlite.jni.capi.sqlite3_value;
/**
The SqlFunction type for scalar SQL functions.
@@ -22,13 +22,13 @@ import org.sqlite.jni.capi.sqlite3_value;
*/
public interface SqlFunction {
public static final int DETERMINISTIC = CApi.SQLITE_DETERMINISTIC;
public static final int INNOCUOUS = CApi.SQLITE_INNOCUOUS;
public static final int DIRECTONLY = CApi.SQLITE_DIRECTONLY;
public static final int SUBTYPE = CApi.SQLITE_SUBTYPE;
public static final int RESULT_SUBTYPE = CApi.SQLITE_RESULT_SUBTYPE;
public static final int UTF8 = CApi.SQLITE_UTF8;
public static final int UTF16 = CApi.SQLITE_UTF16;
int DETERMINISTIC = CApi.SQLITE_DETERMINISTIC;
int INNOCUOUS = CApi.SQLITE_INNOCUOUS;
int DIRECTONLY = CApi.SQLITE_DIRECTONLY;
int SUBTYPE = CApi.SQLITE_SUBTYPE;
int RESULT_SUBTYPE = CApi.SQLITE_RESULT_SUBTYPE;
int UTF8 = CApi.SQLITE_UTF8;
int UTF16 = CApi.SQLITE_UTF16;
/**
The Arguments type is an abstraction on top of the lower-level
@@ -36,7 +36,7 @@ public interface SqlFunction {
of the lower-level interface, insofar as possible without "leaking"
those types into this API.
*/
public final static class Arguments implements Iterable<SqlFunction.Arguments.Arg>{
final class Arguments implements Iterable<SqlFunction.Arguments.Arg>{
private final sqlite3_context cx;
private final sqlite3_value args[];
public final int length;
@@ -144,7 +144,7 @@ public interface SqlFunction {
range.
*/
public void setAuxData(int argNdx, Object o){
/* From the API docs: https://www.sqlite.org/c3ref/get_auxdata.html
/* From the API docs: https://sqlite.org/c3ref/get_auxdata.html
The value of the N parameter to these interfaces should be
non-negative. Future enhancements may make use of negative N
@@ -207,7 +207,7 @@ public interface SqlFunction {
Internal-use adapter for wrapping this package's ScalarFunction
for use with the org.sqlite.jni.capi.ScalarFunction interface.
*/
static final class ScalarAdapter extends org.sqlite.jni.capi.ScalarFunction {
final class ScalarAdapter extends org.sqlite.jni.capi.ScalarFunction {
private final ScalarFunction impl;
ScalarAdapter(ScalarFunction impl){
this.impl = impl;
@@ -234,8 +234,8 @@ public interface SqlFunction {
Internal-use adapter for wrapping this package's AggregateFunction
for use with the org.sqlite.jni.capi.AggregateFunction interface.
*/
static /*cannot be final without duplicating the whole body in WindowAdapter*/
class AggregateAdapter extends org.sqlite.jni.capi.AggregateFunction {
/*cannot be final without duplicating the whole body in WindowAdapter*/
private final AggregateFunction impl;
AggregateAdapter(AggregateFunction impl){
this.impl = impl;
@@ -277,7 +277,7 @@ public interface SqlFunction {
Internal-use adapter for wrapping this package's WindowFunction
for use with the org.sqlite.jni.capi.WindowFunction interface.
*/
static final class WindowAdapter extends AggregateAdapter {
final class WindowAdapter extends AggregateAdapter {
private final WindowFunction impl;
WindowAdapter(WindowFunction impl){
super(impl);
+24 -21
View File
@@ -19,7 +19,6 @@ import org.sqlite.jni.capi.sqlite3_stmt;
import org.sqlite.jni.capi.sqlite3_backup;
import org.sqlite.jni.capi.sqlite3_blob;
import org.sqlite.jni.capi.OutputPointer;
import java.nio.ByteBuffer;
/**
This class represents a database connection, analog to the C-side
@@ -388,10 +387,10 @@ public final class Sqlite implements AutoCloseable {
return CApi.sqlite3_compileoption_used(optName);
}
private static boolean hasNormalizeSql =
private static final boolean hasNormalizeSql =
compileOptionUsed("ENABLE_NORMALIZE");
private static boolean hasSqlLog =
private static final boolean hasSqlLog =
compileOptionUsed("ENABLE_SQLLOG");
/**
@@ -450,7 +449,7 @@ public final class Sqlite implements AutoCloseable {
long current;
/** The peak value for the requested status() or libStatus() metric. */
long peak;
};
}
/**
As per sqlite3_status64(), but returns its current and high-water
@@ -696,7 +695,7 @@ public final class Sqlite implements AutoCloseable {
final org.sqlite.jni.capi.OutputPointer.Int32 oTail =
new org.sqlite.jni.capi.OutputPointer.Int32();
while( pos < sqlChunk.length ){
sqlite3_stmt stmt = null;
sqlite3_stmt stmt;
if( pos>0 ){
sqlChunk = java.util.Arrays.copyOfRange(sqlChunk, pos, sqlChunk.length);
}
@@ -988,15 +987,15 @@ public final class Sqlite implements AutoCloseable {
}
};
checkRc( CApi.sqlite3_trace_v2(thisDb(), traceMask, tc) );
};
}
/**
Corresponds to the sqlite3_stmt class. Use Sqlite.prepare() to
create new instances.
*/
public static final class Stmt implements AutoCloseable {
private Sqlite _db = null;
private sqlite3_stmt stmt = null;
private Sqlite _db;
private sqlite3_stmt stmt;
/** Only called by the prepare() factory functions. */
Stmt(Sqlite db, sqlite3_stmt stmt){
@@ -1379,9 +1378,9 @@ public final class Sqlite implements AutoCloseable {
Sqlite.initBackup() to create new instances.
*/
public static final class Backup implements AutoCloseable {
private sqlite3_backup b = null;
private Sqlite dbTo = null;
private Sqlite dbFrom = null;
private sqlite3_backup b;
private Sqlite dbTo;
private Sqlite dbFrom;
Backup(Sqlite dbDest, String schemaDest,Sqlite dbSrc, String schemaSrc){
this.dbTo = dbDest;
@@ -1491,7 +1490,7 @@ public final class Sqlite implements AutoCloseable {
Warning: the SQLite core has no mechanism for reporting errors
from custom collations and its workflow does not accommodate
propagation of exceptions from callbacks. Any exceptions thrown
from collations will be silently supressed and sorting results
from collations will be silently suppressed and sorting results
will be unpredictable.
*/
int call(byte[] lhs, byte[] rhs);
@@ -1506,7 +1505,7 @@ public final class Sqlite implements AutoCloseable {
*/
public void createCollation(String name, int encoding, Collation c){
thisDb();
if( null==name || 0==name.length()){
if( null==name || name.isEmpty()){
throw new IllegalArgumentException("Collation name may not be null or empty.");
}
if( null==c ){
@@ -1599,11 +1598,12 @@ public final class Sqlite implements AutoCloseable {
public void setBusyHandler( BusyHandler b ){
org.sqlite.jni.capi.BusyHandlerCallback bhc = null;
if( null!=b ){
bhc = new org.sqlite.jni.capi.BusyHandlerCallback(){
/*bhc = new org.sqlite.jni.capi.BusyHandlerCallback(){
@Override public int call(int n){
return b.call(n);
}
};
};*/
bhc = b::call;
}
checkRc( CApi.sqlite3_busy_handler(thisDb(), bhc) );
}
@@ -1781,9 +1781,10 @@ public final class Sqlite implements AutoCloseable {
public void setProgressHandler( int n, ProgressHandler p ){
org.sqlite.jni.capi.ProgressHandlerCallback phc = null;
if( null!=p ){
phc = new org.sqlite.jni.capi.ProgressHandlerCallback(){
/*phc = new org.sqlite.jni.capi.ProgressHandlerCallback(){
@Override public int call(){ return p.call(); }
};
};*/
phc = p::call;
}
CApi.sqlite3_progress_handler( thisDb(), n, phc );
}
@@ -1808,11 +1809,12 @@ public final class Sqlite implements AutoCloseable {
public void setAuthorizer( Authorizer a ) {
org.sqlite.jni.capi.AuthorizerCallback ac = null;
if( null!=a ){
ac = new org.sqlite.jni.capi.AuthorizerCallback(){
/*ac = new org.sqlite.jni.capi.AuthorizerCallback(){
@Override public int call(int opId, String s1, String s2, String s3, String s4){
return a.call(opId, s1, s2, s3, s4);
}
};
};*/
ac = a::call;
}
checkRc( CApi.sqlite3_set_authorizer( thisDb(), ac ) );
}
@@ -1932,11 +1934,12 @@ public final class Sqlite implements AutoCloseable {
final org.sqlite.jni.capi.ConfigLogCallback l =
null==log
? null
: new org.sqlite.jni.capi.ConfigLogCallback() {
/*: new org.sqlite.jni.capi.ConfigLogCallback() {
@Override public void call(int errCode, String msg){
log.call(errCode, msg);
}
};
};*/
: log::call;
checkRcStatic(CApi.sqlite3_config(l));
}
@@ -13,7 +13,6 @@
*/
package org.sqlite.jni.wrapper1;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
@@ -53,14 +52,14 @@ public class Tester2 implements Runnable {
//! List of test*() methods to run.
private static List<java.lang.reflect.Method> testMethods = null;
//! List of exceptions collected by run()
private static List<Exception> listErrors = new ArrayList<>();
private static final List<Exception> listErrors = new ArrayList<>();
private static final class Metrics {
//! Number of times createNewDb() (or equivalent) is invoked.
volatile int dbOpen = 0;
}
//! Instance ID.
private Integer tId;
private final Integer tId;
Tester2(Integer id){
tId = id;
@@ -70,7 +69,7 @@ public class Tester2 implements Runnable {
public static synchronized void outln(){
if( !quietMode ){
System.out.println("");
System.out.println();
}
}
@@ -547,7 +546,7 @@ public class Tester2 implements Runnable {
err = e;
}
affirm( err!=null );
affirm( err.getMessage().indexOf(toss.value)>=0 );
affirm( err.getMessage().contains(toss.value) );
toss.value = null;
val.value = 0;
@@ -616,7 +615,7 @@ public class Tester2 implements Runnable {
final Sqlite db = openDb();
execSql(db, "CREATE TABLE t(a); INSERT INTO t(a) VALUES('a'),('b'),('c')");
final Sqlite.Collation myCollation = new Sqlite.Collation() {
private String myState =
private final String myState =
"this is local state. There is much like it, but this is mine.";
@Override
// Reverse-sorts its inputs...
@@ -1038,9 +1037,9 @@ public class Tester2 implements Runnable {
-v: emit some developer-mode info at the end.
*/
public static void main(String[] args) throws Exception {
Integer nThread = 1;
int nThread = 1;
int nRepeat = 1;
boolean doSomethingForDev = false;
Integer nRepeat = 1;
boolean forceFail = false;
boolean sqlLog = false;
boolean configLog = false;
@@ -1097,7 +1096,7 @@ public class Tester2 implements Runnable {
Sqlite.libConfigLog( new Sqlite.ConfigLog() {
@Override public void call(int code, String msg){
outln("ConfigLog: ",Sqlite.errstr(code),": ", msg);
};
}
}
);
}
+6 -6
View File
@@ -1,7 +1,7 @@
## Miscellaneous Extensions
This folder contains a collection of smaller loadable extensions.
See <https://www.sqlite.org/loadext.html> for instructions on how
See <https://sqlite.org/loadext.html> for instructions on how
to compile and use loadable extensions.
Each extension in this folder is implemented in a single file of C code.
@@ -10,9 +10,9 @@ header comments for details about each extension. Additional notes are
as follows:
* **carray.c** &mdash; This module implements the
[carray](https://www.sqlite.org/carray.html) table-valued function.
[carray](https://sqlite.org/carray.html) table-valued function.
It is a good example of how to go about implementing a custom
[table-valued function](https://www.sqlite.org/vtab.html#tabfunc2).
[table-valued function](https://sqlite.org/vtab.html#tabfunc2).
* **csv.c** &mdash; A [virtual table](https://sqlite.org/vtab.html)
for reading
@@ -21,7 +21,7 @@ as follows:
* **dbdump.c** &mdash; This is not actually a loadable extension, but
rather a library that implements an approximate equivalent to the
".dump" command of the
[command-line shell](https://www.sqlite.org/cli.html).
[command-line shell](https://sqlite.org/cli.html).
* **json1.c** &mdash; Various SQL functions and table-valued functions
for processing JSON. This extension is already built into the
@@ -29,7 +29,7 @@ as follows:
<https://sqlite.org/json1.html> for additional information.
* **memvfs.c** &mdash; This file implements a custom
[VFS](https://www.sqlite.org/vfs.html) that stores an entire database
[VFS](https://sqlite.org/vfs.html) that stores an entire database
file in a single block of RAM. It serves as a good example of how
to implement a simple custom VFS.
@@ -38,7 +38,7 @@ as follows:
new custom SQL functions for SQLite.
* **series.c** &mdash; This is an implementation of the
"generate_series" [virtual table](https://www.sqlite.org/vtab.html).
"generate_series" [virtual table](https://sqlite.org/vtab.html).
It can make a good template for new custom virtual table implementations.
* **shathree.c** &mdash; An implementation of the sha3() and
+1 -1
View File
@@ -137,7 +137,7 @@
** AND closure.idname='groupId'
** AND closure.parentname='parentId';
**
** See the documentation at http://www.sqlite.org/loadext.html for information
** See the documentation at http://sqlite.org/loadext.html for information
** on how to compile and use loadable extensions such as this one.
*/
#include "sqlite3ext.h"
+6 -1
View File
@@ -41,6 +41,11 @@ SQLITE_EXTENSION_INIT1
#ifndef SQLITE_OMIT_VIRTUALTABLE
#ifndef IsAlnum
#define IsAlnum(X) isalnum((unsigned char)X)
#endif
/* completion_vtab is a subclass of sqlite3_vtab which will
** serve as the underlying representation of a completion virtual table
*/
@@ -377,7 +382,7 @@ static int completionFilter(
}
if( pCur->zLine!=0 && pCur->zPrefix==0 ){
int i = pCur->nLine;
while( i>0 && (isalnum(pCur->zLine[i-1]) || pCur->zLine[i-1]=='_') ){
while( i>0 && (IsAlnum(pCur->zLine[i-1]) || pCur->zLine[i-1]=='_') ){
i--;
}
pCur->nPrefix = pCur->nLine - i;
+4 -1
View File
@@ -27,6 +27,9 @@ SQLITE_EXTENSION_INIT1
# define UNUSED_PARAMETER(X) (void)(X)
#endif
#ifndef IsSpace
#define IsSpace(X) isspace((unsigned char)X)
#endif
/* A decimal object */
typedef struct Decimal Decimal;
@@ -76,7 +79,7 @@ static Decimal *decimalNewFromText(const char *zIn, int n){
p->nFrac = 0;
p->a = sqlite3_malloc64( n+1 );
if( p->a==0 ) goto new_from_text_failed;
for(i=0; isspace(zIn[i]); i++){}
for(i=0; IsSpace(zIn[i]); i++){}
if( zIn[i]=='-' ){
p->sign = 1;
i++;
+144 -58
View File
@@ -67,6 +67,7 @@
** data: For a regular file, a blob containing the file data. For a
** symlink, a text value containing the text of the link. For a
** directory, NULL.
** level: Directory hierarchy level. Topmost is 1.
**
** If a non-NULL value is specified for the optional $dir parameter and
** $path is a relative path, then $path is interpreted relative to $dir.
@@ -92,20 +93,13 @@ SQLITE_EXTENSION_INIT1
# include <dirent.h>
# include <utime.h>
# include <sys/time.h>
# define STRUCT_STAT struct stat
#else
# include "windows.h"
# include <io.h>
# include "windirent.h"
# include <direct.h>
# include "test_windirent.h"
# define dirent DIRENT
# ifndef chmod
# define chmod _chmod
# endif
# ifndef stat
# define stat _stat
# endif
# define mkdir(path,mode) _mkdir(path)
# define lstat(path,buf) stat(path,buf)
# define STRUCT_STAT struct _stat
# define chmod(path,mode) fileio_chmod(path,mode)
# define mkdir(path,mode) fileio_mkdir(path)
#endif
#include <time.h>
#include <errno.h>
@@ -121,14 +115,50 @@ SQLITE_EXTENSION_INIT1
/*
** Structure of the fsdir() table-valued function
*/
/* 0 1 2 3 4 5 */
#define FSDIR_SCHEMA "(name,mode,mtime,data,path HIDDEN,dir HIDDEN)"
/* 0 1 2 3 4 5 6 */
#define FSDIR_SCHEMA "(name,mode,mtime,data,level,path HIDDEN,dir HIDDEN)"
#define FSDIR_COLUMN_NAME 0 /* Name of the file */
#define FSDIR_COLUMN_MODE 1 /* Access mode */
#define FSDIR_COLUMN_MTIME 2 /* Last modification time */
#define FSDIR_COLUMN_DATA 3 /* File content */
#define FSDIR_COLUMN_PATH 4 /* Path to top of search */
#define FSDIR_COLUMN_DIR 5 /* Path is relative to this directory */
#define FSDIR_COLUMN_LEVEL 4 /* Level. Topmost is 1 */
#define FSDIR_COLUMN_PATH 5 /* Path to top of search */
#define FSDIR_COLUMN_DIR 6 /* Path is relative to this directory */
/*
** UTF8 chmod() function for Windows
*/
#if defined(_WIN32) || defined(WIN32)
static int fileio_chmod(const char *zPath, int pmode){
sqlite3_int64 sz = strlen(zPath);
wchar_t *b1 = sqlite3_malloc64( (sz+1)*sizeof(b1[0]) );
int rc;
if( b1==0 ) return -1;
sz = MultiByteToWideChar(CP_UTF8, 0, zPath, sz, b1, sz);
b1[sz] = 0;
rc = _wchmod(b1, pmode);
sqlite3_free(b1);
return rc;
}
#endif
/*
** UTF8 mkdir() function for Windows
*/
#if defined(_WIN32) || defined(WIN32)
static int fileio_mkdir(const char *zPath){
sqlite3_int64 sz = strlen(zPath);
wchar_t *b1 = sqlite3_malloc64( (sz+1)*sizeof(b1[0]) );
int rc;
if( b1==0 ) return -1;
sz = MultiByteToWideChar(CP_UTF8, 0, zPath, sz, b1, sz);
b1[sz] = 0;
rc = _wmkdir(b1);
sqlite3_free(b1);
return rc;
}
#endif
/*
@@ -260,7 +290,7 @@ LPWSTR utf8_to_utf16(const char *z){
*/
static void statTimesToUtc(
const char *zPath,
struct stat *pStatBuf
STRUCT_STAT *pStatBuf
){
HANDLE hFindFile;
WIN32_FIND_DATAW fd;
@@ -288,10 +318,16 @@ static void statTimesToUtc(
*/
static int fileStat(
const char *zPath,
struct stat *pStatBuf
STRUCT_STAT *pStatBuf
){
#if defined(_WIN32)
int rc = stat(zPath, pStatBuf);
sqlite3_int64 sz = strlen(zPath);
wchar_t *b1 = sqlite3_malloc64( (sz+1)*sizeof(b1[0]) );
int rc;
if( b1==0 ) return 1;
sz = MultiByteToWideChar(CP_UTF8, 0, zPath, sz, b1, sz);
b1[sz] = 0;
rc = _wstat(b1, pStatBuf);
if( rc==0 ) statTimesToUtc(zPath, pStatBuf);
return rc;
#else
@@ -306,12 +342,10 @@ static int fileStat(
*/
static int fileLinkStat(
const char *zPath,
struct stat *pStatBuf
STRUCT_STAT *pStatBuf
){
#if defined(_WIN32)
int rc = lstat(zPath, pStatBuf);
if( rc==0 ) statTimesToUtc(zPath, pStatBuf);
return rc;
return fileStat(zPath, pStatBuf);
#else
return lstat(zPath, pStatBuf);
#endif
@@ -341,7 +375,7 @@ static int makeDirectory(
int i = 1;
while( rc==SQLITE_OK ){
struct stat sStat;
STRUCT_STAT sStat;
int rc2;
for(; zCopy[i]!='/' && i<nCopy; i++);
@@ -391,7 +425,7 @@ static int writeFile(
** be an error though - if there is already a directory at the same
** path and either the permissions already match or can be changed
** to do so using chmod(), it is not an error. */
struct stat sStat;
STRUCT_STAT sStat;
if( errno!=EEXIST
|| 0!=fileStat(zFile, &sStat)
|| !S_ISDIR(sStat.st_mode)
@@ -587,13 +621,14 @@ struct fsdir_cursor {
sqlite3_vtab_cursor base; /* Base class - must be first */
int nLvl; /* Number of entries in aLvl[] array */
int mxLvl; /* Maximum level */
int iLvl; /* Index of current entry */
FsdirLevel *aLvl; /* Hierarchy of directories being traversed */
const char *zBase;
int nBase;
struct stat sStat; /* Current lstat() results */
STRUCT_STAT sStat; /* Current lstat() results */
char *zPath; /* Path to current entry */
sqlite3_int64 iRowid; /* Current rowid */
};
@@ -705,7 +740,7 @@ static int fsdirNext(sqlite3_vtab_cursor *cur){
mode_t m = pCur->sStat.st_mode;
pCur->iRowid++;
if( S_ISDIR(m) ){
if( S_ISDIR(m) && pCur->iLvl+3<pCur->mxLvl ){
/* Descend into this directory */
int iNew = pCur->iLvl + 1;
FsdirLevel *pLvl;
@@ -813,7 +848,11 @@ static int fsdirColumn(
}else{
readFileContents(ctx, pCur->zPath);
}
break;
}
case FSDIR_COLUMN_LEVEL:
sqlite3_result_int(ctx, pCur->iLvl+2);
break;
case FSDIR_COLUMN_PATH:
default: {
/* The FSDIR_COLUMN_PATH and FSDIR_COLUMN_DIR are input parameters.
@@ -847,8 +886,11 @@ static int fsdirEof(sqlite3_vtab_cursor *cur){
/*
** xFilter callback.
**
** idxNum==1 PATH parameter only
** idxNum==2 Both PATH and DIR supplied
** idxNum bit Meaning
** 0x01 PATH=N
** 0x02 DIR=N
** 0x04 LEVEL<N
** 0x08 LEVEL<=N
*/
static int fsdirFilter(
sqlite3_vtab_cursor *cur,
@@ -857,6 +899,7 @@ static int fsdirFilter(
){
const char *zDir = 0;
fsdir_cursor *pCur = (fsdir_cursor*)cur;
int i;
(void)idxStr;
fsdirResetCursor(pCur);
@@ -865,14 +908,24 @@ static int fsdirFilter(
return SQLITE_ERROR;
}
assert( argc==idxNum && (argc==1 || argc==2) );
assert( (idxNum & 0x01)!=0 && argc>0 );
zDir = (const char*)sqlite3_value_text(argv[0]);
if( zDir==0 ){
fsdirSetErrmsg(pCur, "table function fsdir requires a non-NULL argument");
return SQLITE_ERROR;
}
if( argc==2 ){
pCur->zBase = (const char*)sqlite3_value_text(argv[1]);
i = 1;
if( (idxNum & 0x02)!=0 ){
assert( argc>i );
pCur->zBase = (const char*)sqlite3_value_text(argv[i++]);
}
if( (idxNum & 0x0c)!=0 ){
assert( argc>i );
pCur->mxLvl = sqlite3_value_int(argv[i++]);
if( idxNum & 0x08 ) pCur->mxLvl++;
if( pCur->mxLvl<=0 ) pCur->mxLvl = 1000000000;
}else{
pCur->mxLvl = 1000000000;
}
if( pCur->zBase ){
pCur->nBase = (int)strlen(pCur->zBase)+1;
@@ -901,10 +954,11 @@ static int fsdirFilter(
** In this implementation idxNum is used to represent the
** query plan. idxStr is unused.
**
** The query plan is represented by values of idxNum:
** The query plan is represented by bits in idxNum:
**
** (1) The path value is supplied by argv[0]
** (2) Path is in argv[0] and dir is in argv[1]
** 0x01 The path value is supplied by argv[0]
** 0x02 dir is in argv[1]
** 0x04 maxdepth is in argv[1] or [2]
*/
static int fsdirBestIndex(
sqlite3_vtab *tab,
@@ -913,6 +967,9 @@ static int fsdirBestIndex(
int i; /* Loop over constraints */
int idxPath = -1; /* Index in pIdxInfo->aConstraint of PATH= */
int idxDir = -1; /* Index in pIdxInfo->aConstraint of DIR= */
int idxLevel = -1; /* Index in pIdxInfo->aConstraint of LEVEL< or <= */
int idxLevelEQ = 0; /* 0x08 for LEVEL<= or LEVEL=. 0x04 for LEVEL< */
int omitLevel = 0; /* omit the LEVEL constraint */
int seenPath = 0; /* True if an unusable PATH= constraint is seen */
int seenDir = 0; /* True if an unusable DIR= constraint is seen */
const struct sqlite3_index_constraint *pConstraint;
@@ -920,25 +977,48 @@ static int fsdirBestIndex(
(void)tab;
pConstraint = pIdxInfo->aConstraint;
for(i=0; i<pIdxInfo->nConstraint; i++, pConstraint++){
if( pConstraint->op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue;
switch( pConstraint->iColumn ){
case FSDIR_COLUMN_PATH: {
if( pConstraint->usable ){
idxPath = i;
seenPath = 0;
}else if( idxPath<0 ){
seenPath = 1;
if( pConstraint->op==SQLITE_INDEX_CONSTRAINT_EQ ){
switch( pConstraint->iColumn ){
case FSDIR_COLUMN_PATH: {
if( pConstraint->usable ){
idxPath = i;
seenPath = 0;
}else if( idxPath<0 ){
seenPath = 1;
}
break;
}
case FSDIR_COLUMN_DIR: {
if( pConstraint->usable ){
idxDir = i;
seenDir = 0;
}else if( idxDir<0 ){
seenDir = 1;
}
break;
}
case FSDIR_COLUMN_LEVEL: {
if( pConstraint->usable && idxLevel<0 ){
idxLevel = i;
idxLevelEQ = 0x08;
omitLevel = 0;
}
break;
}
break;
}
case FSDIR_COLUMN_DIR: {
if( pConstraint->usable ){
idxDir = i;
seenDir = 0;
}else if( idxDir<0 ){
seenDir = 1;
}
break;
}else
if( pConstraint->iColumn==FSDIR_COLUMN_LEVEL
&& pConstraint->usable
&& idxLevel<0
){
if( pConstraint->op==SQLITE_INDEX_CONSTRAINT_LE ){
idxLevel = i;
idxLevelEQ = 0x08;
omitLevel = 1;
}else if( pConstraint->op==SQLITE_INDEX_CONSTRAINT_LT ){
idxLevel = i;
idxLevelEQ = 0x04;
omitLevel = 1;
}
}
}
@@ -955,14 +1035,20 @@ static int fsdirBestIndex(
}else{
pIdxInfo->aConstraintUsage[idxPath].omit = 1;
pIdxInfo->aConstraintUsage[idxPath].argvIndex = 1;
pIdxInfo->idxNum = 0x01;
pIdxInfo->estimatedCost = 1.0e9;
i = 2;
if( idxDir>=0 ){
pIdxInfo->aConstraintUsage[idxDir].omit = 1;
pIdxInfo->aConstraintUsage[idxDir].argvIndex = 2;
pIdxInfo->idxNum = 2;
pIdxInfo->estimatedCost = 10.0;
}else{
pIdxInfo->idxNum = 1;
pIdxInfo->estimatedCost = 100.0;
pIdxInfo->aConstraintUsage[idxDir].argvIndex = i++;
pIdxInfo->idxNum |= 0x02;
pIdxInfo->estimatedCost /= 1.0e4;
}
if( idxLevel>=0 ){
pIdxInfo->aConstraintUsage[idxLevel].omit = omitLevel;
pIdxInfo->aConstraintUsage[idxLevel].argvIndex = i++;
pIdxInfo->idxNum |= idxLevelEQ;
pIdxInfo->estimatedCost /= 1.0e4;
}
}
+1 -1
View File
@@ -22,7 +22,7 @@
** The delta format is the Fossil delta format, described in a comment
** on the delete_create() function implementation below, and also at
**
** https://www.fossil-scm.org/fossil/doc/trunk/www/delta_format.wiki
** https://fossil-scm.org/fossil/doc/trunk/www/delta_format.wiki
**
** This delta format is used by the RBU extension, which is the main
** reason that these routines are included in the extension library.
+8 -2
View File
@@ -401,8 +401,14 @@ static sqlite3_module memstatModule = {
#endif /* SQLITE_OMIT_VIRTUALTABLE */
int sqlite3MemstatVtabInit(sqlite3 *db){
int sqlite3MemstatVtabInit(
sqlite3 *db,
char **NotUsed1,
const sqlite3_api_routines *NotUsed2
){
int rc = SQLITE_OK;
(void)NotUsed1;
(void)NotUsed2;
#ifndef SQLITE_OMIT_VIRTUALTABLE
rc = sqlite3_create_module(db, "sqlite_memstat", &memstatModule, 0);
#endif
@@ -421,7 +427,7 @@ int sqlite3_memstat_init(
int rc = SQLITE_OK;
SQLITE_EXTENSION_INIT2(pApi);
#ifndef SQLITE_OMIT_VIRTUALTABLE
rc = sqlite3MemstatVtabInit(db);
rc = sqlite3MemstatVtabInit(db, 0, 0);
#endif
return rc;
}
+50 -23
View File
@@ -60,8 +60,7 @@
** step HIDDEN
** );
**
** The virtual table also has a rowid, logically equivalent to n+1 where
** "n" is the ascending integer in the aforesaid production definition.
** The virtual table also has a rowid which is an alias for the value.
**
** Function arguments in queries against this virtual table are translated
** into equality constraints against successive hidden columns. In other
@@ -116,6 +115,7 @@ SQLITE_EXTENSION_INIT1
#include <assert.h>
#include <string.h>
#include <limits.h>
#include <math.h>
#ifndef SQLITE_OMIT_VIRTUALTABLE
/*
@@ -276,6 +276,7 @@ static int seriesConnect(
int rc;
/* Column numbers */
#define SERIES_COLUMN_ROWID (-1)
#define SERIES_COLUMN_VALUE 0
#define SERIES_COLUMN_START 1
#define SERIES_COLUMN_STOP 2
@@ -363,13 +364,11 @@ static int seriesColumn(
#endif
/*
** Return the rowid for the current row, logically equivalent to n+1 where
** "n" is the ascending integer in the aforesaid production definition.
** The rowid is the same as the value.
*/
static int seriesRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
series_cursor *pCur = (series_cursor*)cur;
sqlite3_uint64 n = pCur->ss.uSeqIndexNow;
*pRowid = (sqlite3_int64)((n<LARGEST_UINT64)? n+1 : 0);
*pRowid = pCur->ss.iValueNow;
return SQLITE_OK;
}
@@ -482,25 +481,52 @@ static int seriesFilter(
** constraints on the "value" column.
*/
if( idxNum & 0x0080 ){
iMin = iMax = sqlite3_value_int64(argv[i++]);
if( sqlite3_value_numeric_type(argv[i])==SQLITE_FLOAT ){
double r = sqlite3_value_double(argv[i++]);
if( r==ceil(r) ){
iMin = iMax = (sqlite3_int64)r;
}else{
returnNoRows = 1;
}
}else{
iMin = iMax = sqlite3_value_int64(argv[i++]);
}
}else{
if( idxNum & 0x0300 ){
iMin = sqlite3_value_int64(argv[i++]);
if( idxNum & 0x0200 ){
if( iMin==LARGEST_INT64 ){
returnNoRows = 1;
if( sqlite3_value_numeric_type(argv[i])==SQLITE_FLOAT ){
double r = sqlite3_value_double(argv[i++]);
if( idxNum & 0x0200 && r==ceil(r) ){
iMin = (sqlite3_int64)ceil(r+1.0);
}else{
iMin++;
iMin = (sqlite3_int64)ceil(r);
}
}else{
iMin = sqlite3_value_int64(argv[i++]);
if( idxNum & 0x0200 ){
if( iMin==LARGEST_INT64 ){
returnNoRows = 1;
}else{
iMin++;
}
}
}
}
if( idxNum & 0x3000 ){
iMax = sqlite3_value_int64(argv[i++]);
if( idxNum & 0x2000 ){
if( iMax==SMALLEST_INT64 ){
returnNoRows = 1;
if( sqlite3_value_numeric_type(argv[i])==SQLITE_FLOAT ){
double r = sqlite3_value_double(argv[i++]);
if( (idxNum & 0x2000)!=0 && r==floor(r) ){
iMax = (sqlite3_int64)(r-1.0);
}else{
iMax--;
iMax = (sqlite3_int64)floor(r);
}
}else{
iMax = sqlite3_value_int64(argv[i++]);
if( idxNum & 0x2000 ){
if( iMax==SMALLEST_INT64 ){
returnNoRows = 1;
}else{
iMax--;
}
}
}
}
@@ -519,8 +545,7 @@ static int seriesFilter(
pCur->ss.iBase += ((d+szStep-1)/szStep)*szStep;
}
if( pCur->ss.iTerm>iMax ){
sqlite3_uint64 d = pCur->ss.iTerm - iMax;
pCur->ss.iTerm -= ((d+szStep-1)/szStep)*szStep;
pCur->ss.iTerm = iMax;
}
}else{
sqlite3_int64 szStep = -pCur->ss.iStep;
@@ -530,8 +555,7 @@ static int seriesFilter(
pCur->ss.iBase -= ((d+szStep-1)/szStep)*szStep;
}
if( pCur->ss.iTerm<iMin ){
sqlite3_uint64 d = iMin - pCur->ss.iTerm;
pCur->ss.iTerm += ((d+szStep-1)/szStep)*szStep;
pCur->ss.iTerm = iMin;
}
}
}
@@ -556,7 +580,7 @@ static int seriesFilter(
for(i=0; i<argc; i++){
if( sqlite3_value_type(argv[i])==SQLITE_NULL ){
/* If any of the constraints have a NULL value, then return no rows.
** See ticket https://www.sqlite.org/src/info/fac496b61722daf2 */
** See ticket https://sqlite.org/src/info/fac496b61722daf2 */
returnNoRows = 1;
break;
}
@@ -659,7 +683,10 @@ static int seriesBestIndex(
continue;
}
if( pConstraint->iColumn<SERIES_COLUMN_START ){
if( pConstraint->iColumn==SERIES_COLUMN_VALUE && pConstraint->usable ){
if( (pConstraint->iColumn==SERIES_COLUMN_VALUE ||
pConstraint->iColumn==SERIES_COLUMN_ROWID)
&& pConstraint->usable
){
switch( op ){
case SQLITE_INDEX_CONSTRAINT_EQ:
case SQLITE_INDEX_CONSTRAINT_IS: {
+1 -1
View File
@@ -12,7 +12,7 @@
**
** This module implements the spellfix1 VIRTUAL TABLE that can be used
** to search a large vocabulary for close matches. See separate
** documentation (http://www.sqlite.org/spellfix1.html) for details.
** documentation (http://sqlite.org/spellfix1.html) for details.
*/
#include "sqlite3ext.h"
SQLITE_EXTENSION_INIT1
+1 -1
View File
@@ -22,7 +22,7 @@ SQLITE_EXTENSION_INIT1
** most VFS calls to be recorded.
**
** To use this module, first compile it as a loadable extension. See
** https://www.sqlite.org/loadext.html#build for compilations instructions.
** https://sqlite.org/loadext.html#build for compilations instructions.
**
** After compiling, load this extension, then open database connections to be
** measured. Query usages status using the vfsstat virtual table:
+1 -1
View File
@@ -581,7 +581,7 @@ static int vfstraceFileControl(sqlite3_file *pFile, int op, void *pArg){
const char *const* a = (const char*const*)pArg;
if( a[1] && strcmp(a[1],"vfstrace")==0 && a[2] ){
const u8 *zArg = (const u8*)a[2];
if( zArg[0]>='0' && zArg[0]<=9 ){
if( zArg[0]>='0' && zArg[0]<='9' ){
pInfo->mTrace = (sqlite3_uint64)strtoll(a[2], 0, 0);
}else{
static const struct {

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