Compare commits

..

759 Commits

Author SHA1 Message Date
drh 79a2ca3944 Further fixes to the pread()/pwrite() enabling logic.
FossilOrigin-Name: 38fb54e7854ac0500a88585ff9dd7487b4b2e586
2016-03-04 03:14:39 +00:00
drh a46cadc42e Fix the build for cases when pread()/pwrite() are not available.
FossilOrigin-Name: 7d67d876b70c7a4199697c5b112d809c600e140e
2016-03-04 03:02:06 +00:00
drh e32a256acd Update the configure script to detect pread/pwrite and update os_unix.c to
use those routines if they are available.

FossilOrigin-Name: 2cffb9e50bed77d1079603f5b4a71b7559de7294
2016-03-04 02:38:00 +00:00
drh 862acaa3f4 Reduce the amount of heap memory required to store many schemas by storing
the column datatype appended to the column name (with a \000 separator), 
rather than in separate memory allocation.

FossilOrigin-Name: 16fbf2e19c22df9441aef5c8b7f5670adc38a6b6
2016-03-03 21:22:53 +00:00
drh 2b33f6e775 Allow the left-hand side of IN operators on virtual tables to have the
aConstraintUsage[].omit flag clear.

FossilOrigin-Name: 3eb74342740cd393e03aa38cd01690ccab173b76
2016-03-03 20:42:18 +00:00
drh 5b38201708 Merge 3.11.1 changes into trunk.
FossilOrigin-Name: 7abc2dd953477797fa05421b061d73596aa025fb
2016-03-03 17:54:30 +00:00
drh c5c1507612 Version 3.11.1
FossilOrigin-Name: f047920ce16971e573bc6ec9a48b118c9de2b3a7
2016-03-03 16:17:53 +00:00
drh 2396fce54e Increase the default upper bound on scope to 30.
FossilOrigin-Name: b1258814f6100f594210775e9e3007b5b0c65025
2016-03-03 15:16:15 +00:00
dan b78b83a2f6 Add new test script bestindex1.test to the utf16 permutation.
FossilOrigin-Name: 5893e97244126c80762e55249461f21a4e81bb70
2016-03-02 17:57:53 +00:00
dan 512c09b0bd Add an extra test for the change on this branch.
FossilOrigin-Name: d2d28251566d2a0ec1a07fe5b8ed047136840bfd
2016-03-02 16:13:53 +00:00
dan 9cc24c8002 Enhance test_bestindex.c so that it can be used to test plans generated by xBestIndex.
FossilOrigin-Name: 3c15a9bf45cd7dae2fbd99123b8dd75ce278d6e4
2016-03-02 16:01:41 +00:00
dan 341b20fb12 Fix a recently introduced problem in permutations.test causing an error when the QUICKTEST_OMIT environment variable is defined.
FossilOrigin-Name: 45bc9557722cc2a1398a53fdb2acd8b6692f3121
2016-03-02 15:37:50 +00:00
dan e18ec6acc2 Fix an error in an fts5 test script.
FossilOrigin-Name: b2a03e2d479aec2fc68dfc83a1fa34c740f44e13
2016-03-02 13:26:19 +00:00
drh dbc49161c0 Allow the left-hand side of IN operators on virtual tables to have the
aConstraintUsage[].omit flag clear.

FossilOrigin-Name: 1622623cbbfc4325c53d731aba78ca9c382ec612
2016-03-02 03:28:07 +00:00
drh 47784529cc Add the optional -DSERIES_OMIT_CONSTRAINT_VERIFY=0 option to the series.c
extension that implements the generate_series() virtual table.

FossilOrigin-Name: 3d9daa929c0abe6dc01e800ef343b0eef2f0c76a
2016-03-02 00:58:49 +00:00
drh 7434b1dbf4 New test cases and infrastructure for testing the xBestIndex method of
virtual tables.

FossilOrigin-Name: 1d41c161165006d6c2af47e476f05fb13039f8b8
2016-03-01 22:48:00 +00:00
drh 4fb48e4eb1 Improved debugging output with wheretrace. Fix some typos in test script
comments.

FossilOrigin-Name: 13a37fd487ce7d4f98a12f7a67a9c05dadc66557
2016-03-01 22:41:27 +00:00
dan 23c3c38dd6 Fix a memory leak in the test code on this branch.
FossilOrigin-Name: 7a1add56341f43dc41adc7b370e58860f4dd50a3
2016-03-01 18:35:55 +00:00
dan a3a44dd379 Allow test_bestindex.c to set the omit flag for a constraint.
FossilOrigin-Name: 759b9d5b22aa60cc1d6b606f81eb7366c28cbcbe
2016-03-01 18:24:36 +00:00
dan 8e4251b633 Add test code useful for testing the planners use of teh virtual table xBestIndex() method.
FossilOrigin-Name: de034c0db66298454ae8418949d58eb6e223c0de
2016-03-01 18:07:43 +00:00
dan bce50c734b Do not attempt to run fts5bigtok.test or fts5merge2.test if FTS5 is not compiled in.
FossilOrigin-Name: f7ed373953c2dea0919a85dfb461dfef512cd5fc
2016-03-01 16:56:26 +00:00
dan e82126c9d0 Add -DSQLITE_ENABLE_FTS5 to one of the release-test configurations in releasetest.tcl. Run fts5 tests as part of "make test" if SQLITE_ENABLE_FTS5 is defined.
FossilOrigin-Name: 3cee93716f2aece03bf9b835fb7b5294e4ddc176
2016-03-01 16:02:57 +00:00
drh fb02bad04f Remove a forgotten "breakpoint" command from an FTS5 test script.
FossilOrigin-Name: 61927c8f3156c6e61b768318b3cd3bcc4144e17b
2016-03-01 15:52:41 +00:00
drh 5ec04f0943 Increase the version number to 3.11.1
FossilOrigin-Name: 2dcd2fdafe933b74e2d90923986c5ee5791d8223
2016-03-01 15:41:31 +00:00
dan a93cd623cf Merge branch-3.11-matchinfo into this branch.
FossilOrigin-Name: 42358170b35cc3e25c42f20e56f3f67e809001ba
2016-03-01 15:09:15 +00:00
dan b1e8d31edf Fix a problem in fts5 where a corrupt db could lead to a (huge) buffer overread. Cherrypick of [c9a30e117f].
FossilOrigin-Name: daef5869f4d62ebb24eb03b79fe4be0812fa0496
2016-03-01 14:51:36 +00:00
dan 45a0e4eb59 Fix an fts5 problem causing 'optimize' to corrupt the fts index under some circumstances. Cherrypick of [251d6473f7].
FossilOrigin-Name: 5b1b7ab5d67f3d691e52ba57dbc14c52d90c6631
2016-03-01 14:50:55 +00:00
drh 889cb33b8f Better estimatedCost in the xBestIndex method of the generate_series vtab.
FossilOrigin-Name: f2c16094a536e7ef62444d0fe38cbee2a4999426
2016-03-01 02:11:50 +00:00
dan 4e9d0d5418 Fix a problem in fts5 where a corrupt db could lead to a (huge) buffer overread.
FossilOrigin-Name: c9a30e117f2c6c9ef0cc0c6ca5227d2961715b8f
2016-02-29 17:34:16 +00:00
dan 437a54eaba Fix an fts5 problem causing 'optimize' to corrupt the fts index under some circumstances.
FossilOrigin-Name: 251d6473f7c9ad95adbdcc49cb8eaf7c0956764b
2016-02-29 17:16:26 +00:00
drh 94eaafa9ce Reduce the amount of heap required to store many schemas by storing each
column datatype appended to the column name, rather than as a separate
allocation.

FossilOrigin-Name: 842b21162713bb141b845b01c136457a31af4ab0
2016-02-29 15:53:11 +00:00
drh 743606c3d3 Very minor improvement to the performance and reduction in size to the
parser by capturing the name and datatype of table columns in a single
grammar rule reduction.

FossilOrigin-Name: 4b55c520f554163edc174e5995e66242f169cb04
2016-02-29 13:44:38 +00:00
drh 986dde7052 Further simplifications to the grammar.
FossilOrigin-Name: 519fd03b845c9b53df9e5397282df2e99f36a672
2016-02-29 13:37:21 +00:00
drh 2881ab6298 Update the parser so that it pulls out the column name and type all in one
go, rather than using separate reductions.

FossilOrigin-Name: ad3ffe2eec8e8ea2591a78c723d2665735553cb0
2016-02-27 23:25:36 +00:00
drh 94fa9c414a Eliminate the need for the Column.zDflt (using Column.pDflt instead) to reduce
the amount of memory needed to hold the schema.

FossilOrigin-Name: d8c94a46dfa94930732c2de2aa79675c5087d36e
2016-02-27 21:16:04 +00:00
drh fc1a84c57b Tighter description of I/O stats in the shell. Show I/O stats on speedtest1.c.
FossilOrigin-Name: f681d800340e0e710f73d0f7c09101f899249183
2016-02-27 19:19:22 +00:00
drh 3478490332 Enhance the ".stats" command in sqlite3.exe to show one-time stats information
if invoked with one argument.  Also show /proc/PID/io information if run on
Linux.

FossilOrigin-Name: 3c36948f16b58fe8042c37d0df634308b4e48217
2016-02-27 17:12:36 +00:00
drh 4f8f5e4446 Fix a requirement mark to conform to a typo fix in the documentation.
FossilOrigin-Name: d1392c627934b89cdb86d82e73d56e8f76952b30
2016-02-27 14:04:27 +00:00
drh d892ac97bb Enhance documentation of sqlite3_snapshot_open() to explain that the database
connection must have participated in at least one read operation prior to
the beginning of the transaction for which the snapshot is to be opened.
Add test cases for this fact.

FossilOrigin-Name: 33dd671cb9c17f08dbc61aed91e80eaeb84bfaf5
2016-02-27 14:00:07 +00:00
mistachkin fe41a98fd6 Add 'Replace.exe' to the MSVC clean target.
FossilOrigin-Name: c2277fab12d2aecf9e0f69683741a194df17e854
2016-02-27 00:21:44 +00:00
mistachkin 62ab810014 Fix typo in ICU error message.
FossilOrigin-Name: 00c8fffd47cec763857389e1e91c026ba3179182
2016-02-27 00:21:16 +00:00
drh fee1e8d317 Make sure the Replace.cs file is included in the autoconf tarball.
FossilOrigin-Name: b850df483d4dfc677ec61b119d8c1162b6a823d6
2016-02-27 00:07:18 +00:00
mistachkin 9aeb971ceb Support generating the '.def' file using the autoconf Makefile for MSVC.
FossilOrigin-Name: 3617564cb630ed418badf43d2c0291c11c166d12
2016-02-26 23:13:16 +00:00
drh 88a1650859 Fix a potential buffer overflow in the ICU upper() function.
FossilOrigin-Name: b8dc1b9f5d413000387bfe784b69f5d0ee5c0489
2016-02-26 21:20:57 +00:00
mistachkin fe663fdecb Further refinements to the MSVC batch build process.
FossilOrigin-Name: cf4e4fbdb6a29b7fbd5150958ab4f8f2a1cd7f21
2016-02-26 21:03:16 +00:00
mistachkin 9b88ace822 Further refinements to the MSVC batch build process.
FossilOrigin-Name: 4e54e9c0fefe417f94a2d95921acf61b1dda5ca4
2016-02-26 21:01:37 +00:00
dan 38c3d3d8a5 Fix the ICU extension LIKE function so that it does not read past the end of a buffer if it it passed malformed utf-8.
FossilOrigin-Name: 424b7aee3310b9782bd312589dc3d9f287aa04b8
2016-02-26 16:03:29 +00:00
drh d42908fb0e Provide the new SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER option to
sqlite3_db_config() that can be used to activate the two-argument version
of fts3_tokenizer() for a specific database connection at run-time.

FossilOrigin-Name: 374b5108087a2eae03676c0f3469b37a272145bf
2016-02-26 15:38:24 +00:00
drh 5f7d411e98 Fix a typo in a comment (though an important comment in that it is used
to generate documentation).

FossilOrigin-Name: ff3d7f845e1875d6729f64f5231db1c376892f31
2016-02-26 13:22:21 +00:00
drh 26bcc7cf40 Ephemeral tables used to hold manifested views may not be unordered since
they might be subject to an ordered comparison if they are part of a join.

FossilOrigin-Name: 3ef6a3153267d5328202fea24fd29ff4d5409295
2016-02-26 04:13:39 +00:00
drh c9eaeef1fe Remove a debuggin "exit" command mistakenly left in the "where.test" module.
FossilOrigin-Name: beda0b8c76c2c7328a44156257c978cf8f5df59b
2016-02-26 04:04:07 +00:00
mistachkin 74c2f06668 Add some comments in the VSIX test tool.
FossilOrigin-Name: c871473ffee6dbb0f5b47f1c1329c84b902368ae
2016-02-25 23:27:02 +00:00
mistachkin a85ac12d00 Add tool for smoke-testing the UWP VSIX package.
FossilOrigin-Name: d27f32c6d72182198ae6d6cf8e385be76335dc65
2016-02-25 23:25:00 +00:00
mistachkin 7856c1c0eb Enhance checking of prerequisites in the vsixtest tool.
FossilOrigin-Name: 799d5f09ed058898167e43bd9c8d1bf8c5df23ba
2016-02-25 23:22:26 +00:00
drh 8c098e61b6 Fix an incorrect cost computation for sorting (introduced just a few
check-ins ago).  Should be NlogN, not NloglogN.

FossilOrigin-Name: 2459d3238853951bc3a507dd975e7ec921cf8446
2016-02-25 23:21:41 +00:00
mistachkin 9d970c3c93 Small optimization in FK handling.
FossilOrigin-Name: e0d25913b73a813f5987aa70b364b00f19351663
2016-02-25 21:38:28 +00:00
drh 27b6649f39 Change the srcck1.c utility program to use only unsigned characters.
FossilOrigin-Name: d64d005eb5df2e3eb1248fc8eff8b1b683e48c74
2016-02-25 21:27:03 +00:00
drh d566c95179 Change the "PRAGMA stats" command to report size values in LogEst units.
The eliminates the need for sqlite3LogEstToInt() unless non-standard
compile-time options are used, so leave it out except in those cases.

FossilOrigin-Name: 832c237fcbe83dd4f5a18a06acb0aeb7e2b9e712
2016-02-25 21:19:03 +00:00
dan aa9ffaba4a Disable the RESTRICT foreign key action if "PRAGMA defer_foreign_keys" is set.
FossilOrigin-Name: 9ffff484bb4b67c29dda6180d7d766ad13988fe1
2016-02-25 20:17:55 +00:00
drh eecb80e77e Query planner improvements: Take the LIMIT into account when estimated the
cost of an ORDER BY.  Avoid automatic indexes on query loops that are expected
to run less than twice.

FossilOrigin-Name: bf46179d4484376909dce40ffcc06fecb19b3544
2016-02-25 18:40:18 +00:00
drh 5a6f5ede81 Improvement on the previous check-in: disallow automatic indexes for any
loop that is expected to run less than twice.

FossilOrigin-Name: aab53a21894ba51d325fd8f8f4bb4163ece74391
2016-02-25 18:22:09 +00:00
drh 87eb919d05 Do not use an automatic index on an outer loop that only runs once.
FossilOrigin-Name: 5957e793414ff80ed01a7a67e70c3fd096a3f6e0
2016-02-25 18:03:38 +00:00
drh c3489bbf77 Take the LIMIT clause into account when estimating the cost of sorting.
FossilOrigin-Name: d491745cab951e0de70f1f79b7640ea8aff6e8bb
2016-02-25 16:04:59 +00:00
drh d8c22ac655 In the command-line shell: When the ".import" command is creating a new
table using column names from the first row of CSV input, make sure 
double-quotes in the name are properly escaped.

FossilOrigin-Name: 2e67a1c823c7003e7d2619c7d8b6db6ce046c527
2016-02-25 13:33:02 +00:00
mistachkin 77b7e2afb1 Improve readability and logging of the vsixtest script.
FossilOrigin-Name: 4fe7c4e90b7adbb1630b4aa15709968a1fcc7d83
2016-02-25 08:02:16 +00:00
mistachkin 6ae4d84fdf Enable all steps and add/update comments.
FossilOrigin-Name: 788f99f47f40be42f30d3f324983f39e84d8cfbb
2016-02-25 02:56:53 +00:00
mistachkin c32db469f4 More work. Install and build steps are now tested.
FossilOrigin-Name: 0ab74373bd37d48d6afa7aecb67885afcd3a85b1
2016-02-25 02:49:58 +00:00
mistachkin 5dad68d3c7 Fix typo. Improve interim debugging.
FossilOrigin-Name: e0029bdf20df90abd8b81e5b08133866665b1c87
2016-02-24 23:31:14 +00:00
mistachkin 78007b2f22 Test build all supported configurations and platforms during VSIX testing.
FossilOrigin-Name: cce40a0b8ee792482fb7031113eb190ad316d01a
2016-02-24 23:25:23 +00:00
mistachkin 7aa3ebee0f Initial work on an automated VSIX testing tool. Not working or tested yet.
FossilOrigin-Name: 496e4ac984b2548dd5f2f969cd34656b586cfcfe
2016-02-24 21:42:03 +00:00
dan f769cd61b2 Extend [3e9ed1ae] so that covering indexes on WITHOUT ROWID tables are also identified.
FossilOrigin-Name: e721975faa0925be4029330550ff2a9666041ff7
2016-02-24 20:16:28 +00:00
drh 6ad224e91e Change a char* to const char* in order to suppress some harmless
compiler warnings.

FossilOrigin-Name: 56f62e34ae9d5c7db07367f0007df258b2e76bd2
2016-02-24 19:57:11 +00:00
drh 87993148bd When an index complete covers a table, it can be used as a covering index
even if columns past the 63rd column are indexed and accessed.

FossilOrigin-Name: 3e9ed1aea43e8ce2eb74bb845ea2c05b5882e36e
2016-02-24 17:18:51 +00:00
dan a73086dd9e Fix a problem with handling identifiers that start with "x" if SQLITE_OMIT_BLOB_LITERAL is defined.
FossilOrigin-Name: b65217c69c59cbe9cd1494e2eb42ecf22c336399
2016-02-24 16:14:07 +00:00
drh e1dd060898 Identify indexes that complete cover their table.
FossilOrigin-Name: 71d488b599cbde817de369efac4412569a55b43d
2016-02-24 15:43:05 +00:00
drh 0e0089679f Add the SQLITE_BITMASK_TYPE compile-time option.
FossilOrigin-Name: 0064a8c77b2b048c71277d1cfd1ba3975b513b70
2016-02-23 16:28:34 +00:00
drh b052958657 Remove code not needed now that synchronous=OFF database files no longer
trigger the use of a master journal.

FossilOrigin-Name: aa9f4c622af191edbeb6a535942944f8c91f5c37
2016-02-22 23:44:42 +00:00
drh 600e888454 Avoid an unnecessary seek operation some corner-case skip-scan operations.
FossilOrigin-Name: 2a6003a937a210dfc279e393d3a0b49d1f3ac92e
2016-02-22 23:14:11 +00:00
drh 0bf2ad6a18 Clearer presentation of the logic. No functional changes.
FossilOrigin-Name: a3dcf6db76cc09bdfedb1bbeba3b359b77762cbe
2016-02-22 21:19:54 +00:00
drh a6d2f8eb1e Avoid an unnecessary seek operation on some corner-case skip-scans.
FossilOrigin-Name: 38e837e605076124b73235e1fd832838d9545cb2
2016-02-22 20:52:26 +00:00
drh b9626cfa70 Always use the sqlite3VdbeDeleteAuxdata() routine for clearing auxdata on
function parameter, rather than having a separate deleteAuxdataFromFrame()
for doing the job for trigger frames.

FossilOrigin-Name: 64386fa339adb91439da979d74062f67a6ec68fd
2016-02-22 16:04:31 +00:00
drh 8e6cf0a7c5 Avoid creating a master journal unless two or more databases in the
transaction can actually benefit from that master journal.

FossilOrigin-Name: 3ed1890612bd45bd9c72f670d2cbb0b8fbd35d92
2016-02-22 14:57:38 +00:00
drh e872d5133d Change magic numbers associated with synchronous settings to named constants.
FossilOrigin-Name: 9230ba6c01f4a550d92a0cbbf36dbe81af14fbfc
2016-02-22 13:23:16 +00:00
dan 748e5cd6f9 Add an extra test case for the change in commit [c4295725].
FossilOrigin-Name: a48ac4c347813bd2b416b1cb06c3cbf1f4b3781a
2016-02-22 09:45:27 +00:00
mistachkin d149ea3a3a Further enhancements to the MSVC batch build tool.
FossilOrigin-Name: 06f1495f4b7465e3992f524f56d97847643a9895
2016-02-19 19:46:58 +00:00
mistachkin c03c2cf8b3 Use the arguments to NMAKE consistently in the MSVC batch build tool.
FossilOrigin-Name: 480e5049486b8b047f533d78b040daa47dd6b946
2016-02-19 19:29:44 +00:00
mistachkin 56362a5ab7 Enhance clean target in the MSVC makefiles.
FossilOrigin-Name: 66a9ad4a6df513f4c35c3d337d4e2e80cd38d586
2016-02-19 19:03:04 +00:00
dan 3200132add Use a separate list of aux-data structures for each trigger program at the VDBE level. Fix for [dc9b1c91].
FossilOrigin-Name: c4295725015d394f01b8563f47236e0890f1cc0d
2016-02-19 18:54:29 +00:00
drh b719e3a747 Enhance speedtest1 to display the particular version of SQLite under test.
FossilOrigin-Name: 0cb728c15c66f1bf09cc1e0731a95ba937c6c71c
2016-02-19 16:19:23 +00:00
drh e1ee002891 Fix a couple of harmless warnings generated by clang.
FossilOrigin-Name: a1a3ff1f53145c5a9fbf29398cf4a453729e71f0
2016-02-19 15:17:53 +00:00
drh b1f4efd20b Fix a harmless uninitialized variable access.
FossilOrigin-Name: 398522e686b34e7f82a62e62d8b0a0ea924de064
2016-02-19 14:20:46 +00:00
drh 81fd3497f4 Make sure WhereClause objects are fully initialized before use when
planning OR queries.

FossilOrigin-Name: 162053021795ff40c447498a76de4d31d58aa808
2016-02-19 14:10:44 +00:00
drh 9a1e85ee2e Fix (harmless) compiler warnings in some of the TCL-based test code.
FossilOrigin-Name: 7c26d2b47025edaa289bd4a383b5c1536482ec11
2016-02-19 13:29:52 +00:00
drh 469753d949 Add an SQLITE_DISABLE_INTRINSIC #ifdef to the sqlite3Put4Byte() function.
FossilOrigin-Name: ba9c6827d0890aaed9168c221fefbdbe89f4f9d3
2016-02-19 13:20:02 +00:00
drh 51381c208e Omit the unused yyzerominor constant.
FossilOrigin-Name: 60ad68a9f569d2446d76a6453be4fa1c4ed2cd93
2016-02-19 13:19:22 +00:00
dan 9e2cfad18a Add an "#ifndef SQLITE_AMALGAMATION" guard around a typedef in fts5_test_mi.c to avoid redefining "u32" if it is compiled as part of the amalgamation. Cherrypick of [f9c49ba1].
FossilOrigin-Name: ce0f1ed517e387ca6a687b805088d7c529cd257b
2016-02-19 10:19:43 +00:00
dan 92b859292d Add an "#ifndef SQLITE_AMALGAMATION" guard around a typedef in fts5_test_mi.c to avoid redefining "u32" if it is compiled as part of the amalgamation.
FossilOrigin-Name: f9c49ba1edf13cb8c48d73f1b2e3f80c46b3c030
2016-02-19 10:18:36 +00:00
mistachkin b0c99afeda Modify the MSVC batch build tool to support the MSVC autoconf Makefile.
FossilOrigin-Name: 72b10e5e7d2db436c7b03cc3735a2e9d0e53ab5d
2016-02-19 05:07:56 +00:00
mistachkin 9751730f83 Further improvements to the MSVC batch build tool.
FossilOrigin-Name: b9626b5954068ae2e7733dd14f906a1f6d7090a5
2016-02-19 00:48:23 +00:00
mistachkin b9076ba4c9 Further improvements to the MSVC batch build tool.
FossilOrigin-Name: 90dd6eb1fec22460473d670519d0e730bb37067d
2016-02-19 00:47:18 +00:00
mistachkin d8945d1707 Correct the install location for the UWP VSIX package.
FossilOrigin-Name: f74de325ffb01a1ca8ddd4f011188e38296c3402
2016-02-18 21:15:12 +00:00
mistachkin 45dc877f76 Correct the install location for the UWP VSIX package.
FossilOrigin-Name: b47d03027e973e3c8d77246a2d2100881f6a9bd2
2016-02-18 21:00:29 +00:00
dan 557d0383ff Remove SQLITE_TEST macros from fts5_test_mi.c. Add the SQLITE_FTS5_ENABLE_TEST_MI compile time symbol - to make it easier to create builds that include the fts5 matchinfo demo by default.
FossilOrigin-Name: e2ef6667772eeac6eee3aed5d0609c2a0ef5d8cf
2016-02-18 16:16:43 +00:00
drh b2bddbbc2d Avoid a potential buffer overrun if an SQL statement being parsed ends
with an illegal "!" token.  (This problem was detected by fuzzcheck
running under valgrind. The problem was introduced by check-in [9570b6b43df3].)

FossilOrigin-Name: 2a8d97e7c8976df0312e1294e8c1da8b15686654
2016-02-18 14:49:28 +00:00
drh 4c9d22819f Improved handling of the -v option on the fuzzcheck test program.
FossilOrigin-Name: c8cd7804dc905b2b20cd7c0192bcfaceaaa7e2a8
2016-02-18 14:03:15 +00:00
dan a0c2d3c155 Remove an unnecessary "include <tcl.h>" line from fts5_test_mi.c.
FossilOrigin-Name: 31d8b69e9e0747e573516570bfe2770384e99134
2016-02-18 13:32:34 +00:00
drh 5b081d8a28 Add extra API armor on the sqlite3_bind_blob() interface.
FossilOrigin-Name: 80de1ad5eb4c3839756b6467d5b8195b4abfb1f8
2016-02-18 01:29:12 +00:00
drh 7f149e5173 When VDBE opcodes fail, they cause an immediate exit from the loop, rather
than depending on the rc==SQLITE_OK test at the top of the loop.  This is
faster and smaller.

FossilOrigin-Name: 24c7151c1aabeaffcb8bb5836404e70a3ec4681b
2016-02-17 20:47:24 +00:00
drh 9467abf3dd Fix up all VDBE opcodes so that they cause an immediate exit on any kind of
error, and thereby eliminate the need to test "rc" at the top of the loop.
Resulting code is a little smaller and faster.

FossilOrigin-Name: a444633a827642bcf4d02a461e7e5f66769d39fd
2016-02-17 18:44:11 +00:00
drh b5a55ce77d Bump the version number to 3.12.0.
FossilOrigin-Name: c17d7276b8c114df5fe6e9ea14d59758443c281b
2016-02-17 15:01:18 +00:00
dan 5e29f38d2c Remove the "#ifdef SQLITE_TEST" condition from fts5_test_mi.c. Update fts5_main.c so that if SQLITE_FTS5_TEST_MI is defined when it is built the fts5_test_mi.c entry point is automatically called. This makes it easier to build versions of fts5 that include the matchinfo() demo by default.
FossilOrigin-Name: 87e6e225aea3a4d10476d16eab4a6403a4a128c9
2016-02-17 14:48:26 +00:00
dan 87d6b35541 Improve test coverage of demo code in fts5_test_mi.c.
FossilOrigin-Name: 8a78050dc0e374a0df0f29716df60250e2c4b4f7
2016-02-17 14:11:06 +00:00
drh b7997fe3a9 Enhance Lemon to generate more compact and efficient code for yy_reduce().
Update the main SQL grammar to take advantage of the new capabilities.

FossilOrigin-Name: 53fd040c98d9647ea135d43c493777bf8da4aebd
2016-02-17 13:24:12 +00:00
drh 43303de97e More agressive use of /*A-overwrites-X*/ in the parser. Fix an off-by-one
error in parser stack overflow detection.

FossilOrigin-Name: 417e777701bbf4bd67626d4ca3bc2c5d847f6cd0
2016-02-17 12:34:03 +00:00
drh 0ccbc64fd6 Documentation typo on sqlite3_wal_hook(). No changes to code.
FossilOrigin-Name: fc2043ebaa3f106529500164936bb82f9b921b1c
2016-02-17 11:13:20 +00:00
drh cf82f0d3d2 Enhance Lemon so that if reduce code contains a comment of the form
"/*A-overwrites-X*/" then a LHS label A is allowed to overwrite the
RHS label X.

FossilOrigin-Name: 5cfe9545d478a2c500083613dd20e14b2ffce645
2016-02-17 04:33:10 +00:00
drh dabd04c656 Further improvements to the Lemon-generated code for yy_reduce().
FossilOrigin-Name: ef95a7d6490e33a9af4bc7b4b622de7328742ca7
2016-02-17 01:46:19 +00:00
drh 4dd0d3f819 In Lemon, add the ability for the left-most RHS label to be the same as the
LHS label, causing the LHS values to be written directly into the stack.

FossilOrigin-Name: 4bb94c7c4c3cb3ccad72c2451d88684130dde845
2016-02-17 01:18:33 +00:00
drh 45f31be85d Experimental changes to Lemon for improved parser performance.
FossilOrigin-Name: a65d583ce97b8c08157268bd054479cda3957a94
2016-02-16 21:19:49 +00:00
drh 30c14728b4 Minor simplification to the tokenizer. Slightly smaller and faster.
FossilOrigin-Name: 9570b6b43df3bc5ce314cded20bca8be9e968efe
2016-02-16 13:04:19 +00:00
drh dab943cf3d Improve the Lemon parser template (lempar.c) so that it avoids unnecessary
work when the grammer defines YYNOERRORRECOVERY (as SQLite does).  Slightly
smaller and faster code results.

FossilOrigin-Name: 9235b0cf6a37712ae9e5deeb1e5ee064dd5511fa
2016-02-16 01:01:43 +00:00
drh 7ff89807e0 Fix a harmless compiler warning in FTS5.
FossilOrigin-Name: e52c90758c53cbb0f74e0d8582e4c3c1bee04150
2016-02-15 23:46:36 +00:00
mistachkin b71aef3461 Readability improvements for winRandomness.
FossilOrigin-Name: 1640f814c7a5210f08c81e52e5a3fb89ac26f4d4
2016-02-15 22:37:18 +00:00
mistachkin 0ead47d1c7 Fix comment. No changes to code.
FossilOrigin-Name: 2e1f2eff27e25280fe626c07b6260b0a7aa903d3
2016-02-15 22:28:50 +00:00
mistachkin bfc9b3f45c Revise compiler checks for the rand_s() function.
FossilOrigin-Name: 287f508dd6abc1b9ffdbec6a685ebe79eeac992b
2016-02-15 22:01:24 +00:00
drh 51d5ed97f5 On windows systems when rand_s() is available, use it to obtain additional
seed material in winRandomness().

FossilOrigin-Name: 139081bef9f63c3ebbe9e992408597b1349bdf37
2016-02-15 21:31:51 +00:00
drh 8eb3790a8d Improved entropy gathering for the implementation of winRandomness().
FossilOrigin-Name: fea3705e7750d276a8c8300b7a82dfae2d5979c0
2016-02-15 20:41:56 +00:00
drh 4b7b1c9c12 Add working -q and --help options to testfixture.
FossilOrigin-Name: 404494e52b6385671ccde1c83b7b868986645536
2016-02-15 19:38:17 +00:00
drh 3719d10d11 In the tool/warning.sh script, disable Android-specific compiler warning tests
when not running on Linux.

FossilOrigin-Name: 153f01a821e9844d0a2e418eb83c60f6c7695c8d
2016-02-15 18:58:37 +00:00
drh e683b89880 Fix harmless compiler warnings previously seen in 64-bit MSVC builds.
FossilOrigin-Name: 7026246300392a83cc23817dbc54c2c66bf1f2b3
2016-02-15 18:47:26 +00:00
drh 32c49904a6 Add the SQLITE_NOMEM_BKPT macro to enhance the ability to debug OOM errors.
Only effective with compiling with SQLITE_DEBUG.

FossilOrigin-Name: 9b3454762d142113f5923d754ca6bd2edefbd362
2016-02-15 18:15:15 +00:00
drh 66acf297fd Minor code simplifications.
FossilOrigin-Name: c3b38efd50c3c07b6dee5dea4c1f95b37d1c0994
2016-02-15 18:02:13 +00:00
drh 3bff397248 Make the application-defined SQL function logic more compact and faster,
especially faster for the case where an application defines thousands of
new SQL functions.

FossilOrigin-Name: 7d49ed32a7262ec95d72ce520ab75402633386a1
2016-02-15 17:56:35 +00:00
drh 195c8d5eba Version 3.11.0
FossilOrigin-Name: 3d862f207e3adc00f78066799ac5a8c282430a5f
2016-02-15 17:29:24 +00:00
drh 8e0cea1a5d Make sure the codec is invoked when overwriting existing frames of the
WAL file.  Yikes!

FossilOrigin-Name: f694e60a79024967a3f4574e3928f0b28589d381
2016-02-15 15:06:47 +00:00
drh 80738d9c3e Improvements to the application-defined function mechanism so that it is
more compact and runs faster, especially when the application defines
thousands of new SQL functions.

FossilOrigin-Name: 3201fbcc5105d23132e6b8b7ac825e66af4f8a39
2016-02-15 00:34:16 +00:00
mistachkin 8fd8413aaa Update a comment.
FossilOrigin-Name: e9753d9a2c1269050f886e6cb9bc9cba0a8df6ce
2016-02-14 00:14:35 +00:00
mistachkin fad3039c51 Enhance ability to debug out-of-memory errors.
FossilOrigin-Name: 6a9c4a3ebfb7cc0738ef6634440ccab44a21ff28
2016-02-13 23:43:46 +00:00
drh e75a9eb9bb Provide Sqlite3_SafeInit() and Sqlite3_SafeUnload() entry points on the TCL
interface, but have the always return TCL_ERROR, because the non-standard 
TCL builds on Macs require this.

FossilOrigin-Name: 37ec3015ec95035d31e3672f520908a0d36c9d67
2016-02-13 18:54:10 +00:00
dan 53ff9c2972 Fix a potential buffer overread provoked by invalid utf-8 in fts5.
FossilOrigin-Name: a049fbbde5da2e43d41aa8c2b41f9eb21507ac76
2016-02-12 18:48:09 +00:00
dan f2d328fa25 Fix a fairly obscure buffer overread in fts5.
FossilOrigin-Name: 130580207ab5cee762b2893808acef7c8afad027
2016-02-12 17:56:27 +00:00
drh aa622c1f4f Fix a documentation typo. No changes to code.
FossilOrigin-Name: d9c985878cf7c74a79ccdb9cf94a2d48fdde3e6f
2016-02-12 17:30:39 +00:00
drh cd42352526 Enhance mptester so that it takes great care to delete its test database
prior to start-up, including checking the return code from unlink() and
retrying after a delay if unlink() fails.  Hopefully this will clear 
intermittant startup problems on Windows.

FossilOrigin-Name: 6ea84ec1e02f0a48953bc758027ab7148529c36e
2016-02-12 17:27:32 +00:00
mistachkin a819aed880 Naming updates for Universal Windows Platform.
FossilOrigin-Name: 717c1fc41a2246e27b324a4071073c286bac4efc
2016-02-12 05:19:29 +00:00
drh f981093760 Remove an unused parameter from whereSortingCost().
FossilOrigin-Name: b5d771991686bf86a679b7dff9f16301a5029c8b
2016-02-12 00:13:38 +00:00
drh 4553f6ea91 Automatically disable FTS3 and FTS4 when building with SQLITE_OMIT_VIRTUALTABLE.
FossilOrigin-Name: 0beb32d20d8dd698138cdb2de6b6056de176754d
2016-02-11 22:41:04 +00:00
mistachkin 30470c5162 Enhance the MSVC makefile to enable building 'testfixture' fully from source code.
FossilOrigin-Name: f183e05990608d1a4002fa8a02c2d2eea6bc94b6
2016-02-11 21:59:02 +00:00
drh c50d5908b4 Remove the unexplained extra 3.0 cost factor for the B-tree sorting that is
done to implement DISTINCT in the absence of an index to help.

FossilOrigin-Name: 52571991fcfa2629e8a8354e0c9a62e749a092bf
2016-02-11 21:55:23 +00:00
drh 5d2e2f1267 Remove the unused fts5BlobCompare() routine.
FossilOrigin-Name: defc762dd11144402abd591278819768a080d5ea
2016-02-11 21:53:57 +00:00
mistachkin e2eb259fce Prevent 'expanded command line X too long' errors during the batch 'for' loops used for copying files.
FossilOrigin-Name: 67ee9b5af10a8b57a37f19ac040e49fdfcec4145
2016-02-11 21:38:05 +00:00
mistachkin c04c54b842 Enhance the MSVC makefile to enable building 'testfixture' fully from source code.
FossilOrigin-Name: 54ff3a26bc45a1c3c0690119e8fd00b02e2a16ba
2016-02-11 21:28:16 +00:00
dan df9c59f74d Fix another unused variable warning in fts5 code.
FossilOrigin-Name: 61b4c120540afd80a4021b0d3990f13acc38a059
2016-02-11 18:18:33 +00:00
dan 2a44b3d877 Avoid a buffer overread when reading a corrupt fts5 structure record.
FossilOrigin-Name: facbc424e555061135aced7b134bf6c19f54e484
2016-02-11 18:08:38 +00:00
dan 22e8356368 Handle parser stack overflow when parsing fts5 query expressions. Fix some compiler warnings in fts5 code.
FossilOrigin-Name: bc3f7900d5a06829d123814a5ac7b951bcfc1560
2016-02-11 17:01:32 +00:00
drh df3a907ecc Add JSON1 and FTS5 to the set of extensions subject to close compiler warning
analysis.  Fix some warnings in each.   More (harmless) warnings still exist
in FTS5.

FossilOrigin-Name: cfe2eb88b504f5e9b1351022036641b1ac4c3e78
2016-02-11 15:37:18 +00:00
drh c41c132cf0 Minor simplifications deferred to the next release.
FossilOrigin-Name: a863729ccb75a56330460d3b7d558e639ad733d1
2016-02-11 13:30:36 +00:00
mistachkin 8988aeef60 In the MSVC makefile, include the working directory so that it can pickup build generated files (e.g. sqlite3.h, etc).
FossilOrigin-Name: e9e6000bd2f7e0ef85178db2b5b8f20e4cf0093c
2016-02-10 21:45:25 +00:00
drh 05723a9e3c Add testcase() macros to the CHECK constraint avoidance logic. Avoid creating
an unused VDBE label during CHECK constraint code generation.

FossilOrigin-Name: 970881befd5da6cc837c474d6e917de0bf029350
2016-02-10 19:10:50 +00:00
drh 98bfa16db2 Fix to previous check-in: Make sure CHECK constraints involving the ROWID
are not ignored when the ROWID changes.

FossilOrigin-Name: 7782cb1dd5914b867caf5ff2f0f837407abbfd7a
2016-02-10 18:24:05 +00:00
drh 2a0b527b37 Omit unnecessary CHECK constraints in UPDATE statements, when none of the
columns referenced in the CHECK constraint are modified.

FossilOrigin-Name: 02fbdbc782dd98f080bf4482d820f36c0ef3d519
2016-02-10 16:52:24 +00:00
drh bdb00225ab Omit NOT NULL checks on unchanging columns in an UPDATE.
FossilOrigin-Name: 6a3aaedfb41735996470abbae6d3cd1be1f508b3
2016-02-10 16:03:20 +00:00
drh dd2b59b01d When generating the snapshot-tarball, truncate the date/time in the name to
12 significant digits (YYYYMMDDhhmm) omitting the seconds and fractional
seconds.

FossilOrigin-Name: 604f77754797a4066f6cf275c7bc8a68d2839c2d
2016-02-10 13:36:17 +00:00
drh 0d4f9354db Updates to the autoconf tarball README.txt file.
FossilOrigin-Name: a3e911e3aa3e35446bed7f300bfe03f66e1494db
2016-02-10 13:17:14 +00:00
drh 8809d821b4 Update the snapshot tarball name to use the date (ISO8601 format) instead
of the SHA1 hash in its name.

FossilOrigin-Name: 070ec66f677cdcd30087871feb8afd010a184b75
2016-02-09 22:54:39 +00:00
drh 07f76568da Add the new "snapshot-tarball" target to the unix makefiles, for building
a tarball similar to "amalgamation-tarball" but named by the SHA1 hash of
the current check-out rather than by the version number.

FossilOrigin-Name: 4f360b2ae78b3d4ccfe6c40ac6b27a00fc70cf23
2016-02-09 22:39:39 +00:00
mistachkin c5286de0ee Update the MSVC autoconf makefile with the recent changes from the primary one.
FossilOrigin-Name: c7242aa3e9c08e0c019388e89a785a6e59c915d5
2016-02-09 22:00:48 +00:00
drh 949c5d3cfc Fix the makefiles in the autoconf-tarball so that they build the command-line
shell with SQLITE_ENABLE_EXPLAIN_COMMENTS.

FossilOrigin-Name: 1135ad014aac8a4ae5169375af1b368feaa8331b
2016-02-09 20:37:46 +00:00
mistachkin 6d94555914 In the shell, use the appropriate string constant instead of a literal new-line.
FossilOrigin-Name: 61951b153d47096f30ebc8b84af408d9d709637c
2016-02-09 20:31:50 +00:00
drh d4e2857815 Enhance the command-line shell to be in auto-explain mode by default. It is
no longer necessary to use the ".explain" command to put the shell into a mode
where the EXPLAIN output is formatted nicely.  That now happens automatically.

FossilOrigin-Name: 751915cb7e4981661a40dc5e4d029ab27434c2d9
2016-02-09 20:11:14 +00:00
drh 87a24aa1ca Improved auto-detection of EXPLAIN output in the shell.
FossilOrigin-Name: 6c6d7a6e89e67cdb0813d3eebb869aafb43d43ed
2016-02-09 20:04:07 +00:00
drh 700c252a72 Add auto-explain mode to the command-line shell. Default on. Auto-explain
tries to automatically detect EXPLAIN queries and format them appropriately.

FossilOrigin-Name: 1d62aa6b315df47cafb33da7ca79d3386a2fdd48
2016-02-09 18:39:25 +00:00
mistachkin 406eeff6ff Fix MSVC makefile options that enable control-flow guard.
FossilOrigin-Name: 51b6823f4c9376d549f572f5a33cac1e4c9783a2
2016-02-09 18:28:20 +00:00
drh 74cf74ab7f Fix the top-level makefiles to always include SQLITE_ENABLE_EXPLAIN_COMMENTS
when building the shell.  Still need to fix main.mk and the
amalgamation tarball.

FossilOrigin-Name: 992282399cd2d1fc52ff5a1a4bff59f30b62899a
2016-02-09 17:12:22 +00:00
drh bbde018230 Code simplification: ALTER TABLE ADD COLUMN always upgrades the file_format
to 4 if is not there already.  No need to upgrade to only 2 or 3 since format
4 has now been supported for over 10 years.

FossilOrigin-Name: e1d8ec85546caeca3bb7a05ad962a2aed91194ce
2016-02-09 16:09:22 +00:00
drh 2fade2f791 Make sure every co-routines has its own set of temporary registers and does
not share temporaries, since a co-routine might expect the content of a
temporary register to be preserved across an OP_Yield.
Proposed fix for ticket [d06a25c84454a].

FossilOrigin-Name: ca72be8618e5d466d6f35819ca8bbd2b84269959
2016-02-09 02:12:20 +00:00
mistachkin e48f1ed9bf Fix spelling error in MSVC makefile comments.
FossilOrigin-Name: 6eab74c9ae57676044b5bc82fa14e92fd2448008
2016-02-08 20:45:37 +00:00
mistachkin 55e88d96ed More work on Windows 10 SDK integration.
FossilOrigin-Name: 1e563c6ebbb02d2e89760c7a7f95aa69964629c6
2016-02-08 20:40:57 +00:00
dan c2d0b56e6a Fix a signed/unsigned comparison warning in fts5.
FossilOrigin-Name: 85eb05ddbc3a7cff986af13c3dab6c0063e62171
2016-02-08 20:14:41 +00:00
drh 83d7920e55 Fix a compiler warning when compiling without SQLITE_ENABLE_FTS3_TOKENIZER.
FossilOrigin-Name: 6926f28cd56bf61f7c92877baa54024bee7cbab5
2016-02-08 20:06:52 +00:00
dan e064c4066c Disable the two-argument form of the fts3_tokenizer() SQL function unless the library is built with -DSQLITE_ENABLE_FTS3_TOKENIZER.
FossilOrigin-Name: e0eb217aca7e4aadf9c44ed20822b78139f7c83c
2016-02-08 19:40:17 +00:00
drh e96f361995 Changes to help the tokenizer run about 33% faster.
FossilOrigin-Name: a050e6f096d40aa5b6275797b96e62c228044f5a
2016-02-08 19:36:46 +00:00
drh 34dcee6544 Add code to get the tokenizer character-class logic working for EBCDIC.
FossilOrigin-Name: 04f7da77c13925c1f1e287f4579bb85518297d81
2016-02-08 19:15:48 +00:00
drh 41aab89b31 Faster keywordCode() implementation by taking advantage of the fact that
the input is always pure ASCII alphabetic and underscore and that the keyword
table is always upper-case.

FossilOrigin-Name: ff406b9701ebe3a01834837f380641c6f0c495bc
2016-02-08 03:23:46 +00:00
drh 8974331fc3 Demonstrate a much faster sqlite3GetToken() routine by using a lookup table
to map initial token characters into a character class.  This check-in does
not work for EBCDIC.  More optimization needed.

FossilOrigin-Name: 9115baa1919584dc8ca25bbff54d3b65748a9631
2016-02-08 02:30:50 +00:00
mistachkin 27b6997e9c Fix harmless compiler warning in 'srcck1' tool and add it to the clean targets.
FossilOrigin-Name: 852a529a8b112049f67a3126f677c06ae4a22d73
2016-02-07 20:39:27 +00:00
drh fd0d93fd71 Add the sourcetest target to Makefile.msc.
FossilOrigin-Name: ab269e720552483c5617906837e294c1be3e0a57
2016-02-07 00:08:08 +00:00
drh cc5f8a46b9 Add a utility program that looks for assert(), NEVER(), ALWAYS(), and
testcase() macros that have side-effects, and reports errors when they are
found.  Also fix a bug that this utility detected as it was being tested.

FossilOrigin-Name: b0b4624fc5d53bb0cc9fae7dad51984837d946ac
2016-02-06 22:32:06 +00:00
drh f5818aa560 Make sure variable declarations occur at the beginning of blocks, even
with SQLITE_DEBUG enabled.

FossilOrigin-Name: 2f7778e64d93ef237e23ceac01ea9808df5cf2a1
2016-02-06 19:48:50 +00:00
pdr bb3da060e3 Fix an assert() to have a test instead of a side effect
FossilOrigin-Name: a2952231ac7abe165ed070875728f752ae0be608
2016-02-06 14:14:43 +00:00
dan d120a1e3ab Add tests for and remove unreachable branches from fts5 in order to restore test coverage.
FossilOrigin-Name: 22589018ac3321f7bd89ce9fa69e57eae395e324
2016-02-05 21:09:26 +00:00
mistachkin a6f28893ed More work on Windows 10 SDK integration.
FossilOrigin-Name: ebace2c99b6af9230c4bbc31a764c7f397200148
2016-02-05 19:40:23 +00:00
dan b80b8f482c Further streamlining of fts5 prefix query code.
FossilOrigin-Name: ca91bd8ac70a5b3fef127364f73ec675e58bb92c
2016-02-05 19:18:02 +00:00
drh 1cd0f05492 Make sure the "bak.db" database file does not actually exist before
starting the "quota.test" testing.

FossilOrigin-Name: 1cac6c45eeb7dbbcda0c76ba7d3a2ca77bc725cd
2016-02-05 17:49:43 +00:00
drh a23bc8a345 From test scripts, remove stray "breakpoint" commands and blank lines
at the ends of files.

FossilOrigin-Name: a6b35273239669189f33402144f58328b133d182
2016-02-05 16:46:09 +00:00
drh 0539702b8e Improvements to the way out-of-memory conditions are handled, resulting
in an almost 1% performance gain in the commmon case where OOM errors do
not occur.

FossilOrigin-Name: b082538da774ac77f284fd7e22f9b1b9c2abc343
2016-02-05 14:11:12 +00:00
drh 575fad6500 Add the slightly faster sqlite3DbMallocRawNN(db,n) routine for the majority
cases where db is guaranteed to be not NULL.

FossilOrigin-Name: 0a802e96ab06e2643834b83671fa8353da1a348d
2016-02-05 13:38:36 +00:00
mistachkin b91d2214fe Improve ERRORLEVEL handling in the MSVC batch build tool sub-routine 'fn_UnsetVariable'.
FossilOrigin-Name: fe123ab4f17f97ba9d64a7e0589ac47fd9d43877
2016-02-05 04:55:01 +00:00
drh 98c7a12c00 OOM failures on sqlite3_errmsg16() in an app-defined function are no longer
benign.

FossilOrigin-Name: 9efb223f4ce8ccc00515f8f016f7c494c9ae5096
2016-02-05 04:50:27 +00:00
mistachkin 02de84e562 Another small tweak to the MSVC batch build tool.
FossilOrigin-Name: 76718bbce775e13a82893be519ddd98b2f3a4942
2016-02-05 04:39:11 +00:00
drh 17a936f84a Minor simplification of schema error reporting.
FossilOrigin-Name: a8846aeed9992c6c9f1c8bd6e996a4cbe891751e
2016-02-05 02:50:11 +00:00
drh b84e574c89 Further performance improvements that fall out of the mallocFailed changes.
FossilOrigin-Name: d94416ddca8f7ed727dd335d38155ea5945a86b7
2016-02-05 02:42:54 +00:00
drh 4a642b6060 Improvements to the way that OOM errors are processed.
FossilOrigin-Name: c3ef03478a5788c855b3aef385d43ae7f494f440
2016-02-05 01:55:27 +00:00
drh e514f651d0 Temporarily back out the 0.5% performance improvement from
check-in [632071bac5ff32].  Need a more elaborate solution that works
with reentrant virtual tables and SQL functions.

FossilOrigin-Name: 42736fb0adc82a0fb692850ff3dd3f9b501cbf1f
2016-02-04 19:50:33 +00:00
dan 4786cf5a20 Further improve performance of unindexed fts5 prefix queries.
FossilOrigin-Name: c9c6457d8ea911f6cc63967127e58da3146fd3ef
2016-02-04 19:45:19 +00:00
dan be7721d103 Avoid running some particularly time-consuming tests as part of veryquick.test.
FossilOrigin-Name: f465944b75a800ddc6920229ad32c2f39ff91e19
2016-02-04 17:31:03 +00:00
drh 4df86af329 Remove unnecessary sets of db->mallocFailed.
FossilOrigin-Name: b787165b25a240fd5b4a5c7f73b395f30213a1d7
2016-02-04 11:48:00 +00:00
drh c4703eedab Use sqlite3_malloc64() instead of sqlite3_malloc() in the spellfix extension.
FossilOrigin-Name: 634d008c34bd237fc9cfb88dc291394fc5d31efa
2016-02-04 11:15:57 +00:00
drh 3b7f9a68d5 Escape control characters in JSON.
Fix for ticket [ad2559db380abf8].

FossilOrigin-Name: 4f1b5229a3bbc9d40b7433a5eb3139d59d31dcb1
2016-02-04 10:28:57 +00:00
drh 6d258995e6 Refinements to synchronous logic:
(1) Use PAGER_SYNCHRONOUS_FULL rather than the corresponding magic number.
(2) Honor SQLITE_NO_SYNC on xDelete calls with sync
(3) Count xDelete syncs during testing
(4) Fix #ifs on SQLITE_EXTRA_DURABLE so that directory syncs on journal
unlink are off by default.

FossilOrigin-Name: e3157cb5ad0d22758e766a95fb1463a7810f7d7f
2016-02-04 09:48:12 +00:00
drh fabe393da8 In the VDBE loop, only check for OOM errors at jumps rather than after every
opcode, for about a 0.5% performance increase.

FossilOrigin-Name: 632071bac5ff324a74cec9bdbba2deb60c0945e9
2016-02-03 22:14:38 +00:00
dan eb715c62f9 Improve performance of fts5 prefix queries on detail=col tables.
FossilOrigin-Name: ca11f46db047e7f131cef3893f73824758a2076b
2016-02-03 20:04:59 +00:00
drh 19d720d3a7 Fix markup errors in comments used to generate the documentation - specifically
in the documentation on the OP_Seek opcode.

FossilOrigin-Name: ef252bc4b59d272460aaebdc0d4b8e347b0d25a8
2016-02-03 19:52:06 +00:00
drh 6841b1cb3d Add "PRAGMA synchronous=EXTRA" which syncs the directory containing the
rollback journal when the rollback journal is deleted in order to commit a 
transaction in DELETE mode.

FossilOrigin-Name: af92401826f5cf49e62c278f344ab75252a18da2
2016-02-03 19:20:15 +00:00
drh 1b32554b80 Enhance the internal sqlite3VdbeAddOpList() interface to automatically update
jump destinations.  Use this feature to simplify the AUTOINCREMENT code
generator.

FossilOrigin-Name: ae8b9d2edf1b5aef6108e729754911db7682b6a3
2016-02-03 01:55:44 +00:00
dan b06347a5dc Add tests to restore full coverage of fts5 code.
FossilOrigin-Name: 063755c81574800e7db12a42e17d982a8c1e5181
2016-02-02 21:19:21 +00:00
dan 735ff4a809 Enhance the performance of fts5 AND and OR queries.
FossilOrigin-Name: 62ea9e5ab8bc1a20245beebceb5ea62dcd7ec84e
2016-02-02 17:40:41 +00:00
drh b8db549832 Enhance the comment on the sqlite3_index_constraint object to bring attention
to the fact than iColumn field can be negative for a rowid.

FossilOrigin-Name: d8b7b1996eefae7768bfcb82d4ff22c69392aa63
2016-02-02 02:04:21 +00:00
drh 1861afcdbb Change the OP_SetCookie instruction to write the literal P3 value, not the
value in register P3.

FossilOrigin-Name: 6d7d4703ebf3754bec74123d5ba7e861a705f90f
2016-02-01 21:48:34 +00:00
dan df015945e3 Improve performance of fts5 queries.
FossilOrigin-Name: 2334e88244afe6387208be5d527aba9b5ddf4e4c
2016-02-01 20:12:41 +00:00
drh ed94af5eb9 Number VDBE opcodes starting with 0 instead of 1, as this obviates the
lower-bound test on "switch(opcode){...}", making the code smaller and faster.

FossilOrigin-Name: 4c9222f75bfac47f5422fff86b2d69a61933b3a2
2016-02-01 17:20:08 +00:00
dan 3b37bc4206 Update walcrash.test to ensure that, during a particular test, enough data is written to cause SQLite to sync the wal file 14 times.
FossilOrigin-Name: 5d7c092869137a0ba69f93324fe4ed56a05b5985
2016-02-01 16:36:47 +00:00
dan cddb6ba03b Fix a problem causing the OR/covering-index optimization to be disabled if compile time parameter SQLITE_MAX_ATTACHED were set to greater than 30.
FossilOrigin-Name: a17712bf8d98dd485560f434a5350e6381cf1411
2016-02-01 13:58:56 +00:00
drh b0c886510f Minor simplification to the OP_AutoCommit opcode. Fix some code comments
related to transaction control.

FossilOrigin-Name: a9b6a0672f84dd205f9333951e4c2a608d027d71
2016-02-01 13:21:13 +00:00
drh 38bace84cd Fix an assert() that might fail on a corrupt database.
FossilOrigin-Name: 22eaced7274764eaf7ab4b5fc52cc2fcfc285708
2016-02-01 00:21:08 +00:00
dan 482721ab75 Fix new test cases in stat.test so that they work with -DSQLITE_DEFAULT_AUTOVACUUM=1 builds.
FossilOrigin-Name: a2810cf65db13479e2ab255c37abac7841ee985d
2016-01-30 21:09:02 +00:00
dan 52f5d1ba6b Performance enhancement for fts5 column filter queries on detail=full tables.
FossilOrigin-Name: 13fb4aa6a87c5c6258979953da82eedc1a7bf14f
2016-01-30 19:16:11 +00:00
drh 784c1b93fb Merge the implementation of OP_IdxRowid and OP_Seek so that OP_Seek no longer
requires the rowid register and a separate OP_IdxRowid call.  Shorter and
faster prepared statements result.

FossilOrigin-Name: 9bec50a1e7796a6e038db9b1cc7cc1e7e350bf74
2016-01-30 16:59:56 +00:00
drh b8d66dc4ec Only honor the register subtype value if the MEM_Subtype flag is set.
Revised and improved fix for ticket [f45ac567eaa9f9].

FossilOrigin-Name: 1f4c667f37d63fc3ef2e8f2581ecd3a66c054426
2016-01-30 15:52:39 +00:00
dan 5b6c8e4e1d A different way to clear the subtype on VDBE registers when the value of the register is overwritten with new content. To fix [[f45ac567eaa9f93].
FossilOrigin-Name: 2e9fb1295cd31fc29c97444c3dec82fef68e939f
2016-01-30 15:46:03 +00:00
drh af30fdf6ed Output subtype information on register traces for PRAGMA vdbe_trace.
FossilOrigin-Name: 96b780209cc95c3f3769bb880591380d94bfe38d
2016-01-30 14:17:10 +00:00
drh 4b09ec6e11 Add the BTREE_FORDELETE and BTREE_AUXDELETE flags to the b-tree layer interface
and use them.  Add assert() statement to verify that they are correct.

FossilOrigin-Name: 85c467041c9378cae3038756da815e9117ee8c7d
2016-01-30 13:32:30 +00:00
drh 5f4a686f8c Simplification and size reduction to the printf logic. Remove the bFlags
parameter from sqlite3VXPrintf() and sqlite3XPrintf().  Use sqlite3XPrintf()
instead of sqlite3_snprintf() for rendering P4 values in EXPLAIN output.

FossilOrigin-Name: 0bdb41c45aa1cc8e5c136aaa6605d54b401483bd
2016-01-30 12:50:25 +00:00
drh 8ea0056d5c Make use of covering indexes in the OR optimization.
FossilOrigin-Name: 9de3d7123007636aa97da1c70bc34344b0391078
2016-01-30 02:10:38 +00:00
drh b17020265b Change the P4_INTARRAY so that always begins with a length integer. Print
the content of the INTARRAY on EXPLAIN output.

FossilOrigin-Name: 6c520d5726e80b4251338c43c405270d150ea81e
2016-01-30 00:45:18 +00:00
dan eaa6cd87e8 Add tests for the change on this branch.
FossilOrigin-Name: 7cb697f82932a2581af69350117a29c9c8a2544f
2016-01-29 21:16:13 +00:00
drh 945d302215 Different comment on the alternative cursor fields of VdbeCursor.
FossilOrigin-Name: 6e3dcb6d7d960bb513d9a4a002b6cf5ab7159686
2016-01-29 20:58:40 +00:00
dan de892d9660 Experimental attempt to make better use of covering indexes within OR queries.
FossilOrigin-Name: a323ac3a9d42bd5cb38d724c7e1180584b91054c
2016-01-29 19:29:45 +00:00
drh df31221d33 Improvements to FORDELETE processing, including bug fixes and adding
assert() statements to help verify correct operation.

FossilOrigin-Name: 46080b0474363ca6594d2e5c249a280e2b4fc67a
2016-01-29 19:04:11 +00:00
drh 47ab455c2b Remove a stray "exit" in a test script.
FossilOrigin-Name: 10c88bf9f2c238abbbb54797ee2327ab72713e6f
2016-01-29 18:48:08 +00:00
drh 65875f37bc Avoid unnecessary WHERE clause term tests when coding a join where one of the tables contains a OR constraint.
FossilOrigin-Name: 512caa1ad30e6f699e2d006d5ab7674d55d2c746
2016-01-29 18:11:04 +00:00
dan 83f0ab8087 Prepend "rc!=SQLITE_OK || " to the nExtraDelete assert() condition.
FossilOrigin-Name: 2a055ed0afd56e8c6b17cfc31e7808debe9ec765
2016-01-29 18:04:31 +00:00
drh 3b83f0cd8f Avoid unnecessary WHERE clause term tests when coding a join where one
of the tables contains a OR constraint.

FossilOrigin-Name: ab94603974a0ad5342e5aee27603162652e70492
2016-01-29 16:57:06 +00:00
dan 98a4d5a7fa Avoid two more instances of pointer arithmetic on freed pointers.
FossilOrigin-Name: 2910ef64097b890c9f8929bf609ea2827db7ac97
2016-01-29 08:38:35 +00:00
dan 895c00e16a Modify the order of terms in an "if" condition to avoid implicitly comparing a dangling pointer to NULL following an OOM error.
FossilOrigin-Name: 5372f800835da61736a64dcee8b476bbe7ee2e46
2016-01-28 18:22:46 +00:00
dan e61bbf4417 Modifications to ensure the nExtraDelete-related assert() statement does not fail.
FossilOrigin-Name: f43ff8f82d6c1239e6f9a32e7716421c1180ac74
2016-01-28 17:06:17 +00:00
dan d5cafb380e Remove a duplicate "p->magic = VDBE_MAGIC_RUN;" line from vdbeaux.c.
FossilOrigin-Name: 688eb3b400a3f2f8005c341e8259f4c1485cb0ed
2016-01-28 08:58:45 +00:00
drh ba60fbb621 Fix for pthread detection in the configure scripts.
FossilOrigin-Name: 47633ffdbfead3ce7b1f6560660df99f950d24f8
2016-01-28 02:47:32 +00:00
mistachkin 00029a1add Minor correction to the batch tool changes in the previous check-in.
FossilOrigin-Name: 7c89d75de1e8d44d7ebd8eac1320b50dd6c221a8
2016-01-28 00:04:32 +00:00
mistachkin 5a2412f418 Match the MSVC batch build tool sub-routine 'fn_UnsetVariable' a bit more robust.
FossilOrigin-Name: 1edd5f31b9e6f91bb5434055a539428c000f1084
2016-01-27 23:50:14 +00:00
drh def19e3b48 Change the name of the BTREE_IDXDELETE flag to BTREE_AUXDELETE, to better
reflect its purpose.

FossilOrigin-Name: 1d3bf6bebdda9f96734bc139601e9b05344ea0b4
2016-01-27 16:26:25 +00:00
dan 127f720240 Fix tests in fordelete.test to test for the BTREE_AUXDELETE flag.
FossilOrigin-Name: bbd25cf179df5bda1fe729928d6746248f06e46f
2016-01-27 16:17:41 +00:00
drh b89aeb6aa2 Add assert() statements on the nExtraDelete variable in vdbe.c to try to verify
that the FORDELETE and IDXDELETE flags are being generated correctly.  Those
flags are not currently generated correctly, and so the assert()s trip on this
check-in.

FossilOrigin-Name: dde1db0dd2e2cf04706117629756c352b178ebb8
2016-01-27 15:49:32 +00:00
mistachkin d5be6f01cd Support building for Windows 10 desktop using 'MinCore.lib'.
FossilOrigin-Name: 4bf89891fbb076364dc45a6bf3246efa6bc33d5d
2016-01-27 07:28:33 +00:00
drh 8716bfd8cd Merge all recent trunk enhancements.
FossilOrigin-Name: 9a71d56dcea953cb965f1fdda9a8b8f158cdeff6
2016-01-26 23:32:55 +00:00
dan 2f36f06e10 Performance improvements for fts5, particularly detail=col mode.
FossilOrigin-Name: a3d7b8ac53f94d29a11362f193fd1967f30583df
2016-01-26 20:19:55 +00:00
dan 18205c781d Further minor performance improvements and code-size reductions related to fts5 column filters on detail=col tables.
FossilOrigin-Name: b4ac61aeee976296e7719949cd4fb496147a29e8
2016-01-26 20:08:50 +00:00
dan 1c16bccb79 Improve the performance of fts5 column filters on detail=col tables.
FossilOrigin-Name: 249a2d070c34bf884a04cb248b9691e239f2871c
2016-01-26 19:30:49 +00:00
dan fee981e5b9 Enhance fts5txt2db.tcl, a script used to generate fts5/fts4 databases for performance testing.
FossilOrigin-Name: c646e40350e5aa91abcf52de61fb31275bad38f9
2016-01-26 17:08:22 +00:00
dan 8770677c1e Fix issues on unix with opening database files via symlinks that are not in the current working directory. And with nested symlinks.
FossilOrigin-Name: 4003db4a49c6b623750e56f626fa492c8402067f
2016-01-26 14:48:02 +00:00
dan 2349670262 Ensure that unixFullpathname() always nul-terminates its output buffer, even when returning an error.
FossilOrigin-Name: 4a4385564dd3887a7953820b60c99d6ce289f96a
2016-01-26 13:56:42 +00:00
drh f0fc992936 Remove an unused variable.
FossilOrigin-Name: 1c2656c1d37906230edc142d3a4253b16b6e925f
2016-01-26 00:12:42 +00:00
drh 9e0caad428 Add the ability to do Windows builds to the amalgamation tarball.
FossilOrigin-Name: abd2b357c55fdcdbc8e66a81a3fbb7f822ea0a4f
2016-01-25 23:24:38 +00:00
drh a72d15b5f0 Minor changes to the autoconf/README.txt file.
FossilOrigin-Name: 6df8a9c00a9d067f67d492da7a4617908070c6c0
2016-01-25 23:19:58 +00:00
drh 2aac8c7ba1 Fix a compiler warning about doing pointer arithmetic involving a NULL pointer
even though the result of computation is never used.

FossilOrigin-Name: 7c49a9478bd36564e81d33458ca1f4063ddaca83
2016-01-25 22:08:11 +00:00
dan af1b36b1df Only use lstat() if the HAVE_LSTAT macro is defined. Fix some test file issues.
FossilOrigin-Name: 8a6e4147a680ad6c5fdd588468b6daac82349d2c
2016-01-25 18:43:05 +00:00
dan caf6b150a1 Simplify the unixFullpathname() function. This adds a dependency on lstat().
FossilOrigin-Name: f71249d3db9242b8f38955db51a7a5789d002803
2016-01-25 18:05:49 +00:00
dan e88ec187cd Fix issues on unix with opening database files via symlinks that are not in the current working directory. And with nested symlinks.
FossilOrigin-Name: 80398fd44fb232193450103808e1854e0eba5652
2016-01-25 17:04:48 +00:00
drh cc2fa4cf55 Replace the OP_SetIfNotPos operator with OP_OffsetLimit in the VDBE, for
simpler and smaller code.

FossilOrigin-Name: 7ac017a498b6fb28343eef2d24e400c7800660d6
2016-01-25 15:57:29 +00:00
drh 164c957b09 Add the SQLITE_EXTRA_DURABLE compile-time option.
FossilOrigin-Name: 30671345b1c1ee55a2d1aa17273213f1849efd81
2016-01-25 13:55:47 +00:00
drh a7dc4a321d Small simplification to the prepare statement opcode memory reuse logic.
Easier to read, and slightly smaller and faster.

FossilOrigin-Name: 8a1deae497edf3fa43fa96152d140405398c5ed6
2016-01-25 02:15:02 +00:00
drh d0d0f8dc67 Small simplification and performance improvement in memsys5Free().
FossilOrigin-Name: 0a9cff5c4822874b74e90bfca3963bc7e5c753a5
2016-01-25 01:07:59 +00:00
drh 9084ec1d96 Add the SQLITE_SPELLFIX_STACKALLOC_SZ compile-time option to control how much
stack space is available for use as the Wagner matrix in editDest3 of the
spellfix extension.

FossilOrigin-Name: dd0100dd87e2c7c70fabb2d3188f0906e605583d
2016-01-23 22:55:53 +00:00
mistachkin 76d4b1b835 More updates to the README.
FossilOrigin-Name: 9f02868df71d902a2b9118d0b06df18ee92b666b
2016-01-23 21:57:46 +00:00
drh 74f6e6ccf8 Updates to the autoconf README file.
FossilOrigin-Name: 4ce60fa42d8486d219d40d25d785d7f2cabe5e06
2016-01-23 20:43:48 +00:00
drh 021f9a6605 Move Makefile.min.msc into the autoconf subdir where it belongs and change
its name to Makefile.msc.  Adjust build scripts accordingly.

FossilOrigin-Name: 12eb8db79697ef55228c78011d275f36f58271e1
2016-01-23 20:34:27 +00:00
mistachkin 4a25549b08 Minor coding style tweaks for the mkmsvcmin tool.
FossilOrigin-Name: c15e0fc4be08b92547bea1f1cac65581ef497409
2016-01-23 20:16:40 +00:00
drh ac779bcbe9 Adjust the amalgamation-tarball build process so that it includes the
MSVC makefile and the sqlite3.rc resource file.

FossilOrigin-Name: e420f3dc93a0e3364f0773950b7a125f5221a109
2016-01-23 20:09:30 +00:00
drh 06cee48728 Improved comments on the transformation script and on the generated Makefile.
FossilOrigin-Name: c6e633ab73812fe38f3e969f1652f1b5759096e4
2016-01-23 19:47:00 +00:00
mistachkin 408273e722 Use the -integer option when sorting list elements.
FossilOrigin-Name: 949aa614e1401f6ab61cbb2e0469c60d764e6880
2016-01-23 19:24:19 +00:00
dan e9eb1593f5 Fix an fts5 problem with using both xPhraseFirst() and xPhraseFirstColumn() within a single statement in detail=col mode.
FossilOrigin-Name: 72d53699bf0dcdb9d2a22e229989d7435f061399
2016-01-23 18:51:59 +00:00
drh c6aab32144 Changes to spellfix to try to get it to use stack space instead of heap space
in cases where that makes sense.

FossilOrigin-Name: dfcebc7393a3a780ee9c4f257723c303bb633064
2016-01-23 18:24:52 +00:00
dan e17b646fd5 Merge trunk changes (including fixes for warnings in fts5) with this branch.
FossilOrigin-Name: ceccc9ad788fb4da9120915741995b9f088f85ff
2016-01-23 16:20:16 +00:00
dan c66d03f1e1 Fix some signed/unsigned comparison compiler warnings in fts5.
FossilOrigin-Name: 3be336aa893f9eb0837d7d66c83bab1489792b9a
2016-01-23 15:57:06 +00:00
dan 8498f387be Fix a problem involving detail=col and column filters.
FossilOrigin-Name: 7558a0ad2276e91f2faced8ea405d9fdb4fa0c6e
2016-01-23 14:45:36 +00:00
drh c615097d3d Remove an assert() that can be false if compiled with SQLITE_USE_ALLOCA.
FossilOrigin-Name: f0a551edf87ef061deae34d88b02c3b484ae9adc
2016-01-23 14:05:27 +00:00
mistachkin 3e7860938b Add tooling to create an MSVC Makefile capable of building the core library and shell only, using a pre-built amalgamation.
FossilOrigin-Name: c46f1a13cb00264d1164399059250884c7be4ea0
2016-01-23 07:53:04 +00:00
mistachkin 4cfea5c794 More work on the MSVC build.
FossilOrigin-Name: a79c46bc61a35edbaf6112c26e8052314b0eb16a
2016-01-23 00:07:51 +00:00
drh 147ef39486 In the TCL interface, if a database connection object was opened with
the -uri 1 option, then also honor URI filenames for the "backup" and
"restore" commands.

FossilOrigin-Name: a1c8116ced62d81f3f5ca26bbe0877e829d4cc56
2016-01-22 23:17:51 +00:00
mistachkin a8a1873485 More MSVC makefile cleanup.
FossilOrigin-Name: df22556fd75997111e52f96572da8379dfe948be
2016-01-22 22:16:50 +00:00
dan 795502d26c Experimental performance enhancements for fts5.
FossilOrigin-Name: b5a57b812fd6a734cf2a342bf0b730ae18912d73
2016-01-22 19:48:34 +00:00
drh c3dfa5eba7 Reenable the xCurrentTime and xGetLastError methods on the unix VFSes as long
as SQLITE_OMIT_DEPRECATED is not defined.

FossilOrigin-Name: c11c85fdb6514cae54bb44945cc197dcaba72307
2016-01-22 19:44:03 +00:00
drh 40aced5c65 Add the sqlite3TokenInit() utility function.
FossilOrigin-Name: 7323175337b7ba85ac932ca892b28860f6a5b688
2016-01-22 17:48:09 +00:00
dan b5c557b87e Have the dbstat module dequote any argument passed to the CREATE VIRTUAL TABLE statement before attempting to match it against the names of attached databases.
FossilOrigin-Name: e60461e984b8df09256bb0d733dbfae52568a145
2016-01-22 15:44:07 +00:00
mistachkin d7d305a25a Enable FTS4 when building the shell with the MSVC makefile.
FossilOrigin-Name: e4c07df557cd50786b05eecf011bf94708e6e31b
2016-01-22 04:22:36 +00:00
mistachkin 5d4d941e94 Further refinements to the MSVC makefile.
FossilOrigin-Name: 67625b963a6f5a0c6dff1a04a323e693569c2d94
2016-01-22 03:54:36 +00:00
mistachkin edcb4ebba1 MSVC makefile enhancements for use with the Windows 10 SDK.
FossilOrigin-Name: ac2e9d3de54d299f92fc35927b6df6d3aaa2dc59
2016-01-22 01:25:15 +00:00
mistachkin 153d3e91db Fix typo in 'Makefile.in'.
FossilOrigin-Name: 29a51c6dcc0ef7cab51aba0024e9c5bec89c6973
2016-01-21 18:56:10 +00:00
drh e807bdba86 Add a new hint bit on the flags parameter of sqlite3BtreeDelete(). The new
BTREE_IDXDELETE bit indicates that the call is to delete an index entry 
corresponding to a table row that has already been deleted.

FossilOrigin-Name: ac2cbadd8000947c097da5b00c00090fe58fdcff
2016-01-21 17:06:33 +00:00
drh 9c0c57a4ca Improved comments on the FORDELETE hint. No logic changes.
FossilOrigin-Name: a3cec529f0238e4ca1196fec420f2de80d28db78
2016-01-21 15:55:37 +00:00
mistachkin b5a5a23e92 Add 'rbu' to the clean targets.
FossilOrigin-Name: f60f025027ab3acdbc97701f81ff9c11c8463022
2016-01-20 18:47:59 +00:00
dan bd5af9ea31 Add a -detail option to the loadfts5.tcl script. For creating tables with the detail= option set.
FossilOrigin-Name: 81e830e21f81b6428209afa0b8f42f2fd9bd7aab
2016-01-20 16:36:10 +00:00
dan 30908c97ac Fix a problem in autoconf/configure.ac causing --enable-readline to fail if libedit was not present.
FossilOrigin-Name: e8adeb64d4e463772feb58dbd6f00715b92e735c
2016-01-20 15:19:56 +00:00
drh fb3972602c Case folding in the LIKE operator should look at all bits of the character,
not just the lower 8 bits.  Fix for ticket [80369eddd5c94].  This is a
back-out of check-in [0a99a8c4facf] with a testcase added.

FossilOrigin-Name: 204432ee72fda8e82d244c4aa18de7ec4811b8e1
2016-01-20 14:22:41 +00:00
dan 5c3aa0517e Improve performance of sqlite3VtabImportErrmsg().
FossilOrigin-Name: 18d61c8e40ed1466b6a3a2f53bf0eeb09687c20e
2016-01-20 08:47:55 +00:00
drh 1da26a48dd Performance improvement in sqlite3DbMallocRaw().
FossilOrigin-Name: ff8eadbed5004ab03438f737492387dee6b9750a
2016-01-20 03:36:32 +00:00
drh 939e778bc8 Suppress the display of the P4 operand in EXPLAIN output when an opcode
has been converted into a No-op.

FossilOrigin-Name: 9f8297f862a110ded686d091854fae20c6bc393c
2016-01-20 02:36:12 +00:00
drh 9bfb024de0 Remove an unnecessary memset() from the symbol name resolver.
FossilOrigin-Name: da527ddae06460ab4b706cdb871de2188ebaf5ac
2016-01-20 02:21:50 +00:00
drh 4b31bda2c5 Remove an unnecessary memset() for a small size reduction and speed improvement.
FossilOrigin-Name: 730d7efb6fef54ed7c1f4ae27e3b55778ea6ff01
2016-01-20 02:01:02 +00:00
drh 6d664b4bb3 During compilation, transfer the azVar[0..nzVar-1] array from Parse to Vdbe
rather than copying it.  Smaller and faster code.

FossilOrigin-Name: 80dd495f378614e4eca72e71e43061b1b94ee450
2016-01-20 01:48:25 +00:00
drh 36b78ee7d8 Very small simplification to the btree balancer.
FossilOrigin-Name: f421adf54c9db91ba6ca64a8ba3751680e47924a
2016-01-20 01:32:00 +00:00
drh e40cf40c1a Fix an incorrect VFS version number check in the threadtest3.c test program.
FossilOrigin-Name: 5bf6442bec83977006bc5049adcdbd4dd39369fe
2016-01-19 21:36:26 +00:00
drh b8763639bb Fix two harmless compiler warnings about comparisons of dangling pointers.
FossilOrigin-Name: 86944f193f1f06b64471953bb5713ecea7f3d803
2016-01-19 17:54:21 +00:00
dan 4684ffd495 Add further fts5 tests. 100% code coverage is finally restored.
FossilOrigin-Name: b914ece0d146cfc8adba4dc4e8633e14f174d6ea
2016-01-19 16:06:23 +00:00
dan 6d3c2889ec Add tests for fts5. Fix a crash that can occur in fts5 if the database content is corrupted.
FossilOrigin-Name: acaf426449bf6fd3140fd63141750ff69d1119a5
2016-01-18 17:48:28 +00:00
drh c263f7c4b3 Avoid unnecessary calls to memset() for a small performance improvement.
FossilOrigin-Name: 9e8c23acf74944a165c733682a956948b15bd401
2016-01-18 13:18:54 +00:00
dan 0536a07c0e Add a debugging function to print human-readable versions of fts5 detail=none leaf pages.
FossilOrigin-Name: 8358af3658d888516cdef5f8c8d89e9bdee53f91
2016-01-18 09:08:56 +00:00
drh e617bc8c0c Simplification of the VDBE bytecode for incremental blob I/O.
FossilOrigin-Name: d23849f64a110e336f26282bf2b961a2a2372468
2016-01-18 00:46:11 +00:00
drh dad300d8e1 Fix a problem with SQLITE_TEST_REALLOC_STRESS.
FossilOrigin-Name: 0aaf3febb00f622c5ef0853b2491d69f7ca7a21e
2016-01-18 00:20:26 +00:00
dan 3ed7029921 Add extra tests to cover untested branches in fts5.
FossilOrigin-Name: 61deab043dcea860070dba6b02601a7de627fff1
2016-01-16 21:06:41 +00:00
drh 2ce1865dd8 Improvements to the way sqlite3VdbeAddOpList() works, resulting in a slightly
smaller and faster binary.

FossilOrigin-Name: 88ceb588bcdb3ca86d0c58cfdeb61b5fe070872f
2016-01-16 20:50:21 +00:00
dan 8631402e6a Add further tests for fts5. Fix some problems with detail=col mode and auxiliary functions.
FossilOrigin-Name: de77d6026e8035c505a704e7b8cfe5af6579d35f
2016-01-16 18:58:51 +00:00
drh 9b34abee30 Use sqlite3VdbeAddOp4() rather than a separate sqlite3VdbeChangeP4() call, for
a slightly smaller and faster binary.

FossilOrigin-Name: a4258cd4613c55acacb5c7b61faa3de7eb0759d2
2016-01-16 15:12:35 +00:00
drh 095fb474ef Fix a potential use-after-free problem when compiling with SQLITE_HAS_CODEC.
FossilOrigin-Name: 653ea15ad8e23b333e234eb5dde7b80134db2baf
2016-01-16 03:16:19 +00:00
drh 079d446dd2 Remove an unnecessary memset().
FossilOrigin-Name: 689421a9f73ceeab9786840a2d6ee008124d1f25
2016-01-15 21:55:46 +00:00
dan 25247435be Rationalize some code in fts5_storage.c. Add tests to cover recently added branches in fts5.
FossilOrigin-Name: 3b72df405ac9b3a71144f45317d32e25f0084c4b
2016-01-15 19:54:47 +00:00
drh 241873e55c Remove unnecessary de-initialization of the Parse object.
FossilOrigin-Name: 75ab30c5fcb51e556342dc3112f9acf122f79947
2016-01-15 16:11:58 +00:00
drh 055f298ad4 Work toward making the schema parsing logic simplier and more compact.
FossilOrigin-Name: c52ca2c0662bb30ab34574f933429512655b19ff
2016-01-15 15:06:41 +00:00
mistachkin 1e38927c12 Fix a couple C99-isms in FTS5 that cause compile errors on MSVC.
FossilOrigin-Name: 584848d4396d7755027fab377c97e40fbcc90d21
2016-01-15 05:39:55 +00:00
drh 2d80151f32 Combine the xFunc and xStep pointers of the FuncDef object into a single
pointer xSFunc.

FossilOrigin-Name: 0d1b3d7d3ca66cb0b97493f1aeade1703af3c9f4
2016-01-14 22:19:58 +00:00
dan 2cfe049f40 Add a test to verify that the fts3 and fts5 "unicode61" tokenizers are byte for byte compatible.
FossilOrigin-Name: 8ec8314354edc9d6f7d1c8a6370fd984a552a52f
2016-01-14 20:05:59 +00:00
drh 3349620e9e Simplification to the ISO8610 parser in the imnplementation of date/time
functions.

FossilOrigin-Name: b9159f42a517a95ae52464c96431708c00b7bb36
2016-01-14 19:32:46 +00:00
mistachkin 83a2253409 Minor adjustments to the MSVC makefile.
FossilOrigin-Name: e2cba1bbfdcb24e35b2275e29071d8a4e4943417
2016-01-14 18:01:16 +00:00
drh 0ea94db612 Yet another change to FTS5 trying to get it to merge successfully into sessions.
FossilOrigin-Name: 8dedff3b9ac3e6bf9c131fee19f7d26dc1ebd61f
2016-01-14 14:33:36 +00:00
drh d625adb8db Fix more compiler warnings in FTS5.
FossilOrigin-Name: f791fc7009d68941c60d7bf953bab19d86112133
2016-01-14 14:29:57 +00:00
dan 17535393b9 Fix another compiler warning in fts5 code.
FossilOrigin-Name: d17bc2c92f4d086280e49a3cc72993be7fee2da7
2016-01-14 14:19:50 +00:00
dan f705e9deab Fix compiler warnings in fts5.
FossilOrigin-Name: 5a343cc0336bba056df4449e6cd2e3fb9e75a105
2016-01-14 14:15:54 +00:00
drh 7647377f52 Fix harmless compiler warnings in RBU and add RBU to the autoconf and windows
makefiles.

FossilOrigin-Name: fabe78c5d8ab353988f6fe0decacd651edc17ec2
2016-01-14 13:22:24 +00:00
drh 62e63bb9a9 Fix harmless compiler warnings in sqldiff.c.
FossilOrigin-Name: 74808a79ea3194f6cc00084b9dccc380846a6051
2016-01-14 12:23:16 +00:00
drh b4acd6a8d6 Fix the build so that it works for SQLITE_OMIT_WAL again.
FossilOrigin-Name: d55a557bc70460c46a67ae5acd9f8a8356a580c2
2016-01-14 01:56:43 +00:00
drh 13c808a9fc Look for pthread_mutexattr_init() instead of pthread_create() in autoconf
scripts, to work around issues with ASAN.

FossilOrigin-Name: 9c3a0dc2e8bf202cd846841bd5d4ea67aa189c1a
2016-01-13 21:23:48 +00:00
dan 7f50d69359 Add documentation for new API functions to the comments in fts5.h.
FossilOrigin-Name: 14d296fa7b43b4999a1fd070cf030f83fe1b94c3
2016-01-13 18:25:36 +00:00
drh 31a2313fa8 Add the SQLITE_FCNTL_JOURNAL_POINTER file control.
FossilOrigin-Name: ad3daa5427672d2d236939ad3285b765f4601801
2016-01-13 18:12:44 +00:00
drh 504ef44022 Add documentation for the SQLITE_FCNTL_JOURNAL_POINTER file-control.
FossilOrigin-Name: 807c5aee2e5e5c01eb33688a199755c345c3664e
2016-01-13 18:06:08 +00:00
drh a04a8be2c2 When the [https://www.sqlite.org/queryplanner.html#partialsort|block sorting optimization]
is used in a scalar subquery, be sure to exit the loop as soon as the first
valid output row is received.  Fix for ticket [cb3aa0641d9a4].

FossilOrigin-Name: cdbb0947f9ce18d6d7e29ffab5ea6a2ee5365fbb
2016-01-13 17:50:10 +00:00
dan 8656b24144 Add the "detail" option to fts5. Used to reduce the amount of information stored in an fts5 index.
FossilOrigin-Name: a220e85fe535af5ef2da6ef5fb76abe5a96b5abf
2016-01-12 19:45:01 +00:00
drh b19e7352c1 Add the ".vfslist" command to the command-line shell.
FossilOrigin-Name: 5727562b75edf25102cd72607c420d245379c96d
2016-01-12 19:37:20 +00:00
dan fd7601a125 Improve performance of fts5 low level iterators.
FossilOrigin-Name: bc5118f40a11f64ffb4e1c086277fa80b9764745
2016-01-12 19:28:51 +00:00
drh d1dd7507e4 Fix a harmless use of an uninitialized variable following system errors
in the multi-threaded sorter.

FossilOrigin-Name: 4bb2c1df105c2d21f5c4c7ef656ff1d6e15f78bc
2016-01-12 14:10:05 +00:00
drh 8f3f65ec1c Remove an unused field from the MemPage object.
FossilOrigin-Name: 5fc0a4c1f353c4c06fcbc4bce8bbe1897ef49eee
2016-01-12 04:08:54 +00:00
drh 869aaf0941 Make sure all bytes of the WAL file are initialized even if the checksums are
not being computed until commit due to WAL overwrite.

FossilOrigin-Name: 1f44a9bdc1577aed088d9b91882527228015dcd3
2016-01-12 02:28:19 +00:00
drh 9ca33fa4c2 Fix an uninitialized field in the Select object when SELECTTRACE is enabled.
FossilOrigin-Name: fc62851667d9120f98a2641c87bbc5a2485482b2
2016-01-12 02:00:24 +00:00
drh e2258a2076 Various #ifdef enhancements for improved VxWorks support.
FossilOrigin-Name: 75cd41ff179e29c5d45f9d7fed784bc339e0d7a0
2016-01-12 00:37:55 +00:00
drh 00dcecab19 Performance optimization in the sqlite3VdbeChangeP4() routine of the
code generator.

FossilOrigin-Name: 28bd8d5fc541464b69886b7e886939035b42a869
2016-01-11 22:58:50 +00:00
mistachkin 46414c29ba Fix duplicate test number in 'waloverwrite'.
FossilOrigin-Name: f5fb82686697e5fa1937323b1c1b35cf90ad0302
2016-01-11 22:43:04 +00:00
dan 166e7e9705 Merge trunk with this branch.
FossilOrigin-Name: a73d245f2e523a57163bc93d9fb6a74c4cdf21e7
2016-01-11 18:30:34 +00:00
dan 6a657b2477 Add the fts5speed.tcl script to ext/fts5/tool/.
FossilOrigin-Name: 2c0b93553ebb00a70c611eb8dac021877933f088
2016-01-11 18:23:07 +00:00
drh 69f6e2587b Performance optimization on the Column opcode.
FossilOrigin-Name: ecc98bef43c2fd07d64e4efddf340929a875ebac
2016-01-11 18:05:00 +00:00
dan aaf17c41ec Fix bugs in fts5 synonym processing for detail=col and other modes.
FossilOrigin-Name: 0e3c545423246231ddac8fed2f103d71d556e17f
2016-01-11 17:30:28 +00:00
drh 50922cfc7c Performance optimization in sqlite3WalkExpr().
FossilOrigin-Name: 2f8bd5fab8cc51d1f8932c3490fd24dbccf6ef31
2016-01-11 14:19:14 +00:00
drh 2fca70569d Increase the version number to 3.11.0 due to the WAL overwrite enhancement.
FossilOrigin-Name: 8e807bfaa197027d0cb73532baa96755ce71ea12
2016-01-11 12:52:55 +00:00
dan 87dc2bc841 If a single page is written to the wal file more than once, instead of appending the second and subsequent copy to the wal file, overwrite the first.
FossilOrigin-Name: d493d4f1186c15da50558a13490cba0191e6f649
2016-01-11 12:13:47 +00:00
dan c3bd870f09 Add a test case to waloverwrite.test to check that savepoint rollback does not cause a problem.
FossilOrigin-Name: 87dae56c322454094d445e474ae36a4f464272a4
2016-01-11 08:12:40 +00:00
drh 07e8347221 Slightly smaller and faster LIKE/GLOB comparison implementation.
FossilOrigin-Name: 5dddcc78eec5bcd0c7e8fe1b70875ce775488f0c
2016-01-11 03:48:18 +00:00
drh 8997087a00 Improved testability.
FossilOrigin-Name: e83d3a2a4e06665e8a056f63063bd6df03f063b9
2016-01-11 00:52:32 +00:00
drh b7c2f86b85 All WAL frame overwrites even if there are active savepoints. This is safe
because a ROLLBACK TO will cause all reverted pages to be rewritten to the
WAL file prior to COMMIT.

FossilOrigin-Name: 99b31a6b491c1c51227f478d3713b020d37a17cf
2016-01-09 23:55:47 +00:00
dan c9a9022b21 If it is known that checksums will be recalculated on transaction commit, skip calculating checksums when appending frames to the wal file. When recalculating checksums, recalculate them starting with the first overwritten frame - not the first frame in the transaction.
FossilOrigin-Name: 16b34f2537bbc7846d8e6dc2b35daae5af241c1b
2016-01-09 18:57:35 +00:00
dan d6f7c97952 If a single page is written to the wal file more than once, have each subsequent copy overwrite the original frame.
FossilOrigin-Name: 5d113aef2c7d746e8eda88d4e36c04a39b0a11be
2016-01-09 16:39:29 +00:00
drh a829992969 Typo fix in the previous commit.
FossilOrigin-Name: 52c166039831cc8423e2252019ef64a21b9d7c2a
2016-01-08 22:31:00 +00:00
drh 24dbeae6f5 More #ifdef fixes for the unix VFS.
FossilOrigin-Name: 122c111e360761de8166e16ca151cb7260ee9bf8
2016-01-08 22:18:00 +00:00
drh 5a1fb1885a Fix the build for SQLITE_OMIT_SHARED_CACHE, which was broken, possibly
by check-in [2d96aeba].

FossilOrigin-Name: 3392f8fa2ddf2c10ffe91ddd92470040c909b36d
2016-01-08 19:34:39 +00:00
drh e4a08f9e39 Fix a problem with #ifdefs on the system calls in the unix VFS that causes
problems when compiling with SQLITE_OMIT_WAL.

FossilOrigin-Name: ceceea4c5ee242b20ebf216593c15c11ce2c369a
2016-01-08 19:17:30 +00:00
drh c0fba6d8e8 Remove an obsolete #ifdef related to iOS support.
FossilOrigin-Name: e9a51d2a580daa0fb152fe4c891149caa8025b9d
2016-01-08 17:28:24 +00:00
dan 4f40cc6f3d Begin adding fts5 tests involving synonyms and detail=none/col tables.
FossilOrigin-Name: b3e6f15ec2d9a834e2c80b91ffd7097553816228
2016-01-08 17:21:18 +00:00
drh ca3862dc6e Reduce the number of calls to memset() in sqlite3DbMallocZero().
FossilOrigin-Name: cede2bf8e42ac140a8cc75a1d173083f543ba467
2016-01-08 12:46:39 +00:00
dan 33d09da1f8 Fix test file vtabH.test so that it works with SQLITE_ENABLE_ICU builds.
FossilOrigin-Name: 19c1f4483e3df7fa1e9ac7c8a510fa1c906ac7c7
2016-01-08 08:35:14 +00:00
dan 4ca02079cf Fix fts5vocab.test so that it works with detail=none tables.
FossilOrigin-Name: d9135cc723fc4227aace6dcf4ffa4630c9d23aa0
2016-01-08 07:53:09 +00:00
drh 21d61853e7 Add the experimental SQLITE_FCNTL_JOURNAL_POINTER file control for obtaining
the sqlite3_file pointer associated with a rollback journal or WAL file.

FossilOrigin-Name: a02ace9a746ff02fc1a5969bf13939b568624f93
2016-01-08 02:27:01 +00:00
drh c9d6d1b67b Omit performance tracking from the memsys5 memory allocator if neither
SQLITE_DEBUG nor SQLITE_TEST are defined.

FossilOrigin-Name: af5c7714e993f060841f1e893f754ddf3870e6d0
2016-01-07 21:12:40 +00:00
dan 2598b833f0 Update the fts5vocab module to work with detail=col and detail=none tables.
FossilOrigin-Name: eedd095dc1c81ce45df00093ba237dd7b3cdff3d
2016-01-07 20:07:41 +00:00
drh cad2486543 Fix to cause BtShared.db to be set correctly on shared-cache
connections in SQLITE_THREADSAFE=0 builds.  Added assert()s to verify
the correct setting of BtShared.db.

FossilOrigin-Name: 2d96aeba2460779a0a20356739a0ba49144c8a85
2016-01-07 17:19:24 +00:00
drh 8549d55ead Small performance and size optimization spotted while working on the
shared-cache problem.

FossilOrigin-Name: 828958ff77a5c239d55302f570077835c093e0fa
2016-01-07 17:09:43 +00:00
dan 7a2347e20b Add some assert() statements to verify, where possible, that BtShared.db is set correctly.
FossilOrigin-Name: 359277e0e5338f6d7743d58cf99e1c934a8460d5
2016-01-07 16:43:54 +00:00
dan 20d876fa1c Have the vdbe layer call sqlite3BtreeEnter() on all b-trees in use from within sqlite3VdbeExec() even in SQLITE_THREADSAFE=0 builds. This ensures that BtShared.db is set correctly.
FossilOrigin-Name: d0214602d44d6b84b7463d530720e2560aee6edf
2016-01-07 16:06:22 +00:00
drh 72bf6a3e9c Add the "sqlite3 -sourceid" command in the TCL interface. Use that command and
others to output additional information about the test configuration at the 
conclusion of a TCL test.

FossilOrigin-Name: 4f80440bf566959306f6ca8cbb1fd29d138ee38b
2016-01-07 02:06:55 +00:00
dan 7c230dd99c Fix a test script problem caused by a change in constraint handling within the core.
FossilOrigin-Name: 625695b3d7d4eae7536b5f761b96cd7519ac6ada
2016-01-06 19:43:26 +00:00
dan 4d14398a61 Merge latest trunk changes into this branch.
FossilOrigin-Name: e7dcd013516723941c2fb78ecdc96806d49d310b
2016-01-06 19:35:52 +00:00
dan 4364e5c9f7 Fix an fts5 problem involving detail=none, "ORDER BY rowid DESC" and deleted items. Also add tests to verify that the documented operator precedences are correct.
FossilOrigin-Name: 8d05cfd48db1462dfd3efd502d53bd33214403fb
2016-01-06 18:53:57 +00:00
drh 8d52c3b767 Disable the --limit-mem option on fuzzcheck unless the SQLITE_ENABLE_MEMSYS5 or
SQLITE_ENABLE_MEMSYS3 compile-time options are used.

FossilOrigin-Name: 55a11fd627eaf046b3783622b2925399a50a65b4
2016-01-06 15:54:53 +00:00
drh 02a59fab74 Version 3.10.0
FossilOrigin-Name: fd0a50f0797d154fefff724624f00548b5320566
2016-01-06 11:01:07 +00:00
dan f062d676ef Fix a problem with the xPhraseFirstColumn() API in detail=col mode. Remove some unused test code from fts5ac.test.
FossilOrigin-Name: a4e55f73b3c81e28b917395089c0201f9a2c9178
2016-01-06 10:17:26 +00:00
dan 10e1535dee Rationalize and extend some fts5 test code. Fix bugs revealed by the same.
FossilOrigin-Name: fd217fdb396cf22278a496de0e9dec7902ba8b1f
2016-01-05 21:04:35 +00:00
drh 9d4c9824da Always use -DSQLITE_ENABLE_MEMSYS5 for fuzzcheck so that the --limit-mem
option will work.

FossilOrigin-Name: a855697719e288c908ddb7950d32fd17ef546509
2016-01-05 03:39:52 +00:00
drh 0816905cdd Another attempt to get reuse of excess opcode array space working correctly
on all architectures and platforms.

FossilOrigin-Name: 2f8583748abab1e15029d3a8693ba9a66c978c2b
2016-01-05 03:39:25 +00:00
mistachkin 98486c046f Permit the 'test_fs' test module to be compiled and used on MinGW.
FossilOrigin-Name: ac27f38eef7a241d56124c263d9f8c91f372a77f
2016-01-05 01:48:29 +00:00
drh 11e3e538d6 Fix a corner case in the opcode-array reuse logic where the number of bytes of
reusable space might be computed to be a negative number, due to unusual
system alignment restrictions and rounding error.

FossilOrigin-Name: 1aa530144643582658c8c1dd66548662f950efe3
2016-01-04 23:43:47 +00:00
dan 211bd3a20a Fix an OOM handling problem in fts5 detail=none and detail=col modes. Also a bug in the xInst() API when used with detail=col and column filtering expressions. Update the matchinfo() test function so that 'b' is fast with detail=col tables.
FossilOrigin-Name: ee38f9dff5e9239c541515cd8a1aa3d81fdc0ae9
2016-01-04 19:12:00 +00:00
dan 5af1019691 Update more fts5 tests to run in detail=none and detail=column modes as well as the default detail=full.
FossilOrigin-Name: 3fcf3b1e24483b2cd1c1710f053ed8403e09106d
2016-01-04 16:19:51 +00:00
drh 4b4da16344 Fix the conflict2.test module which was broken by check-in [e30062e9f6c].
FossilOrigin-Name: b779ca8a7580e2a0bb1176316c4540867b635229
2016-01-04 13:06:53 +00:00
drh fa385edff3 A new approach to very large sqlite3_mprintf() strings: Back out the
[d655a665] check-in and instead make the size fields in StrAccum unsigned.
Strings generated by sqlite3_mprintf() can now be as large as 2^31-1 bytes.

FossilOrigin-Name: 7adb789f45698e5569b840d23f3f9488db3ed109
2016-01-04 12:07:27 +00:00
drh cc54f43442 Improved comment on the vtabH-3.1 test.
FossilOrigin-Name: 22abe08038cc7b66cbc25e733246d210197c9215
2016-01-04 04:44:31 +00:00
drh 5a60c7d142 Adjust the vtabH.test module to ignore files in the root directory of Windows
machines that contain the "$" character.

FossilOrigin-Name: 73e3355004b8b7ce2e1bb937725f429795528a4f
2016-01-04 04:41:13 +00:00
drh 6044bf8bf3 Limit the length of sqlite3_mprintf() output to 2^30 bytes, even if
SQLITE_MAX_LENGTH is set larger at compile-time.

FossilOrigin-Name: d655a665acfae676d30e90e3731f483bee6acc63
2016-01-04 04:28:11 +00:00
drh 9fbc885afc Fix a harmless compiler warning.
FossilOrigin-Name: 4b404a99aa9bfa6cfe8998f5dc1f84f8be20b840
2016-01-04 03:48:46 +00:00
drh 7f10579a82 Add releasetest.tcl cases for SQLITE_LIKE_DOESNT_MATCH_BLOB and
for SQLITE_ENABLE_CURSOR_HINTS.

FossilOrigin-Name: f300c35efa5f7383b2a74b1c9466c243c17815e4
2016-01-04 01:08:50 +00:00
drh dc0b1f1c29 Bug fix: the conflict resolution behavior for the implied NOT NULL constraint
on the PRIMARY KEY of a WITHOUT ROWID table should be ABORT.

FossilOrigin-Name: e30062e9f6cae980150dda7df440b36dfdcb7bbe
2016-01-03 18:07:57 +00:00
drh 41d0ba72ae Fix a premature reference to utf8_printf in shell.c.
FossilOrigin-Name: 76f5efa68728d899a63a74f2528dfd0c497aa5f0
2016-01-03 11:27:47 +00:00
drh 573d88e8ed Add the number of cores used and the name of the host computer to the
summary at the end of releasetest.tcl.

FossilOrigin-Name: cd3ae0f14c6b28b328b208431d0effcb7b062ec6
2016-01-03 11:17:04 +00:00
dan fe0c3cfee1 Changes to run many fts5 tests with detail=none and detail=col tables as well as the default detail=full. Also fixes for the bugs uncovered by running said tests.
FossilOrigin-Name: 6322a1d984e7946735bace8a069ef24b31754b3b
2016-01-02 19:01:56 +00:00
drh 9abe841e9e Fix a (harmless) typo in an #ifdef for SQLITE_ENABLE_CURSOR_HINTS
FossilOrigin-Name: 2047d2deabf2021ea05d620c3dd4919448027b11
2016-01-02 05:00:31 +00:00
drh bd57308eef Remember the size of the Vdbe.aOp[] array in bytes, to avoid unnecessary
calls to sqlite3_msize().

FossilOrigin-Name: 3e852804c85a5c9f4c4ffafd55d03af6d19fe5cc
2016-01-01 16:42:09 +00:00
drh 3c19bb60d1 Avoid misaligned memory allocations on Sparc in sqlite3VdbeMakeReady().
FossilOrigin-Name: a304e34675404aee860fcc97fa4ffcc57c014812
2016-01-01 16:26:22 +00:00
drh a660caf2f0 Fix an assert() that might be false for a corrupt database.
FossilOrigin-Name: 68360cd2211b7ab25dd4ca55a2e82e31f51f2976
2016-01-01 03:37:44 +00:00
drh 2307926ea9 Remove unreachable branches from the new JSON aggregate functions.
FossilOrigin-Name: 6e30f8c6c3af9b0df39783888a1479f88271f989
2016-01-01 00:15:59 +00:00
drh bdfa1b94e9 Fix the ieee754.test module so that it works both on systems that report
infinity as "inf" and as "Inf".

FossilOrigin-Name: d41d4d7396fba60895535f21c438f8c75e7b2097
2015-12-31 22:29:36 +00:00
mistachkin aae280ef8b In the shell, use utf8_printf() when any string formatting is present and raw_printf() otherwise.
FossilOrigin-Name: 8cf01fff232d15d3c7b7b62b2d890d983e1945f2
2015-12-31 19:06:24 +00:00
mistachkin 5905f86b33 Fix harmless compiler warning seen with MSVC.
FossilOrigin-Name: 98ec778daac835d9ae103f6460b7d897981a5dd6
2015-12-31 19:04:42 +00:00
dan 811501e237 Fix the fts5 integrity-check code so that it works with detail=none tables.
FossilOrigin-Name: 3a1df69e58e5830da1dff158eedbe3817743f58f
2015-12-31 18:39:14 +00:00
dan 841243156f Fix some problems with fts5 detail=none tables. Some still remain.
FossilOrigin-Name: 6a6f7bc40d6b4c8a4a254a9098c9d2f31fde69ca
2015-12-31 17:36:58 +00:00
drh e6110505c9 Fix harmless compiler warnings associated with SQLITE_ENABLE_HIDDEN_COLUMNS.
FossilOrigin-Name: 9c392c1019ee15f27c8e05b41246d2844f91f6c0
2015-12-31 15:34:03 +00:00
drh e5520e2f06 Small size and performance optimization to the VDBE comparison opcodes.
FossilOrigin-Name: 7a0b9413fa94d3f4fa9751ddf9b213a1238954f1
2015-12-31 04:34:26 +00:00
dan d11e397b2c Updates to fts5 to support detail=none mode. As of this commit, many cases are still broken.
FossilOrigin-Name: ac8f4cf0cede6bcbe47eeefb85d80a27e9278212
2015-12-30 19:58:57 +00:00
drh 13778518e7 Reduce the size of the CellInfo object from 32 to 24 bytes on 64-bit machines,
for a small performance increase and library size reduction.

FossilOrigin-Name: 6a4cfc7ab62046eb718ce59eff6b632f239312ac
2015-12-30 18:18:46 +00:00
drh 9906738494 Enhance the command-line shell so that it can handle MBCS characters on
input and output.

FossilOrigin-Name: 3d81dfe3bc5ca9588b7796769d9be7a182f38b1c
2015-12-30 17:03:40 +00:00
drh f19aa5fa6f Changes to the way that the default BINARY collating sequence is recorded
result in a slightly smaller and slightly faster executable.  More work could
be done to make this cleaner.

FossilOrigin-Name: 2081d75767dc590b4c8457e5f8e5f18ba5f8eaa7
2015-12-30 16:51:20 +00:00
drh 0472af91ec Simplification to the xfer-optimization logic.
FossilOrigin-Name: f35ba018da843897acca58f70541b940598bc271
2015-12-30 15:18:16 +00:00
drh 31d175dde4 Remove unnecessary tests from the LIKE pattern matcher. Slightly faster and
slightly smaller, and it should also now works with EBCDIC.

FossilOrigin-Name: 0a99a8c4facf65ec67d8d86108c9a3f723f7cbd6
2015-12-30 14:06:22 +00:00
drh e05461cc8e Enhance the command-line shell to handle MBCS characters on input and output.
FossilOrigin-Name: a0a08b8c0bbd4d71955261f6b7e997701ca68e18
2015-12-30 13:36:57 +00:00
drh ff135ae4c3 Add the json_group_array() and json_group_object() aggregate functions to
the JSON1 extension.

FossilOrigin-Name: 7f386a9332237100a345035ca213327e21d95855
2015-12-30 01:07:02 +00:00
dan 9a3a5275cd Add the xPhraseFirstColumn() and xPhraseNextColumn() API functions to fts5. For iterating through the set of columns that contain intances of a phrase.
FossilOrigin-Name: 8c30605bcd0a78a5015948171145bc6f640b8358
2015-12-29 19:35:03 +00:00
dan 9f44deed93 Change the name of the offsets=0 option to "detail=column". Have the xInst, xPhraseFirst and other API functions work by parsing the original text for detail=column tables.
FossilOrigin-Name: 228b4d10e38f7d70e1b008c3c9b4a1ae3e32e30d
2015-12-28 19:55:00 +00:00
drh e1462a762c Avoid a harmless compiler warning on systems where the byteorder cannot
be determined at compile-time.

FossilOrigin-Name: 7c7b7f26306b6aa6ff35b871ad756f43f5db9838
2015-12-24 14:53:27 +00:00
dan 3e6a141130 Fix some harmless gcc compiler warnings. Mostly in fts5, but also two in the core code.
FossilOrigin-Name: 5d44d4a6cf5c6b983cbd846d9bc34251df8f4bc5
2015-12-23 16:42:27 +00:00
drh caeca516a7 Enhance the 'utc' modifier on date/time functions so that if the LHS is
already known to be in UTC, the modifier becomes a no-op.  This is not an
incompatibility because the behavior is documented as "undefined" in that
scenario.

FossilOrigin-Name: b910a3d53769689d9212a06f974ccce54844bbe4
2015-12-23 10:54:48 +00:00
dan 8f9ced636f Updates so that fts5 API functions xInst, xPhraseFirst and xPhraseNext work with the offsets=0 option.
FossilOrigin-Name: 69bffc1632c8a8f3bfe5bf92607e64fed982e48c
2015-12-22 18:54:16 +00:00
dan 159fd77e0f Fix an fts5 integrity-check problem that affects offsets=0 tables with prefix indexes.
FossilOrigin-Name: 609a0bc7f34e6dae74ce756aff920f3df78fe828
2015-12-21 18:45:09 +00:00
drh 1c75c9d7f1 Ensure that the Expr objects that describe indexed expressions are not modified
by code generation.  Fix for an assert() problem found by Jon Metzman using AFL.

FossilOrigin-Name: 34073ce87d88a02313217023ae92e15939192cd9
2015-12-21 15:22:13 +00:00
dan c58b9eeaaa Fix a problem with prefix queries on fts5 offsets=0 tables.
FossilOrigin-Name: ad0987d83c252dd8d6a69321893629d7be805c28
2015-12-18 19:07:14 +00:00
drh d319b8c143 Micro-optimizations and comment fixes on the mem5.c memory allocator module.
FossilOrigin-Name: 8bf5e056eb8beb6e0ed5874fb24d7fe9f0b66d2b
2015-12-18 16:29:47 +00:00
drh 45ac1c70b3 Reduce the size of the CellInfo object from 32 to 24 bytes on 64-bit machines.
FossilOrigin-Name: 7850715406458a61cff9eba5ad915f61f6d99482
2015-12-18 03:59:16 +00:00
dan b12dc84fbb Add the "offsets=0" option to fts5, to create a smaller index without term offset information. A few things are currently broken on this branch.
FossilOrigin-Name: 40b5bbf02a824ca73b33aa4ae1c7d5f65b7cda10
2015-12-17 20:36:13 +00:00
drh 1db0a72be2 Fix the spellfix1_scriptcode() function to ignore whitespace and punctuation,
and to recognize hebrew and arabic scripts.

FossilOrigin-Name: 7adfa4a5794e47f97491c08abeaaac90e826b331
2015-12-17 14:18:21 +00:00
drh 5732671db9 Fixes for harmless compiler warnings.
FossilOrigin-Name: 85ebd46c701e0a094a4690cd8f1d0cbae9aa257c
2015-12-17 13:28:50 +00:00
mistachkin b9becaa268 Fix even more harmless compiler warnings.
FossilOrigin-Name: 1d0e6aa119da8e15d35508f5d75ffc729979da92
2015-12-16 23:30:30 +00:00
mistachkin 8ccdef6be4 Fix some more harmless compiler warnings.
FossilOrigin-Name: 18f531e1cf3c8bb986d912c9c5e3f5698360c93e
2015-12-16 22:06:52 +00:00
mistachkin 8c7cd6a9d8 Fix compiler warning seen with MSVC.
FossilOrigin-Name: 18a4c0540bf4f02335e9e9def1f2b0d4d784ef08
2015-12-16 21:09:53 +00:00
drh 8b0ba7b0b8 Make greater use of the SQLITE_WITHIN macro.
FossilOrigin-Name: f2fc3aede55c8fa0351697f9f5ce4e544334c9af
2015-12-16 13:07:35 +00:00
dan 991c5d6413 Update the mkautoconfamal.sh script to make the building of the sqlite3-autoconf-VERSION.tar.gz package more orthodox.
FossilOrigin-Name: 1928f8945b7cdf733129619b7ab02d1addf63478
2015-12-15 19:32:12 +00:00
drh 3592680734 Add the SQLITE_OMIT_PARSER_TRACE compile-time option.
FossilOrigin-Name: 2fda43e6e097a4a5510cce7784c31ceedc3d6e6d
2015-12-15 13:50:22 +00:00
dan b1d6b53694 Add a missing memAboutToChange() macro to vdbe.c, the lack of which was causing an assert() to fail incorrectly. Problem found by libfuzzer.
FossilOrigin-Name: 1a24791109da607d502ac41f179fe6c1dc46c774
2015-12-14 19:42:19 +00:00
dan 0f308f5d47 Add a new assert() statement to the snapshot-specific part of sqlite3WalBeginReadTrans().
FossilOrigin-Name: d8a12023be32bdc6df18b0a5f38b917799854342
2015-12-11 14:59:49 +00:00
drh 567a43bbc3 Simplified alignment constraints in the memory reuse logic of
sqlite3VdbeMakeReady().

FossilOrigin-Name: e998513e442ce1206b12dc28bdc996d7b5f9f94d
2015-12-11 13:51:02 +00:00
drh cc99e24491 Add the experimental snapshot interface. Because it is experimental, it is
subject to change or removal at a later date.

FossilOrigin-Name: 9b124a5a310aec0145495c9980bc0c1308fcca02
2015-12-11 12:44:52 +00:00
drh 9b810ae8f3 Fix a memory allocation bug introduced last week by check-in
[a9e819082ba].  The bug only appears on systems where the size of a structure
is not always a multiple of 8 - which in practice means only on 32-bit 
windows systems.

FossilOrigin-Name: 96d3e99ffe59b5280b8b7fc269c94a72e15c345b
2015-12-11 04:11:17 +00:00
drh 5a6e89c644 Mention that the snapshot interfaces are only available if SQLite is compiled
with SQLITE_ENABLE_SNAPSHOT.

FossilOrigin-Name: 843c15a552657ca43ff200edb7da7566752d7941
2015-12-11 03:27:36 +00:00
drh 68d28ea4f0 Disable the snapshot test scripts if not compiled with SQLITE_ENABLE_SNAPSHOT.
FossilOrigin-Name: 5fd008f0433833e4341d526dcc2387570ffe1fea
2015-12-11 03:20:39 +00:00
drh c49e960d41 Fix a variable type mismatch problem in the snapshot logic.
FossilOrigin-Name: 93fb8010e4999b6b832d63a7c5a152f65d4415a3
2015-12-11 03:16:54 +00:00
drh 71b62fa456 Fix a bad assert related to snapshots.
FossilOrigin-Name: 767ee30efa5dd469e3a51d4e44cbe473061819b9
2015-12-11 01:22:22 +00:00
drh e230a8994e Snapshot documentation updates. Comment changes only - no changes to code.
FossilOrigin-Name: ef51a398a04963508389ffe2f9d8359c1ec48261
2015-12-10 22:48:22 +00:00
dan 7116dc60dc Update the sqlite3_snapshot_get() API so that if the caller does not have an open read transaction on the named database, one is automatically opened.
FossilOrigin-Name: b9c90f10297d8516a661449e8af898e682c930aa
2015-12-10 20:03:08 +00:00
dan 745c14eb15 Add tests to snapshot.test.
FossilOrigin-Name: f3b743623a4501833478c8a86c0922931955aeb6
2015-12-10 19:44:34 +00:00
dan a7aeb39836 Return SQLITE_BUSY (not SQLITE_BUSY_SNAPSHOT) if sqlite3_snapshot_open() fails to obtain the shared checkpointer lock.
FossilOrigin-Name: 5343060bcc6c99029f731f8020d2cba3f405f207
2015-12-10 19:11:34 +00:00
dan 7d15979420 Add tests to ensure that an sqlite3_snapshot_open() client cannot be tricked into reading a corrupt snapshot even if another process fails mid-checkpoint.
FossilOrigin-Name: b908048b6cfa1ee2fe1f7a17bae475ddd9d0376c
2015-12-10 18:06:21 +00:00
drh 34628b4b4f Move pointer range comparisons into a macro, where they can be dealt with in a more portable way.
FossilOrigin-Name: 05bc4f920ce23da48d1da6cd36a956fd6fd7c862
2015-12-10 17:59:50 +00:00
dan 3bf83ccd70 Have sqlite3_snapshot_open() avoid a race condition by taking a shared CHECKPOINTER lock while checking pInfo->nBackfillAttempted.
FossilOrigin-Name: 8084eae0bc4f6513b1147fb890a6b2813f1c0a09
2015-12-10 15:45:15 +00:00
drh ac536e613a Move pointer range comparisons into a macro, where they can be dealt with
in a more portable way.

FossilOrigin-Name: ad3124c834b080aaaf24934d6f08b3601ac3ae53
2015-12-10 15:09:17 +00:00
mistachkin c9fb38e7ad Fix spacing typo in comment. No changes to code.
FossilOrigin-Name: 3a18526fc2253658dad84c5e600481c8a62efe40
2015-12-10 03:16:47 +00:00
drh 998147ec38 Add the nBackfillAttempted field in formerly unused space in WalCkptInfo and
use that field to close the race condition on opening a snapshot.

FossilOrigin-Name: cb68e9d0738fc7db7316947b4d2aab91aae819f2
2015-12-10 02:15:03 +00:00
dan 65127cd57d Update sqlite3_snapshot_open() to reduce the chances of reading a corrupt snapshot created by a checkpointer process exiting unexpectedly.
FossilOrigin-Name: 7315f7cbf4179aadda0f1a0baa1526a9b9f9729f
2015-12-09 20:05:27 +00:00
drh 5ef09bf918 Further simplifications to the VDBE code generation logic that flow out
of the previous check-in.

FossilOrigin-Name: 6a5dfe85b519b920ce8c842057767a8793d92236
2015-12-09 17:23:12 +00:00
drh 8c8dddc904 Simplification of the DROP TRIGGER logic using sqlite3NestedParse() instead
of hand-coded VDBE code.  This is a manual cherry-pick of the key change from
check-in [c80bbf14b365d].

FossilOrigin-Name: 8021b4c8139ba56d6b1e2e26aeec4f9bf77f37c9
2015-12-09 16:26:38 +00:00
drh ee3b7a2767 Merge unrelated fixes from trunk.
FossilOrigin-Name: 362615b4df94358d0264b0991c3090a0878f054c
2015-12-09 16:04:06 +00:00
drh 72ea29d7ae Changes to avoid undefined behavior in memset() and memcpy() and in the
comparisons of pointers from different allocations.  All problems are found
by analysis tools - none have been seen in the wild.

FossilOrigin-Name: 901d0b8f3b72e96ffa8e9436993a12980f5ebd51
2015-12-08 16:58:45 +00:00
drh ea06a271a4 Avoid doing comparisons with pointers that might have been previously been
passed to realloc() and/or free().

FossilOrigin-Name: f20396adb2cff12a17a3fc90b36241ae3fdfd62a
2015-12-08 16:08:10 +00:00
drh 92a8277149 Add a test case of the form "WHERE a<2 OR a<3" using PRAGMA count_changes.
This test case was failing before the 3.9.0 release.

FossilOrigin-Name: 177862c1d50ba899d890fbc35f35e7423bc6aed5
2015-12-08 04:18:33 +00:00
mistachkin a295d1521a Update the TclKit download URL.
FossilOrigin-Name: 07e5199c6f868cc02a0b708865254056c4f3daf3
2015-12-08 00:47:32 +00:00
mistachkin 855ed4a3b4 Update MSVC batch build tool to the latest Windows 10 SDK version.
FossilOrigin-Name: 2ad5017190334b7dd53294a30c3b3232e0c35869
2015-12-07 23:31:59 +00:00
drh df12f1c69b Add the ".changes ON|OFF" command to the sqlite3.exe command-line shell, for
testing and verifying the sqlite3_changes() and
sqlite3_total_changes() interfaces.

FossilOrigin-Name: 9bbe1afc1521b111a0a93803b41ff04e0ee55630
2015-12-07 21:46:19 +00:00
drh dc27851e21 Fix the openDirectory() routine in the unix VFS so that it works for databases
located in the root of the filesystem and for database files that have no
pathname at all.

FossilOrigin-Name: e7ae120d04cffafd9bc2b4ecd68571c17e05ed72
2015-12-07 18:18:33 +00:00
drh d797a9b5cb Changes to avoid obscure, theoretical undefined behavior. This is preventative
measures only - no actual problems observed on tested compilers.

FossilOrigin-Name: a9e819082ba19e72db03bba37edfb7702ff489a5
2015-12-07 16:43:44 +00:00
dan 818b11aebb Add tests for snapshot_get(), _open() and _free().
FossilOrigin-Name: 502cc6f353358946080d9bcd335aed526825b88a
2015-12-07 14:33:07 +00:00
dan fc1acf33b8 Add untested implementations of experimental APIs sqlite3_snapshot_get(), _open() and _free().
FossilOrigin-Name: 0715eb00aa8891400cd50a15509d3d7b13789626
2015-12-05 20:51:54 +00:00
drh 28a6a1168b Remove the dependence on "exec ls -U" from the vtabH.test module, as the -U
option to "ls" is not universally available.

FossilOrigin-Name: 4ecbc75b465533cf80e166a9d0879b9afd3fe2be
2015-12-04 13:44:07 +00:00
drh 2f5bfd959a Prevent a segfault on Solaris in the test_fs.c due to differences in the
definition of the dirent object.

FossilOrigin-Name: 042738ad3b769ad70fd7603f928d5b94a952267d
2015-12-04 03:27:45 +00:00
drh 15427279c8 Fix typos in requirements text and update requirements marks. No changes
to code.

FossilOrigin-Name: 8534a46c06601ad35b97caee442371f24c718d0f
2015-12-03 22:33:55 +00:00
drh 9802947fd8 Improved OOM recovery in the SELECT code generator logic.
FossilOrigin-Name: e6521a436d464a42b87a7d5ba5cc98235b92440a
2015-12-03 21:47:30 +00:00
drh 7a7f688979 Make the SQLITE_ENABLE_8_3_NAMES compile-time option available to
sqlite3_compileoption_used().

FossilOrigin-Name: 06338201f3f00151232e5c6a40edcdbea04d7553
2015-12-03 20:50:10 +00:00
drh 90e5dda217 Cleaner code and additional comments on the handling of 8+3 filenames when
trying to find the name of a database file based on its journal filename, 
in the unix VFS.

FossilOrigin-Name: 9e489a71f2aeb1f13f9ca6f106b9144d07ca25aa
2015-12-03 20:42:28 +00:00
drh 7be53fe441 Make the sqlite3_status64(), sqlite3_strlike(), and
sqlite3_db_cacheflush() APIs available to loadable extensions.

FossilOrigin-Name: a78e865607194718e2ef958879dbf549ac3c9970
2015-12-03 13:43:07 +00:00
dan 5fcc1ba4e7 Fix threadtest3 so that it builds using the autoconf build system.
FossilOrigin-Name: d96de532cc4a192cfebae900701dcee0a7d29273
2015-12-03 12:01:54 +00:00
dan 48c06f32ca Improve concurrency in test_multiplex.c. Add a switch to "threadtest3" allowing it to run using the multiplexor VFS.
FossilOrigin-Name: 9d2c62b04e3a9ac5d9adea2aac7ec3f3bc3e88bd
2015-12-03 11:51:18 +00:00
drh c18ed977e8 A unix VFS change replaces fsync() with fstat() when using SQLITE_NO_SYNC, so
set PRAGMA synchronous=OFF in the sysfault-3 test to avoid erroneously causing
errors in xSync.

FossilOrigin-Name: 4f7f355021f9eb048fffc84e559bfb3fdb1e1e69
2015-12-03 01:48:32 +00:00
drh f7ce4291a9 Remove unreachable branches from the decltype computation logic in the query
planner.

FossilOrigin-Name: 4f2bcff94c672312805be1400050a7026f93a9d7
2015-12-02 19:46:12 +00:00
dan 9a8941fc83 Have the sqlite3_column_decltype() API report the declared types for the left-most SELECT statement in a compound SELECT.
FossilOrigin-Name: 3e1d71fcaf57c0223ab9a7366c8607f8f66bb21c
2015-12-02 18:59:44 +00:00
drh af19f173d3 Fix an incorrect, though harmless, assert() in the unix VFS.
FossilOrigin-Name: 4692ae84f93530e27d7c106a60236355e176b7fd
2015-12-02 17:40:13 +00:00
drh ab37277367 Remove more (dead) SQLITE_FCNTL_WAL_BLOCK logic from wal.c - code that was
missed during the [e1d5320ca08933] check-in.

FossilOrigin-Name: 58c15c6af964563ac7ece8606d16730ccf9ee72b
2015-12-02 16:10:16 +00:00
drh 333e6ca9a5 Remove an unreachable branch from the unixMapfile() routine of the unix VFS.
FossilOrigin-Name: b50f67bc46e65fe4e51667d48b4add58706a9443
2015-12-02 15:44:39 +00:00
drh f3b1ed0fc2 Minor simplifications to the unix VFS.
FossilOrigin-Name: 2f13c16b45685ec6850cbd9da79e8198bad6a491
2015-12-02 13:11:03 +00:00
drh 2c8fd12f42 Change the SQLITE_NO_SYNC compile-time option to call fstat() in place of
fsync() rather than being a total no-op.

FossilOrigin-Name: f64ea8a052af9790d5e6987cbd5e81d77da6f172
2015-12-02 02:33:36 +00:00
drh adfa22e118 Fix a (harmless) off-by-one error in the unix VFS logic that fsync()s a
directory after deleting a file.

FossilOrigin-Name: 3d02711a709a7e708edb0ea8ca5d17b39dd307f6
2015-12-02 02:08:30 +00:00
drh 50358adfaa Simplification of the logic used to take the process-wide lock in the
unix-excl VFS.

FossilOrigin-Name: 73defd52bb0e3e5db763d3bfbeebc972b645867e
2015-12-02 01:04:33 +00:00
drh dcfb9652fd Remove all traces of SQLITE_FCNTL_WAL_BLOCK from the unix VFS - that feature
had been disabled for a long time and never actually worked.

FossilOrigin-Name: e1d5320ca089336e26d200305b744b06ce883be4
2015-12-02 00:05:26 +00:00
drh 053378dfa8 Simplification to the posix_fallocate() replacement used for the
SQLITE_FCNTL_SIZE_HINT file control in the unix VFS.

FossilOrigin-Name: 74934d3f60ad9f6550297410eada0f288e0123c4
2015-12-01 22:09:42 +00:00
drh 41d2e66ef3 Add the SQLITE_LIKE_DOESNT_MATCH_BLOBS compile-time option.
FossilOrigin-Name: 9e1d6d4c391ff90077f0d1cdeb567969fee9f747
2015-12-01 21:23:07 +00:00
drh 415afddaae The test_fs.c test module now works on Windows.
FossilOrigin-Name: e3d8628456848a70035bbdeca6dc6c21f688b9a5
2015-12-01 17:48:45 +00:00
drh e1818ec740 Simplification to the read and write primatives in the unix VFS.
FossilOrigin-Name: 9eefa449792f03c4c149edcbc6b9b7692617994c
2015-12-01 16:21:35 +00:00
mistachkin 92af1ebc75 Add experimental support for the 'test_fs' test module on Win32.
FossilOrigin-Name: f3ffb3aeea95712e92919fd5071741327add9643
2015-11-30 23:29:07 +00:00
drh c386ef4f2c Add the SQLITE_PRINTF_PRECISION_LIMIT compile-time option.
FossilOrigin-Name: ecad75d69e0d5c83dd3584d363e557e84b65f7f2
2015-11-30 22:52:14 +00:00
drh 025d2f7ad8 Fix a problem in xFullPathname for the unix VFS. The problem was found by
Kostya Serebryany using libFuzzer.

FossilOrigin-Name: bb1e2c4df0b81327923f121dd6c002845486a314
2015-11-30 22:22:23 +00:00
drh 40fe8d31f5 The EOVERFLOW errors from fstat() is not possible unless SQLite has been
compiled with SQLITE_DISABLE_LFS.

FossilOrigin-Name: 8cfb7a50bb70ba1e021c1d12d31563e98a20d291
2015-11-30 20:36:26 +00:00
drh f8b0be48d1 Fix the threadtest3 test program so that it works with VFSes that omit the
xCurrentTime() method and supply only xCurrentTimeInt64().

FossilOrigin-Name: 3b155855f3d5918f1df7dbd19783215b3da0ca3e
2015-11-30 19:15:25 +00:00
dan d6b459c996 Add the "colUsed" field to the sqlite3_index_info structure passed to virtual table xBestIndex methods. To indicate the subset of the virtual table columns that may be required by the current scan.
FossilOrigin-Name: 47f10b7e5d8c1d965df891990090623444933cc9
2015-11-30 12:01:37 +00:00
drh a8de1e1c90 Simplifications to the locking logic in the unix-dotfile VFS.
FossilOrigin-Name: 583813525888c7e106f3e8cb46c1a507006daee6
2015-11-30 00:05:39 +00:00
drh 06db66f989 Fix the sqldiff utility program so that it works for schemas that have
tables with zero-length column names.

FossilOrigin-Name: 64263ccb8f9835c615242de6e28db24f953422fa
2015-11-29 21:46:19 +00:00
drh b7e50ad555 Improvements to temporary file creation logic in the unix VFS.
FossilOrigin-Name: d6e177fd09c83d46adc5b5d36e9a439aa5397450
2015-11-28 21:49:53 +00:00
drh 790f287c53 Add the SQLITE_FCNTL_VFS_POINTER file control which obtains a pointer to
the top-level VFS in use by a database connection.

FossilOrigin-Name: 7c6a809e25138950f50554e1fb96e0b6ebbe0bd4
2015-11-28 18:06:36 +00:00
drh ecf0c275bb Disable testing with SQLITE_USER_AUTHENTICATION as the makefiles are not set
up to do that.

FossilOrigin-Name: 14bbcdc64ecc21f47aed8935858788928ca63107
2015-11-28 17:38:22 +00:00
drh a6082f699e The first argument to SQLITE_CONFIG_PAGECACHE, SQLITE_CONFIG_SCRATCH, and
SQLITE_CONFIG_HEAP must always be a pointer.

FossilOrigin-Name: 5e14cadff09d7425c8e1cc5e817f2b0609e52a46
2015-11-26 22:12:41 +00:00
dan 1acb539f4c Add the "colUsed" field to the sqlite3_index_info structure passed to virtual table xBestIndex methods. To indicate the subset of the virtual table columns that may be required by the current scan.
FossilOrigin-Name: 116b206494eb8ba963c7c5acfbf9e7b6db11c79c
2015-11-26 19:33:41 +00:00
dan fab1d401f8 Fix a problem with the userauth extension and no-authentication databases. Run the tests for this extension as part of the Debug-One module in releasetest.tcl.
FossilOrigin-Name: 8b15621952889b4ba53b2ea3171fef7ef0479ddb
2015-11-26 15:51:55 +00:00
drh acb6b28d60 Simplify logic for syncing directories after creating or deleting a file in
the unix VFS.

FossilOrigin-Name: eb180b4f04d412dcd0af138e2dd7f62fbb5ac439
2015-11-26 10:37:05 +00:00
drh 5a2d970a1a Small simplification to the xOpen method in the unix VFS.
FossilOrigin-Name: 96e7d638ecdabbf84a152036eb01d408d142839e
2015-11-26 02:21:05 +00:00
drh 970942e4fc Simplify the temporary filename generator and the time-of-day functions in
the unix VFS.

FossilOrigin-Name: 6c5621ce1b1a65913b088ed8be65f9b689260d2c
2015-11-25 23:13:14 +00:00
drh 489f1e86e3 Fix harmless compiler warnings in test_fs.c. Fix typos and clean up the text
of the documentation for sqlite3_strglob() and sqlite3_strlike().

FossilOrigin-Name: 697b20534c2d780cdd8cc165d2930f6e56480770
2015-11-25 18:40:38 +00:00
dan 1e93173ffc Update test_fs.c to include a virtual table that reads a file-system hierarchy. Use it to further test GLOB and LIKE support for virtual tables.
FossilOrigin-Name: 6ef6578c03b7cfbeaaf3627b9eea2febf501ace5
2015-11-25 18:07:46 +00:00
drh d260b5b2ce Make the xAccess method of the unix VFS smaller and faster.
FossilOrigin-Name: 191aef986ffc4ef34d813e417e52a4ec820b0300
2015-11-25 18:03:33 +00:00
drh 5337dacbad Remove unused methods from the unix VFS.
FossilOrigin-Name: 228bd15bbb7a1e6e3e0d03832e7f39ba169356a8
2015-11-25 15:15:03 +00:00
drh 91c4defbcf Simplification of the error code translator in os_unix.c. Code cleanup only.
The logic is unchanged.

FossilOrigin-Name: 2a20f793fdf6a2e88b679a7bd4e8ccf2935df049
2015-11-25 14:00:07 +00:00
dan f5d8c58950 Fix the fts5 "prefix=" option to match the documentation (space separated list, multiple prefix= options supported). The undocumented comma-separated format (compatible with fts4) still works.
FossilOrigin-Name: 11eb8e877e2ba859ef6b44318f286597186dfaf2
2015-11-25 11:56:24 +00:00
drh d4a3ce49d7 Enhancement the virtual table interface to support LIKE, GLOB, and REGEXP
operators.  Also add the sqlite3_strlike() interface, which might be useful
as part of the implementation of LIKE on some virtual tables.

FossilOrigin-Name: a6bfd4692c3f8b107546fbcaeb985d2c1817b3c1
2015-11-25 01:57:42 +00:00
drh 8b4a94adc1 Add the sqlite3_strlike() interface, which might be useful for implementing
LIKE operators on virtual tables.

FossilOrigin-Name: e70ec71d6883f2f8fc75301ff985bccb5aa06127
2015-11-24 21:23:59 +00:00
dan ff7b22b714 Fix a problem in whereexpr.c causing a crash while processing a user-function taht accepts zero arguments.
FossilOrigin-Name: 069e51b19c773aa3017a8d307c8daa0766c224ba
2015-11-24 18:16:15 +00:00
drh 060f9a4a18 Fix harmless compiler warnings in the TCL test harness logic.
FossilOrigin-Name: 2fba7a96566b5448f527a4ec6a26e860c4889813
2015-11-24 18:04:39 +00:00
dan 898f70bc28 Merge latest trunk changes with this branch.
FossilOrigin-Name: 99222bb3e5f9b2a9a10d9561a9fd8c0f717baaff
2015-11-24 17:44:26 +00:00
dan 43970dd774 Add further tests and related fixes for GLOB/REGEXP/LIKE support in virtual tables.
FossilOrigin-Name: c5e9fd0dc92a07db3d3b5f5c5ad8fb63b3425c2b
2015-11-24 17:39:01 +00:00
drh 5a8d190b9e Remove from os_unix.c pointless logic that tries to prevent a recurrence of
a warning message that can only occur once.

FossilOrigin-Name: 20256177072caa4f2b4114038ad1c8f6e26bc562
2015-11-24 16:40:23 +00:00
drh aaeaa18e2e Fix a comment typo in the unix VFS. No changes to code.
FossilOrigin-Name: 32e138796c66c88e8cbb77aa3a4282a38d1f959a
2015-11-24 15:12:47 +00:00
drh 6226ca2a6d Make the geteuid() system call overloadable using xSetSystemCall() on the
unix VFSes.

FossilOrigin-Name: 6c2ddea65e1871b2fcb4991c5b3e6992993db3ea
2015-11-24 15:06:28 +00:00
drh 7060ef9294 Add a test case for the fix of check-in [19d9f9ce691963310]
FossilOrigin-Name: 19a9c07b26a4123dc60abdcc84a956f88c352bab
2015-11-24 03:50:16 +00:00
drh 2edc5fd73a Remove an incorrect ALWAYS() macro. Fix for ticket [e5c6268dd807fa8950] -
a problem introduced in SQLite 3.9.0 and found by libFuzzer.

FossilOrigin-Name: 824ad96f72cb0c948ec98aca9d17a7e6790c575f
2015-11-24 02:10:52 +00:00
mistachkin a9124d359b Add a clarifying comment to the virtual table test module 'test8'.
FossilOrigin-Name: e92f97a6794440eb9d64e21218d39cb0e297a98e
2015-11-24 01:17:01 +00:00
drh 3d4143a38a Do not try to eliminate No-ops at the end of VDBE program as this can cause
problems for some DISTINCT handling algorithms, and does not improve
performance.  This also fixes an assertion fault found by libFuzzer.

FossilOrigin-Name: 19d9f9ce691963310fa73ac5ff728ea8dea9d2b2
2015-11-24 00:49:44 +00:00
dan 07bdba86d5 Add experimental support for LIKE, GLOB and REGEXP to the virtual table interface.
FossilOrigin-Name: 277a5b4027d4c2caba8143228a4f7d6df899dbb4
2015-11-23 21:09:54 +00:00
dan 8836cbbcb4 Fix an obscure memory leak found by libfuzzer that may occur under some circumstances if expanding a "*" expression causes a SELECT to return more than 32767 columns.
FossilOrigin-Name: 60de5f23424552c98aa760ac89149a3d51f895be
2015-11-21 19:43:29 +00:00
drh 62aaa6ca88 Fix over-length source code lines. No logic changes.
FossilOrigin-Name: 198d191b2f5ef7d63ac0093c701955c9052fd734
2015-11-21 17:27:42 +00:00
drh 202923107d Do not allow table-valued function syntax on ordinary tables and views as those
objects are not table-valued functions.
Fix for ticket [73eba7ba5c7c0fc].

FossilOrigin-Name: ff5716b89f99d9c4568a39f1f52524528a631623
2015-11-21 13:24:46 +00:00
drh c960dcbace Refactor the VdbeCursor object. It is now slightly smaller and faster and is
easier to understand.

FossilOrigin-Name: 9b1d174d862500a627840008ffac4c8419dc97e2
2015-11-20 19:22:01 +00:00
drh 5f7dacb443 In the OP_Column opcode, only test the btree payload size for exceeding the
string length limit if the payload does not fit on a single page.

FossilOrigin-Name: 35c7f6cba6febf2480de01fca9d61b8065bf1c12
2015-11-20 13:33:56 +00:00
drh 7977fa3ab2 Enhancements to a comment in sqliteInt.h. No changes to code.
FossilOrigin-Name: 5446ae64d7f92444ca40aae2108015d1d77bc03f
2015-11-20 13:17:29 +00:00
drh 18f8e73453 Fix problems with the way the IsHiddenColumn() macro is defined.
FossilOrigin-Name: 126b998cf163dcdd5a222634f1e929f04db3c700
2015-11-19 18:11:20 +00:00
dan aaea31439d Fix a problem with VACUUM and __hidden__ columns.
FossilOrigin-Name: 13995756ad8b80568aa2f74387788a8cab1123ef
2015-11-19 18:09:05 +00:00
drh 80090f9221 When manifesting a view as part of an DELETE or UPDATE, be sure to include
the hidden columns in the manifestation.

FossilOrigin-Name: 28df5dc4a9569f388af2ee0d1f016afbea132277
2015-11-19 17:55:11 +00:00
dan ba68f8f3f5 Fix problems with INSERT INTO ... SELECT ... statements that write to tables with __hidden__ columns.
FossilOrigin-Name: 59bd0ec7d4327852ee8c0206b2c59d0a12484db8
2015-11-19 16:46:46 +00:00
drh 1a1d3cd2f3 Create the new TK_ASTERISK token to represent the "*" in "SELECT *". Formerly
that operator was TK_ALL, which was also used for UNION ALL.  Less confusion if
they operator symbols are distinct.

FossilOrigin-Name: 201ac6d449431dadc6b29faecd68b559bd64bc9f
2015-11-19 16:33:31 +00:00
drh 05bdfa4a6f If compiled with SQLITE_ENABLE_HIDDEN_COLUMNS, then columns in ordinary
tables and views that have names beginning with "__hidden__" are omitted from
the "*" expansion in SELECT statements and from the automatic list of columns
following the table name in an INSERT INTO statement.

FossilOrigin-Name: 011904cad2be2ce34e2f37ffae8ff2f1044a2969
2015-11-19 14:11:58 +00:00
drh 03d69a6826 Only support the magic "__hidden__" column name prefix interpretation when
compiled with SQLITE_ENABLE_HIDDEN_COLUMNS.

FossilOrigin-Name: 5490646b2eb74ea8bd5ab2690f69b9c707a0165f
2015-11-19 13:53:57 +00:00
drh a6f88ffd3a Fix a 10-year-old misguided attempt at parser performance improvement that
actually made parsing slightly slower.

FossilOrigin-Name: 3833cbac0706ecac9a641d70b786d26f7e1a42b1
2015-11-19 13:21:31 +00:00
drh b1daa3f469 Get the __hidden__ column mechanism working on views with INSTEAD OF triggers.
FossilOrigin-Name: 20c1e9ce75cc0b5f7456379f35a4fe24edd98088
2015-11-18 21:22:02 +00:00
dan ab5a8ee3e4 Add tests for views to hidden.test.
FossilOrigin-Name: 27d4b6f5756c7b19c00c95d46a77280c8b6f03a4
2015-11-18 20:59:47 +00:00
drh 6aed239acc Honor the "__hidden__" prefix on the columns of views.
FossilOrigin-Name: 3071ba2bdbda7018d0a285eceb04b8527209ec1e
2015-11-18 20:57:50 +00:00
dan d1ce65fc76 Add a test for the __hidden__ hack on this branch.
FossilOrigin-Name: ebf4bbffec58111a670c46a9eb469bfd2440b0b1
2015-11-18 20:07:12 +00:00
drh f0c9145a36 If a table column name begins with "__hidden__" then do not include that
column in "*" expansions in SELECT statements, nor fill in that column in
an INSERT INTO that omits the column list.  <b>This branch is a 
proof-of-concept only and is not intended to ever be merged into trunk.</b>

FossilOrigin-Name: 2dbffb3a3b20dba7d7d86c8ad2e34633f616c78a
2015-11-18 18:43:15 +00:00
mistachkin c88cd13753 When using mmap mode on Win32, use a read-only mapping by default. Write to the database file using WriteFile(). Unless SQLITE_MMAP_READWRITE is defined, in which case use a read/write mapping and write into the file using memcpy().
FossilOrigin-Name: 4f521b5bb36a1117db324e92dcf80abd2f1a5bc1
2015-11-17 21:42:32 +00:00
dan fe33e39ba6 When using mmap mode on unix, use a read-only mapping by default. Write to the database file using write(). Unless SQLITE_MMAP_READWRITE is defined, in which case use a read/write mapping and write into the file using memcpy().
FossilOrigin-Name: 67c5d3c646c8198c8637069140aca952b802df25
2015-11-17 20:56:06 +00:00
mistachkin bfe8bd5a5e Fix uninitialized variable in the command line shell.
FossilOrigin-Name: dc2ac024d31a898bbc3e7fc824d806e63e993234
2015-11-17 19:17:14 +00:00
mistachkin 81c7811fe7 Fix harmless compiler warning.
FossilOrigin-Name: eea26b6caea37422c9b46a7a3a538b0c9575f392
2015-11-17 19:16:39 +00:00
dan e4e416e87e Add testfixture command "vfs_current_time_int64". Returns the value returned by the xCurrentTimeInt64 method of the default VFS.
FossilOrigin-Name: f79d5b1853b3d4316ea08de8206ffca33e44c395
2015-11-16 15:28:54 +00:00
dan 3fd415b2bf In the shell tool, avoid testing if (sqlite3_vfs.xGetCurrentInt64) is NULL for a version 1 VFS. This field is only defined for version 2 and greater.
FossilOrigin-Name: ad5fcaa583ef743d143b6c030e0d78019709fe71
2015-11-16 08:54:10 +00:00
drh f7ee8965a5 Fix the column name uniquifier so that it works with zero-length column names.
FossilOrigin-Name: 791761ebac26c82ab67bdf867117ec5b5d8b20b0
2015-11-15 11:13:49 +00:00
drh 96ceaf8680 Code simplification in sqlite3ColumnsFromExprList(). Update the %z format
code so that it works with buffers obtained from sqlite3DbMalloc().  Add a
testcase for the slow column name uniquifier.

FossilOrigin-Name: 9272426057b6cb2d913519ff4c97aa6e211f7d51
2015-11-14 22:04:22 +00:00
drh 0315e3cc14 Use a hash table to improve the preformance of column name uniqueness checking.
FossilOrigin-Name: 5b08f29f458c600401860c7d70d8174cf61e69f8
2015-11-14 20:52:43 +00:00
drh ebed3fa3e1 Use randomness to prevent showness in the generated-column-name uniqueness
checking.

FossilOrigin-Name: 6266712968a2cdcd6f5a3007d60c2cf1b3faf912
2015-11-14 16:47:23 +00:00
drh 6653fbe91f Fix a memory leak in the fuzzcheck utility.
FossilOrigin-Name: dfd6d9f4fbe902086f9158dfa5f37e781765a683
2015-11-13 20:52:49 +00:00
dan ce6cbf9ff4 Add the "--enable-static-shell" option to the amalgamation autoconf script. If set (the default) the compiled shell tool is statically linked against sqlite3.o. Otherwise, it is linked against libsqlite3.so.
FossilOrigin-Name: 499a02a34316cada9e197ef1d2e77c4cd75c41be
2015-11-13 16:59:00 +00:00
drh 05d4ebf6c3 Add the --transaction option to the sqldiff tool.
FossilOrigin-Name: 8882d1f3ef0fc53d7c19918c3af43c5bdd79e88f
2015-11-13 13:15:42 +00:00
drh d63fbb7103 Fix the releasetest-out.txt log output from releasetest.tcl so that it works
when the --jobs option is used.

FossilOrigin-Name: 6bb314a5022c8bae63f6cdb48652915e05c06a38
2015-11-13 12:52:34 +00:00
drh 29fbdb731b Disable two PRAGMA cache_spill tests when MEMORY_MANAGEMENT is enabled.
FossilOrigin-Name: ebda77aad4d964593606ded2fdb19259ef9ebb8e
2015-11-13 12:32:01 +00:00
drh 061d35c145 Change the error messages so that they begin can be grepped using '^!' instead
of '^ '.  There are far too many extraneous outputs that being with a space.

FossilOrigin-Name: 367ec0db49607559960d58891771113c205fd951
2015-11-13 00:03:14 +00:00
drh 5e3cefe3d0 Update the SQLLOG logic so that to builds in accordance with the instructions
in the header comment.

FossilOrigin-Name: ee6f2feec7d777a969ddba6dc00fb571d64e57f8
2015-11-12 23:48:08 +00:00
drh 8d4482da96 Always parse the schema *before* running "PRAGMA cache_size", not after.
FossilOrigin-Name: 12e7d9ec023db4dd837f76006c87defc5a3e9388
2015-11-12 22:15:18 +00:00
drh d66b2e02ee Add a space before each line of error output in the test scripts so that all
errors can be conveniently located in logs by doing "grep '^ '".

FossilOrigin-Name: 9d532fb50d310df629ea65193f21dc9b3594ff5f
2015-11-12 21:42:40 +00:00
dan d83f7ca114 Add support for the SQLITE_SQLLOG_CONDITIONAL environment variable to the logging code in test_sqllog.c. When defined, logging is only performed if the "<database>-sqllog" file is present in the file system when the main database is opened.
FossilOrigin-Name: cab8126be9f63dd596719b12704ba77c128282bc
2015-11-12 20:12:51 +00:00
drh c2e0dd4ddd Enhance the "PRAGMA cache_spill" statement to accept an integer argument which
is the threshold at which spilling will begin.

FossilOrigin-Name: f79d264db24a470d1a4571e15a99cd3d68b5166c
2015-11-12 16:44:40 +00:00
drh 4f9c8ec62d Test cases. Minor problems fixed. All appears to work now.
FossilOrigin-Name: 9a431362dccbc9b8f93375f30a3b8955903cca79
2015-11-12 15:47:48 +00:00
drh 644f4c1bbb Fix a #define in parse.y that disabled unused code in the generated parser.
FossilOrigin-Name: f84e3085c87cfffe4aba0eb4c4a3298b4027db83
2015-11-12 15:04:05 +00:00
drh 9b0cf34f81 First attempt at enhancing the "PRAGMA cache_spill" statement to accept a
cache threashold size.

FossilOrigin-Name: 549d42be0dac87dc04c3eeccfdc60615c3a6ad3f
2015-11-12 14:57:19 +00:00
mistachkin 24e9895f81 Fix missing word in a documentation comment. No changes to code.
FossilOrigin-Name: ed24d302657e8495bef7f5ed698c7cca12717be9
2015-11-11 18:43:49 +00:00
drh 3d38cec99a Improvements to the SQLITE_CONFIG_PAGECACHE documentation. Enhance the
command-line shell to be able to take advantage of the full range of
SQLITE_CONFIG_PAGECACHE capabilities, such as setting pMem==NULL and N<0.

FossilOrigin-Name: 2518d5c971c4b32d9227b3bb7259162e3e27b00b
2015-11-11 15:28:52 +00:00
drh 0c4105ee19 Improved output formatting for "PRAGMA parser_trace=ON;".
FossilOrigin-Name: e43e1171fd7837a08069dc25df4eac14db1c2afe
2015-11-10 14:51:22 +00:00
drh 97e58a2feb Make the output of "PRAGMA parser_trace" go to stdout instead of stderr.
FossilOrigin-Name: 1e4849911e3eed65eabee18fdee63bab4faae57a
2015-11-10 14:27:17 +00:00
drh 3334d08989 Save a few bytes in the parser by using "int" instead of "u8" or "u16" for
all small integer types.

FossilOrigin-Name: 5dcd212bf6489f4698a0ed0f21497c78379f7c0f
2015-11-10 13:45:21 +00:00
drh 634b242ebe Change all parsers to use the standard "lempar.c" template in the tool/
folder and remove the customized lempar.c from src/, plus other compiler
performance and space enhancements.

FossilOrigin-Name: 0e7fb24ad3c010884763a97e6ae7a3fd39d0e5a9
2015-11-10 12:41:03 +00:00
drh 43509768e1 Fix harmless compiler warnings in FTS5.
FossilOrigin-Name: 09752e51a18ac1b4c9642965e6ee1b6a32de00df
2015-11-10 12:31:25 +00:00
drh 54bb56d82a Performance enhancement to the tokenizer.
FossilOrigin-Name: 6ea2df86c95c226052f528424e9bee367a2e765a
2015-11-10 03:30:51 +00:00
drh 07b09a9420 Remove an unused non-terminal from the grammar.
FossilOrigin-Name: 3c37c522883ea9f2eec4f0ba5c5141912c003425
2015-11-10 00:02:49 +00:00
drh 822a62f84d Fix a comment typo in the lempar.c template that was missed by the prior
check-in.

FossilOrigin-Name: c4a7e93fca622fd11a6e16161fbd2f39c2575f00
2015-11-09 19:35:18 +00:00
drh 82415f2d8d Change the parser to use the standard "lempar.c" template over in the tool/
folder rather than the customized "lempar.c" found in src/.

FossilOrigin-Name: 0a72991f4e54548f6c3268c5a9cac1c8d6437d26
2015-11-09 19:33:42 +00:00
drh a441404f92 Avoid recursion in the yy_find_shift_action() routine of the Lemon-generated
parser, so that routine can be inlined, for a size reduction and performance
increase.

FossilOrigin-Name: 0557a179f932296cc1fd5217f9a0d2f74e34ce1d
2015-11-09 15:06:26 +00:00
drh 3781f01780 Size reduction and performance improvement in the stack-popping logic of
the Lemon-generated parser.

FossilOrigin-Name: 9748c48a4fbd5c06208bbf80e7bfcb159ec026d9
2015-11-09 14:11:37 +00:00
drh 7450494c50 Fix incorrect WHERE clause in sqldiff, as reported on the mailing list
by Youcef Hilem.

FossilOrigin-Name: e0ed4c3e376248dfbf903e4b5845f910824fa6c6
2015-11-09 12:47:04 +00:00
drh f10b1f78ee Check in the cg_anno.tcl and run-speed-test.sh scripts, as an historical
record.

FossilOrigin-Name: 836418d3b7cfcd5ec375c4e08c09bd6b78646307
2015-11-09 12:44:19 +00:00
drh d797035ac7 Avoid unnecessary function prologues in the sqlite3VdbeAddOp3() routine.
FossilOrigin-Name: 7c6a19ba9b0bdb1cc0b9a9796b7c1c114944d927
2015-11-09 12:33:39 +00:00
drh 0739e45bcd Small size reduction and performance increase in the parser.
FossilOrigin-Name: d62cd757a69cc49c2d309e27c948610b5868632f
2015-11-09 02:08:09 +00:00
drh edd2260b40 Enhance the sqldiff utility to deal gracefully with ALTER TABLE ADD COLUMN.
FossilOrigin-Name: 7ea036ac37397ed8f6a0fa9f5bfc0994364b53dc
2015-11-07 18:32:17 +00:00
dan cc03305473 Fix a bug in CTE handling discovered by LibFuzzer that can cause an infinite loop in the query planner.
FossilOrigin-Name: 088009efdd56160bb4eee0fbd829a529b141274e
2015-11-07 18:07:15 +00:00
dan fe88fbfc82 Add test cases for WITH clauses.
FossilOrigin-Name: e7e65c7559ed43e7065adc2ec1bd242bf187b7c3
2015-11-07 17:51:39 +00:00
drh 6e7722669e Proposed fix for an infinite loop bug in the WITH clause semantic analysis
logic.

FossilOrigin-Name: 028475cb17a4b50baf0e9aba9bd3403d0a5d03b0
2015-11-07 17:48:21 +00:00
drh 2476a6f2cb Enhance TreeView to show WITH clauses. Add an assert to detect the
infinite loop behavior when certain kinds of errors occur on a nested
WITH clause.

FossilOrigin-Name: 2040d88e877bdb69de125a047cefb4a1558e89e8
2015-11-07 15:19:59 +00:00
drh d6b7946c32 The OPFLAG_SEEKEQ optimization is only applicable to equality comparisons
against an index, not against a rowid table.

FossilOrigin-Name: 0f5b147d1fe83c34d0fbeacc7422be94d8441bc1
2015-11-07 01:19:00 +00:00
drh 3901692ede Fix a harmless sanitizer warning in the ieee754 extension.
FossilOrigin-Name: dd9a26ecdeaef7b0b9cbf4ff70448ab13a276b4e
2015-11-07 00:51:15 +00:00
drh 3adf8783b0 Avoid an unnecessary key comparison when doing an indexed lookup against an
equality constraint.

FossilOrigin-Name: d741e1ccdce96e6142e294fbdd20a0282296dcea
2015-11-06 20:22:25 +00:00
drh f83075201f Work around a sign-extension bug in the optimizer on the HP C compiler that
comes with HP/UX.

FossilOrigin-Name: 46c36b1543d7a8156eaa866c67080526153fb10d
2015-11-06 20:13:48 +00:00
drh 51675f24f3 Test changes: Omit numindex1.test from valgrind, since valgrind uses a
none-standard floating-point processor which gives inconsistent answers.
Run one releasetest.tcl module using LONGDOUBLE_TYPE=double.

FossilOrigin-Name: d421efbf9a5688f5a20b6dfe3aa216299c7b9c86
2015-11-06 20:04:08 +00:00
drh c750ee999e Enforce consistent comparison results between integer and floating point
values.  Fix for ticket [38a97a87a6e4e83].

FossilOrigin-Name: 849e686da2d20fd7f938427475fc792384d2aa7c
2015-11-06 19:53:09 +00:00
drh 9ced20d892 Merge the fixes and tests for the ieee754 extension.
FossilOrigin-Name: 7a9988d38cd7ab3df79eed97631ff23d5928b4ad
2015-11-06 17:59:33 +00:00
drh c8bb430dfe A proposed patch for working around a bug in the optimizer for the HP compiler
found on HP/UX Itanium.

FossilOrigin-Name: 8a171548e4f665f03d00af6dcb46669a4a78fad5
2015-11-06 17:28:00 +00:00
drh ff621c6894 Test cases for the ieee754 extension.
FossilOrigin-Name: 840cbda88675b6012dae2423252bf42d0d563874
2015-11-06 17:01:20 +00:00
drh 2ab410aa1e A different approach to handling integer/float comparisons. This seems to
work better on systems where "long double" and "double" are the same type,
but still needs refinement and testing.

FossilOrigin-Name: a3f7614b2095fbc1eca54801b2da88f85f294ec5
2015-11-06 14:59:07 +00:00
dan dbbda39453 Have fts5 load its configuration from the xConnect() method is invoked. This ensures that the very first query run uses the correct value of the 'rank' option.
FossilOrigin-Name: 33e6606f5e497e81119ec491cf2370f60bddafc0
2015-11-06 12:50:57 +00:00
drh aa8ff2ff6a More test cases for indexes on large numeric values.
FossilOrigin-Name: c220741a62808c64d42c6161152ab06af74cb48c
2015-11-06 04:14:38 +00:00
drh 06d7b00b6a Some simple test cases from the mailing list.
FossilOrigin-Name: 1d642b73f9e93a1ba291bf265b3d17e46551d70e
2015-11-06 03:37:02 +00:00
drh 8b8446fc21 Increase the precision of integer vs. floating-point comparisons.
Candidate fix for ticket [38a97a87a6e4e8].

FossilOrigin-Name: cfcaa0ff276b1936418abe72c7e0c99d90d37885
2015-11-06 01:04:41 +00:00
drh b1d607de25 Improvements and simplifications to the equality seek logic. Tests are
adjusted so that they all pass now.

FossilOrigin-Name: 997ce6c90b454c03cc2ef6934752ee8dd2e520e3
2015-11-05 22:30:54 +00:00
mistachkin 9030d0ac28 Fix typo in help information for an FTS5 script.
FossilOrigin-Name: 777ae8007f6ff303b120b25f2dc37d7ef6b6a4f8
2015-11-05 21:49:19 +00:00
drh 70528d7868 The top of an index equality loop normally starts with OP_SeekGE and OP_IdxGT.
This check-in adds a flag to OP_SeekGE such that it fails immediately if
the key is not equal, then jumps over the OP_IdxGT, saving a call to the key
comparison functions.  Consider this check-in a proof-of-concept.  It needs 
improvement before going on trunk.  Some tests fail, but only because they
new use fewer key comparisons than expected (which is a good thing!).

FossilOrigin-Name: 32e31b9bc8664afcd326a1ff3892d86dc5202474
2015-11-05 20:25:09 +00:00
dan d82211db56 Add the 'hashsize' configuration option to fts5, for configuring the amount of memory allocated to the in-memory hash table while writing.
FossilOrigin-Name: 445480095e6877cce8220b1c095f334bbb04c1c3
2015-11-05 18:09:16 +00:00
drh 780b02de4a Remove a #pragma used to work around an issues with MSVC 2012 that has been
overcome but subsequent changes.

FossilOrigin-Name: 8303e4cfed715464c710668c2bdc58a8e3d4cd9f
2015-11-05 11:47:48 +00:00
mistachkin 63225522f9 Remove #pragma that was used to work around an obsolete issue with MSVC 2012.
FossilOrigin-Name: b9b22fae69000ca506656f9cf847e713c6304b75
2015-11-05 03:26:36 +00:00
drh 8dd1c25388 Performance improvements in the getAndInitPage() routine of btree.c.
FossilOrigin-Name: 2aa50f6f2029e3c91a4cb91224df8ec1194f215e
2015-11-04 22:31:02 +00:00
drh 9584f58cc2 Rename the sqlite3PagerAcquire() function to sqlite3PagerGet(). The former
macro called sqlite3PagerGet() has been removed.

FossilOrigin-Name: 708253be34084b89987efe955c34557516171a3a
2015-11-04 20:22:37 +00:00
drh 71258abf0d In releasetest.tcl, run larger test first if --jobs is greater than 1. Run
smaller tests cases first if --jobs is 1.

FossilOrigin-Name: 3fece5d02a8790701d8f0af18db4b4db33986369
2015-11-04 16:34:58 +00:00
drh 85979cd818 Exclude cffault.test and symlink.test from the (incompatible) inmemory_journal
permutation.

FossilOrigin-Name: 4f16e9686d827311d069ac5856771db23bd610ff
2015-11-04 13:03:36 +00:00
drh 25b0c4094f Increase the fuzzcheck timeout when running valgrind.
FossilOrigin-Name: a5816877bdc7fae69ed83d1fc95c29bf390eb641
2015-11-03 23:39:47 +00:00
mistachkin e3b63599a3 In 'e_uri.test', make sure all created test database files get deleted.
FossilOrigin-Name: 40c4f4a65ef3ebda96e0de8bd791ce5ccb8d3ef5
2015-11-03 19:13:57 +00:00
drh 7f8a93d72c In the releasetest.tcl script, add the --progress option to cause the start
of each subprocess to be shown.  Otherwise, revert to the old-style display.
Improvements to the handling of the --buildonly option.

FossilOrigin-Name: d969792f34c484bd055c933b1c2c5a99eb88b61b
2015-11-03 15:39:29 +00:00
drh 4380ff8887 In the releasetest.tcl script, show the --jobs object on the command-line
summary.  Report the time of each "starting:" event.  Do not show errors
on a --dryrun.

FossilOrigin-Name: b75107778f67a4c4f33b1c003af87ca57e98ae4b
2015-11-03 15:16:21 +00:00
drh b3ebc805ed Update the releasetest.tcl script so that it can run multiple tests in
parallel in separate processes.

FossilOrigin-Name: e3de82919d6f7ef5c2c5ab9a932a480604856950
2015-11-03 14:49:35 +00:00
mistachkin 7d3bfa2713 Further enhancement and a bit of cleanup.
FossilOrigin-Name: 0d8b59783e0a84bc59661b3469e1ca1b1fa90c71
2015-11-03 06:23:33 +00:00
mistachkin 98fea32c83 Use the native name for the MSVC makefile as well.
FossilOrigin-Name: e457c615647a5bacb32d7d1d9ddfcfb0c7d56e82
2015-11-03 02:47:11 +00:00
mistachkin da9da5624a Attempt to centralize and simplify the MSVC handling.
FossilOrigin-Name: 4ae96d6dde7fc0a913d7719ec498686f9a1e3b98
2015-11-02 23:29:58 +00:00
drh 3e6d22ad4d Fix the backcompat.test module so that it does not try to compare against itself
on windows.

FossilOrigin-Name: f625bce8b7c2884a092c70675a9c6ce15c29937e
2015-11-02 23:21:17 +00:00
mistachkin 59189433ba Get things working better on Windows with MSVC.
FossilOrigin-Name: 22cc3e6c8e7f7eed854f8a50138ccb9c79bb7a23
2015-11-02 21:05:56 +00:00
dan d08a63ab62 Fix the --dryrun option on the releasetest.tcl script.
FossilOrigin-Name: e565e0261501e4c21e4ad3d12f9f5b24c761bf96
2015-11-02 20:52:20 +00:00
dan e9e1505b3c Fix releasetest.tcl so that it does not choke if a test fails so badly that there is no log file. Add the --jobs switch to the usage message.
FossilOrigin-Name: 20e96f521fce12ffeb6be788e57bce88f287cff5
2015-11-02 20:28:48 +00:00
dan 9525a86ba1 Fix releasetest.tcl so that output lines are less than 80 characters wide.
FossilOrigin-Name: aef177fef049f9ffb0d138b947326dc0186b1f4f
2015-11-02 20:24:29 +00:00
dan a7f6597400 Add the "--jobs N" option to the releasetest.tcl script to allow tests to be run in parallel by N processes. N defaults to 1.
FossilOrigin-Name: 3d29f912cb7c6ee3e4903b1b14dd7ae82e4d02b1
2015-11-02 18:32:00 +00:00
dan f0db464b93 On unix, if a file is opened via a symlink, create, read and write journal and wal files based on the name of the actual db file, not the symlink.
FossilOrigin-Name: 6d5ce3ede4c7038c19a77268a5a7b9d5650933c2
2015-11-02 15:08:56 +00:00
drh 153110a7da If a table-constraint PRIMARY KEY lists a single column in single-quotes and
that column has type INTEGER, then make that column an integer primary key,
for historical compatibility.  Fix for ticket [ac661962a2aeab3c331].

FossilOrigin-Name: db319a035feeb6f8fcd04f90fb10cd4b06e68184
2015-11-01 21:19:13 +00:00
dan 245fdc60d6 On unix, if a file is opened via a symlink, create, read and write journal and wal files based on the name of the actual db file, not the symlink.
FossilOrigin-Name: c7c8105099c0412ac6c605f98987092c10bde57c
2015-10-31 17:58:33 +00:00
dan 6a75c8ad94 Add mutex operations to test code in test3.c to avoid triggering assert() failures in certain configurations.
FossilOrigin-Name: 9f19420b0a79dff65fc3a9d548f4b3fc4955f9f9
2015-10-30 20:54:25 +00:00
drh b457764d01 Increase the version number to 3.10.0, due to the addition of the
sqlite3_db_cacheflush() interface.

FossilOrigin-Name: 7565b046ff939e8310631397a4526fbd98b99aaf
2015-10-30 16:36:42 +00:00
dan 3bfab7c6d6 Add new API function sqlite3_db_cacheflush().
FossilOrigin-Name: ad80d3073388c59f67171720efc6ef766e19886f
2015-10-30 16:14:03 +00:00
dan 5596eb3020 Return immediately if sqlite3PagerWrite() is called when the pager is in PAGER_ERROR state.
FossilOrigin-Name: a6695b008487aeb7badf572fa32bfcba3c9fab03
2015-10-30 14:28:16 +00:00
drh e44b835e63 Add the --enable-editline option to various autoconf scripts.
FossilOrigin-Name: 866f0277781dedf0db287ec5902a138406a172e3
2015-10-30 14:25:57 +00:00
dan e8e6657fa7 Test that calling sqlite3_db_cacheflush() does not interfere with savepoints.
FossilOrigin-Name: 0e09e4a26938cfe0f573449526a8f0f527cef921
2015-10-30 09:13:29 +00:00
dan 9fb13abc6e Do not attempt to flush the pages of an in-memory database to disk if sqlite3_db_cacheflush() is called.
FossilOrigin-Name: 9b79a390440a23542a370b591e567b31ebb35c42
2015-10-29 21:11:22 +00:00
dan 4a6beac28b Add a test case that calls sqlite3_db_cacheflush() on an in-memory database.
FossilOrigin-Name: f0cdfb547b0976e753e94958f29cb294edf31bed
2015-10-29 20:57:06 +00:00
dan dbf6773e88 Avoid automatically rolling back the transaction if an SQLITE_IOERR or SQLITE_FULL error occurs within sqlite3_db_cacheflush().
FossilOrigin-Name: 370b5d520c6523526988d0db5299f1bd09567782
2015-10-29 18:16:40 +00:00
drh c56fac7483 Fix uses of ctype functions (ex: isspace()) on signed characters in test
programs and in some obscure extensions.  No changes to the core.

FossilOrigin-Name: 34eb6911afee09e779318b79baf953f616200128
2015-10-29 13:48:15 +00:00
mistachkin de4148e304 Enhance comments in the MSVC batch build tool.
FossilOrigin-Name: 2964ce25864e8aec86272af741caf49c23c86590
2015-10-29 01:11:39 +00:00
drh 1167d32716 Make the internal sqlite3PExpr() interface responsive to the
TKFLG_DONTFOLD flag on the operator parameter.

FossilOrigin-Name: b10ab59fb8a696d11a269f3904e799c687246aea
2015-10-28 20:01:45 +00:00
dan 6fa255fd5c Add experimental API sqlite3_db_cacheflush().
FossilOrigin-Name: 65b86dc1fa4a57cc3cde86a820d9f848aa288a15
2015-10-28 19:46:57 +00:00
drh 9109b7f8e1 Factor out adding NOT expression nodes in the parser into a subroutine.
FossilOrigin-Name: 001854181640bd9b088f2bc16083d84808c3da18
2015-10-28 16:05:10 +00:00
dan 36c33aa633 Have contentless and external content fts5 tables ignore "OR REPLACE" conflict handling.
FossilOrigin-Name: a85c2a4758c27e8d5d0395751eb3cfd9985ce696
2015-10-27 20:04:53 +00:00
dan 24b8457911 Fix problems with prefix queries in fts5.
FossilOrigin-Name: 3b5758c647530bd5c2e68d0ee3e9f58a96347ca4
2015-10-27 17:48:57 +00:00
drh 1bbbd85bd2 Provide hints to the storage engine using the sqlite3BtreeCursorHint()
interface when compiling with SQLITE_ENABLE_CURSOR_HINTS.

FossilOrigin-Name: 45d3539e152a44629639723f18ce70d9ef01f31a
2015-10-27 13:35:14 +00:00
drh f7854c7329 Split out sqlite3BtreeCursorHintFlags() from sqlite3BtreeCursorHint()
the interface for improved performance.

FossilOrigin-Name: b3ec9a0d62c5543e91d4be2cd634ec4a3d6dca11
2015-10-27 13:24:37 +00:00
dan 2853c688ad Add new extended error code SQLITE_IOERR_AUTH.
FossilOrigin-Name: b4e70dd08e79decaa09f7b99e2dc7e2df92f26ee
2015-10-26 20:39:56 +00:00
dan c5dc3dcd6e Merge the BTREE_FORDELETE enhancement with this branch.
FossilOrigin-Name: 20da0849ce910ceb445954dfc5f985acf9a02695
2015-10-26 20:11:24 +00:00
drh 0691191d26 Merge in all trunk changes prior to the BTREE_FORDELETE enhancement.
FossilOrigin-Name: 53d5a4add6b60722ad77daf98b6b8983b081e16a
2015-10-26 18:51:09 +00:00
drh ad61c46409 Capture BTREE_FORDELETE test cases that were mistakenly omitted from the
previous merge.

FossilOrigin-Name: de6972515f65c5cf5da7cfdf876a05718299e9b8
2015-10-26 18:01:36 +00:00
drh 3d541a5b8c Provide the BTREE_FORDELETE flag to sqlite3BtreeCursor() if the cursor will
be used only for deletions and seeking.

FossilOrigin-Name: 871b1c78bcbea1cb03d482f2f424c4e012633695
2015-10-26 17:50:54 +00:00
dan 433d5aaed1 Fix an uninitialized variable problem in the test code added by the previous commit.
FossilOrigin-Name: 7849662ef94fa48fe53177db5623f46b3cb401e8
2015-10-26 16:34:13 +00:00
dan 6b513640c0 Test that the binary record "0x01 0x00" is interpreted by OP_Column as a vector of NULL (or default) values.
FossilOrigin-Name: 5bdc3c82bd10f924c12568eb0fa7a07393fc864f
2015-10-26 16:31:18 +00:00
drh 4dd83a22f2 Fix a C99-ism and a harmless compiler warning.
FossilOrigin-Name: 138783b553602a055b3efdeac5947cf5ccd76b5d
2015-10-26 14:54:32 +00:00
drh 46e6ea0282 When compiling with SQLITE_HAS_CODEC, honor the hexkey= query parameter on
URI pathnames in sqlite3_open_v2().

FossilOrigin-Name: e0ce3fc089c2523b8b718b4a4f9ab8c4d0432fc7
2015-10-26 14:41:35 +00:00
drh 56d90be183 Remove an unreachable branch in malloc.c.
FossilOrigin-Name: a36b7fe92372a13ff0b6e08f1704496045c6f62a
2015-10-26 12:55:56 +00:00
dan fb785b2c2b When creating an automatic-index on a sub-query, add a unique integer to the end of each index key to ensure the entire key is unique. Fix for [8a2adec1].
FossilOrigin-Name: bfea226d0d226a046a8bfb7a7a6288850d69bd26
2015-10-24 20:31:22 +00:00
dan 2b4e95226c Remove an unused #define from whereInt.h. Add comments describing the new sqlite3BtreeCursor() flags.
FossilOrigin-Name: 4c0ba8be43bb7c7100456bd8cd6921c164be31e1
2015-10-23 11:50:23 +00:00
dan fd261ec67e Modifications to pass a flag to internal routine sqlite3BtreeCursor() when a cursor that is used solely for deleting b-tree entries, or for obtaining the components of keys to delete from other b-trees, is opened.
FossilOrigin-Name: cdc92919e600007cae5eb61223684f48a65babc0
2015-10-22 20:54:33 +00:00
mistachkin 7ef855f156 Alternate compiler warning fix for sqlite3StatusHighwater.
FossilOrigin-Name: 4315d20200d578c9252dcb26e60739063a8eff1d
2015-10-22 18:06:40 +00:00
mistachkin 16158eeb49 Fix harmless compiler warnings in FTS5.
FossilOrigin-Name: aa4e01ea1af327d1f8398ebea1c5bacc46698c3d
2015-10-21 22:08:36 +00:00
mistachkin 1dfaa5c4b2 Fix compilation of 'testfixture' with MSVC when the FTS5 and JSON1 extensions are enabled.
FossilOrigin-Name: e31aa97a9298e49507256036cfb8fa7517a48461
2015-10-21 22:07:25 +00:00
dan 99b25309d0 Remove some branches made unreachable by recent changes from fts5.
FossilOrigin-Name: ae350bfbfd59f912c469a51bf7d1409f3c8d958a
2015-10-21 20:56:27 +00:00
dan f2c9995dbe Minor optimization for fts5 queries.
FossilOrigin-Name: 363b36d50b6f3e3d3e79c538be1167b071a5a710
2015-10-21 20:07:08 +00:00
dan 5c22e82a17 Add extra debugging function to test_rbu.c. Enhance the documentation for sqlite3rbu_db() to define the validity of the returned database handles.
FossilOrigin-Name: b9c4aa521156d8ca09151a82a7e80aa8d1d7a313
2015-10-21 08:26:01 +00:00
mistachkin 6d7734c27d Fix harmless compiler warnings in FTS5.
FossilOrigin-Name: 0a903ec26bfbbe9bfd18bc34934e689ffdb01ce5
2015-10-20 23:27:14 +00:00
dan 219f4d48a2 More optimizations for fts5 prefix queries.
FossilOrigin-Name: b8fb263ed1b36d085437131795505e53af103d26
2015-10-20 21:05:53 +00:00
dan 9cc4ae6f2a Fix #line directives added to generated file fts5.c.
FossilOrigin-Name: 1f5f5804cd394a81b1c0712ce6d1052f228d0a40
2015-10-20 19:55:35 +00:00
dan 3f9bfa740f Initialize variables in the fts5 integrity-check code to avoid compiler warnings.
FossilOrigin-Name: e979e2cccac257ad554803e6a1103558b0f159d8
2015-10-20 15:49:02 +00:00
dan 8789fbb2bd Another optimization for fts5 prefix (and other) queries.
FossilOrigin-Name: 60a8bde055a960c5b8cb4e231802c75617c942d8
2015-10-19 20:49:10 +00:00
dan 5e5b454cd8 Another tweak to improve performance of fts5 prefix queries.
FossilOrigin-Name: 69be427c864dc3de804ca3c5f1c6addcd33cd188
2015-10-19 17:43:24 +00:00
dan 3c060c2aef Fix a problem in the fts5txt2db.tcl script causing it to fail when creating tables with more than 8 columns.
FossilOrigin-Name: 68ee426a6432ac63655909ff70cb22bde33cf28c
2015-10-19 15:59:08 +00:00
dan 0206920e27 Add tests to cover new branches added to the fts5 code by the previous commit.
FossilOrigin-Name: cf618334a8a05a067e844236e4d461b2e5706da6
2015-10-17 20:34:49 +00:00
dan 05903e6a87 Handle equality and range constraints on the "term" column of fts5vocab tables. Also have the same module report columns using names instead of indexes.
FossilOrigin-Name: 6020d96ab47a0bebe41f691a3f44fd55d8b2d2b7
2015-10-17 19:49:01 +00:00
drh b0df963465 Fix a comment in expr.c and add a CORRUPT_DB to an assert() in btree.c.
FossilOrigin-Name: 0df371d1a51c2028aefa4c704707773750317689
2015-10-16 23:55:08 +00:00
drh 0030aaad67 Merge recent enhancements from trunk. Version now 3.9.1.
FossilOrigin-Name: 26fa091d68e89a0b6af61ba706d23a9f37e8025a
2015-10-16 20:53:57 +00:00
mistachkin f170ea44d4 Enhancements to the MSVC makefile.
FossilOrigin-Name: 39e8a5d93fa370afb03223bf0c20ea0f3448b9fc
2015-10-16 20:13:57 +00:00
drh 04ce31fafe Merge the 3.9.1 changes into trunk. (This only updates the version number
and configure script since all the other changes in 3.9.1 were cherrypicked
from trunk.)

FossilOrigin-Name: eb2317429fc3fc81ccd92e6f84f873585829259d
2015-10-16 20:12:12 +00:00
drh a649776664 Version 3.9.1
FossilOrigin-Name: 767c1727fec4ce11b83f25b3f1bfcfe68a2c8b02
2015-10-16 17:31:12 +00:00
drh 0b086403b4 Cherrypick the json form-feed fix, and other #ifdef and build script changes
to address minor issues that came to light after the 3.9.0 release.  Update
the version number to 3.9.0.  No logic changes except for the form-feed
bug-fix in json1 (ticket [57eec374ae1d0a1d4a]).

FossilOrigin-Name: 746fcd2fd412ddc27071827fb20eb6df0741dfb1
2015-10-16 15:56:27 +00:00
drh 1cfc44392c Fix the fuzzershell utility program so that it compiles with the
amalgamation that includes JSON1 support.

FossilOrigin-Name: d6fc616e4c8a024f71a044e61f0493dea7d9c812
2015-10-16 15:42:50 +00:00
drh 49472655d4 Fix the JSON1 extension so that it does not depend on isdigit() and
strtod() from the standard library when compiled into SQLite as part of the
amalgamation.

FossilOrigin-Name: bc9a9a60c31ebf9b11ac89ae5f99a3b66d6efc67
2015-10-16 15:35:39 +00:00
drh b9e8f59b63 Form-feed is not valid whitespace for json.
Fix for ticket [57eec374ae1d0a1d]

FossilOrigin-Name: 28957d635961c525f735a52b8ffe3e69ccf31382
2015-10-16 15:16:06 +00:00
drh be37c12423 Have the sqlite3VdbeSerialType() function go ahead and compute the serial
length as well, since it is always needed.  This avoids unnecessary calls
to sqlite3VdbeSerialTypeLen().

FossilOrigin-Name: 2ad72be12477b0e8e33e56a9a17e29abbd283ec1
2015-10-16 14:54:17 +00:00
drh faf3727904 Use a lookup table to compute the content length for serial types less
than 128, for a 1.2% performance improvement.

FossilOrigin-Name: 3395724814099d28829ef6875ca1ba77d6fe7ffa
2015-10-16 14:23:42 +00:00
drh 95fa606616 Simplify the OP_Column logic slightly. One very small performance
improvement added.

FossilOrigin-Name: 0114b45dc286c13db0d640f0486d8a5bef9ff078
2015-10-16 13:50:08 +00:00
drh 848a3326f7 OP_Column optimization: Do not check for an oversize row header unless the
row header size is larger than the content available on the local page.

FossilOrigin-Name: 8125b74cb46c372b9a319f6270f1c396767accd7
2015-10-16 12:53:47 +00:00
drh c24658b5d7 Improved header comment on the tool/vdbe_profile.tcl script. No changes to code.
FossilOrigin-Name: b17ad8fc046ebc9529d1c146437a383e72217b01
2015-10-16 12:39:52 +00:00
drh c6ce388301 Performance optimization for the OP_Column opcode.
FossilOrigin-Name: 076be5474df628bbbfd2b645adba30e1e093acd0
2015-10-15 21:30:24 +00:00
drh ce78bc6e7e Enhance the use of the column cache for UPDATE statements, making them
more efficient for the case where a column is modified to be an expression
of other unmodified columns.

FossilOrigin-Name: 871e091df651b2275a672c35ff938bd4b6db0d7f
2015-10-15 19:21:51 +00:00
drh fed7ac6f04 Add the OP_IntCopy opcode - an optimized version of OP_SCopy that only works
for integer values.

FossilOrigin-Name: 3a2f73a4924860fde8ee41ad646e7a02d29ad9d5
2015-10-15 18:04:59 +00:00
drh 9eef8c6934 Optimization to the out2Prerelease() helper routine in the VDBE engine.
FossilOrigin-Name: 79298fe8c42f64b6a6110a70b84033873ac0630d
2015-10-15 17:31:41 +00:00
drh 59a052359d Remove a superfluous conditional from the memory allocation initialization.
FossilOrigin-Name: 9ccf8f8d35723f2a9b59010b6d5f37a14164a188
2015-10-15 17:21:35 +00:00
drh 039ca6ab59 Performance optimizations to the sqlite3MallocSize() by requiring the
argument to always be non-NULL.

FossilOrigin-Name: cb65989b0710c65e4df69063b346344fdb1d12c7
2015-10-15 16:20:57 +00:00
drh b02392e6f0 Change sqlite3StatusSet() into sqlite3StatusHighwater() so that only the
highwater mark is recorded.  This gives a small size reduction and
performance improvement.

FossilOrigin-Name: 6422d223dd10018703c6b083d29a3c35c837fc97
2015-10-15 15:28:56 +00:00
drh 9676c48199 Make sure sqlite.h is not #included by itself.
FossilOrigin-Name: a61880c223c2229ecc3b4da7e5647eca17f7ddf5
2015-10-15 12:06:11 +00:00
mistachkin 8873996b7b In the MSVC makefile, add LIBTCLPATH variable to make it easier to run tests when the Tcl library is not already present in the PATH.
FossilOrigin-Name: 54127602b9a555f73f5e446b91e460386cb8fb17
2015-10-14 23:04:08 +00:00
mistachkin 460cd9ccfd In the MSVC makefile, make sure LDFLAGS is used for the tool executables as well.
FossilOrigin-Name: 0a17ee49c6895256fefd13425b790414935efb9d
2015-10-14 22:46:37 +00:00
dan 5f93ccd7fc Tests and minor fixes to improve coverage of FTS5 code.
FossilOrigin-Name: f4de6d450e143cb1dd5447800d4b178e3db114c8
2015-10-14 21:08:48 +00:00
mistachkin cdabd7bd50 Fix harmless compiler warnings.
FossilOrigin-Name: 1c46c194a2da24fe613d77b5a8d727cc2fc9faa4
2015-10-14 20:34:57 +00:00
drh 99f4647ef5 Merge in all the 3.9.0 updates from trunk.
FossilOrigin-Name: 29444149342fc6b1ea8cd34c2c8e1fcb06eaa7ed
2015-10-14 20:09:54 +00:00
drh fdefc36792 Update makefiles to remove all uses of "awk" - to make building SQLite easier
on Windows systems.  The only requirements now are tclsh, a C compiler, and
common file utilities.

FossilOrigin-Name: 4bd0d43db7c1877f2d8a8d2f2a48f24a10f0c3b8
2015-10-14 20:03:00 +00:00
mistachkin 78e3f61f22 Enable cross-compiling the various tool EXEs with MSVC.
FossilOrigin-Name: 7d77233389c595237d5b3d244b8aeca1524290c0
2015-10-14 20:01:12 +00:00
drh 501b402c65 Fixes to the JSON1 extension and to its use by fuzzcheck to avoid problems
when building DLLs.

FossilOrigin-Name: 01d3ee7bbe4feeb82dcedecbe3c9058c807b18f6
2015-10-14 19:52:27 +00:00
drh 021643560b Fix fuzzcheck.c so that it assumes that JSON1 is already compiled in and
does not need to be initialized further.

FossilOrigin-Name: ec003958359d6b69b1b1a75be2a988796268e063
2015-10-14 19:44:42 +00:00
dan 8d32e8042c Avoid exporting sqlite3_json_init() from amalgamation builds.
FossilOrigin-Name: 8463f7e7908d0a96ed036377dfa3805328c62925
2015-10-14 18:45:42 +00:00
mistachkin fcbe99ae38 Remove AWK requirement from the MSVC batch build tool.
FossilOrigin-Name: 6d9cdb931cf4e2f0830184cff32e441e4966bd7e
2015-10-12 03:56:21 +00:00
mistachkin cf9fb7eb1c The TclKit batch tool should not download the TclKit SDK when the TCLKIT_NOSDK environment variable is set.
FossilOrigin-Name: 7c5d583bac89f8db94e7f73df09e1d04f0f24990
2015-10-12 03:44:39 +00:00
mistachkin 5b66350ac7 Enhance TclKit batch tool (and MSVC makefile) to support targets that require the Tcl stub library.
FossilOrigin-Name: bc6223b1d6c31a47c7b734cfb8a9ecf15ab809fc
2015-10-10 23:39:55 +00:00
mistachkin ba461cac7b Remove a couple superfluous double quotes in the MSVC makefile.
FossilOrigin-Name: 0f9e205b28e013412b19dfd588f2a6cf341c40e8
2015-10-10 02:06:05 +00:00
mistachkin 946ef60ad0 Fix typo in the MSVC makefile. Replace remaining uses of AWK in the MSVC makefile with a Tcl script.
FossilOrigin-Name: f8c2193b64979a2fe480fcf913573b5fac06235e
2015-10-10 01:55:57 +00:00
mistachkin cc7304888f More fine-tuning to the new TclKit tools.
FossilOrigin-Name: 43addd8aa04c3faceb9d303672e330294af01a16
2015-10-10 00:53:28 +00:00
mistachkin dfff1ffec6 Tweak batch tool added in the previous check-in to permit the base URI to be overridden.
FossilOrigin-Name: 1d2f82df6774f8d66bfc5d67d5dad9f068a1069c
2015-10-09 18:48:47 +00:00
mistachkin 80372ae248 Add tool capable of downloading a TclKit (and its associated SDK) on Windows.
FossilOrigin-Name: 50673ddaf813335777673fa8585997a7551e5323
2015-10-09 17:36:06 +00:00
drh 48cc9a31e1 Convert the tool/tostr.awk script into tool/tostr.tcl. Remove two obsolete
Makefiles.  Purge NAWK from the configure script and from unix makefiles.
There are still two uses of NAWK in Makefile.msc.

FossilOrigin-Name: 5b6775215327a89232f5059653747a18e83b8b4b
2015-10-07 12:36:42 +00:00
drh 60a15a48c5 Change the addopcodes.awk script into tool/addopcodes.tcl.
FossilOrigin-Name: 8bbf37142ef2759274668f6da114b5c8072e42db
2015-10-07 12:21:14 +00:00
drh 7651e0a439 Convert the mkopcodec.awk script into tool/mkopcodec.tcl.
FossilOrigin-Name: 1506cb33fcf61e2ef97b35b99e58fbf21f4f5496
2015-10-07 12:11:36 +00:00
drh b15393b8d5 Change mkopcodeh.awk into tool/mkopcodeh.tcl.
FossilOrigin-Name: ed0ebc460b54939862e3bddee2bb9bcb9f69c747
2015-10-07 02:52:09 +00:00
drh ae1a015c87 Merge trunk changes into the cursor-hints branch.
FossilOrigin-Name: fbe637620fb7f2c9395c9ddac77d26746d6d4178
2015-09-24 15:06:30 +00:00
drh 81966bea22 Merge enhancements from trunk.
FossilOrigin-Name: 66fe06832614010d3156d7b21a760af9957018cc
2015-09-15 17:31:47 +00:00
drh 163c29c5f3 Merge enhancements from trunk.
FossilOrigin-Name: 25ee3000e94d60d8c1d7b980f416dcc33eb11105
2015-09-03 14:39:33 +00:00
drh 4970d4032e Merge enhancements from trunk.
FossilOrigin-Name: 29570a604806e2a60a8eef7eaf1dce022d2a7004
2015-09-01 18:31:19 +00:00
drh c1bd84124b Merge recent enhancements from trunk, including table-valued expressions.
FossilOrigin-Name: b9927c876c1d4e146cb6a603d82cd2489594084d
2015-08-20 23:45:59 +00:00
drh bcf40a7f12 Provide hints for all terms in a range constraint if there are any equality
terms anywhere in the constraint.  Range constraint terms are only omitted
for a pure range constraint with no equality prefix.

FossilOrigin-Name: b5897bc0f003c470eeb2a75e0a2b2bb202681531
2015-08-18 15:58:05 +00:00
drh b413a5467a Avoid generating hints using constraints that are also used to initialize the
cursor, since presumably the cursor already knows about those constraints.

FossilOrigin-Name: 142b048ac778620dd4e448c2e969982eb8188501
2015-08-17 17:19:28 +00:00
drh a67a31624d Change the display of the P4 operand of CursorHint in EXPLAIN output to
function notation.

FossilOrigin-Name: bee73d429cb0e99b43fb191ac15e298d0353b135
2015-08-15 00:51:23 +00:00
drh 0403cb3012 Always provide the BTREE_BULKLOAD hint, even when SQLITE_ENABLE_CURSOR_HINTS
is not defined, as that hint gives a 4% performance increase.

FossilOrigin-Name: 83a844357e132683ab3d88eee0fe32a8beeb6662
2015-08-14 23:57:04 +00:00
drh 1eb6eeb829 Updated testing of cursor-hints. Remove the test_cursorhint.c file and
associated logic in the core and do tests based purely on the newly enhanced
EXPLAIN output.

FossilOrigin-Name: bf383e665a191a4f33a540d1240960a922e22813
2015-08-14 20:08:13 +00:00
drh 2f2b02785a Fix the cursor hint mechanism so that it does the right thing for indexed
lookups.

FossilOrigin-Name: 581e3d4988e98975fea5daaeb9f854c54a4976b7
2015-08-14 18:50:04 +00:00
drh 0df57012da Refactor the sqlite3BtreeCursorHint() interface for improved maintainability.
FossilOrigin-Name: fc3fb5cd0d2c123a069e5b18b62bb1f708c8698a
2015-08-14 15:05:55 +00:00
drh fe66352d17 Fix the CursorHint so that it includes the scan boundary constraints.
On the expression text for the CursorHint opcode, show rowid correctly.

FossilOrigin-Name: f0d428d13a787251c2ca7685fec2a91b550eefba
2015-08-14 01:03:21 +00:00
drh ffc648cfa9 Fix a harmless compiler warning.
FossilOrigin-Name: 608ab4ac1911d5f32a17ea043bd5f0748598691d
2015-08-13 21:38:09 +00:00
drh f7e369070e Convert the hint expression of the CursorHint opcode into a string for
display by EXPLAIN.

FossilOrigin-Name: 206884718782331a7aaacc2c811e4e9d2effae91
2015-08-13 21:32:41 +00:00
drh 07194bff0e Fix a bug in sqlite3ExprContainsSubquery().
FossilOrigin-Name: be254715b5f56900e57ed57a179ca8d7bb68685d
2015-08-13 20:34:41 +00:00
drh bec2476afc Merge in all the trunk changes from the previous year. This breaks the
cursor-hint mechanism, but provides a baseline for trouble-shooting.

FossilOrigin-Name: 82a7a61bc0883b1e7432548e4890791717aa1bb3
2015-08-13 20:07:13 +00:00
dan 91d3a61f8a Add simple tests for new sqlite3BtreeCursorHint() functionality.
FossilOrigin-Name: 1efa6ed584172291edce78faf9021e577583d03b
2014-07-15 11:59:44 +00:00
dan 159c1a18db In the expression passed to sqlite3BtreeCursorHint() for the inner loops of joins, replace any TK_COLUMN references to columns in the outer loops with TK_REGISTER expressions (Expr.iTable indicates the specific register containing the value).
FossilOrigin-Name: f9dddd008c6ef7940a1d66363fbb456cff7207c1
2014-07-14 19:04:29 +00:00
drh 5b88bc4bec Do not allow cursor hints to use expressions containing subqueries. This
change fixes the problem seen in the previous check-in.

FossilOrigin-Name: bfefc57554853e467ee6aeaba8d08331406fa216
2013-12-07 23:35:21 +00:00
drh 28935364ef If the SQLITE_ENABLE_CURSOR_HINTS macro is defined, then invoke the
sqlite3BtreeCursorHint() interface to provide hints to the storage engine
about rows that need not be returned.  Hints can be disabled using
SQLITE_TESTCTRL_OPTIMIZATIONS with SQLITE_CursorHints (0x2000).  Cursor
hints are not used by the built-in storage engine of SQLite but might
be useful to applications that provide their own storage engine.  The
current code is work-in-progrss and contains bugs.

FossilOrigin-Name: 3a9bec524ef2de44028b4058e67dc962082888d3
2013-12-07 20:39:19 +00:00
407 changed files with 27620 additions and 25404 deletions
-138
View File
@@ -1,138 +0,0 @@
#!/usr/make
#
# Makefile for SQLITE
#
# This is a template makefile for SQLite. Most people prefer to
# use the autoconf generated "configure" script to generate the
# makefile automatically. But that does not work for everybody
# and in every situation. If you are having problems with the
# "configure" script, you might want to try this makefile as an
# alternative. Create a copy of this file, edit the parameters
# below and type "make".
#
#### The directory where to find the mingw32ce tools
MINGW32CE = /opt/mingw32ce/bin
#### The target prefix of the mingw32ce tools
TARGET = arm-wince-mingw32ce
#### The toplevel directory of the source tree. This is the directory
# that contains this "Makefile.in" and the "configure.in" script.
#
TOP = ../sqlite
#### C Compiler and options for use in building executables that
# will run on the platform that is doing the build.
#
BCC = gcc -g -O2
#BCC = /opt/ancic/bin/c89 -0
#### If the target operating system supports the "usleep()" system
# call, then define the HAVE_USLEEP macro for all C modules.
#
USLEEP =
#USLEEP = -DHAVE_USLEEP=1
#### If you want the SQLite library to be safe for use within a
# multi-threaded program, then define the following macro
# appropriately:
#
THREADSAFE = -DTHREADSAFE=1
#THREADSAFE = -DTHREADSAFE=0
#### Specify any extra linker options needed to make the library
# thread safe
#
#THREADLIB = -lpthread
THREADLIB =
#### Specify any extra libraries needed to access required functions.
#
#TLIBS = -lrt # fdatasync on Solaris 8
TLIBS =
#### Leave SQLITE_DEBUG undefined for maximum speed. Use SQLITE_DEBUG=1
# to check for memory leaks. Use SQLITE_DEBUG=2 to print a log of all
# malloc()s and free()s in order to track down memory leaks.
#
# SQLite uses some expensive assert() statements in the inner loop.
# You can make the library go almost twice as fast if you compile
# with -DNDEBUG=1
#
#OPTS = -DSQLITE_DEBUG=2
#OPTS = -DSQLITE_DEBUG=1
#OPTS =
OPTS = -DNDEBUG=1 -DSQLITE_OS_WIN=1 -D_WIN32_WCE=1
#OPTS += -DHAVE_FDATASYNC=1
#### The suffix to add to executable files. ".exe" for windows.
# Nothing for unix.
#
EXE = .exe
#EXE =
#### C Compile and options for use in building executables that
# will run on the target platform. This is usually the same
# as BCC, unless you are cross-compiling.
#
#TCC = gcc -O6
#TCC = gcc -g -O0 -Wall
#TCC = gcc -g -O0 -Wall -fprofile-arcs -ftest-coverage
#TCC = /opt/mingw/bin/i386-mingw32-gcc -O6
TCC = $(MINGW32CE)/$(TARGET)-gcc -O2
#TCC = /opt/ansic/bin/c89 -O +z -Wl,-a,archive
#### Tools used to build a static library.
#
#AR = ar cr
#AR = /opt/mingw/bin/i386-mingw32-ar cr
AR = $(MINGW32CE)/$(TARGET)-ar cr
#RANLIB = ranlib
#RANLIB = /opt/mingw/bin/i386-mingw32-ranlib
RANLIB = $(MINGW32CE)/$(TARGET)-ranlib
#MKSHLIB = gcc -shared
#SO = so
#SHPREFIX = lib
MKSHLIB = $(MINGW32CE)/$(TARGET)-gcc -shared
SO = dll
SHPREFIX =
#### Extra compiler options needed for programs that use the TCL library.
#
#TCL_FLAGS =
#TCL_FLAGS = -DSTATIC_BUILD=1
TCL_FLAGS = -I/home/drh/tcltk/8.5linux
#TCL_FLAGS = -I/home/drh/tcltk/8.5win -DSTATIC_BUILD=1
#TCL_FLAGS = -I/home/drh/tcltk/8.3hpux
#### Linker options needed to link against the TCL library.
#
#LIBTCL = -ltcl -lm -ldl
LIBTCL = /home/drh/tcltk/8.5linux/libtcl8.5g.a -lm -ldl
#LIBTCL = /home/drh/tcltk/8.5win/libtcl85s.a -lmsvcrt
#LIBTCL = /home/drh/tcltk/8.3hpux/libtcl8.3.a -ldld -lm -lc
#### Additional objects for SQLite library when TCL support is enabled.
TCLOBJ =
#TCLOBJ = tclsqlite.o
#### Compiler options needed for programs that use the readline() library.
#
READLINE_FLAGS =
#READLINE_FLAGS = -DHAVE_READLINE=1 -I/usr/include/readline
#### Linker options needed by programs using readline() must link against.
#
LIBREADLINE =
#LIBREADLINE = -static -lreadline -ltermcap
#### Which "awk" program provides nawk compatibilty
#
# NAWK = nawk
NAWK = awk
# You should not have to change anything below this line
###############################################################################
include $(TOP)/main.mk
+48 -24
View File
@@ -54,6 +54,7 @@ LIBTCL = @TCL_LIB_SPEC@
# Compiler options needed for programs that use the readline() library.
#
READLINE_FLAGS = -DHAVE_READLINE=@TARGET_HAVE_READLINE@ @TARGET_READLINE_INC@
READLINE_FLAGS += -DHAVE_EDITLINE=@TARGET_HAVE_EDITLINE@
# The library that programs using readline() must link against.
#
@@ -155,9 +156,6 @@ LTCOMPILE = $(LIBTOOL) --mode=compile --tag=CC $(TCC) $(LTCOMPILE_EXTRAS)
LTLINK = $(LIBTOOL) --mode=link $(TCC) $(LTCOMPILE_EXTRAS) @LDFLAGS@ $(LTLINK_EXTRAS)
LTINSTALL = $(LIBTOOL) --mode=install $(INSTALL)
# nawk compatible awk.
NAWK = @AWK@
# You should not have to change anything below this line
###############################################################################
@@ -181,7 +179,7 @@ LIBOBJS0 = alter.lo analyze.lo attach.lo auth.lo \
mutex.lo mutex_noop.lo mutex_unix.lo mutex_w32.lo \
notify.lo opcodes.lo os.lo os_unix.lo os_win.lo \
pager.lo parse.lo pcache.lo pcache1.lo pragma.lo prepare.lo printf.lo \
random.lo resolve.lo rowset.lo rtree.lo select.lo status.lo \
random.lo resolve.lo rowset.lo rtree.lo select.lo sqlite3rbu.lo status.lo \
table.lo threads.lo tokenize.lo treeview.lo trigger.lo \
update.lo util.lo vacuum.lo \
vdbe.lo vdbeapi.lo vdbeaux.lo vdbeblob.lo vdbemem.lo vdbesort.lo \
@@ -404,6 +402,7 @@ TESTSRC = \
$(TOP)/src/test_tclvar.c \
$(TOP)/src/test_thread.c \
$(TOP)/src/test_vfs.c \
$(TOP)/src/test_windirent.c \
$(TOP)/src/test_wsd.c \
$(TOP)/ext/fts3/fts3_term.c \
$(TOP)/ext/fts3/fts3_test.c \
@@ -419,6 +418,7 @@ TESTSRC += \
$(TOP)/ext/misc/fuzzer.c \
$(TOP)/ext/fts5/fts5_tcl.c \
$(TOP)/ext/fts5/fts5_test_mi.c \
$(TOP)/ext/fts5/fts5_test_tok.c \
$(TOP)/ext/misc/ieee754.c \
$(TOP)/ext/misc/nextchar.c \
$(TOP)/ext/misc/percentile.c \
@@ -549,9 +549,10 @@ TESTOPTS = --verbose=file --output=test-out.txt
# Extra compiler options for various shell tools
#
SHELL_OPT = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_FTS5
SHELL_OPT = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_FTS4
SHELL_OPT += -DSQLITE_ENABLE_EXPLAIN_COMMENTS
FUZZERSHELL_OPT = -DSQLITE_ENABLE_JSON1
FUZZCHECK_OPT = -DSQLITE_ENABLE_JSON1
FUZZCHECK_OPT = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_MEMSYS5
# This is the default Makefile target. The objects listed here
# are what get build when you type just "make" with no arguments.
@@ -575,14 +576,20 @@ libtclsqlite3.la: tclsqlite.lo libsqlite3.la
-version-info "8:6:8" \
-avoid-version
sqlite3$(TEXE): $(TOP)/src/shell.c libsqlite3.la sqlite3.h
sqlite3$(TEXE): $(TOP)/src/shell.c sqlite3.c
$(LTLINK) $(READLINE_FLAGS) $(SHELL_OPT) -o $@ \
$(TOP)/src/shell.c libsqlite3.la \
$(TOP)/src/shell.c sqlite3.c \
$(LIBREADLINE) $(TLIBS) -rpath "$(libdir)"
sqldiff$(TEXE): $(TOP)/tool/sqldiff.c sqlite3.c sqlite3.h
$(LTLINK) -o $@ $(TOP)/tool/sqldiff.c sqlite3.c $(TLIBS)
srcck1$(BEXE): $(TOP)/tool/srcck1.c
$(BCC) -o srcck1$(BEXE) $(TOP)/tool/srcck1.c
sourcetest: srcck1$(BEXE) sqlite3.c
./srcck1 sqlite3.c
fuzzershell$(TEXE): $(TOP)/tool/fuzzershell.c sqlite3.c sqlite3.h
$(LTLINK) -o $@ $(FUZZERSHELL_OPT) \
$(TOP)/tool/fuzzershell.c sqlite3.c $(TLIBS)
@@ -647,9 +654,9 @@ sqlite3.lo: sqlite3.c
# Rules to build the LEMON compiler generator
#
lemon$(BEXE): $(TOP)/tool/lemon.c $(TOP)/src/lempar.c
lemon$(BEXE): $(TOP)/tool/lemon.c $(TOP)/tool/lempar.c
$(BCC) -o $@ $(TOP)/tool/lemon.c
cp $(TOP)/src/lempar.c .
cp $(TOP)/tool/lempar.c .
# Rules to build individual *.o files from generated *.c files. This
# applies to:
@@ -902,22 +909,22 @@ tclsqlite3$(TEXE): tclsqlite-shell.lo libsqlite3.la
# Rules to build opcodes.c and opcodes.h
#
opcodes.c: opcodes.h $(TOP)/mkopcodec.awk
$(NAWK) -f $(TOP)/mkopcodec.awk opcodes.h >opcodes.c
opcodes.c: opcodes.h $(TOP)/tool/mkopcodec.tcl
$(TCLSH_CMD) $(TOP)/tool/mkopcodec.tcl opcodes.h >opcodes.c
opcodes.h: parse.h $(TOP)/src/vdbe.c $(TOP)/mkopcodeh.awk
cat parse.h $(TOP)/src/vdbe.c | $(NAWK) -f $(TOP)/mkopcodeh.awk >opcodes.h
opcodes.h: parse.h $(TOP)/src/vdbe.c $(TOP)/tool/mkopcodeh.tcl
cat parse.h $(TOP)/src/vdbe.c | $(TCLSH_CMD) $(TOP)/tool/mkopcodeh.tcl >opcodes.h
# Rules to build parse.c and parse.h - the outputs of lemon.
#
parse.h: parse.c
parse.c: $(TOP)/src/parse.y lemon$(BEXE) $(TOP)/addopcodes.awk
parse.c: $(TOP)/src/parse.y lemon$(BEXE) $(TOP)/tool/addopcodes.tcl
cp $(TOP)/src/parse.y .
rm -f parse.h
./lemon$(BEXE) $(OPT_FEATURE_FLAGS) $(OPTS) parse.y
mv parse.h parse.h.temp
$(NAWK) -f $(TOP)/addopcodes.awk parse.h.temp >parse.h
$(TCLSH_CMD) $(TOP)/tool/addopcodes.tcl parse.h.temp >parse.h
sqlite3.h: $(TOP)/src/sqlite.h.in $(TOP)/manifest.uuid $(TOP)/VERSION
$(TCLSH_CMD) $(TOP)/tool/mksqlite3h.tcl $(TOP) >sqlite3.h
@@ -1029,6 +1036,9 @@ fts5.c: $(FTS5_SRC)
fts5.lo: fts5.c $(HDR) $(EXTHDR)
$(LTCOMPILE) -DSQLITE_CORE -c fts5.c
sqlite3rbu.lo: $(TOP)/ext/rbu/sqlite3rbu.c $(HDR) $(EXTHDR)
$(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/rbu/sqlite3rbu.c
# Rules to build the 'testfixture' application.
#
@@ -1040,6 +1050,7 @@ fts5.lo: fts5.c $(HDR) $(EXTHDR)
TESTFIXTURE_FLAGS = -DTCLSH=1 -DSQLITE_TEST=1 -DSQLITE_CRASH_TEST=1
TESTFIXTURE_FLAGS += -DSQLITE_SERVER=1 -DSQLITE_PRIVATE="" -DSQLITE_CORE
TESTFIXTURE_FLAGS += -DBUILD_sqlite
TESTFIXTURE_FLAGS += -DSQLITE_SERIES_CONSTRAINT_VERIFY=1
TESTFIXTURE_SRC0 = $(TESTSRC2) libsqlite3.la
TESTFIXTURE_SRC1 = sqlite3.c
@@ -1070,7 +1081,7 @@ fastfuzztest: fuzzcheck$(TEXE) $(FUZZDATA)
./fuzzcheck$(TEXE) --limit-mem 100M $(FUZZDATA)
valgrindfuzz: fuzzcheck$(TEXT) $(FUZZDATA)
valgrind ./fuzzcheck$(TEXE) --cell-size-check --limit-mem 10M $(FUZZDATA)
valgrind ./fuzzcheck$(TEXE) --cell-size-check --limit-mem 10M --timeout 600 $(FUZZDATA)
# Minimal testing that runs in less than 3 minutes
#
@@ -1080,7 +1091,7 @@ quicktest: ./testfixture$(TEXE)
# This is the common case. Run many tests that do not take too long,
# including fuzzcheck, sqlite3_analyzer, and sqldiff tests.
#
test: $(TESTPROGS) fastfuzztest
test: $(TESTPROGS) sourcetest fastfuzztest
./testfixture$(TEXE) $(TOP)/test/veryquick.test $(TESTOPTS)
# Run a test using valgrind. This can take a really long time
@@ -1102,7 +1113,7 @@ sqlite3_analyzer.c: sqlite3.c $(TOP)/src/tclsqlite.c $(TOP)/tool/spaceanal.tcl
cat sqlite3.c $(TOP)/src/tclsqlite.c >> $@
echo "static const char *tclsh_main_loop(void){" >> $@
echo "static const char *zMainloop = " >> $@
$(NAWK) -f $(TOP)/tool/tostr.awk $(TOP)/tool/spaceanal.tcl >> $@
$(TCLSH_CMD) $(TOP)/tool/tostr.tcl $(TOP)/tool/spaceanal.tcl >> $@
echo "; return zMainloop; }" >> $@
sqlite3_analyzer$(TEXE): sqlite3_analyzer.c
@@ -1132,6 +1143,12 @@ wordcount$(TEXE): $(TOP)/test/wordcount.c sqlite3.c
speedtest1$(TEXE): $(TOP)/test/speedtest1.c sqlite3.lo
$(LTLINK) -o $@ $(TOP)/test/speedtest1.c sqlite3.lo $(TLIBS)
rbu$(EXE): $(TOP)/ext/rbu/rbu.c $(TOP)/ext/rbu/sqlite3rbu.c sqlite3.lo
$(LTLINK) -I. -o $@ $(TOP)/ext/rbu/rbu.c sqlite3.lo $(TLIBS)
loadfts$(EXE): $(TOP)/tool/loadfts.c libsqlite3.la
$(LTLINK) $(TOP)/tool/loadfts.c libsqlite3.la -o $@ $(TLIBS)
# This target will fail if the SQLite amalgamation contains any exported
# symbols that do not begin with "sqlite3_". It is run as part of the
# releasetest.tcl script.
@@ -1140,10 +1157,15 @@ checksymbols: sqlite3.lo
nm -g --defined-only sqlite3.o | grep -v " sqlite3_" ; test $$? -ne 0
echo '0 errors out of 1 tests'
# Build the amalgamation-autoconf package.
# Build the amalgamation-autoconf package. The amalamgation-tarball target builds
# a tarball named for the version number. Ex: sqlite-autoconf-3110000.tar.gz.
# The snapshot-tarball target builds a tarball named by the SHA1 hash
#
amalgamation-tarball: sqlite3.c
TOP=$(TOP) sh $(TOP)/tool/mkautoconfamal.sh
TOP=$(TOP) sh $(TOP)/tool/mkautoconfamal.sh --normal
snapshot-tarball: sqlite3.c
TOP=$(TOP) sh $(TOP)/tool/mkautoconfamal.sh --snapshot
# The next two rules are used to support the "threadtest" target. Building
# threadtest runs a few thread-safety tests that are implemented in C. This
@@ -1157,7 +1179,7 @@ THREADTEST3_SRC = $(TOP)/test/threadtest3.c \
$(TOP)/test/tt3_lookaside1.c
threadtest3$(TEXE): sqlite3.lo $(THREADTEST3_SRC)
$(LTLINK) $(TOP)/test/threadtest3.c sqlite3.lo -o $@ $(TLIBS)
$(LTLINK) $(TOP)/test/threadtest3.c $(TOP)/src/test_multiplex.c sqlite3.lo -o $@ $(TLIBS)
threadtest: threadtest3$(TEXE)
./threadtest3$(TEXE)
@@ -1171,9 +1193,9 @@ lib_install: libsqlite3.la
$(INSTALL) -d $(DESTDIR)$(libdir)
$(LTINSTALL) libsqlite3.la $(DESTDIR)$(libdir)
install: sqlite3$(BEXE) lib_install sqlite3.h sqlite3.pc ${HAVE_TCL:1=tcl_install}
install: sqlite3$(TEXE) lib_install sqlite3.h sqlite3.pc ${HAVE_TCL:1=tcl_install}
$(INSTALL) -d $(DESTDIR)$(bindir)
$(LTINSTALL) sqlite3$(BEXE) $(DESTDIR)$(bindir)
$(LTINSTALL) sqlite3$(TEXE) $(DESTDIR)$(bindir)
$(INSTALL) -d $(DESTDIR)$(includedir)
$(INSTALL) -m 0644 sqlite3.h $(DESTDIR)$(includedir)
$(INSTALL) -m 0644 $(TOP)/src/sqlite3ext.h $(DESTDIR)$(includedir)
@@ -1209,6 +1231,8 @@ clean:
rm -f sqlite3_analyzer$(TEXE) sqlite3_analyzer.c
rm -f sqlite-*-output.vsix
rm -f mptester mptester.exe
rm -f rbu rbu.exe
rm -f srcck1 srcck1.exe
rm -f fuzzershell fuzzershell.exe
rm -f fuzzcheck fuzzcheck.exe
rm -f sqldiff sqldiff.exe
-5
View File
@@ -118,11 +118,6 @@ READLINE_FLAGS =
LIBREADLINE =
#LIBREADLINE = -static -lreadline -ltermcap
#### Which "awk" program provides nawk compatibilty
#
# NAWK = nawk
NAWK = awk
# You should not have to change anything below this line
###############################################################################
include $(TOP)/main.mk
+452 -241
View File
File diff suppressed because it is too large Load Diff
-673
View File
@@ -1,673 +0,0 @@
#!/usr/make
#
# Makefile for SQLITE on VxWorks
ifeq ($(FORCPU),)
FORCPU = SH32gnule
endif
TOOL_FAMILY = gnu
include $(WIND_USR)/tool/gnu/make.$(FORCPU)
#### The toplevel directory of the source tree. This is the directory
# that contains this "Makefile.in" and the "configure.in" script.
#
TOP = .
#### C Compiler and options for use in building executables that
# will run on the platform that is doing the build.
#
BCC = gcc -g -O2
#BCC = /opt/ancic/bin/c89 -0
#### If the target operating system supports the "usleep()" system
# call, then define the HAVE_USLEEP macro for all C modules.
#
USLEEP =
#USLEEP = -DHAVE_USLEEP=1
#### If you want the SQLite library to be safe for use within a
# multi-threaded program, then define the following macro
# appropriately:
#
THREADSAFE = -DSQLITE_THREADSAFE=1
#THREADSAFE = -DSQLITE_THREADSAFE=0
#### Specify any extra linker options needed to make the library
# thread safe
#
#THREADLIB = -lpthread
THREADLIB =
#### Specify any extra libraries needed to access required functions.
#
ifeq ($(CPU),SH32)
# for SH4 shared library
TLIBS_SHARED += -L$(WIND_USR)/lib/sh/SH32/commonle/PIC
else
# for all other CPUs shared library
TLIBS_SHARED += $(LD_LINK_PATH_ATEND) $(LD_PARTIAL_LAST_FLAGS)
endif
# for static library
TLIBS += $(LD_LINK_PATH_ATEND) $(LD_PARTIAL_LAST_FLAGS)
#### Leave SQLITE_DEBUG undefined for maximum speed. Use SQLITE_DEBUG=1
# to check for memory leaks. Use SQLITE_DEBUG=2 to print a log of all
# malloc()s and free()s in order to track down memory leaks.
#
# SQLite uses some expensive assert() statements in the inner loop.
# You can make the library go almost twice as fast if you compile
# with -DNDEBUG=1
#
#OPTS = -DSQLITE_DEBUG=2
#OPTS = -DSQLITE_DEBUG=1
#OPTS =
OPTS = -DNDEBUG=1 -DSQLITE_OS_UNIX=1 $(THREADSAFE)
OPTS += -DSQLITE_OMIT_LOAD_EXTENSION=1
OPTS += -DSQLITE_ENABLE_LOCKING_STYLE=1
OPTS += -DSQLITE_THREAD_OVERRIDE_LOCK=0
OPTS += -DSQLITE_ENABLE_COLUMN_METADATA=1
OPTS += -DHAVE_FDATASYNC=1
#### The suffix to add to executable files. ".exe" for windows.
# Nothing for unix.
#
EXE = .vxe
#EXE =
#### C Compile and options for use in building executables that
# will run on the target platform. This is usually the same
# as BCC, unless you are cross-compiling.
#
#TCC = gcc -O6
#TCC = gcc -g -O0 -Wall
#TCC = gcc -g -O0 -Wall -fprofile-arcs -ftest-coverage
#TCC = /opt/mingw/bin/i386-mingw32-gcc -O6
TCC = $(CC) $(DEFINE_CC) -O2 -g -mrtp $(CC_ARCH_SPEC) -D_REENTRANT=1 -D_VX_CPU=_VX_$(CPU) -D_VX_TOOL_FAMILY=$(TOOL_FAMILY) -D_VX_TOOL=$(TOOL)
TCC += -I$(WIND_USR)/h -I$(WIND_USR)/h/wrn/coreip
#TCC = /opt/ansic/bin/c89 -O +z -Wl,-a,archive
#TCC_SHARED = $(TCC) -fPIC
TCC_SHARED = $(TCC)
#### Tools used to build a static library.
#
#ARX = ar cr
#ARX = /opt/mingw/bin/i386-mingw32-ar cr
AR += cr
#RANLIB = ranlib
#RANLIB = /opt/mingw/bin/i386-mingw32-ranlib
#MKSHLIB = gcc -shared
#SO = so
#SHPREFIX = lib
MKSHLIB = $(CC) $(DEFINE_CC) -mrtp -shared $(CC_ARCH_SPEC) -D_VX_CPU=_VX_$(CPU) -D_VX_TOOL_FAMILY=$(TOOL_FAMILY) -D_VX_TOOL=$(TOOL)
SO = so
SHPREFIX = lib
#### Extra compiler options needed for programs that use the TCL library.
#
#TCL_FLAGS =
#TCL_FLAGS = -DSTATIC_BUILD=1
TCL_FLAGS = -I/home/drh/tcltk/8.5linux
#TCL_FLAGS = -I/home/drh/tcltk/8.5win -DSTATIC_BUILD=1
#TCL_FLAGS = -I/home/drh/tcltk/8.3hpux
#### Linker options needed to link against the TCL library.
#
#LIBTCL = -ltcl -lm -ldl
LIBTCL = /home/drh/tcltk/8.5linux/libtcl8.5g.a -lm -ldl
#LIBTCL = /home/drh/tcltk/8.5win/libtcl85s.a -lmsvcrt
#LIBTCL = /home/drh/tcltk/8.3hpux/libtcl8.3.a -ldld -lm -lc
#### Additional objects for SQLite library when TCL support is enabled.
TCLOBJ =
#TCLOBJ = tclsqlite.o
#### Compiler options needed for programs that use the readline() library.
#
READLINE_FLAGS =
#READLINE_FLAGS = -DHAVE_READLINE=1 -I/usr/include/readline
#### Linker options needed by programs using readline() must link against.
#
LIBREADLINE =
#LIBREADLINE = -static -lreadline -ltermcap
#### Which "awk" program provides nawk compatibilty
#
# NAWK = nawk
NAWK = awk
#### Pasted and adapted main.mk file
###############################################################################
# The following macros should be defined before this script is
# invoked:
#
# TOP The toplevel directory of the source tree. This is the
# directory that contains this "Makefile.in" and the
# "configure.in" script.
#
# BCC C Compiler and options for use in building executables that
# will run on the platform that is doing the build.
#
# THREADLIB Specify any extra linker options needed to make the library
# thread safe
#
# OPTS Extra compiler command-line options.
#
# EXE The suffix to add to executable files. ".exe" for windows
# and "" for Unix.
#
# TCC C Compiler and options for use in building executables that
# will run on the target platform. This is usually the same
# as BCC, unless you are cross-compiling.
#
# AR Tools used to build a static library.
# RANLIB
#
# TCL_FLAGS Extra compiler options needed for programs that use the
# TCL library.
#
# LIBTCL Linker options needed to link against the TCL library.
#
# READLINE_FLAGS Compiler options needed for programs that use the
# readline() library.
#
# LIBREADLINE Linker options needed by programs using readline() must
# link against.
#
# NAWK Nawk compatible awk program. Older (obsolete?) solaris
# systems need this to avoid using the original AT&T AWK.
#
# Once the macros above are defined, the rest of this make script will
# build the SQLite library and testing tools.
################################################################################
# This is how we compile
#
TCCX = $(TCC) $(OPTS) -I. -I$(TOP)/src -I$(TOP)
TCCX_SHARED = $(TCC_SHARED) $(OPTS) -I. -I$(TOP)/src -I$(TOP) \
-I$(TOP)/ext/rtree -I$(TOP)/ext/icu -I$(TOP)/ext/fts3 \
-I$(TOP)/ext/async
# Object files for the SQLite library.
#
LIBOBJ+= alter.o analyze.o attach.o auth.o \
backup.o bitvec.o btmutex.o btree.o build.o \
callback.o complete.o date.o delete.o expr.o fault.o \
fts3.o fts3_expr.o fts3_hash.o fts3_icu.o fts3_porter.o \
fts3_tokenizer.o fts3_tokenizer1.o \
func.o global.o hash.o \
icu.o insert.o journal.o legacy.o loadext.o \
main.o malloc.o mem0.o mem1.o mem2.o mem3.o mem5.o \
memjournal.o \
mutex.o mutex_noop.o mutex_unix.o mutex_w32.o \
notify.o opcodes.o os.o os_unix.o os_win.o \
pager.o parse.o pcache.o pcache1.o pragma.o prepare.o printf.o \
random.o resolve.o rowset.o rtree.o select.o status.o \
table.o tokenize.o trigger.o \
update.o util.o vacuum.o \
vdbe.o vdbeapi.o vdbeaux.o vdbeblob.o vdbemem.o \
walker.o where.o utf.o vtab.o
# All of the source code files.
#
SRC = \
$(TOP)/src/alter.c \
$(TOP)/src/analyze.c \
$(TOP)/src/attach.c \
$(TOP)/src/auth.c \
$(TOP)/src/backup.c \
$(TOP)/src/bitvec.c \
$(TOP)/src/btmutex.c \
$(TOP)/src/btree.c \
$(TOP)/src/btree.h \
$(TOP)/src/btreeInt.h \
$(TOP)/src/build.c \
$(TOP)/src/callback.c \
$(TOP)/src/complete.c \
$(TOP)/src/ctime.c \
$(TOP)/src/date.c \
$(TOP)/src/delete.c \
$(TOP)/src/expr.c \
$(TOP)/src/fault.c \
$(TOP)/src/func.c \
$(TOP)/src/global.c \
$(TOP)/src/hash.c \
$(TOP)/src/hash.h \
$(TOP)/src/hwtime.h \
$(TOP)/src/insert.c \
$(TOP)/src/journal.c \
$(TOP)/src/legacy.c \
$(TOP)/src/loadext.c \
$(TOP)/src/main.c \
$(TOP)/src/malloc.c \
$(TOP)/src/mem0.c \
$(TOP)/src/mem1.c \
$(TOP)/src/mem2.c \
$(TOP)/src/mem3.c \
$(TOP)/src/mem5.c \
$(TOP)/src/memjournal.c \
$(TOP)/src/msvc.h \
$(TOP)/src/mutex.c \
$(TOP)/src/mutex.h \
$(TOP)/src/mutex_noop.c \
$(TOP)/src/mutex_unix.c \
$(TOP)/src/mutex_w32.c \
$(TOP)/src/notify.c \
$(TOP)/src/os.c \
$(TOP)/src/os.h \
$(TOP)/src/os_common.h \
$(TOP)/src/os_setup.h \
$(TOP)/src/os_unix.c \
$(TOP)/src/os_win.c \
$(TOP)/src/os_win.h \
$(TOP)/src/pager.c \
$(TOP)/src/pager.h \
$(TOP)/src/parse.y \
$(TOP)/src/pcache.c \
$(TOP)/src/pcache.h \
$(TOP)/src/pcache1.c \
$(TOP)/src/pragma.c \
$(TOP)/src/prepare.c \
$(TOP)/src/printf.c \
$(TOP)/src/random.c \
$(TOP)/src/resolve.c \
$(TOP)/src/rowset.c \
$(TOP)/src/select.c \
$(TOP)/src/status.c \
$(TOP)/src/shell.c \
$(TOP)/src/sqlite.h.in \
$(TOP)/src/sqlite3ext.h \
$(TOP)/src/sqliteInt.h \
$(TOP)/src/sqliteLimit.h \
$(TOP)/src/table.c \
$(TOP)/src/tclsqlite.c \
$(TOP)/src/tokenize.c \
$(TOP)/src/trigger.c \
$(TOP)/src/utf.c \
$(TOP)/src/update.c \
$(TOP)/src/util.c \
$(TOP)/src/vacuum.c \
$(TOP)/src/vdbe.c \
$(TOP)/src/vdbe.h \
$(TOP)/src/vdbeapi.c \
$(TOP)/src/vdbeaux.c \
$(TOP)/src/vdbeblob.c \
$(TOP)/src/vdbemem.c \
$(TOP)/src/vdbeInt.h \
$(TOP)/src/vtab.c \
$(TOP)/src/walker.c \
$(TOP)/src/where.c
# Source code for extensions
#
SRC += \
$(TOP)/ext/fts1/fts1.c \
$(TOP)/ext/fts1/fts1.h \
$(TOP)/ext/fts1/fts1_hash.c \
$(TOP)/ext/fts1/fts1_hash.h \
$(TOP)/ext/fts1/fts1_porter.c \
$(TOP)/ext/fts1/fts1_tokenizer.h \
$(TOP)/ext/fts1/fts1_tokenizer1.c
SRC += \
$(TOP)/ext/fts2/fts2.c \
$(TOP)/ext/fts2/fts2.h \
$(TOP)/ext/fts2/fts2_hash.c \
$(TOP)/ext/fts2/fts2_hash.h \
$(TOP)/ext/fts2/fts2_icu.c \
$(TOP)/ext/fts2/fts2_porter.c \
$(TOP)/ext/fts2/fts2_tokenizer.h \
$(TOP)/ext/fts2/fts2_tokenizer.c \
$(TOP)/ext/fts2/fts2_tokenizer1.c
SRC += \
$(TOP)/ext/fts3/fts3.c \
$(TOP)/ext/fts3/fts3.h \
$(TOP)/ext/fts3/fts3_expr.c \
$(TOP)/ext/fts3/fts3_expr.h \
$(TOP)/ext/fts3/fts3_hash.c \
$(TOP)/ext/fts3/fts3_hash.h \
$(TOP)/ext/fts3/fts3_icu.c \
$(TOP)/ext/fts3/fts3_porter.c \
$(TOP)/ext/fts3/fts3_tokenizer.h \
$(TOP)/ext/fts3/fts3_tokenizer.c \
$(TOP)/ext/fts3/fts3_tokenizer1.c
SRC += \
$(TOP)/ext/icu/sqliteicu.h \
$(TOP)/ext/icu/icu.c
SRC += \
$(TOP)/ext/rtree/rtree.h \
$(TOP)/ext/rtree/rtree.c
# Generated source code files
#
SRC += \
keywordhash.h \
opcodes.c \
opcodes.h \
parse.c \
parse.h \
sqlite3.h
# Source code to the test files.
#
TESTSRC = \
$(TOP)/src/test1.c \
$(TOP)/src/test2.c \
$(TOP)/src/test3.c \
$(TOP)/src/test4.c \
$(TOP)/src/test5.c \
$(TOP)/src/test6.c \
$(TOP)/src/test7.c \
$(TOP)/src/test8.c \
$(TOP)/src/test9.c \
$(TOP)/src/test_autoext.c \
$(TOP)/src/test_async.c \
$(TOP)/src/test_backup.c \
$(TOP)/src/test_btree.c \
$(TOP)/src/test_config.c \
$(TOP)/src/test_devsym.c \
$(TOP)/src/test_func.c \
$(TOP)/src/test_hexio.c \
$(TOP)/src/test_journal.c \
$(TOP)/src/test_malloc.c \
$(TOP)/src/test_md5.c \
$(TOP)/src/test_mutex.c \
$(TOP)/src/test_onefile.c \
$(TOP)/src/test_osinst.c \
$(TOP)/src/test_pcache.c \
$(TOP)/src/test_schema.c \
$(TOP)/src/test_server.c \
$(TOP)/src/test_tclvar.c \
$(TOP)/src/test_thread.c \
$(TOP)/src/test_vfs.c \
$(TOP)/src/test_wsd.c \
#TESTSRC += $(TOP)/ext/fts2/fts2_tokenizer.c
#TESTSRC += $(TOP)/ext/fts3/fts3_tokenizer.c
TESTSRC2 = \
$(TOP)/src/attach.c $(TOP)/src/backup.c $(TOP)/src/btree.c \
$(TOP)/src/build.c $(TOP)/src/ctime.c $(TOP)/src/date.c \
$(TOP)/src/expr.c $(TOP)/src/func.c $(TOP)/src/insert.c $(TOP)/src/os.c \
$(TOP)/src/os_unix.c $(TOP)/src/os_win.c \
$(TOP)/src/pager.c $(TOP)/src/pragma.c $(TOP)/src/prepare.c \
$(TOP)/src/printf.c $(TOP)/src/random.c $(TOP)/src/pcache.c \
$(TOP)/src/pcache1.c $(TOP)/src/select.c $(TOP)/src/tokenize.c \
$(TOP)/src/utf.c $(TOP)/src/util.c $(TOP)/src/vdbeapi.c $(TOP)/src/vdbeaux.c \
$(TOP)/src/vdbe.c $(TOP)/src/vdbemem.c $(TOP)/src/where.c parse.c \
$(TOP)/ext/fts3/fts3.c $(TOP)/ext/fts3/fts3_expr.c \
$(TOP)/ext/fts3/fts3_tokenizer.c \
$(TOP)/ext/async/sqlite3async.c
# Header files used by all library source files.
#
HDR = \
$(TOP)/src/btree.h \
$(TOP)/src/btreeInt.h \
$(TOP)/src/hash.h \
$(TOP)/src/hwtime.h \
keywordhash.h \
$(TOP)/src/msvc.h \
$(TOP)/src/mutex.h \
opcodes.h \
$(TOP)/src/os.h \
$(TOP)/src/os_common.h \
$(TOP)/src/os_setup.h \
$(TOP)/src/os_win.h \
$(TOP)/src/pager.h \
$(TOP)/src/pcache.h \
parse.h \
sqlite3.h \
$(TOP)/src/sqlite3ext.h \
$(TOP)/src/sqliteInt.h \
$(TOP)/src/sqliteLimit.h \
$(TOP)/src/vdbe.h \
$(TOP)/src/vdbeInt.h
# Header files used by extensions
#
EXTHDR += \
$(TOP)/ext/fts1/fts1.h \
$(TOP)/ext/fts1/fts1_hash.h \
$(TOP)/ext/fts1/fts1_tokenizer.h
EXTHDR += \
$(TOP)/ext/fts2/fts2.h \
$(TOP)/ext/fts2/fts2_hash.h \
$(TOP)/ext/fts2/fts2_tokenizer.h
EXTHDR += \
$(TOP)/ext/fts3/fts3.h \
$(TOP)/ext/fts3/fts3_expr.h \
$(TOP)/ext/fts3/fts3_hash.h \
$(TOP)/ext/fts3/fts3_tokenizer.h
EXTHDR += \
$(TOP)/ext/rtree/rtree.h
EXTHDR += \
$(TOP)/ext/icu/sqliteicu.h
# This is the default Makefile target. The objects listed here
# are what get build when you type just "make" with no arguments.
#
all: sqlite3.h libsqlite3.a sqlite3$(EXE)
libsqlite3.a: $(LIBOBJ)
$(AR) libsqlite3.a $(LIBOBJ)
$(RANLIB) libsqlite3.a
$(SHPREFIX)sqlite3.$(SO): $(LIBOBJ)
$(MKSHLIB) -o $(SHPREFIX)sqlite3.$(SO) $(LIBOBJ) $(TLIBS_SHARED)
sqlite3$(EXE): $(TOP)/src/shell.c libsqlite3.a sqlite3.h
$(TCCX) $(READLINE_FLAGS) -o sqlite3$(EXE) \
$(TOP)/src/shell.c \
$(LIBREADLINE) $(TLIBS) $(THREADLIB) -L. -lsqlite3
# This target creates a directory named "tsrc" and fills it with
# copies of all of the C source code and header files needed to
# build on the target system. Some of the C source code and header
# files are automatically generated. This target takes care of
# all that automatic generation.
#
target_source: $(SRC)
rm -rf tsrc
mkdir tsrc
cp -f $(SRC) tsrc
rm tsrc/sqlite.h.in tsrc/parse.y
touch target_source
sqlite3.c: target_source $(TOP)/tool/mksqlite3c.tcl
tclsh $(TOP)/tool/mksqlite3c.tcl
cp sqlite3.c tclsqlite3.c
cat $(TOP)/src/tclsqlite.c >>tclsqlite3.c
fts2amal.c: target_source $(TOP)/ext/fts2/mkfts2amal.tcl
tclsh $(TOP)/ext/fts2/mkfts2amal.tcl
fts3amal.c: target_source $(TOP)/ext/fts3/mkfts3amal.tcl
tclsh $(TOP)/ext/fts3/mkfts3amal.tcl
# Rules to build the LEMON compiler generator
#
lemon: $(TOP)/tool/lemon.c $(TOP)/src/lempar.c
$(BCC) -o lemon $(TOP)/tool/lemon.c
cp $(TOP)/src/lempar.c .
# Rules to build individual *.o files from generated *.c files. This
# applies to:
#
# parse.o
# opcodes.o
#
%.o: %.c $(HDR)
$(TCCX_SHARED) -c $<
# Rules to build individual *.o files from files in the src directory.
#
%.o: $(TOP)/src/%.c $(HDR)
$(TCCX_SHARED) -c $<
tclsqlite.o: $(TOP)/src/tclsqlite.c $(HDR)
$(TCCX_SHARED) $(TCL_FLAGS) -c $(TOP)/src/tclsqlite.c
# Rules to build opcodes.c and opcodes.h
#
opcodes.c: opcodes.h $(TOP)/mkopcodec.awk
$(NAWK) -f $(TOP)/mkopcodec.awk opcodes.h >opcodes.c
opcodes.h: parse.h $(TOP)/src/vdbe.c $(TOP)/mkopcodeh.awk
cat parse.h $(TOP)/src/vdbe.c | \
$(NAWK) -f $(TOP)/mkopcodeh.awk >opcodes.h
# Rules to build parse.c and parse.h - the outputs of lemon.
#
parse.h: parse.c
parse.c: $(TOP)/src/parse.y lemon $(TOP)/addopcodes.awk
cp $(TOP)/src/parse.y .
rm -f parse.h
./lemon $(OPTS) parse.y
mv parse.h parse.h.temp
awk -f $(TOP)/addopcodes.awk parse.h.temp >parse.h
sqlite3.h: $(TOP)/src/sqlite.h.in
sed -e s/--VERS--/`cat ${TOP}/VERSION`/ \
-e s/--VERSION-NUMBER--/`cat ${TOP}/VERSION | sed 's/[^0-9]/ /g' | $(NAWK) '{printf "%d%03d%03d",$$1,$$2,$$3}'`/ \
$(TOP)/src/sqlite.h.in >sqlite3.h
keywordhash.h: $(TOP)/tool/mkkeywordhash.c
$(BCC) -o mkkeywordhash $(OPTS) $(TOP)/tool/mkkeywordhash.c
./mkkeywordhash >keywordhash.h
# Rules to build the extension objects.
#
icu.o: $(TOP)/ext/icu/icu.c $(HDR) $(EXTHDR)
$(TCCX_SHARED) -DSQLITE_CORE -c $(TOP)/ext/icu/icu.c
fts2.o: $(TOP)/ext/fts2/fts2.c $(HDR) $(EXTHDR)
$(TCCX_SHARED) -DSQLITE_CORE -c $(TOP)/ext/fts2/fts2.c
fts2_hash.o: $(TOP)/ext/fts2/fts2_hash.c $(HDR) $(EXTHDR)
$(TCCX_SHARED) -DSQLITE_CORE -c $(TOP)/ext/fts2/fts2_hash.c
fts2_icu.o: $(TOP)/ext/fts2/fts2_icu.c $(HDR) $(EXTHDR)
$(TCCX_SHARED) -DSQLITE_CORE -c $(TOP)/ext/fts2/fts2_icu.c
fts2_porter.o: $(TOP)/ext/fts2/fts2_porter.c $(HDR) $(EXTHDR)
$(TCCX_SHARED) -DSQLITE_CORE -c $(TOP)/ext/fts2/fts2_porter.c
fts2_tokenizer.o: $(TOP)/ext/fts2/fts2_tokenizer.c $(HDR) $(EXTHDR)
$(TCCX_SHARED) -DSQLITE_CORE -c $(TOP)/ext/fts2/fts2_tokenizer.c
fts2_tokenizer1.o: $(TOP)/ext/fts2/fts2_tokenizer1.c $(HDR) $(EXTHDR)
$(TCCX_SHARED) -DSQLITE_CORE -c $(TOP)/ext/fts2/fts2_tokenizer1.c
fts3.o: $(TOP)/ext/fts3/fts3.c $(HDR) $(EXTHDR)
$(TCCX_SHARED) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3.c
fts3_expr.o: $(TOP)/ext/fts3/fts3_expr.c $(HDR) $(EXTHDR)
$(TCCX_SHARED) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_expr.c
fts3_hash.o: $(TOP)/ext/fts3/fts3_hash.c $(HDR) $(EXTHDR)
$(TCCX_SHARED) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_hash.c
fts3_icu.o: $(TOP)/ext/fts3/fts3_icu.c $(HDR) $(EXTHDR)
$(TCCX_SHARED) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_icu.c
fts3_porter.o: $(TOP)/ext/fts3/fts3_porter.c $(HDR) $(EXTHDR)
$(TCCX_SHARED) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_porter.c
fts3_tokenizer.o: $(TOP)/ext/fts3/fts3_tokenizer.c $(HDR) $(EXTHDR)
$(TCCX_SHARED) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_tokenizer.c
fts3_tokenizer1.o: $(TOP)/ext/fts3/fts3_tokenizer1.c $(HDR) $(EXTHDR)
$(TCCX_SHARED) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_tokenizer1.c
rtree.o: $(TOP)/ext/rtree/rtree.c $(HDR) $(EXTHDR)
$(TCCX_SHARED) -DSQLITE_CORE -c $(TOP)/ext/rtree/rtree.c
# Rules for building test programs and for running tests
#
tclsqlite3: $(TOP)/src/tclsqlite.c libsqlite3.a
$(TCCX_SHARED) $(TCL_FLAGS) -DTCLSH=1 -o tclsqlite3 \
$(TOP)/src/tclsqlite.c libsqlite3.a $(LIBTCL) $(THREADLIB)
# Rules to build the 'testfixture' application.
#
TESTFIXTURE_FLAGS = -DTCLSH=1 -DSQLITE_TEST=1 -DSQLITE_CRASH_TEST=1
TESTFIXTURE_FLAGS += -DSQLITE_SERVER=1 -DSQLITE_PRIVATE="" -DSQLITE_CORE
testfixture$(EXE): $(TESTSRC2) libsqlite3.a $(TESTSRC) $(TOP)/src/tclsqlite.c
$(TCCX) $(TCL_FLAGS) $(TESTFIXTURE_FLAGS) \
$(TESTSRC) $(TESTSRC2) $(TOP)/src/tclsqlite.c \
-o testfixture$(EXE) $(LIBTCL) $(THREADLIB) libsqlite3.a
amalgamation-testfixture$(EXE): sqlite3.c $(TESTSRC) $(TOP)/src/tclsqlite.c
$(TCCX) $(TCL_FLAGS) $(TESTFIXTURE_FLAGS) \
$(TESTSRC) $(TOP)/src/tclsqlite.c sqlite3.c \
-o testfixture$(EXE) $(LIBTCL) $(THREADLIB)
fts3-testfixture$(EXE): sqlite3.c fts3amal.c $(TESTSRC) $(TOP)/src/tclsqlite.c
$(TCCX) $(TCL_FLAGS) $(TESTFIXTURE_FLAGS) \
-DSQLITE_ENABLE_FTS3=1 \
$(TESTSRC) $(TOP)/src/tclsqlite.c sqlite3.c fts3amal.c \
-o testfixture$(EXE) $(LIBTCL) $(THREADLIB)
fulltest: testfixture$(EXE) sqlite3$(EXE)
./testfixture$(EXE) $(TOP)/test/all.test
soaktest: testfixture$(EXE) sqlite3$(EXE)
./testfixture$(EXE) $(TOP)/test/all.test -soak=1
fulltestonly: testfixture$(EXE) sqlite3$(EXE)
./testfixture$(EXE) $(TOP)/test/full.test
test: testfixture$(EXE) sqlite3$(EXE)
./testfixture$(EXE) $(TOP)/test/veryquick.test
sqlite3_analyzer$(EXE): $(TOP)/src/tclsqlite.c sqlite3.c $(TESTSRC) \
$(TOP)/tool/spaceanal.tcl
sed \
-e '/^#/d' \
-e 's,\\,\\\\,g' \
-e 's,",\\",g' \
-e 's,^,",' \
-e 's,$$,\\n",' \
$(TOP)/tool/spaceanal.tcl >spaceanal_tcl.h
$(TCCX) $(TCL_FLAGS) $(TESTFIXTURE_FLAGS) \
-DTCLSH=2 -DSQLITE_TEST=1 -DSQLITE_DEBUG=1 -DSQLITE_PRIVATE="" \
$(TESTSRC) $(TOP)/src/tclsqlite.c sqlite3.c \
-o sqlite3_analyzer$(EXE) \
$(LIBTCL) $(THREADLIB)
TEST_EXTENSION = $(SHPREFIX)testloadext.$(SO)
$(TEST_EXTENSION): $(TOP)/src/test_loadext.c
$(MKSHLIB) $(TOP)/src/test_loadext.c -o $(TEST_EXTENSION)
extensiontest: testfixture$(EXE) $(TEST_EXTENSION)
./testfixture$(EXE) $(TOP)/test/loadext.test
clean:
rm -f *.o sqlite3$(EXE) libsqlite3.a sqlite3.h opcodes.*
rm -f lemon lempar.c parse.* sqlite*.tar.gz mkkeywordhash keywordhash.h
rm -f $(PUBLISH)
rm -f *.da *.bb *.bbg gmon.out
rm -rf quota2a quota2b quota2c
rm -rf tsrc target_source
rm -f testloadext.dll libtestloadext.so
rm -f sqlite3.c fts?amal.c tclsqlite3.c
rm -f sqlite3rc.h
rm -f shell.c sqlite3ext.h
rm -f $(SHPREFIX)sqlite3.$(SO)
+1 -1
View File
@@ -1 +1 @@
3.9.0
3.12.0
-34
View File
@@ -1,34 +0,0 @@
#!/usr/bin/awk
#
# This script appends additional token codes to the end of the
# parse.h file that lemon generates. These extra token codes are
# not used by the parser. But they are used by the tokenizer and/or
# the code generator.
#
#
BEGIN {
max = 0
}
/^#define TK_/ {
print $0
if( max<$3 ) max = $3
}
END {
printf "#define TK_%-29s %4d\n", "TO_TEXT", ++max
printf "#define TK_%-29s %4d\n", "TO_BLOB", ++max
printf "#define TK_%-29s %4d\n", "TO_NUMERIC", ++max
printf "#define TK_%-29s %4d\n", "TO_INT", ++max
printf "#define TK_%-29s %4d\n", "TO_REAL", ++max
printf "#define TK_%-29s %4d\n", "ISNOT", ++max
printf "#define TK_%-29s %4d\n", "END_OF_FILE", ++max
printf "#define TK_%-29s %4d\n", "ILLEGAL", ++max
printf "#define TK_%-29s %4d\n", "SPACE", ++max
printf "#define TK_%-29s %4d\n", "UNCLOSED_STRING", ++max
printf "#define TK_%-29s %4d\n", "FUNCTION", ++max
printf "#define TK_%-29s %4d\n", "COLUMN", ++max
printf "#define TK_%-29s %4d\n", "AGG_FUNCTION", ++max
printf "#define TK_%-29s %4d\n", "AGG_COLUMN", ++max
printf "#define TK_%-29s %4d\n", "UMINUS", ++max
printf "#define TK_%-29s %4d\n", "UPLUS", ++max
printf "#define TK_%-29s %4d\n", "REGISTER", ++max
}
+3 -2
View File
@@ -8,11 +8,12 @@ libsqlite3_la_LDFLAGS = -no-undefined -version-info 8:6:8
bin_PROGRAMS = sqlite3
sqlite3_SOURCES = shell.c sqlite3.c sqlite3.h
sqlite3_LDADD = @READLINE_LIBS@
sqlite3_CFLAGS = $(AM_CFLAGS)
sqlite3_DEPENDENCIES = @EXTRA_SHELL_OBJ@
sqlite3_CFLAGS = $(AM_CFLAGS) -DSQLITE_ENABLE_EXPLAIN_COMMENTS
include_HEADERS = sqlite3.h sqlite3ext.h
EXTRA_DIST = sqlite3.1 tea
EXTRA_DIST = sqlite3.1 tea Makefile.msc sqlite3.rc README.txt Replace.cs
pkgconfigdir = ${libdir}/pkgconfig
pkgconfig_DATA = sqlite3.pc
+946
View File
@@ -0,0 +1,946 @@
#### DO NOT EDIT ####
# This makefile is automatically generated from the Makefile.msc at
# the root of the canonical SQLite source tree (not the
# amalgamation tarball) using the tool/mkmsvcmin.tcl
# script.
#
#
# nmake Makefile for SQLite
#
###############################################################################
############################## START OF OPTIONS ###############################
###############################################################################
# The toplevel directory of the source tree. This is the directory
# that contains this "Makefile.msc".
#
TOP = .
# Set this non-0 to enable full warnings (-W4, etc) when compiling.
#
!IFNDEF USE_FULLWARN
USE_FULLWARN = 0
!ENDIF
# Set this non-0 to use "stdcall" calling convention for the core library
# and shell executable.
#
!IFNDEF USE_STDCALL
USE_STDCALL = 0
!ENDIF
# Set this non-0 to have the shell executable link against the core dynamic
# link library.
#
!IFNDEF DYNAMIC_SHELL
DYNAMIC_SHELL = 0
!ENDIF
# Set this non-0 to enable extra code that attempts to detect misuse of the
# SQLite API.
#
!IFNDEF API_ARMOR
API_ARMOR = 0
!ENDIF
# If necessary, create a list of harmless compiler warnings to disable when
# compiling the various tools. For the SQLite source code itself, warnings,
# if any, will be disabled from within it.
#
!IFNDEF NO_WARN
!IF $(USE_FULLWARN)!=0
NO_WARN = -wd4054 -wd4055 -wd4100 -wd4127 -wd4130 -wd4152 -wd4189 -wd4206
NO_WARN = $(NO_WARN) -wd4210 -wd4232 -wd4305 -wd4306 -wd4702 -wd4706
!ENDIF
!ENDIF
# Set this non-0 to use the library paths and other options necessary for
# Windows Phone 8.1.
#
!IFNDEF USE_WP81_OPTS
USE_WP81_OPTS = 0
!ENDIF
# Set this non-0 to split the SQLite amalgamation file into chunks to
# be used for debugging with Visual Studio.
#
!IFNDEF SPLIT_AMALGAMATION
SPLIT_AMALGAMATION = 0
!ENDIF
# Set this non-0 to dynamically link to the MSVC runtime library.
#
!IFNDEF USE_CRT_DLL
USE_CRT_DLL = 0
!ENDIF
# Set this non-0 to link to the RPCRT4 library.
#
!IFNDEF USE_RPCRT4_LIB
USE_RPCRT4_LIB = 0
!ENDIF
# Set this non-0 to generate assembly code listings for the source code
# files.
#
!IFNDEF USE_LISTINGS
USE_LISTINGS = 0
!ENDIF
# Set this non-0 to attempt setting the native compiler automatically
# for cross-compiling the command line tools needed during the compilation
# process.
#
!IFNDEF XCOMPILE
XCOMPILE = 0
!ENDIF
# Set this non-0 to use the native libraries paths for cross-compiling
# the command line tools needed during the compilation process.
#
!IFNDEF USE_NATIVE_LIBPATHS
USE_NATIVE_LIBPATHS = 0
!ENDIF
# Set this 0 to skip the compiling and embedding of version resources.
#
!IFNDEF USE_RC
USE_RC = 1
!ENDIF
# Set this non-0 to compile binaries suitable for the WinRT environment.
# This setting does not apply to any binaries that require Tcl to operate
# properly (i.e. the text fixture, etc).
#
!IFNDEF FOR_WINRT
FOR_WINRT = 0
!ENDIF
# Set this non-0 to compile binaries suitable for the UWP environment.
# This setting does not apply to any binaries that require Tcl to operate
# properly (i.e. the text fixture, etc).
#
!IFNDEF FOR_UWP
FOR_UWP = 0
!ENDIF
# Set this non-0 to compile binaries suitable for the Windows 10 platform.
#
!IFNDEF FOR_WIN10
FOR_WIN10 = 0
!ENDIF
# Set this to non-0 to create and use PDBs.
#
!IFNDEF SYMBOLS
SYMBOLS = 1
!ENDIF
# Set this to non-0 to use the SQLite debugging heap subsystem.
#
!IFNDEF MEMDEBUG
MEMDEBUG = 0
!ENDIF
# Set this to non-0 to use the Win32 native heap subsystem.
#
!IFNDEF WIN32HEAP
WIN32HEAP = 0
!ENDIF
# Set this to non-0 to enable OSTRACE() macros, which can be useful when
# debugging.
#
!IFNDEF OSTRACE
OSTRACE = 0
!ENDIF
# Set this to one of the following values to enable various debugging
# features. Each level includes the debugging options from the previous
# levels. Currently, the recognized values for DEBUG are:
#
# 0 == NDEBUG: Disables assert() and other runtime diagnostics.
# 1 == SQLITE_ENABLE_API_ARMOR: extra attempts to detect misuse of the API.
# 2 == Disables NDEBUG and all optimizations and then enables PDBs.
# 3 == SQLITE_DEBUG: Enables various diagnostics messages and code.
# 4 == SQLITE_WIN32_MALLOC_VALIDATE: Validate the Win32 native heap per call.
# 5 == SQLITE_DEBUG_OS_TRACE: Enables output from the OSTRACE() macros.
# 6 == SQLITE_ENABLE_IOTRACE: Enables output from the IOTRACE() macros.
#
!IFNDEF DEBUG
DEBUG = 0
!ENDIF
# Enable use of available compiler optimizations? Normally, this should be
# non-zero. Setting this to zero, thus disabling all compiler optimizations,
# can be useful for testing.
#
!IFNDEF OPTIMIZATIONS
OPTIMIZATIONS = 2
!ENDIF
# Set the source code file to be used by executables and libraries when
# they need the amalgamation.
#
!IFNDEF SQLITE3C
!IF $(SPLIT_AMALGAMATION)!=0
SQLITE3C = sqlite3-all.c
!ELSE
SQLITE3C = sqlite3.c
!ENDIF
!ENDIF
# Set the include code file to be used by executables and libraries when
# they need SQLite.
#
!IFNDEF SQLITE3H
SQLITE3H = sqlite3.h
!ENDIF
# This is the name to use for the SQLite dynamic link library (DLL).
#
!IFNDEF SQLITE3DLL
!IF $(FOR_WIN10)!=0
SQLITE3DLL = winsqlite3.dll
!ELSE
SQLITE3DLL = sqlite3.dll
!ENDIF
!ENDIF
# This is the name to use for the SQLite import library (LIB).
#
!IFNDEF SQLITE3LIB
!IF $(FOR_WIN10)!=0
SQLITE3LIB = winsqlite3.lib
!ELSE
SQLITE3LIB = sqlite3.lib
!ENDIF
!ENDIF
# This is the name to use for the SQLite shell executable (EXE).
#
!IFNDEF SQLITE3EXE
!IF $(FOR_WIN10)!=0
SQLITE3EXE = winsqlite3shell.exe
!ELSE
SQLITE3EXE = sqlite3.exe
!ENDIF
!ENDIF
# This is the argument used to set the program database (PDB) file for the
# SQLite shell executable (EXE).
#
!IFNDEF SQLITE3EXEPDB
!IF $(FOR_WIN10)!=0
SQLITE3EXEPDB =
!ELSE
SQLITE3EXEPDB = /pdb:sqlite3sh.pdb
!ENDIF
!ENDIF
# These are the "standard" SQLite compilation options used when compiling for
# the Windows platform.
#
!IFNDEF OPT_FEATURE_FLAGS
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_FTS3=1
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_RTREE=1
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_COLUMN_METADATA=1
!ENDIF
# These are the "extended" SQLite compilation options used when compiling for
# the Windows 10 platform.
#
!IFNDEF EXT_FEATURE_FLAGS
!IF $(FOR_WIN10)!=0
EXT_FEATURE_FLAGS = $(EXT_FEATURE_FLAGS) -DSQLITE_ENABLE_FTS4=1
EXT_FEATURE_FLAGS = $(EXT_FEATURE_FLAGS) -DSQLITE_SYSTEM_MALLOC=1
EXT_FEATURE_FLAGS = $(EXT_FEATURE_FLAGS) -DSQLITE_OMIT_LOCALTIME=1
!ELSE
EXT_FEATURE_FLAGS =
!ENDIF
!ENDIF
###############################################################################
############################### END OF OPTIONS ################################
###############################################################################
# When compiling for the Windows 10 platform, the PLATFORM macro must be set
# to an appropriate value (e.g. x86, x64, arm, arm64, etc).
#
!IF $(FOR_WIN10)!=0
!IFNDEF PLATFORM
!ERROR Using the FOR_WIN10 option requires a value for PLATFORM.
!ENDIF
!ENDIF
# This assumes that MSVC is always installed in 32-bit Program Files directory
# and sets the variable for use in locating other 32-bit installs accordingly.
#
PROGRAMFILES_X86 = $(VCINSTALLDIR)\..\..
PROGRAMFILES_X86 = $(PROGRAMFILES_X86:\\=\)
# Check for the predefined command macro CC. This should point to the compiler
# binary for the target platform. If it is not defined, simply define it to
# the legacy default value 'cl.exe'.
#
!IFNDEF CC
CC = cl.exe
!ENDIF
# Check for the predefined command macro CSC. This should point to a working
# C Sharp compiler binary. If it is not defined, simply define it to the
# legacy default value 'csc.exe'.
#
!IFNDEF CSC
CSC = csc.exe
!ENDIF
# Check for the command macro LD. This should point to the linker binary for
# the target platform. If it is not defined, simply define it to the legacy
# default value 'link.exe'.
#
!IFNDEF LD
LD = link.exe
!ENDIF
# Check for the predefined command macro RC. This should point to the resource
# compiler binary for the target platform. If it is not defined, simply define
# it to the legacy default value 'rc.exe'.
#
!IFNDEF RC
RC = rc.exe
!ENDIF
# Check for the MSVC runtime library path macro. Otherwise, this value will
# default to the 'lib' directory underneath the MSVC installation directory.
#
!IFNDEF CRTLIBPATH
CRTLIBPATH = $(VCINSTALLDIR)\lib
!ENDIF
CRTLIBPATH = $(CRTLIBPATH:\\=\)
# Check for the command macro NCC. This should point to the compiler binary
# for the platform the compilation process is taking place on. If it is not
# defined, simply define it to have the same value as the CC macro. When
# cross-compiling, it is suggested that this macro be modified via the command
# line (since nmake itself does not provide a built-in method to guess it).
# For example, to use the x86 compiler when cross-compiling for x64, a command
# line similar to the following could be used (all on one line):
#
# nmake /f Makefile.msc sqlite3.dll
# XCOMPILE=1 USE_NATIVE_LIBPATHS=1
#
# Alternatively, the full path and file name to the compiler binary for the
# platform the compilation process is taking place may be specified (all on
# one line):
#
# nmake /f Makefile.msc sqlite3.dll
# "NCC=""%VCINSTALLDIR%\bin\cl.exe"""
# USE_NATIVE_LIBPATHS=1
#
!IFDEF NCC
NCC = $(NCC:\\=\)
!ELSEIF $(XCOMPILE)!=0
NCC = "$(VCINSTALLDIR)\bin\$(CC)"
NCC = $(NCC:\\=\)
!ELSE
NCC = $(CC)
!ENDIF
# Check for the MSVC native runtime library path macro. Otherwise,
# this value will default to the 'lib' directory underneath the MSVC
# installation directory.
#
!IFNDEF NCRTLIBPATH
NCRTLIBPATH = $(VCINSTALLDIR)\lib
!ENDIF
NCRTLIBPATH = $(NCRTLIBPATH:\\=\)
# Check for the Platform SDK library path macro. Otherwise, this
# value will default to the 'lib' directory underneath the Windows
# SDK installation directory (the environment variable used appears
# to be available when using Visual C++ 2008 or later via the
# command line).
#
!IFNDEF NSDKLIBPATH
NSDKLIBPATH = $(WINDOWSSDKDIR)\lib
!ENDIF
NSDKLIBPATH = $(NSDKLIBPATH:\\=\)
# Check for the UCRT library path macro. Otherwise, this value will
# default to the version-specific, platform-specific 'lib' directory
# underneath the Windows SDK installation directory.
#
!IFNDEF UCRTLIBPATH
UCRTLIBPATH = $(WINDOWSSDKDIR)\lib\$(WINDOWSSDKLIBVERSION)\ucrt\$(PLATFORM)
!ENDIF
UCRTLIBPATH = $(UCRTLIBPATH:\\=\)
# C compiler and options for use in building executables that
# will run on the platform that is doing the build.
#
!IF $(USE_FULLWARN)!=0
BCC = $(NCC) -nologo -W4 $(CCOPTS) $(BCCOPTS)
!ELSE
BCC = $(NCC) -nologo -W3 $(CCOPTS) $(BCCOPTS)
!ENDIF
# Check if assembly code listings should be generated for the source
# code files to be compiled.
#
!IF $(USE_LISTINGS)!=0
BCC = $(BCC) -FAcs
!ENDIF
# Check if the native library paths should be used when compiling
# the command line tools used during the compilation process. If
# so, set the necessary macro now.
#
!IF $(USE_NATIVE_LIBPATHS)!=0
NLTLIBPATHS = "/LIBPATH:$(NCRTLIBPATH)" "/LIBPATH:$(NSDKLIBPATH)"
!IFDEF NUCRTLIBPATH
NUCRTLIBPATH = $(NUCRTLIBPATH:\\=\)
NLTLIBPATHS = $(NLTLIBPATHS) "/LIBPATH:$(NUCRTLIBPATH)"
!ENDIF
!ENDIF
# C compiler and options for use in building executables that
# will run on the target platform. (BCC and TCC are usually the
# same unless your are cross-compiling.)
#
!IF $(USE_FULLWARN)!=0
TCC = $(CC) -nologo -W4 -DINCLUDE_MSVC_H=1 $(CCOPTS) $(TCCOPTS)
!ELSE
TCC = $(CC) -nologo -W3 $(CCOPTS) $(TCCOPTS)
!ENDIF
TCC = $(TCC) -DSQLITE_OS_WIN=1 -I. -I$(TOP) -fp:precise
RCC = $(RC) -DSQLITE_OS_WIN=1 -I. -I$(TOP) $(RCOPTS) $(RCCOPTS)
# Check if we want to use the "stdcall" calling convention when compiling.
# This is not supported by the compilers for non-x86 platforms. It should
# also be noted here that building any target with these "stdcall" options
# will most likely fail if the Tcl library is also required. This is due
# to how the Tcl library functions are declared and exported (i.e. without
# an explicit calling convention, which results in "cdecl").
#
!IF $(USE_STDCALL)!=0 || $(FOR_WIN10)!=0
!IF "$(PLATFORM)"=="x86"
CORE_CCONV_OPTS = -Gz -DSQLITE_CDECL=__cdecl -DSQLITE_STDCALL=__stdcall
SHELL_CCONV_OPTS = -Gz -DSQLITE_CDECL=__cdecl -DSQLITE_STDCALL=__stdcall
!ELSE
!IFNDEF PLATFORM
CORE_CCONV_OPTS = -Gz -DSQLITE_CDECL=__cdecl -DSQLITE_STDCALL=__stdcall
SHELL_CCONV_OPTS = -Gz -DSQLITE_CDECL=__cdecl -DSQLITE_STDCALL=__stdcall
!ELSE
CORE_CCONV_OPTS =
SHELL_CCONV_OPTS =
!ENDIF
!ENDIF
!ELSE
CORE_CCONV_OPTS =
SHELL_CCONV_OPTS =
!ENDIF
# These are additional compiler options used for the core library.
#
!IFNDEF CORE_COMPILE_OPTS
!IF $(DYNAMIC_SHELL)!=0 || $(FOR_WIN10)!=0
CORE_COMPILE_OPTS = $(CORE_CCONV_OPTS) -DSQLITE_API=__declspec(dllexport)
!ELSE
CORE_COMPILE_OPTS = $(CORE_CCONV_OPTS)
!ENDIF
!ENDIF
# These are the additional targets that the core library should depend on
# when linking.
#
!IFNDEF CORE_LINK_DEP
!IF $(DYNAMIC_SHELL)!=0
CORE_LINK_DEP =
!ELSEIF $(FOR_WIN10)==0 || "$(PLATFORM)"=="x86"
CORE_LINK_DEP = sqlite3.def
!ELSE
CORE_LINK_DEP =
!ENDIF
!ENDIF
# These are additional linker options used for the core library.
#
!IFNDEF CORE_LINK_OPTS
!IF $(DYNAMIC_SHELL)!=0
CORE_LINK_OPTS =
!ELSEIF $(FOR_WIN10)==0 || "$(PLATFORM)"=="x86"
CORE_LINK_OPTS = /DEF:sqlite3.def
!ELSE
CORE_LINK_OPTS =
!ENDIF
!ENDIF
# These are additional compiler options used for the shell executable.
#
!IFNDEF SHELL_COMPILE_OPTS
!IF $(DYNAMIC_SHELL)!=0 || $(FOR_WIN10)!=0
SHELL_COMPILE_OPTS = $(SHELL_CCONV_OPTS) -DSQLITE_API=__declspec(dllimport)
!ELSE
SHELL_COMPILE_OPTS = $(SHELL_CCONV_OPTS)
!ENDIF
!ENDIF
# This is the source code that the shell executable should be compiled
# with.
#
!IFNDEF SHELL_CORE_SRC
!IF $(DYNAMIC_SHELL)!=0 || $(FOR_WIN10)!=0
SHELL_CORE_SRC =
!ELSE
SHELL_CORE_SRC = $(SQLITE3C)
!ENDIF
!ENDIF
# This is the core library that the shell executable should depend on.
#
!IFNDEF SHELL_CORE_DEP
!IF $(DYNAMIC_SHELL)!=0 || $(FOR_WIN10)!=0
SHELL_CORE_DEP = $(SQLITE3DLL)
!ELSE
SHELL_CORE_DEP =
!ENDIF
!ENDIF
# This is the core library that the shell executable should link with.
#
!IFNDEF SHELL_CORE_LIB
!IF $(DYNAMIC_SHELL)!=0 || $(FOR_WIN10)!=0
SHELL_CORE_LIB = $(SQLITE3LIB)
!ELSE
SHELL_CORE_LIB =
!ENDIF
!ENDIF
# These are additional linker options used for the shell executable.
#
!IFNDEF SHELL_LINK_OPTS
SHELL_LINK_OPTS = $(SHELL_CORE_LIB)
!ENDIF
# Check if assembly code listings should be generated for the source
# code files to be compiled.
#
!IF $(USE_LISTINGS)!=0
TCC = $(TCC) -FAcs
!ENDIF
# When compiling the library for use in the WinRT environment,
# the following compile-time options must be used as well to
# disable use of Win32 APIs that are not available and to enable
# use of Win32 APIs that are specific to Windows 8 and/or WinRT.
#
!IF $(FOR_WINRT)!=0
TCC = $(TCC) -DSQLITE_OS_WINRT=1
RCC = $(RCC) -DSQLITE_OS_WINRT=1
TCC = $(TCC) -DWINAPI_FAMILY=WINAPI_FAMILY_APP
RCC = $(RCC) -DWINAPI_FAMILY=WINAPI_FAMILY_APP
!ENDIF
# C compiler options for the Windows 10 platform (needs MSVC 2015).
#
!IF $(FOR_WIN10)!=0
TCC = $(TCC) /d2guard4 -D_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE
BCC = $(BCC) /d2guard4 -D_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE
!ENDIF
# Also, we need to dynamically link to the correct MSVC runtime
# when compiling for WinRT (e.g. debug or release) OR if the
# USE_CRT_DLL option is set to force dynamically linking to the
# MSVC runtime library.
#
!IF $(FOR_WINRT)!=0 || $(USE_CRT_DLL)!=0
!IF $(DEBUG)>1
TCC = $(TCC) -MDd
BCC = $(BCC) -MDd
!ELSE
TCC = $(TCC) -MD
BCC = $(BCC) -MD
!ENDIF
!ELSE
!IF $(DEBUG)>1
TCC = $(TCC) -MTd
BCC = $(BCC) -MTd
!ELSE
TCC = $(TCC) -MT
BCC = $(BCC) -MT
!ENDIF
!ENDIF
# Define -DNDEBUG to compile without debugging (i.e., for production usage)
# Omitting the define will cause extra debugging code to be inserted and
# includes extra comments when "EXPLAIN stmt" is used.
#
!IF $(DEBUG)==0
TCC = $(TCC) -DNDEBUG
BCC = $(BCC) -DNDEBUG
RCC = $(RCC) -DNDEBUG
!ENDIF
!IF $(DEBUG)>0 || $(API_ARMOR)!=0 || $(FOR_WIN10)!=0
TCC = $(TCC) -DSQLITE_ENABLE_API_ARMOR=1
RCC = $(RCC) -DSQLITE_ENABLE_API_ARMOR=1
!ENDIF
!IF $(DEBUG)>2
TCC = $(TCC) -DSQLITE_DEBUG=1
RCC = $(RCC) -DSQLITE_DEBUG=1
!ENDIF
!IF $(DEBUG)>4 || $(OSTRACE)!=0
TCC = $(TCC) -DSQLITE_FORCE_OS_TRACE=1 -DSQLITE_DEBUG_OS_TRACE=1
RCC = $(RCC) -DSQLITE_FORCE_OS_TRACE=1 -DSQLITE_DEBUG_OS_TRACE=1
!ENDIF
!IF $(DEBUG)>5
TCC = $(TCC) -DSQLITE_ENABLE_IOTRACE=1
RCC = $(RCC) -DSQLITE_ENABLE_IOTRACE=1
!ENDIF
# Prevent warnings about "insecure" MSVC runtime library functions
# being used.
#
TCC = $(TCC) -D_CRT_SECURE_NO_DEPRECATE -D_CRT_SECURE_NO_WARNINGS
BCC = $(BCC) -D_CRT_SECURE_NO_DEPRECATE -D_CRT_SECURE_NO_WARNINGS
RCC = $(RCC) -D_CRT_SECURE_NO_DEPRECATE -D_CRT_SECURE_NO_WARNINGS
# Prevent warnings about "deprecated" POSIX functions being used.
#
TCC = $(TCC) -D_CRT_NONSTDC_NO_DEPRECATE -D_CRT_NONSTDC_NO_WARNINGS
BCC = $(BCC) -D_CRT_NONSTDC_NO_DEPRECATE -D_CRT_NONSTDC_NO_WARNINGS
RCC = $(RCC) -D_CRT_NONSTDC_NO_DEPRECATE -D_CRT_NONSTDC_NO_WARNINGS
# Use the SQLite debugging heap subsystem?
#
!IF $(MEMDEBUG)!=0
TCC = $(TCC) -DSQLITE_MEMDEBUG=1
RCC = $(RCC) -DSQLITE_MEMDEBUG=1
# Use native Win32 heap subsystem instead of malloc/free?
#
!ELSEIF $(WIN32HEAP)!=0
TCC = $(TCC) -DSQLITE_WIN32_MALLOC=1
RCC = $(RCC) -DSQLITE_WIN32_MALLOC=1
# Validate the heap on every call into the native Win32 heap subsystem?
#
!IF $(DEBUG)>3
TCC = $(TCC) -DSQLITE_WIN32_MALLOC_VALIDATE=1
RCC = $(RCC) -DSQLITE_WIN32_MALLOC_VALIDATE=1
!ENDIF
!ENDIF
# Compiler options needed for programs that use the readline() library.
#
!IFNDEF READLINE_FLAGS
READLINE_FLAGS = -DHAVE_READLINE=0
!ENDIF
# The library that programs using readline() must link against.
#
!IFNDEF LIBREADLINE
LIBREADLINE =
!ENDIF
# Should the database engine be compiled threadsafe
#
TCC = $(TCC) -DSQLITE_THREADSAFE=1
RCC = $(RCC) -DSQLITE_THREADSAFE=1
# Do threads override each others locks by default (1), or do we test (-1)
#
TCC = $(TCC) -DSQLITE_THREAD_OVERRIDE_LOCK=-1
RCC = $(RCC) -DSQLITE_THREAD_OVERRIDE_LOCK=-1
# Any target libraries which libsqlite must be linked against
#
!IFNDEF TLIBS
TLIBS =
!ENDIF
# Flags controlling use of the in memory btree implementation
#
# SQLITE_TEMP_STORE is 0 to force temporary tables to be in a file, 1 to
# default to file, 2 to default to memory, and 3 to force temporary
# tables to always be in memory.
#
TCC = $(TCC) -DSQLITE_TEMP_STORE=1
RCC = $(RCC) -DSQLITE_TEMP_STORE=1
# Enable/disable loadable extensions, and other optional features
# based on configuration. (-DSQLITE_OMIT*, -DSQLITE_ENABLE*).
# The same set of OMIT and ENABLE flags should be passed to the
# LEMON parser generator and the mkkeywordhash tool as well.
# These are the required SQLite compilation options used when compiling for
# the Windows platform.
#
REQ_FEATURE_FLAGS = $(REQ_FEATURE_FLAGS) -DSQLITE_MAX_TRIGGER_DEPTH=100
# If we are linking to the RPCRT4 library, enable features that need it.
#
!IF $(USE_RPCRT4_LIB)!=0
REQ_FEATURE_FLAGS = $(REQ_FEATURE_FLAGS) -DSQLITE_WIN32_USE_UUID=1
!ENDIF
# Add the required and optional SQLite compilation options into the command
# lines used to invoke the MSVC code and resource compilers.
#
TCC = $(TCC) $(REQ_FEATURE_FLAGS) $(OPT_FEATURE_FLAGS) $(EXT_FEATURE_FLAGS)
RCC = $(RCC) $(REQ_FEATURE_FLAGS) $(OPT_FEATURE_FLAGS) $(EXT_FEATURE_FLAGS)
# Add in any optional parameters specified on the commane line, e.g.
# nmake /f Makefile.msc all "OPTS=-DSQLITE_ENABLE_FOO=1 -DSQLITE_OMIT_FOO=1"
#
TCC = $(TCC) $(OPTS)
RCC = $(RCC) $(OPTS)
# If compiling for debugging, add some defines.
#
!IF $(DEBUG)>1
TCC = $(TCC) -D_DEBUG
BCC = $(BCC) -D_DEBUG
RCC = $(RCC) -D_DEBUG
!ENDIF
# If optimizations are enabled or disabled (either implicitly or
# explicitly), add the necessary flags.
#
!IF $(DEBUG)>1 || $(OPTIMIZATIONS)==0
TCC = $(TCC) -Od
BCC = $(BCC) -Od
!ELSEIF $(OPTIMIZATIONS)>=3
TCC = $(TCC) -Ox
BCC = $(BCC) -Ox
!ELSEIF $(OPTIMIZATIONS)==2
TCC = $(TCC) -O2
BCC = $(BCC) -O2
!ELSEIF $(OPTIMIZATIONS)==1
TCC = $(TCC) -O1
BCC = $(BCC) -O1
!ENDIF
# If symbols are enabled (or compiling for debugging), enable PDBs.
#
!IF $(DEBUG)>1 || $(SYMBOLS)!=0
TCC = $(TCC) -Zi
BCC = $(BCC) -Zi
!ENDIF
# Command line prefixes for compiling code, compiling resources,
# linking, etc.
#
LTCOMPILE = $(TCC) -Fo$@
LTRCOMPILE = $(RCC) -r
LTLIB = lib.exe
LTLINK = $(TCC) -Fe$@
# If requested, link to the RPCRT4 library.
#
!IF $(USE_RPCRT4_LIB)!=0
LTLINK = $(LTLINK) rpcrt4.lib
!ENDIF
# If a platform was set, force the linker to target that.
# Note that the vcvars*.bat family of batch files typically
# set this for you. Otherwise, the linker will attempt
# to deduce the binary type based on the object files.
!IFDEF PLATFORM
LTLINKOPTS = /NOLOGO /MACHINE:$(PLATFORM)
LTLIBOPTS = /NOLOGO /MACHINE:$(PLATFORM)
!ELSE
LTLINKOPTS = /NOLOGO
LTLIBOPTS = /NOLOGO
!ENDIF
# When compiling for use in the WinRT environment, the following
# linker option must be used to mark the executable as runnable
# only in the context of an application container.
#
!IF $(FOR_WINRT)!=0
LTLINKOPTS = $(LTLINKOPTS) /APPCONTAINER
!IF "$(VISUALSTUDIOVERSION)"=="12.0" || "$(VISUALSTUDIOVERSION)"=="14.0"
!IFNDEF STORELIBPATH
!IF "$(PLATFORM)"=="x86"
STORELIBPATH = $(CRTLIBPATH)\store
!ELSEIF "$(PLATFORM)"=="x64"
STORELIBPATH = $(CRTLIBPATH)\store\amd64
!ELSEIF "$(PLATFORM)"=="ARM"
STORELIBPATH = $(CRTLIBPATH)\store\arm
!ELSE
STORELIBPATH = $(CRTLIBPATH)\store
!ENDIF
!ENDIF
STORELIBPATH = $(STORELIBPATH:\\=\)
LTLINKOPTS = $(LTLINKOPTS) "/LIBPATH:$(STORELIBPATH)"
!ENDIF
!ENDIF
# When compiling for Windows Phone 8.1, an extra library path is
# required.
#
!IF $(USE_WP81_OPTS)!=0
!IFNDEF WP81LIBPATH
!IF "$(PLATFORM)"=="x86"
WP81LIBPATH = $(PROGRAMFILES_X86)\Windows Phone Kits\8.1\lib\x86
!ELSEIF "$(PLATFORM)"=="ARM"
WP81LIBPATH = $(PROGRAMFILES_X86)\Windows Phone Kits\8.1\lib\ARM
!ELSE
WP81LIBPATH = $(PROGRAMFILES_X86)\Windows Phone Kits\8.1\lib\x86
!ENDIF
!ENDIF
!ENDIF
# When compiling for Windows Phone 8.1, some extra linker options
# are also required.
#
!IF $(USE_WP81_OPTS)!=0
!IFDEF WP81LIBPATH
LTLINKOPTS = $(LTLINKOPTS) "/LIBPATH:$(WP81LIBPATH)"
!ENDIF
LTLINKOPTS = $(LTLINKOPTS) /DYNAMICBASE
LTLINKOPTS = $(LTLINKOPTS) WindowsPhoneCore.lib RuntimeObject.lib PhoneAppModelHost.lib
LTLINKOPTS = $(LTLINKOPTS) /NODEFAULTLIB:kernel32.lib /NODEFAULTLIB:ole32.lib
!ENDIF
# When compiling for UWP or the Windows 10 platform, some extra linker
# options are also required.
#
!IF $(FOR_UWP)!=0 || $(FOR_WIN10)!=0
LTLINKOPTS = $(LTLINKOPTS) /DYNAMICBASE /NODEFAULTLIB:kernel32.lib
LTLINKOPTS = $(LTLINKOPTS) mincore.lib
!IFDEF PSDKLIBPATH
LTLINKOPTS = $(LTLINKOPTS) "/LIBPATH:$(PSDKLIBPATH)"
!ENDIF
!ENDIF
!IF $(FOR_WIN10)!=0
LTLINKOPTS = $(LTLINKOPTS) /guard:cf "/LIBPATH:$(UCRTLIBPATH)"
!IF $(DEBUG)>1
LTLINKOPTS = $(LTLINKOPTS) /NODEFAULTLIB:libucrtd.lib /DEFAULTLIB:ucrtd.lib
!ELSE
LTLINKOPTS = $(LTLINKOPTS) /NODEFAULTLIB:libucrt.lib /DEFAULTLIB:ucrt.lib
!ENDIF
!ENDIF
# If either debugging or symbols are enabled, enable PDBs.
#
!IF $(DEBUG)>1 || $(SYMBOLS)!=0
LDFLAGS = /DEBUG $(LDOPTS)
!ELSE
LDFLAGS = $(LDOPTS)
!ENDIF
# You should not have to change anything below this line
###############################################################################
# Object files for the amalgamation.
#
LIBOBJS1 = sqlite3.lo
# Determine the real value of LIBOBJ based on the 'configure' script
#
LIBOBJ = $(LIBOBJS1)
# Determine if embedded resource compilation and usage are enabled.
#
!IF $(USE_RC)!=0
LIBRESOBJS = sqlite3res.lo
!ELSE
LIBRESOBJS =
!ENDIF
# Additional compiler options for the shell. These are only effective
# when the shell is not being dynamically linked.
#
!IF $(DYNAMIC_SHELL)==0 && $(FOR_WIN10)==0
SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_SHELL_JSON1 -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_EXPLAIN_COMMENTS
!ENDIF
# This is the default Makefile target. The objects listed here
# are what get build when you type just "make" with no arguments.
#
all: dll shell
# Dynamic link library section.
#
dll: $(SQLITE3DLL)
# Shell executable.
#
shell: $(SQLITE3EXE)
$(SQLITE3DLL): $(LIBOBJ) $(LIBRESOBJS) $(CORE_LINK_DEP)
$(LD) $(LDFLAGS) $(LTLINKOPTS) $(LTLIBPATHS) /DLL $(CORE_LINK_OPTS) /OUT:$@ $(LIBOBJ) $(LIBRESOBJS) $(LTLIBS) $(TLIBS)
Replace.exe:
$(CSC) /target:exe $(TOP)\Replace.cs
sqlite3.def: Replace.exe $(LIBOBJ)
echo EXPORTS > sqlite3.def
dumpbin /all $(LIBOBJ) \
| .\Replace.exe "^\s+/EXPORT:_?(sqlite3_[^@,]*)(?:@\d+|,DATA)?$$" $$1 true \
| sort >> sqlite3.def
$(SQLITE3EXE): $(TOP)\shell.c $(SHELL_CORE_DEP) $(LIBRESOBJS) $(SHELL_CORE_SRC) $(SQLITE3H)
$(LTLINK) $(SHELL_COMPILE_OPTS) $(READLINE_FLAGS) $(TOP)\shell.c $(SHELL_CORE_SRC) \
/link $(SQLITE3EXEPDB) $(LDFLAGS) $(LTLINKOPTS) $(SHELL_LINK_OPTS) $(LTLIBPATHS) $(LIBRESOBJS) $(LIBREADLINE) $(LTLIBS) $(TLIBS)
# Rule to build the amalgamation
#
sqlite3.lo: $(SQLITE3C)
$(LTCOMPILE) $(CORE_COMPILE_OPTS) -c $(SQLITE3C)
# Rule to build the Win32 resources object file.
#
!IF $(USE_RC)!=0
_HASHCHAR=^#
!IF ![echo !IFNDEF VERSION > rcver.vc] && \
![for /F "delims=" %V in ('type "$(SQLITE3H)" ^| find "$(_HASHCHAR)define SQLITE_VERSION "') do (echo VERSION = ^^%V >> rcver.vc)] && \
![echo !ENDIF >> rcver.vc]
!INCLUDE rcver.vc
!ENDIF
RESOURCE_VERSION = $(VERSION:^#=)
RESOURCE_VERSION = $(RESOURCE_VERSION:define=)
RESOURCE_VERSION = $(RESOURCE_VERSION:SQLITE_VERSION=)
RESOURCE_VERSION = $(RESOURCE_VERSION:"=)
RESOURCE_VERSION = $(RESOURCE_VERSION:.=,)
$(LIBRESOBJS): $(TOP)\sqlite3.rc rcver.vc $(SQLITE3H)
echo #ifndef SQLITE_RESOURCE_VERSION > sqlite3rc.h
echo #define SQLITE_RESOURCE_VERSION $(RESOURCE_VERSION) >> sqlite3rc.h
echo #endif >> sqlite3rc.h
$(LTRCOMPILE) -fo $(LIBRESOBJS) -DRC_VERONLY $(TOP)\sqlite3.rc
!ENDIF
clean:
del /Q *.exp *.lo *.ilk *.lib *.obj *.ncb *.pdb *.sdf *.suo 2>NUL
del /Q *.bsc *.def *.cod *.da *.bb *.bbg *.vc gmon.out 2>NUL
del /Q $(SQLITE3EXE) $(SQLITE3DLL) Replace.exe 2>NUL
-32
View File
@@ -1,32 +0,0 @@
This package contains:
* the SQLite library amalgamation (single file) source code distribution,
* the shell.c file used to build the sqlite3 shell too, and
* the sqlite3.h and sqlite3ext.h header files required to link programs
and sqlite extensions against the installed libary.
* autoconf/automake installation infrastucture.
The generic installation instructions for autoconf/automake are found
in the INSTALL file.
The following SQLite specific boolean options are supported:
--enable-readline use readline in shell tool [default=yes]
--enable-threadsafe build a thread-safe library [default=yes]
--enable-dynamic-extensions support loadable extensions [default=yes]
The default value for the CFLAGS variable (options passed to the C
compiler) includes debugging symbols in the build, resulting in larger
binaries than are necessary. Override it on the configure command
line like this:
$ CFLAGS="-Os" ./configure
to produce a smaller installation footprint.
Other SQLite compilation parameters can also be set using CFLAGS. For
example:
$ CFLAGS="-Os -DSQLITE_OMIT_TRIGGERS" ./configure
+113
View File
@@ -0,0 +1,113 @@
This package contains:
* the SQLite library amalgamation source code file: sqlite3.c
* the sqlite3.h and sqlite3ext.h header files that define the C-language
interface to the sqlite3.c library file
* the shell.c file used to build the sqlite3 command-line shell program
* autoconf/automake installation infrastucture for building on POSIX
compliant systems
* a Makefile.msc, sqlite3.rc, and Replace.cs for building with Microsoft
Visual C++ on Windows
SUMMARY OF HOW TO BUILD
=======================
Unix: ./configure; make
Windows: nmake /f Makefile.msc
BUILDING ON POSIX
=================
The generic installation instructions for autoconf/automake are found
in the INSTALL file.
The following SQLite specific boolean options are supported:
--enable-readline use readline in shell tool [default=yes]
--enable-threadsafe build a thread-safe library [default=yes]
--enable-dynamic-extensions support loadable extensions [default=yes]
The default value for the CFLAGS variable (options passed to the C
compiler) includes debugging symbols in the build, resulting in larger
binaries than are necessary. Override it on the configure command
line like this:
$ CFLAGS="-Os" ./configure
to produce a smaller installation footprint.
Other SQLite compilation parameters can also be set using CFLAGS. For
example:
$ CFLAGS="-Os -DSQLITE_THREADSAFE=0" ./configure
BUILDING WITH MICROSOFT VISUAL C++
==================================
To compile for Windows using Microsoft Visual C++:
$ nmake /f Makefile.msc
Using Microsoft Visual C++ 2005 (or later) is recommended. Several Windows
platform variants may be built by adding additional macros to the NMAKE
command line.
Building for WinRT 8.0
----------------------
FOR_WINRT=1
Using Microsoft Visual C++ 2012 (or later) is required. When using the
above, something like the following macro will need to be added to the
NMAKE command line as well:
"NSDKLIBPATH=%WindowsSdkDir%\..\8.0\lib\win8\um\x86"
Building for WinRT 8.1
----------------------
FOR_WINRT=1
Using Microsoft Visual C++ 2013 (or later) is required. When using the
above, something like the following macro will need to be added to the
NMAKE command line as well:
"NSDKLIBPATH=%WindowsSdkDir%\..\8.1\lib\winv6.3\um\x86"
Building for UWP 10.0
---------------------
FOR_WINRT=1 FOR_UWP=1
Using Microsoft Visual C++ 2015 (or later) is required. When using the
above, something like the following macros will need to be added to the
NMAKE command line as well:
"NSDKLIBPATH=%WindowsSdkDir%\..\10\lib\10.0.10586.0\um\x86"
"PSDKLIBPATH=%WindowsSdkDir%\..\10\lib\10.0.10586.0\um\x86"
"NUCRTLIBPATH=%UniversalCRTSdkDir%\..\10\lib\10.0.10586.0\ucrt\x86"
Building for the Windows 10 SDK
-------------------------------
FOR_WIN10=1
Using Microsoft Visual C++ 2015 (or later) is required. When using the
above, no other macros should be needed on the NMAKE command line.
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
following will work:
"OPTS=-DSQLITE_ENABLE_STAT4=1 -DSQLITE_ENABLE_JSON1=1"
However, the following will not compile unless the amalgamation was built
with it enabled:
"OPTS=-DSQLITE_ENABLE_UPDATE_DELETE_LIMIT=1"
-1530
View File
File diff suppressed because it is too large Load Diff
-1773
View File
File diff suppressed because it is too large Load Diff
+38 -4
View File
@@ -4,11 +4,13 @@
#
# --enable-threadsafe
# --enable-readline
# --enable-editline
# --enable-static-shell
# --enable-dynamic-extensions
#
AC_PREREQ(2.61)
AC_INIT(sqlite, 3.7.5, http://www.sqlite.org)
AC_INIT(sqlite, --SQLITE-VERSION--, http://www.sqlite.org)
AC_CONFIG_SRCDIR([sqlite3.c])
# Use automake.
@@ -18,7 +20,6 @@ AC_SYS_LARGEFILE
# Check for required programs.
AC_PROG_CC
AC_PROG_RANLIB
AC_PROG_LIBTOOL
AC_PROG_MKDIR_P
@@ -30,12 +31,29 @@ AC_CONFIG_FILES([Makefile sqlite3.pc])
AC_SUBST(BUILD_CFLAGS)
#-----------------------------------------------------------------------
# --enable-editline
# --enable-readline
#
AC_ARG_ENABLE(editline, [AS_HELP_STRING(
[--enable-editline],
[use BSD libedit])],
[], [enable_editline=yes])
AC_ARG_ENABLE(readline, [AS_HELP_STRING(
[--enable-readline],
[use readline in shell tool (yes, no) [default=yes]])],
[], [enable_readline=yes])
[use readline])],
[], [enable_readline=no])
if test x"$enable_editline" != xno ; then
sLIBS=$LIBS
LIBS=""
AC_SEARCH_LIBS([readline],[edit],[enable_readline=no],[enable_editline=no])
READLINE_LIBS=$LIBS
if test x"$LIBS" != "x"; then
AC_DEFINE([HAVE_EDITLINE],1,Define to use BSD editline)
else
unset ac_cv_search_readline
fi
LIBS=$sLIBS
fi
if test x"$enable_readline" != xno ; then
sLIBS=$LIBS
LIBS=""
@@ -58,6 +76,7 @@ THREADSAFE_FLAGS=-DSQLITE_THREADSAFE=0
if test x"$enable_threadsafe" != "xno"; then
THREADSAFE_FLAGS="-D_REENTRANT=1 -DSQLITE_THREADSAFE=1"
AC_SEARCH_LIBS(pthread_create, pthread)
AC_SEARCH_LIBS(pthread_mutexattr_init, pthread)
fi
AC_SUBST(THREADSAFE_FLAGS)
#-----------------------------------------------------------------------
@@ -103,6 +122,21 @@ fi
AC_SUBST(JSON1_FLAGS)
#-----------------------------------------------------------------------
#-----------------------------------------------------------------------
# --enable-static-shell
#
AC_ARG_ENABLE(static-shell, [AS_HELP_STRING(
[--enable-static-shell],
[statically link libsqlite3 into shell tool [default=yes]])],
[], [enable_static_shell=yes])
if test x"$enable_static_shell" == "xyes"; then
EXTRA_SHELL_OBJ=sqlite3.$OBJEXT
else
EXTRA_SHELL_OBJ=libsqlite3.la
fi
AC_SUBST(EXTRA_SHELL_OBJ)
#-----------------------------------------------------------------------
AC_CHECK_FUNCS(posix_fallocate)
#-----------------------------------------------------------------------
-708
View File
@@ -1,708 +0,0 @@
#! /bin/sh
# depcomp - compile a program generating dependencies as side-effects
scriptversion=2012-03-27.16; # UTC
# Copyright (C) 1999, 2000, 2003, 2004, 2005, 2006, 2007, 2009, 2010,
# 2011, 2012 Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
# Originally written by Alexandre Oliva <oliva@dcc.unicamp.br>.
case $1 in
'')
echo "$0: No command. Try '$0 --help' for more information." 1>&2
exit 1;
;;
-h | --h*)
cat <<\EOF
Usage: depcomp [--help] [--version] PROGRAM [ARGS]
Run PROGRAMS ARGS to compile a file, generating dependencies
as side-effects.
Environment variables:
depmode Dependency tracking mode.
source Source file read by 'PROGRAMS ARGS'.
object Object file output by 'PROGRAMS ARGS'.
DEPDIR directory where to store dependencies.
depfile Dependency file to output.
tmpdepfile Temporary file to use when outputting dependencies.
libtool Whether libtool is used (yes/no).
Report bugs to <bug-automake@gnu.org>.
EOF
exit $?
;;
-v | --v*)
echo "depcomp $scriptversion"
exit $?
;;
esac
# A tabulation character.
tab=' '
# A newline character.
nl='
'
if test -z "$depmode" || test -z "$source" || test -z "$object"; then
echo "depcomp: Variables source, object and depmode must be set" 1>&2
exit 1
fi
# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po.
depfile=${depfile-`echo "$object" |
sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`}
tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`}
rm -f "$tmpdepfile"
# Some modes work just like other modes, but use different flags. We
# parameterize here, but still list the modes in the big case below,
# to make depend.m4 easier to write. Note that we *cannot* use a case
# here, because this file can only contain one case statement.
if test "$depmode" = hp; then
# HP compiler uses -M and no extra arg.
gccflag=-M
depmode=gcc
fi
if test "$depmode" = dashXmstdout; then
# This is just like dashmstdout with a different argument.
dashmflag=-xM
depmode=dashmstdout
fi
cygpath_u="cygpath -u -f -"
if test "$depmode" = msvcmsys; then
# This is just like msvisualcpp but w/o cygpath translation.
# Just convert the backslash-escaped backslashes to single forward
# slashes to satisfy depend.m4
cygpath_u='sed s,\\\\,/,g'
depmode=msvisualcpp
fi
if test "$depmode" = msvc7msys; then
# This is just like msvc7 but w/o cygpath translation.
# Just convert the backslash-escaped backslashes to single forward
# slashes to satisfy depend.m4
cygpath_u='sed s,\\\\,/,g'
depmode=msvc7
fi
if test "$depmode" = xlc; then
# IBM C/C++ Compilers xlc/xlC can output gcc-like dependency informations.
gccflag=-qmakedep=gcc,-MF
depmode=gcc
fi
case "$depmode" in
gcc3)
## gcc 3 implements dependency tracking that does exactly what
## we want. Yay! Note: for some reason libtool 1.4 doesn't like
## it if -MD -MP comes after the -MF stuff. Hmm.
## Unfortunately, FreeBSD c89 acceptance of flags depends upon
## the command line argument order; so add the flags where they
## appear in depend2.am. Note that the slowdown incurred here
## affects only configure: in makefiles, %FASTDEP% shortcuts this.
for arg
do
case $arg in
-c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;;
*) set fnord "$@" "$arg" ;;
esac
shift # fnord
shift # $arg
done
"$@"
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile"
exit $stat
fi
mv "$tmpdepfile" "$depfile"
;;
gcc)
## There are various ways to get dependency output from gcc. Here's
## why we pick this rather obscure method:
## - Don't want to use -MD because we'd like the dependencies to end
## up in a subdir. Having to rename by hand is ugly.
## (We might end up doing this anyway to support other compilers.)
## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like
## -MM, not -M (despite what the docs say).
## - Using -M directly means running the compiler twice (even worse
## than renaming).
if test -z "$gccflag"; then
gccflag=-MD,
fi
"$@" -Wp,"$gccflag$tmpdepfile"
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile"
exit $stat
fi
rm -f "$depfile"
echo "$object : \\" > "$depfile"
alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
## The second -e expression handles DOS-style file names with drive letters.
sed -e 's/^[^:]*: / /' \
-e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile"
## This next piece of magic avoids the "deleted header file" problem.
## The problem is that when a header file which appears in a .P file
## is deleted, the dependency causes make to die (because there is
## typically no way to rebuild the header). We avoid this by adding
## dummy dependencies for each header file. Too bad gcc doesn't do
## this for us directly.
tr ' ' "$nl" < "$tmpdepfile" |
## Some versions of gcc put a space before the ':'. On the theory
## that the space means something, we add a space to the output as
## well. hp depmode also adds that space, but also prefixes the VPATH
## to the object. Take care to not repeat it in the output.
## Some versions of the HPUX 10.20 sed can't process this invocation
## correctly. Breaking it into two sed invocations is a workaround.
sed -e 's/^\\$//' -e '/^$/d' -e "s|.*$object$||" -e '/:$/d' \
| sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
hp)
# This case exists only to let depend.m4 do its work. It works by
# looking at the text of this script. This case will never be run,
# since it is checked for above.
exit 1
;;
sgi)
if test "$libtool" = yes; then
"$@" "-Wp,-MDupdate,$tmpdepfile"
else
"$@" -MDupdate "$tmpdepfile"
fi
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile"
exit $stat
fi
rm -f "$depfile"
if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files
echo "$object : \\" > "$depfile"
# Clip off the initial element (the dependent). Don't try to be
# clever and replace this with sed code, as IRIX sed won't handle
# lines with more than a fixed number of characters (4096 in
# IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines;
# the IRIX cc adds comments like '#:fec' to the end of the
# dependency line.
tr ' ' "$nl" < "$tmpdepfile" \
| sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \
tr "$nl" ' ' >> "$depfile"
echo >> "$depfile"
# The second pass generates a dummy entry for each header file.
tr ' ' "$nl" < "$tmpdepfile" \
| sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \
>> "$depfile"
else
# The sourcefile does not contain any dependencies, so just
# store a dummy comment line, to avoid errors with the Makefile
# "include basename.Plo" scheme.
echo "#dummy" > "$depfile"
fi
rm -f "$tmpdepfile"
;;
xlc)
# This case exists only to let depend.m4 do its work. It works by
# looking at the text of this script. This case will never be run,
# since it is checked for above.
exit 1
;;
aix)
# The C for AIX Compiler uses -M and outputs the dependencies
# in a .u file. In older versions, this file always lives in the
# current directory. Also, the AIX compiler puts '$object:' at the
# start of each line; $object doesn't have directory information.
# Version 6 uses the directory in both cases.
dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
test "x$dir" = "x$object" && dir=
base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
if test "$libtool" = yes; then
tmpdepfile1=$dir$base.u
tmpdepfile2=$base.u
tmpdepfile3=$dir.libs/$base.u
"$@" -Wc,-M
else
tmpdepfile1=$dir$base.u
tmpdepfile2=$dir$base.u
tmpdepfile3=$dir$base.u
"$@" -M
fi
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
exit $stat
fi
for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
do
test -f "$tmpdepfile" && break
done
if test -f "$tmpdepfile"; then
# Each line is of the form 'foo.o: dependent.h'.
# Do two passes, one to just change these to
# '$object: dependent.h' and one to simply 'dependent.h:'.
sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
sed -e 's,^.*\.[a-z]*:['"$tab"' ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
else
# The sourcefile does not contain any dependencies, so just
# store a dummy comment line, to avoid errors with the Makefile
# "include basename.Plo" scheme.
echo "#dummy" > "$depfile"
fi
rm -f "$tmpdepfile"
;;
icc)
# Intel's C compiler anf tcc (Tiny C Compiler) understand '-MD -MF file'.
# However on
# $CC -MD -MF foo.d -c -o sub/foo.o sub/foo.c
# ICC 7.0 will fill foo.d with something like
# foo.o: sub/foo.c
# foo.o: sub/foo.h
# which is wrong. We want
# sub/foo.o: sub/foo.c
# sub/foo.o: sub/foo.h
# sub/foo.c:
# sub/foo.h:
# ICC 7.1 will output
# foo.o: sub/foo.c sub/foo.h
# and will wrap long lines using '\':
# foo.o: sub/foo.c ... \
# sub/foo.h ... \
# ...
# tcc 0.9.26 (FIXME still under development at the moment of writing)
# will emit a similar output, but also prepend the continuation lines
# with horizontal tabulation characters.
"$@" -MD -MF "$tmpdepfile"
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile"
exit $stat
fi
rm -f "$depfile"
# Each line is of the form 'foo.o: dependent.h',
# or 'foo.o: dep1.h dep2.h \', or ' dep3.h dep4.h \'.
# Do two passes, one to just change these to
# '$object: dependent.h' and one to simply 'dependent.h:'.
sed -e "s/^[ $tab][ $tab]*/ /" -e "s,^[^:]*:,$object :," \
< "$tmpdepfile" > "$depfile"
sed '
s/[ '"$tab"'][ '"$tab"']*/ /g
s/^ *//
s/ *\\*$//
s/^[^:]*: *//
/^$/d
/:$/d
s/$/ :/
' < "$tmpdepfile" >> "$depfile"
rm -f "$tmpdepfile"
;;
hp2)
# The "hp" stanza above does not work with aCC (C++) and HP's ia64
# compilers, which have integrated preprocessors. The correct option
# to use with these is +Maked; it writes dependencies to a file named
# 'foo.d', which lands next to the object file, wherever that
# happens to be.
# Much of this is similar to the tru64 case; see comments there.
dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
test "x$dir" = "x$object" && dir=
base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
if test "$libtool" = yes; then
tmpdepfile1=$dir$base.d
tmpdepfile2=$dir.libs/$base.d
"$@" -Wc,+Maked
else
tmpdepfile1=$dir$base.d
tmpdepfile2=$dir$base.d
"$@" +Maked
fi
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile1" "$tmpdepfile2"
exit $stat
fi
for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2"
do
test -f "$tmpdepfile" && break
done
if test -f "$tmpdepfile"; then
sed -e "s,^.*\.[a-z]*:,$object:," "$tmpdepfile" > "$depfile"
# Add 'dependent.h:' lines.
sed -ne '2,${
s/^ *//
s/ \\*$//
s/$/:/
p
}' "$tmpdepfile" >> "$depfile"
else
echo "#dummy" > "$depfile"
fi
rm -f "$tmpdepfile" "$tmpdepfile2"
;;
tru64)
# The Tru64 compiler uses -MD to generate dependencies as a side
# effect. 'cc -MD -o foo.o ...' puts the dependencies into 'foo.o.d'.
# At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put
# dependencies in 'foo.d' instead, so we check for that too.
# Subdirectories are respected.
dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
test "x$dir" = "x$object" && dir=
base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
if test "$libtool" = yes; then
# With Tru64 cc, shared objects can also be used to make a
# static library. This mechanism is used in libtool 1.4 series to
# handle both shared and static libraries in a single compilation.
# With libtool 1.4, dependencies were output in $dir.libs/$base.lo.d.
#
# With libtool 1.5 this exception was removed, and libtool now
# generates 2 separate objects for the 2 libraries. These two
# compilations output dependencies in $dir.libs/$base.o.d and
# in $dir$base.o.d. We have to check for both files, because
# one of the two compilations can be disabled. We should prefer
# $dir$base.o.d over $dir.libs/$base.o.d because the latter is
# automatically cleaned when .libs/ is deleted, while ignoring
# the former would cause a distcleancheck panic.
tmpdepfile1=$dir.libs/$base.lo.d # libtool 1.4
tmpdepfile2=$dir$base.o.d # libtool 1.5
tmpdepfile3=$dir.libs/$base.o.d # libtool 1.5
tmpdepfile4=$dir.libs/$base.d # Compaq CCC V6.2-504
"$@" -Wc,-MD
else
tmpdepfile1=$dir$base.o.d
tmpdepfile2=$dir$base.d
tmpdepfile3=$dir$base.d
tmpdepfile4=$dir$base.d
"$@" -MD
fi
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4"
exit $stat
fi
for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4"
do
test -f "$tmpdepfile" && break
done
if test -f "$tmpdepfile"; then
sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
sed -e 's,^.*\.[a-z]*:['"$tab"' ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
else
echo "#dummy" > "$depfile"
fi
rm -f "$tmpdepfile"
;;
msvc7)
if test "$libtool" = yes; then
showIncludes=-Wc,-showIncludes
else
showIncludes=-showIncludes
fi
"$@" $showIncludes > "$tmpdepfile"
stat=$?
grep -v '^Note: including file: ' "$tmpdepfile"
if test "$stat" = 0; then :
else
rm -f "$tmpdepfile"
exit $stat
fi
rm -f "$depfile"
echo "$object : \\" > "$depfile"
# The first sed program below extracts the file names and escapes
# backslashes for cygpath. The second sed program outputs the file
# name when reading, but also accumulates all include files in the
# hold buffer in order to output them again at the end. This only
# works with sed implementations that can handle large buffers.
sed < "$tmpdepfile" -n '
/^Note: including file: *\(.*\)/ {
s//\1/
s/\\/\\\\/g
p
}' | $cygpath_u | sort -u | sed -n '
s/ /\\ /g
s/\(.*\)/'"$tab"'\1 \\/p
s/.\(.*\) \\/\1:/
H
$ {
s/.*/'"$tab"'/
G
p
}' >> "$depfile"
rm -f "$tmpdepfile"
;;
msvc7msys)
# This case exists only to let depend.m4 do its work. It works by
# looking at the text of this script. This case will never be run,
# since it is checked for above.
exit 1
;;
#nosideeffect)
# This comment above is used by automake to tell side-effect
# dependency tracking mechanisms from slower ones.
dashmstdout)
# Important note: in order to support this mode, a compiler *must*
# always write the preprocessed file to stdout, regardless of -o.
"$@" || exit $?
# Remove the call to Libtool.
if test "$libtool" = yes; then
while test "X$1" != 'X--mode=compile'; do
shift
done
shift
fi
# Remove '-o $object'.
IFS=" "
for arg
do
case $arg in
-o)
shift
;;
$object)
shift
;;
*)
set fnord "$@" "$arg"
shift # fnord
shift # $arg
;;
esac
done
test -z "$dashmflag" && dashmflag=-M
# Require at least two characters before searching for ':'
# in the target name. This is to cope with DOS-style filenames:
# a dependency such as 'c:/foo/bar' could be seen as target 'c' otherwise.
"$@" $dashmflag |
sed 's:^['"$tab"' ]*[^:'"$tab"' ][^:][^:]*\:['"$tab"' ]*:'"$object"'\: :' > "$tmpdepfile"
rm -f "$depfile"
cat < "$tmpdepfile" > "$depfile"
tr ' ' "$nl" < "$tmpdepfile" | \
## Some versions of the HPUX 10.20 sed can't process this invocation
## correctly. Breaking it into two sed invocations is a workaround.
sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
dashXmstdout)
# This case only exists to satisfy depend.m4. It is never actually
# run, as this mode is specially recognized in the preamble.
exit 1
;;
makedepend)
"$@" || exit $?
# Remove any Libtool call
if test "$libtool" = yes; then
while test "X$1" != 'X--mode=compile'; do
shift
done
shift
fi
# X makedepend
shift
cleared=no eat=no
for arg
do
case $cleared in
no)
set ""; shift
cleared=yes ;;
esac
if test $eat = yes; then
eat=no
continue
fi
case "$arg" in
-D*|-I*)
set fnord "$@" "$arg"; shift ;;
# Strip any option that makedepend may not understand. Remove
# the object too, otherwise makedepend will parse it as a source file.
-arch)
eat=yes ;;
-*|$object)
;;
*)
set fnord "$@" "$arg"; shift ;;
esac
done
obj_suffix=`echo "$object" | sed 's/^.*\././'`
touch "$tmpdepfile"
${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@"
rm -f "$depfile"
# makedepend may prepend the VPATH from the source file name to the object.
# No need to regex-escape $object, excess matching of '.' is harmless.
sed "s|^.*\($object *:\)|\1|" "$tmpdepfile" > "$depfile"
sed '1,2d' "$tmpdepfile" | tr ' ' "$nl" | \
## Some versions of the HPUX 10.20 sed can't process this invocation
## correctly. Breaking it into two sed invocations is a workaround.
sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile" "$tmpdepfile".bak
;;
cpp)
# Important note: in order to support this mode, a compiler *must*
# always write the preprocessed file to stdout.
"$@" || exit $?
# Remove the call to Libtool.
if test "$libtool" = yes; then
while test "X$1" != 'X--mode=compile'; do
shift
done
shift
fi
# Remove '-o $object'.
IFS=" "
for arg
do
case $arg in
-o)
shift
;;
$object)
shift
;;
*)
set fnord "$@" "$arg"
shift # fnord
shift # $arg
;;
esac
done
"$@" -E |
sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \
-e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' |
sed '$ s: \\$::' > "$tmpdepfile"
rm -f "$depfile"
echo "$object : \\" > "$depfile"
cat < "$tmpdepfile" >> "$depfile"
sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
msvisualcpp)
# Important note: in order to support this mode, a compiler *must*
# always write the preprocessed file to stdout.
"$@" || exit $?
# Remove the call to Libtool.
if test "$libtool" = yes; then
while test "X$1" != 'X--mode=compile'; do
shift
done
shift
fi
IFS=" "
for arg
do
case "$arg" in
-o)
shift
;;
$object)
shift
;;
"-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI")
set fnord "$@"
shift
shift
;;
*)
set fnord "$@" "$arg"
shift
shift
;;
esac
done
"$@" -E 2>/dev/null |
sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile"
rm -f "$depfile"
echo "$object : \\" > "$depfile"
sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::'"$tab"'\1 \\:p' >> "$depfile"
echo "$tab" >> "$depfile"
sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile"
rm -f "$tmpdepfile"
;;
msvcmsys)
# This case exists only to let depend.m4 do its work. It works by
# looking at the text of this script. This case will never be run,
# since it is checked for above.
exit 1
;;
none)
exec "$@"
;;
*)
echo "Unknown depmode $depmode" 1>&2
exit 1
;;
esac
exit 0
# Local Variables:
# mode: shell-script
# sh-indentation: 2
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-time-zone: "UTC"
# time-stamp-end: "; # UTC"
# End:
-527
View File
@@ -1,527 +0,0 @@
#!/bin/sh
# install - install a program, script, or datafile
scriptversion=2011-01-19.21; # 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.
nl='
'
IFS=" "" $nl"
# set DOITPROG to echo to test this script
# Don't use :- since 4.3BSD and earlier shells don't like it.
doit=${DOITPROG-}
if test -z "$doit"; then
doit_exec=exec
else
doit_exec=$doit
fi
# 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_glob='?'
initialize_posix_glob='
test "$posix_glob" != "?" || {
if (set -f) 2>/dev/null; then
posix_glob=
else
posix_glob=:
fi
}
'
posix_mkdir=
# Desired mode of installed file.
mode=0755
chgrpcmd=
chmodcmd=$chmodprog
chowncmd=
mvcmd=$mvprog
rmcmd="$rmprog -f"
stripcmd=
src=
dst=
dir_arg=
dst_arg=
copy_on_change=false
no_target_directory=
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 the last 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.
-s $stripprog installed files.
-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
"
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
*' '* | *' '* | *'
'* | *'*'* | *'?'* | *'['*)
echo "$0: invalid mode: $mode" >&2
exit 1;;
esac
shift;;
-o) chowncmd="$chownprog $2"
shift;;
-s) stripcmd=$stripprog;;
-t) dst_arg=$2
# Protect names problematic for `test' and other utilities.
case $dst_arg in
-* | [=\(\)!]) dst_arg=./$dst_arg;;
esac
shift;;
-T) no_target_directory=true;;
--version) echo "$0 $scriptversion"; exit $?;;
--) shift
break;;
-*) echo "$0: invalid option: $1" >&2
exit 1;;
*) break;;
esac
shift
done
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
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=$?
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; won't work
# if double slashes aren't ignored.
if test -d "$dst"; then
if test -n "$no_target_directory"; then
echo "$0: $dst_arg: Is a directory" >&2
exit 1
fi
dstdir=$dst
dst=$dstdir/`basename "$src"`
dstdir_status=0
else
# Prefer dirname, but fall back on a substitute if dirname fails.
dstdir=`
(dirname "$dst") 2>/dev/null ||
expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
X"$dst" : 'X\(//\)[^/]' \| \
X"$dst" : 'X\(//\)$' \| \
X"$dst" : 'X\(/\)' \| . 2>/dev/null ||
echo X"$dst" |
sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
s//\1/
q
}
/^X\(\/\/\)[^/].*/{
s//\1/
q
}
/^X\(\/\/\)$/{
s//\1/
q
}
/^X\(\/\).*/{
s//\1/
q
}
s/.*/./; q'
`
test -d "$dstdir"
dstdir_status=$?
fi
fi
obsolete_mkdir_used=false
if test $dstdir_status != 0; then
case $posix_mkdir in
'')
# Create intermediate dirs using mode 755 as modified by the umask.
# This is like FreeBSD 'install' as of 1997-10-28.
umask=`umask`
case $stripcmd.$umask in
# Optimize common cases.
*[2367][2367]) mkdir_umask=$umask;;
.*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
*[0-7])
mkdir_umask=`expr $umask + 22 \
- $umask % 100 % 40 + $umask % 20 \
- $umask % 10 % 4 + $umask % 2
`;;
*) mkdir_umask=$umask,go-w;;
esac
# 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
case $umask in
*[123567][0-7][0-7])
# POSIX mkdir -p sets u+wx bits regardless of umask, which
# is incompatible with FreeBSD 'install' when (umask & 300) != 0.
;;
*)
tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0
if (umask $mkdir_umask &&
exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/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-writeable bit of parent directory when it shouldn't.
# FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
ls_ld_tmpdir=`ls -ld "$tmpdir"`
case $ls_ld_tmpdir in
d????-?r-*) different_mode=700;;
d????-?--*) different_mode=755;;
*) false;;
esac &&
$mkdirprog -m$different_mode -p -- "$tmpdir" && {
ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
}
}
then posix_mkdir=:
fi
rmdir "$tmpdir/d" "$tmpdir"
else
# Remove any dirs left behind by ancient mkdir implementations.
rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
fi
trap '' 0;;
esac;;
esac
if
$posix_mkdir && (
umask $mkdir_umask &&
$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
)
then :
else
# The umask is ridiculous, or 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
eval "$initialize_posix_glob"
oIFS=$IFS
IFS=/
$posix_glob set -f
set fnord $dstdir
shift
$posix_glob 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=$dstdir/_inst.$$_
rmtmp=$dstdir/_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 && $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` &&
eval "$initialize_posix_glob" &&
$posix_glob set -f &&
set X $old && old=:$2:$4:$5:$6 &&
set X $new && new=:$2:$4:$5:$6 &&
$posix_glob set +f &&
test "$old" = "$new" &&
$cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
then
rm -f "$dsttmp"
else
# 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 -f "$dst" 2>/dev/null ||
{ $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
{ $doit $rmcmd -f "$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 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-time-zone: "UTC"
# time-stamp-end: "; # UTC"
# End:
-9655
View File
File diff suppressed because it is too large Load Diff
-331
View File
@@ -1,331 +0,0 @@
#! /bin/sh
# Common stub for a few missing GNU programs while installing.
scriptversion=2012-01-06.13; # UTC
# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005, 2006,
# 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc.
# Originally by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
if test $# -eq 0; then
echo 1>&2 "Try \`$0 --help' for more information"
exit 1
fi
run=:
sed_output='s/.* --output[ =]\([^ ]*\).*/\1/p'
sed_minuso='s/.* -o \([^ ]*\).*/\1/p'
# In the cases where this matters, `missing' is being run in the
# srcdir already.
if test -f configure.ac; then
configure_ac=configure.ac
else
configure_ac=configure.in
fi
msg="missing on your system"
case $1 in
--run)
# Try to run requested program, and just exit if it succeeds.
run=
shift
"$@" && exit 0
# Exit code 63 means version mismatch. This often happens
# when the user try to use an ancient version of a tool on
# a file that requires a minimum version. In this case we
# we should proceed has if the program had been absent, or
# if --run hadn't been passed.
if test $? = 63; then
run=:
msg="probably too old"
fi
;;
-h|--h|--he|--hel|--help)
echo "\
$0 [OPTION]... PROGRAM [ARGUMENT]...
Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an
error status if there is no known handling for PROGRAM.
Options:
-h, --help display this help and exit
-v, --version output version information and exit
--run try to run the given command, and emulate it if it fails
Supported PROGRAM values:
aclocal touch file \`aclocal.m4'
autoconf touch file \`configure'
autoheader touch file \`config.h.in'
autom4te touch the output file, or create a stub one
automake touch all \`Makefile.in' files
bison create \`y.tab.[ch]', if possible, from existing .[ch]
flex create \`lex.yy.c', if possible, from existing .c
help2man touch the output file
lex create \`lex.yy.c', if possible, from existing .c
makeinfo touch the output file
yacc create \`y.tab.[ch]', if possible, from existing .[ch]
Version suffixes to PROGRAM as well as the prefixes \`gnu-', \`gnu', and
\`g' are ignored when checking the name.
Send bug reports to <bug-automake@gnu.org>."
exit $?
;;
-v|--v|--ve|--ver|--vers|--versi|--versio|--version)
echo "missing $scriptversion (GNU Automake)"
exit $?
;;
-*)
echo 1>&2 "$0: Unknown \`$1' option"
echo 1>&2 "Try \`$0 --help' for more information"
exit 1
;;
esac
# normalize program name to check for.
program=`echo "$1" | sed '
s/^gnu-//; t
s/^gnu//; t
s/^g//; t'`
# Now exit if we have it, but it failed. Also exit now if we
# don't have it and --version was passed (most likely to detect
# the program). This is about non-GNU programs, so use $1 not
# $program.
case $1 in
lex*|yacc*)
# Not GNU programs, they don't have --version.
;;
*)
if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
# We have it, but it failed.
exit 1
elif test "x$2" = "x--version" || test "x$2" = "x--help"; then
# Could not run --version or --help. This is probably someone
# running `$TOOL --version' or `$TOOL --help' to check whether
# $TOOL exists and not knowing $TOOL uses missing.
exit 1
fi
;;
esac
# If it does not exist, or fails to run (possibly an outdated version),
# try to emulate it.
case $program in
aclocal*)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified \`acinclude.m4' or \`${configure_ac}'. You might want
to install the \`Automake' and \`Perl' packages. Grab them from
any GNU archive site."
touch aclocal.m4
;;
autoconf*)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified \`${configure_ac}'. You might want to install the
\`Autoconf' and \`GNU m4' packages. Grab them from any GNU
archive site."
touch configure
;;
autoheader*)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified \`acconfig.h' or \`${configure_ac}'. You might want
to install the \`Autoconf' and \`GNU m4' packages. Grab them
from any GNU archive site."
files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}`
test -z "$files" && files="config.h"
touch_files=
for f in $files; do
case $f in
*:*) touch_files="$touch_files "`echo "$f" |
sed -e 's/^[^:]*://' -e 's/:.*//'`;;
*) touch_files="$touch_files $f.in";;
esac
done
touch $touch_files
;;
automake*)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'.
You might want to install the \`Automake' and \`Perl' packages.
Grab them from any GNU archive site."
find . -type f -name Makefile.am -print |
sed 's/\.am$/.in/' |
while read f; do touch "$f"; done
;;
autom4te*)
echo 1>&2 "\
WARNING: \`$1' is needed, but is $msg.
You might have modified some files without having the
proper tools for further handling them.
You can get \`$1' as part of \`Autoconf' from any GNU
archive site."
file=`echo "$*" | sed -n "$sed_output"`
test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
if test -f "$file"; then
touch $file
else
test -z "$file" || exec >$file
echo "#! /bin/sh"
echo "# Created by GNU Automake missing as a replacement of"
echo "# $ $@"
echo "exit 0"
chmod +x $file
exit 1
fi
;;
bison*|yacc*)
echo 1>&2 "\
WARNING: \`$1' $msg. You should only need it if
you modified a \`.y' file. You may need the \`Bison' package
in order for those modifications to take effect. You can get
\`Bison' from any GNU archive site."
rm -f y.tab.c y.tab.h
if test $# -ne 1; then
eval LASTARG=\${$#}
case $LASTARG in
*.y)
SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'`
if test -f "$SRCFILE"; then
cp "$SRCFILE" y.tab.c
fi
SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'`
if test -f "$SRCFILE"; then
cp "$SRCFILE" y.tab.h
fi
;;
esac
fi
if test ! -f y.tab.h; then
echo >y.tab.h
fi
if test ! -f y.tab.c; then
echo 'main() { return 0; }' >y.tab.c
fi
;;
lex*|flex*)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified a \`.l' file. You may need the \`Flex' package
in order for those modifications to take effect. You can get
\`Flex' from any GNU archive site."
rm -f lex.yy.c
if test $# -ne 1; then
eval LASTARG=\${$#}
case $LASTARG in
*.l)
SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'`
if test -f "$SRCFILE"; then
cp "$SRCFILE" lex.yy.c
fi
;;
esac
fi
if test ! -f lex.yy.c; then
echo 'main() { return 0; }' >lex.yy.c
fi
;;
help2man*)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified a dependency of a manual page. You may need the
\`Help2man' package in order for those modifications to take
effect. You can get \`Help2man' from any GNU archive site."
file=`echo "$*" | sed -n "$sed_output"`
test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
if test -f "$file"; then
touch $file
else
test -z "$file" || exec >$file
echo ".ab help2man is required to generate this page"
exit $?
fi
;;
makeinfo*)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified a \`.texi' or \`.texinfo' file, or any other file
indirectly affecting the aspect of the manual. The spurious
call might also be the consequence of using a buggy \`make' (AIX,
DU, IRIX). You might want to install the \`Texinfo' package or
the \`GNU make' package. Grab either from any GNU archive site."
# The file to touch is that specified with -o ...
file=`echo "$*" | sed -n "$sed_output"`
test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
if test -z "$file"; then
# ... or it is the one specified with @setfilename ...
infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'`
file=`sed -n '
/^@setfilename/{
s/.* \([^ ]*\) *$/\1/
p
q
}' $infile`
# ... or it is derived from the source name (dir/f.texi becomes f.info)
test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info
fi
# If the file does not exist, the user really needs makeinfo;
# let's fail without touching anything.
test -f $file || exit 1
touch $file
;;
*)
echo 1>&2 "\
WARNING: \`$1' is needed, and is $msg.
You might have modified some files without having the
proper tools for further handling them. Check the \`README' file,
it often tells you about the needed prerequisites for installing
this package. You may also peek at any GNU archive site, in case
some other package would contain this missing \`$1' program."
exit 1
;;
esac
exit 0
# Local variables:
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-time-zone: "UTC"
# time-stamp-end: "; # UTC"
# End:
+3 -3
View File
@@ -603,8 +603,8 @@ SubstituteFile(
sp = fopen(substitutions, "rt");
if (sp != NULL) {
while (fgets(szBuffer, cbBuffer, sp) != NULL) {
char *ks, *ke, *vs, *ve;
ks = szBuffer;
unsigned char *ks, *ke, *vs, *ve;
ks = (unsigned char*)szBuffer;
while (ks && *ks && isspace(*ks)) ++ks;
ke = ks;
while (ke && *ke && !isspace(*ke)) ++ke;
@@ -613,7 +613,7 @@ SubstituteFile(
ve = vs;
while (ve && *ve && !(*ve == '\r' || *ve == '\n')) ++ve;
*ke = 0, *ve = 0;
list_insert(&substPtr, ks, vs);
list_insert(&substPtr, (char*)ks, (char*)vs);
}
fclose(sp);
}
+12
View File
@@ -45,6 +45,18 @@
/* Define to 1 if you have the <memory.h> header file. */
#undef HAVE_MEMORY_H
/* Define to 1 if you have the pread() function. */
#undef HAVE_PREAD
/* Define to 1 if you have the pread64() function. */
#undef HAVE_PREAD64
/* Define to 1 if you have the pwrite() function. */
#undef HAVE_PWRITE
/* Define to 1 if you have the pwrite64() function. */
#undef HAVE_PWRITE64
/* Define to 1 if you have the <stdint.h> header file. */
#undef HAVE_STDINT_H
Vendored
+158 -69
View File
@@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.69 for sqlite 3.9.0.
# Generated by GNU Autoconf 2.69 for sqlite 3.12.0.
#
#
# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
@@ -726,8 +726,8 @@ MAKEFLAGS=
# Identity of this package.
PACKAGE_NAME='sqlite'
PACKAGE_TARNAME='sqlite'
PACKAGE_VERSION='3.9.0'
PACKAGE_STRING='sqlite 3.9.0'
PACKAGE_VERSION='3.12.0'
PACKAGE_STRING='sqlite 3.12.0'
PACKAGE_BUGREPORT=''
PACKAGE_URL=''
@@ -774,6 +774,7 @@ USE_GCOV
OPT_FEATURE_FLAGS
USE_AMALGAMATION
TARGET_DEBUG
TARGET_HAVE_EDITLINE
TARGET_HAVE_READLINE
TARGET_READLINE_INC
TARGET_READLINE_LIBS
@@ -803,7 +804,6 @@ VERSION
program_prefix
TCLLIBDIR
TCLSH_CMD
AWK
INSTALL_DATA
INSTALL_SCRIPT
INSTALL_PROGRAM
@@ -896,6 +896,7 @@ enable_releasemode
enable_tempstore
enable_tcl
with_tcl
enable_editline
enable_readline
with_readline_lib
with_readline_inc
@@ -1459,7 +1460,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
\`configure' configures sqlite 3.9.0 to adapt to many kinds of systems.
\`configure' configures sqlite 3.12.0 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1524,7 +1525,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
short | recursive ) echo "Configuration of sqlite 3.9.0:";;
short | recursive ) echo "Configuration of sqlite 3.12.0:";;
esac
cat <<\_ACEOF
@@ -1543,7 +1544,8 @@ Optional Features:
--enable-tempstore Use an in-ram database for temporary tables
(never,no,yes,always)
--disable-tcl do not build TCL extension
--disable-readline disable readline support [default=detect]
--enable-editline enable BSD editline support
--disable-readline disable readline support
--enable-debug enable debugging & verbose explain
--disable-amalgamation Disable the amalgamation and instead build all files
separately
@@ -1644,7 +1646,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
sqlite configure 3.9.0
sqlite configure 3.12.0
generated by GNU Autoconf 2.69
Copyright (C) 2012 Free Software Foundation, Inc.
@@ -2063,7 +2065,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
It was created by sqlite $as_me 3.9.0, which was
It was created by sqlite $as_me 3.12.0, which was
generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@
@@ -3921,13 +3923,13 @@ if ${lt_cv_nm_interface+:} false; then :
else
lt_cv_nm_interface="BSD nm"
echo "int some_variable = 0;" > conftest.$ac_ext
(eval echo "\"\$as_me:3924: $ac_compile\"" >&5)
(eval echo "\"\$as_me:3926: $ac_compile\"" >&5)
(eval "$ac_compile" 2>conftest.err)
cat conftest.err >&5
(eval echo "\"\$as_me:3927: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
(eval echo "\"\$as_me:3929: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
(eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out)
cat conftest.err >&5
(eval echo "\"\$as_me:3930: output\"" >&5)
(eval echo "\"\$as_me:3932: output\"" >&5)
cat conftest.out >&5
if $GREP 'External.*some_variable' conftest.out > /dev/null; then
lt_cv_nm_interface="MS dumpbin"
@@ -5133,7 +5135,7 @@ ia64-*-hpux*)
;;
*-*-irix6*)
# Find out which ABI we are using.
echo '#line 5136 "configure"' > conftest.$ac_ext
echo '#line 5138 "configure"' > conftest.$ac_ext
if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
(eval $ac_compile) 2>&5
ac_status=$?
@@ -6658,11 +6660,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
(eval echo "\"\$as_me:6661: $lt_compile\"" >&5)
(eval echo "\"\$as_me:6663: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
echo "$as_me:6665: \$? = $ac_status" >&5
echo "$as_me:6667: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings other than the usual output.
@@ -6997,11 +6999,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
(eval echo "\"\$as_me:7000: $lt_compile\"" >&5)
(eval echo "\"\$as_me:7002: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
echo "$as_me:7004: \$? = $ac_status" >&5
echo "$as_me:7006: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings other than the usual output.
@@ -7102,11 +7104,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
(eval echo "\"\$as_me:7105: $lt_compile\"" >&5)
(eval echo "\"\$as_me:7107: $lt_compile\"" >&5)
(eval "$lt_compile" 2>out/conftest.err)
ac_status=$?
cat out/conftest.err >&5
echo "$as_me:7109: \$? = $ac_status" >&5
echo "$as_me:7111: \$? = $ac_status" >&5
if (exit $ac_status) && test -s out/conftest2.$ac_objext
then
# The compiler can only warn and ignore the option if not recognized
@@ -7157,11 +7159,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
(eval echo "\"\$as_me:7160: $lt_compile\"" >&5)
(eval echo "\"\$as_me:7162: $lt_compile\"" >&5)
(eval "$lt_compile" 2>out/conftest.err)
ac_status=$?
cat out/conftest.err >&5
echo "$as_me:7164: \$? = $ac_status" >&5
echo "$as_me:7166: \$? = $ac_status" >&5
if (exit $ac_status) && test -s out/conftest2.$ac_objext
then
# The compiler can only warn and ignore the option if not recognized
@@ -9537,7 +9539,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
#line 9540 "configure"
#line 9542 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -9633,7 +9635,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
#line 9636 "configure"
#line 9638 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -9953,48 +9955,6 @@ test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}'
test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
for ac_prog in gawk mawk nawk awk
do
# Extract the first word of "$ac_prog", so it can be a program name with args.
set dummy $ac_prog; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
if ${ac_cv_prog_AWK+:} false; then :
$as_echo_n "(cached) " >&6
else
if test -n "$AWK"; then
ac_cv_prog_AWK="$AWK" # Let the user override the test.
else
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_AWK="$ac_prog"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
fi
done
done
IFS=$as_save_IFS
fi
fi
AWK=$ac_cv_prog_AWK
if test -n "$AWK"; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5
$as_echo "$AWK" >&6; }
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi
test -n "$AWK" && break
done
#########
# Enable large file support (if special flags are necessary)
@@ -10313,7 +10273,7 @@ done
#########
# Figure out whether or not we have these functions
#
for ac_func in fdatasync gmtime_r isnan localtime_r localtime_s malloc_usable_size strchrnul usleep utime
for ac_func in fdatasync gmtime_r isnan localtime_r localtime_s malloc_usable_size strchrnul usleep utime pread pread64 pwrite pwrite64
do :
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
@@ -10558,6 +10518,62 @@ ac_res=$ac_cv_search_pthread_create
if test "$ac_res" != no; then :
test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing pthread_mutexattr_init" >&5
$as_echo_n "checking for library containing pthread_mutexattr_init... " >&6; }
if ${ac_cv_search_pthread_mutexattr_init+:} false; then :
$as_echo_n "(cached) " >&6
else
ac_func_search_save_LIBS=$LIBS
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
/* Override any GCC internal prototype to avoid an error.
Use char because int might match the return type of a GCC
builtin and then its argument prototype would still apply. */
#ifdef __cplusplus
extern "C"
#endif
char pthread_mutexattr_init ();
int
main ()
{
return pthread_mutexattr_init ();
;
return 0;
}
_ACEOF
for ac_lib in '' pthread; do
if test -z "$ac_lib"; then
ac_res="none required"
else
ac_res=-l$ac_lib
LIBS="-l$ac_lib $ac_func_search_save_LIBS"
fi
if ac_fn_c_try_link "$LINENO"; then :
ac_cv_search_pthread_mutexattr_init=$ac_res
fi
rm -f core conftest.err conftest.$ac_objext \
conftest$ac_exeext
if ${ac_cv_search_pthread_mutexattr_init+:} false; then :
break
fi
done
if ${ac_cv_search_pthread_mutexattr_init+:} false; then :
else
ac_cv_search_pthread_mutexattr_init=no
fi
rm conftest.$ac_ext
LIBS=$ac_func_search_save_LIBS
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_pthread_mutexattr_init" >&5
$as_echo "$ac_cv_search_pthread_mutexattr_init" >&6; }
ac_res=$ac_cv_search_pthread_mutexattr_init
if test "$ac_res" != no; then :
test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
fi
fi
@@ -10875,6 +10891,14 @@ fi
TARGET_READLINE_LIBS=""
TARGET_READLINE_INC=""
TARGET_HAVE_READLINE=0
TARGET_HAVE_EDITLINE=0
# Check whether --enable-editline was given.
if test "${enable_editline+set}" = set; then :
enableval=$enable_editline; with_editline=$enableval
else
with_editline=auto
fi
# Check whether --enable-readline was given.
if test "${enable_readline+set}" = set; then :
enableval=$enable_readline; with_readline=$enableval
@@ -10883,6 +10907,71 @@ else
fi
if test x"$with_editline" != xno; then
sLIBS=$LIBS
LIBS=""
TARGET_HAVE_EDITLINE=1
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing readline" >&5
$as_echo_n "checking for library containing readline... " >&6; }
if ${ac_cv_search_readline+:} false; then :
$as_echo_n "(cached) " >&6
else
ac_func_search_save_LIBS=$LIBS
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
/* Override any GCC internal prototype to avoid an error.
Use char because int might match the return type of a GCC
builtin and then its argument prototype would still apply. */
#ifdef __cplusplus
extern "C"
#endif
char readline ();
int
main ()
{
return readline ();
;
return 0;
}
_ACEOF
for ac_lib in '' edit; do
if test -z "$ac_lib"; then
ac_res="none required"
else
ac_res=-l$ac_lib
LIBS="-l$ac_lib $ac_func_search_save_LIBS"
fi
if ac_fn_c_try_link "$LINENO"; then :
ac_cv_search_readline=$ac_res
fi
rm -f core conftest.err conftest.$ac_objext \
conftest$ac_exeext
if ${ac_cv_search_readline+:} false; then :
break
fi
done
if ${ac_cv_search_readline+:} false; then :
else
ac_cv_search_readline=no
fi
rm conftest.$ac_ext
LIBS=$ac_func_search_save_LIBS
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_readline" >&5
$as_echo "$ac_cv_search_readline" >&6; }
ac_res=$ac_cv_search_readline
if test "$ac_res" != no; then :
test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
with_readline=no
else
TARGET_HAVE_EDITLINE=0
fi
TARGET_READLINE_LIBS=$LIBS
LIBS=$sLIBS
fi
if test x"$with_readline" != xno; then
found="yes"
@@ -11071,6 +11160,7 @@ fi
##########
# Figure out what C libraries are required to compile programs
# that use "fdatasync()" function.
@@ -11989,7 +12079,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
This file was extended by sqlite $as_me 3.9.0, which was
This file was extended by sqlite $as_me 3.12.0, which was
generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -12055,7 +12145,7 @@ _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\
sqlite config.status 3.9.0
sqlite config.status 3.12.0
configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\"
@@ -12066,7 +12156,6 @@ gives unlimited permission to copy, distribute and modify it."
ac_pwd='$ac_pwd'
srcdir='$srcdir'
INSTALL='$INSTALL'
AWK='$AWK'
test -n "\$AWK" || AWK=awk
_ACEOF
+17 -3
View File
@@ -90,7 +90,6 @@ fi
#
AC_PROG_LIBTOOL
AC_PROG_INSTALL
AC_PROG_AWK
#########
# Enable large file support (if special flags are necessary)
@@ -109,7 +108,7 @@ AC_CHECK_HEADERS([sys/types.h stdlib.h stdint.h inttypes.h malloc.h])
#########
# Figure out whether or not we have these functions
#
AC_CHECK_FUNCS([fdatasync gmtime_r isnan localtime_r localtime_s malloc_usable_size strchrnul usleep utime])
AC_CHECK_FUNCS([fdatasync gmtime_r isnan localtime_r localtime_s malloc_usable_size strchrnul usleep utime pread pread64 pwrite pwrite64])
#########
# By default, we use the amalgamation (this may be changed below...)
@@ -196,6 +195,7 @@ AC_SUBST(SQLITE_THREADSAFE)
if test "$SQLITE_THREADSAFE" = "1"; then
AC_SEARCH_LIBS(pthread_create, pthread)
AC_SEARCH_LIBS(pthread_mutexattr_init, pthread)
fi
##########
@@ -461,11 +461,24 @@ AC_SUBST(HAVE_TCL)
TARGET_READLINE_LIBS=""
TARGET_READLINE_INC=""
TARGET_HAVE_READLINE=0
TARGET_HAVE_EDITLINE=0
AC_ARG_ENABLE([editline],
[AC_HELP_STRING([--enable-editline],[enable BSD editline support])],
[with_editline=$enableval],
[with_editline=auto])
AC_ARG_ENABLE([readline],
[AC_HELP_STRING([--disable-readline],[disable readline support [default=detect]])],
[AC_HELP_STRING([--disable-readline],[disable readline support])],
[with_readline=$enableval],
[with_readline=auto])
if test x"$with_editline" != xno; then
sLIBS=$LIBS
LIBS=""
TARGET_HAVE_EDITLINE=1
AC_SEARCH_LIBS(readline,edit,[with_readline=no],[TARGET_HAVE_EDITLINE=0])
TARGET_READLINE_LIBS=$LIBS
LIBS=$sLIBS
fi
if test x"$with_readline" != xno; then
found="yes"
@@ -520,6 +533,7 @@ fi
AC_SUBST(TARGET_READLINE_LIBS)
AC_SUBST(TARGET_READLINE_INC)
AC_SUBST(TARGET_HAVE_READLINE)
AC_SUBST(TARGET_HAVE_EDITLINE)
##########
# Figure out what C libraries are required to compile programs
+10 -2
View File
@@ -161,8 +161,9 @@ such as ``identifier'' or ``number'' and the third argument will
be the name of the identifier or the value of the number.</p>
<p>The Parse() function may have either three or four arguments,
depending on the grammar. If the grammar specification file request
it, the Parse() function will have a fourth parameter that can be
depending on the grammar. If the grammar specification file requests
it (via the <a href='#extraarg'><tt>extra_argument</tt> directive</a>),
the Parse() function will have a fourth parameter that can be
of any type chosen by the programmer. The parser doesn't do anything
with this argument except to pass it through to action routines.
This is a convenient mechanism for passing state information down
@@ -263,6 +264,12 @@ with prior yacc and bison experience.
But after years of experience using Lemon, I firmly
believe that the Lemon way of doing things is better.</p>
<p><i>Updated as of 2016-02-16:</i>
The text above was written in the 1990s.
We are told that Bison has lately been enhanced to support the
tokenizer-calls-parser paradigm used by Lemon, and to obviate the
need for global variables.</p>
<h2>Input File Syntax</h2>
<p>The main purpose of the grammar specification file for Lemon is
@@ -617,6 +624,7 @@ build a parser using Lemon that can be used within a long-running
program, such as a GUI, that will not leak memory or other resources.
To do the same using yacc or bison is much more difficult.</p>
<a name="extraarg"></a>
<h4>The <tt>%extra_argument</tt> directive</h4>
The %extra_argument directive instructs Lemon to add a 4th parameter
+3 -3
View File
@@ -205,13 +205,13 @@ static int getVarint32(const char *p, int *pi){
*/
/* TODO(shess) Is __isascii() a portable version of (c&0x80)==0? */
static int safe_isspace(char c){
return (c&0x80)==0 ? isspace(c) : 0;
return (c&0x80)==0 ? isspace((unsigned char)c) : 0;
}
static int safe_tolower(char c){
return (c&0x80)==0 ? tolower(c) : c;
return (c&0x80)==0 ? tolower((unsigned char)c) : c;
}
static int safe_isalnum(char c){
return (c&0x80)==0 ? isalnum(c) : 0;
return (c&0x80)==0 ? isalnum((unsigned char)c) : 0;
}
typedef enum DocListType {
+1 -1
View File
@@ -138,7 +138,7 @@ static int simpleNext(
** case-insensitivity.
*/
char ch = c->pCurrent[ii];
c->zToken[ii] = (unsigned char)ch<0x80 ? tolower(ch) : ch;
c->zToken[ii] = (unsigned char)ch<0x80 ? tolower((unsigned char)ch):ch;
}
c->zToken[n] = '\0';
*ppToken = c->zToken;
+6
View File
@@ -18,6 +18,12 @@
# define NDEBUG 1
#endif
/* FTS3/FTS4 require virtual tables */
#ifdef SQLITE_OMIT_VIRTUALTABLE
# undef SQLITE_ENABLE_FTS3
# undef SQLITE_ENABLE_FTS4
#endif
/*
** FTS4 is really an extension for FTS3. It is enabled using the
** SQLITE_ENABLE_FTS3 macro. But to avoid confusion we also all
+2 -1
View File
@@ -526,7 +526,8 @@ static int fts3_test_varint_cmd(
#ifdef SQLITE_ENABLE_FTS3
char aBuf[24];
int rc;
Tcl_WideInt w, w2;
Tcl_WideInt w;
sqlite3_int64 w2;
int nByte, nByte2;
if( objc!=2 ){
+38 -20
View File
@@ -29,6 +29,18 @@
#include <assert.h>
#include <string.h>
/*
** Return true if the two-argument version of fts3_tokenizer()
** has been activated via a prior call to sqlite3_db_config(db,
** SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER, 1, 0);
*/
static int fts3TokenizerEnabled(sqlite3_context *context){
sqlite3 *db = sqlite3_context_db_handle(context);
int isEnabled = 0;
sqlite3_db_config(db,SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER,-1,&isEnabled);
return isEnabled;
}
/*
** Implementation of the SQL scalar function for accessing the underlying
** hash table. This function may be called as follows:
@@ -49,7 +61,7 @@
** is a blob containing the pointer stored as the hash data corresponding
** to string <key-name> (after the hash-table is updated, if applicable).
*/
static void scalarFunc(
static void fts3TokenizerFunc(
sqlite3_context *context,
int argc,
sqlite3_value **argv
@@ -67,16 +79,20 @@ static void scalarFunc(
nName = sqlite3_value_bytes(argv[0])+1;
if( argc==2 ){
void *pOld;
int n = sqlite3_value_bytes(argv[1]);
if( zName==0 || n!=sizeof(pPtr) ){
sqlite3_result_error(context, "argument type mismatch", -1);
return;
}
pPtr = *(void **)sqlite3_value_blob(argv[1]);
pOld = sqlite3Fts3HashInsert(pHash, (void *)zName, nName, pPtr);
if( pOld==pPtr ){
sqlite3_result_error(context, "out of memory", -1);
if( fts3TokenizerEnabled(context) ){
void *pOld;
int n = sqlite3_value_bytes(argv[1]);
if( zName==0 || n!=sizeof(pPtr) ){
sqlite3_result_error(context, "argument type mismatch", -1);
return;
}
pPtr = *(void **)sqlite3_value_blob(argv[1]);
pOld = sqlite3Fts3HashInsert(pHash, (void *)zName, nName, pPtr);
if( pOld==pPtr ){
sqlite3_result_error(context, "out of memory", -1);
}
}else{
sqlite3_result_error(context, "fts3tokenize disabled", -1);
return;
}
}else{
@@ -90,7 +106,6 @@ static void scalarFunc(
return;
}
}
sqlite3_result_blob(context, (void *)&pPtr, sizeof(pPtr), SQLITE_TRANSIENT);
}
@@ -350,6 +365,7 @@ int registerTokenizer(
return sqlite3_finalize(pStmt);
}
static
int queryTokenizer(
sqlite3 *db,
@@ -420,11 +436,13 @@ static void intTestFunc(
assert( 0==strcmp(sqlite3_errmsg(db), "unknown tokenizer: nosuchtokenizer") );
/* Test the storage function */
rc = registerTokenizer(db, "nosuchtokenizer", p1);
assert( rc==SQLITE_OK );
rc = queryTokenizer(db, "nosuchtokenizer", &p2);
assert( rc==SQLITE_OK );
assert( p2==p1 );
if( fts3TokenizerEnabled(context) ){
rc = registerTokenizer(db, "nosuchtokenizer", p1);
assert( rc==SQLITE_OK );
rc = queryTokenizer(db, "nosuchtokenizer", &p2);
assert( rc==SQLITE_OK );
assert( p2==p1 );
}
sqlite3_result_text(context, "ok", -1, SQLITE_STATIC);
}
@@ -440,7 +458,7 @@ static void intTestFunc(
** sqlite3Fts3HashInit(pHash, FTS3_HASH_STRING, 1);
**
** This function adds a scalar function (see header comment above
** scalarFunc() in this file for details) and, if ENABLE_TABLE is
** fts3TokenizerFunc() in this file for details) and, if ENABLE_TABLE is
** defined at compilation time, a temporary virtual table (see header
** comment above struct HashTableVtab) to the database schema. Both
** provide read/write access to the contents of *pHash.
@@ -469,10 +487,10 @@ int sqlite3Fts3InitHashTable(
#endif
if( SQLITE_OK==rc ){
rc = sqlite3_create_function(db, zName, 1, any, p, scalarFunc, 0, 0);
rc = sqlite3_create_function(db, zName, 1, any, p, fts3TokenizerFunc, 0, 0);
}
if( SQLITE_OK==rc ){
rc = sqlite3_create_function(db, zName, 2, any, p, scalarFunc, 0, 0);
rc = sqlite3_create_function(db, zName, 2, any, p, fts3TokenizerFunc, 0, 0);
}
#ifdef SQLITE_TEST
if( SQLITE_OK==rc ){
+1 -1
View File
@@ -398,7 +398,7 @@ static void showSegmentStats(sqlite3 *db, const char *zTab){
if( sqlite3_step(pStmt)==SQLITE_ROW
&& (nLeaf = sqlite3_column_int(pStmt, 0))>0
){
int nIdx = sqlite3_column_int(pStmt, 5);
nIdx = sqlite3_column_int(pStmt, 5);
sqlite3_int64 sz;
printf("For level %d:\n", i);
printf(" Number of indexes...................... %9d\n", nIdx);
+2 -2
View File
@@ -226,9 +226,9 @@ proc print_isalnum {zFunc lRange} {
an_print_range_array $lRange
an_print_ascii_bitmap $lRange
puts {
if( c<128 ){
if( (unsigned int)c<128 ){
return ( (aAscii[c >> 5] & (1 << (c & 0x001F)))==0 );
}else if( c<(1<<22) ){
}else if( (unsigned int)c<(1<<22) ){
unsigned int key = (((unsigned int)c)<<10) | 0x000003FF;
int iRes = 0;
int iHi = sizeof(aEntry)/sizeof(aEntry[0]) - 1;
+62 -4
View File
@@ -84,6 +84,9 @@ struct Fts5PhraseIter {
** an OOM condition or IO error), an appropriate SQLite error code is
** returned.
**
** This function may be quite inefficient if used with an FTS5 table
** created with the "columnsize=0" option.
**
** xColumnText:
** This function attempts to retrieve the text of column iCol of the
** current document. If successful, (*pz) is set to point to a buffer
@@ -104,15 +107,29 @@ struct Fts5PhraseIter {
** the query within the current row. Return SQLITE_OK if successful, or
** an error code (i.e. SQLITE_NOMEM) if an error occurs.
**
** This API can be quite slow if used with an FTS5 table created with the
** "detail=none" or "detail=column" option. If the FTS5 table is created
** with either "detail=none" or "detail=column" and "content=" option
** (i.e. if it is a contentless table), then this API always returns 0.
**
** xInst:
** Query for the details of phrase match iIdx within the current row.
** Phrase matches are numbered starting from zero, so the iIdx argument
** should be greater than or equal to zero and smaller than the value
** output by xInstCount().
**
** Usually, output parameter *piPhrase is set to the phrase number, *piCol
** to the column in which it occurs and *piOff the token offset of the
** first token of the phrase. The exception is if the table was created
** with the offsets=0 option specified. In this case *piOff is always
** set to -1.
**
** Returns SQLITE_OK if successful, or an error code (i.e. SQLITE_NOMEM)
** if an error occurs.
**
** This API can be quite slow if used with an FTS5 table created with the
** "detail=none" or "detail=column" option.
**
** xRowid:
** Returns the rowid of the current row.
**
@@ -196,7 +213,7 @@ struct Fts5PhraseIter {
** Fts5PhraseIter iter;
** int iCol, iOff;
** for(pApi->xPhraseFirst(pFts, iPhrase, &iter, &iCol, &iOff);
** iOff>=0;
** iCol>=0;
** pApi->xPhraseNext(pFts, &iter, &iCol, &iOff)
** ){
** // An instance of phrase iPhrase at offset iOff of column iCol
@@ -204,13 +221,51 @@ struct Fts5PhraseIter {
**
** The Fts5PhraseIter structure is defined above. Applications should not
** modify this structure directly - it should only be used as shown above
** with the xPhraseFirst() and xPhraseNext() API methods.
** with the xPhraseFirst() and xPhraseNext() API methods (and by
** xPhraseFirstColumn() and xPhraseNextColumn() as illustrated below).
**
** This API can be quite slow if used with an FTS5 table created with the
** "detail=none" or "detail=column" option. If the FTS5 table is created
** with either "detail=none" or "detail=column" and "content=" option
** (i.e. if it is a contentless table), then this API always iterates
** through an empty set (all calls to xPhraseFirst() set iCol to -1).
**
** xPhraseNext()
** See xPhraseFirst above.
**
** xPhraseFirstColumn()
** This function and xPhraseNextColumn() are similar to the xPhraseFirst()
** and xPhraseNext() APIs described above. The difference is that instead
** of iterating through all instances of a phrase in the current row, these
** APIs are used to iterate through the set of columns in the current row
** that contain one or more instances of a specified phrase. For example:
**
** Fts5PhraseIter iter;
** int iCol;
** for(pApi->xPhraseFirstColumn(pFts, iPhrase, &iter, &iCol);
** iCol>=0;
** pApi->xPhraseNextColumn(pFts, &iter, &iCol)
** ){
** // Column iCol contains at least one instance of phrase iPhrase
** }
**
** This API can be quite slow if used with an FTS5 table created with the
** "detail=none" option. If the FTS5 table is created with either
** "detail=none" "content=" option (i.e. if it is a contentless table),
** then this API always iterates through an empty set (all calls to
** xPhraseFirstColumn() set iCol to -1).
**
** The information accessed using this API and its companion
** xPhraseFirstColumn() may also be obtained using xPhraseFirst/xPhraseNext
** (or xInst/xInstCount). The chief advantage of this API is that it is
** significantly more efficient than those alternatives when used with
** "detail=column" tables.
**
** xPhraseNextColumn()
** See xPhraseFirstColumn above.
*/
struct Fts5ExtensionApi {
int iVersion; /* Currently always set to 1 */
int iVersion; /* Currently always set to 3 */
void *(*xUserData)(Fts5Context*);
@@ -240,8 +295,11 @@ struct Fts5ExtensionApi {
int (*xSetAuxdata)(Fts5Context*, void *pAux, void(*xDelete)(void*));
void *(*xGetAuxdata)(Fts5Context*, int bClear);
void (*xPhraseFirst)(Fts5Context*, int iPhrase, Fts5PhraseIter*, int*, int*);
int (*xPhraseFirst)(Fts5Context*, int iPhrase, Fts5PhraseIter*, int*, int*);
void (*xPhraseNext)(Fts5Context*, Fts5PhraseIter*, int *piCol, int *piOff);
int (*xPhraseFirstColumn)(Fts5Context*, int iPhrase, Fts5PhraseIter*, int*);
void (*xPhraseNextColumn)(Fts5Context*, Fts5PhraseIter*, int *piCol);
};
/*
+81 -24
View File
@@ -26,10 +26,11 @@ SQLITE_EXTENSION_INIT1
typedef unsigned char u8;
typedef unsigned int u32;
typedef unsigned short u16;
typedef short i16;
typedef sqlite3_int64 i64;
typedef sqlite3_uint64 u64;
#define ArraySize(x) (sizeof(x) / sizeof(x[0]))
#define ArraySize(x) ((int)(sizeof(x) / sizeof(x[0])))
#define testcase(x)
#define ALWAYS(x) 1
@@ -80,6 +81,16 @@ extern int sqlite3_fts5_may_be_corrupt;
# define assert_nc(x) assert(x)
#endif
/* Mark a function parameter as unused, to suppress nuisance compiler
** warnings. */
#ifndef UNUSED_PARAM
# define UNUSED_PARAM(X) (void)(X)
#endif
#ifndef UNUSED_PARAM2
# define UNUSED_PARAM2(X, Y) (void)(X), (void)(Y)
#endif
typedef struct Fts5Global Fts5Global;
typedef struct Fts5Colset Fts5Colset;
@@ -151,6 +162,7 @@ struct Fts5Config {
char *zContent; /* content table */
char *zContentRowid; /* "content_rowid=" option value */
int bColumnsize; /* "columnsize=" option value (dflt==1) */
int eDetail; /* FTS5_DETAIL_XXX value */
char *zContentExprlist;
Fts5Tokenizer *pTok;
fts5_tokenizer *pTokApi;
@@ -160,6 +172,7 @@ struct Fts5Config {
int pgsz; /* Approximate page size used in %_data */
int nAutomerge; /* 'automerge' setting */
int nCrisisMerge; /* Maximum allowed segments per level */
int nHashSize; /* Bytes of memory for in-memory hash */
char *zRank; /* Name of rank function */
char *zRankArgs; /* Arguments to rank function */
@@ -178,6 +191,9 @@ struct Fts5Config {
#define FTS5_CONTENT_NONE 1
#define FTS5_CONTENT_EXTERNAL 2
#define FTS5_DETAIL_FULL 0
#define FTS5_DETAIL_NONE 1
#define FTS5_DETAIL_COLUMNS 2
@@ -224,25 +240,27 @@ struct Fts5Buffer {
int nSpace;
};
int sqlite3Fts5BufferGrow(int*, Fts5Buffer*, int);
int sqlite3Fts5BufferSize(int*, Fts5Buffer*, u32);
void sqlite3Fts5BufferAppendVarint(int*, Fts5Buffer*, i64);
void sqlite3Fts5BufferAppendBlob(int*, Fts5Buffer*, int, const u8*);
void sqlite3Fts5BufferAppendBlob(int*, Fts5Buffer*, u32, const u8*);
void sqlite3Fts5BufferAppendString(int *, Fts5Buffer*, const char*);
void sqlite3Fts5BufferFree(Fts5Buffer*);
void sqlite3Fts5BufferZero(Fts5Buffer*);
void sqlite3Fts5BufferSet(int*, Fts5Buffer*, int, const u8*);
void sqlite3Fts5BufferAppendPrintf(int *, Fts5Buffer*, char *zFmt, ...);
void sqlite3Fts5BufferAppend32(int*, Fts5Buffer*, int);
char *sqlite3Fts5Mprintf(int *pRc, const char *zFmt, ...);
#define fts5BufferZero(x) sqlite3Fts5BufferZero(x)
#define fts5BufferGrow(a,b,c) sqlite3Fts5BufferGrow(a,b,c)
#define fts5BufferAppendVarint(a,b,c) sqlite3Fts5BufferAppendVarint(a,b,c)
#define fts5BufferFree(a) sqlite3Fts5BufferFree(a)
#define fts5BufferAppendBlob(a,b,c,d) sqlite3Fts5BufferAppendBlob(a,b,c,d)
#define fts5BufferSet(a,b,c,d) sqlite3Fts5BufferSet(a,b,c,d)
#define fts5BufferAppend32(a,b,c) sqlite3Fts5BufferAppend32(a,b,c)
#define fts5BufferGrow(pRc,pBuf,nn) ( \
(u32)((pBuf)->n) + (u32)(nn) <= (u32)((pBuf)->nSpace) ? 0 : \
sqlite3Fts5BufferSize((pRc),(pBuf),(nn)+(pBuf)->n) \
)
/* Write and decode big-endian 32-bit integer values */
void sqlite3Fts5Put32(u8*, int);
@@ -275,6 +293,7 @@ struct Fts5PoslistWriter {
i64 iPrev;
};
int sqlite3Fts5PoslistWriterAppend(Fts5Buffer*, Fts5PoslistWriter*, i64);
void sqlite3Fts5PoslistSafeAppend(Fts5Buffer*, i64*, i64);
int sqlite3Fts5PoslistNext64(
const u8 *a, int n, /* Buffer containing poslist */
@@ -289,6 +308,13 @@ char *sqlite3Fts5Strndup(int *pRc, const char *pIn, int nIn);
/* Character set tests (like isspace(), isalpha() etc.) */
int sqlite3Fts5IsBareword(char t);
/* Bucket of terms object used by the integrity-check in offsets=0 mode. */
typedef struct Fts5Termset Fts5Termset;
int sqlite3Fts5TermsetNew(Fts5Termset**);
int sqlite3Fts5TermsetAdd(Fts5Termset*, int, const char*, int, int *pbPresent);
void sqlite3Fts5TermsetFree(Fts5Termset*);
/*
** End of interface to code in fts5_buffer.c.
**************************************************************************/
@@ -301,6 +327,15 @@ int sqlite3Fts5IsBareword(char t);
typedef struct Fts5Index Fts5Index;
typedef struct Fts5IndexIter Fts5IndexIter;
struct Fts5IndexIter {
i64 iRowid;
const u8 *pData;
int nData;
u8 bEof;
};
#define sqlite3Fts5IterEof(x) ((x)->bEof)
/*
** Values used as part of the flags argument passed to IndexQuery().
*/
@@ -309,6 +344,12 @@ typedef struct Fts5IndexIter Fts5IndexIter;
#define FTS5INDEX_QUERY_TEST_NOIDX 0x0004 /* Do not use prefix index */
#define FTS5INDEX_QUERY_SCAN 0x0008 /* Scan query (fts5vocab) */
/* The following are used internally by the fts5_index.c module. They are
** defined here only to make it easier to avoid clashes with the flags
** above. */
#define FTS5INDEX_QUERY_SKIPEMPTY 0x0010
#define FTS5INDEX_QUERY_NOOUTPUT 0x0020
/*
** Create/destroy an Fts5Index object.
*/
@@ -316,14 +357,27 @@ int sqlite3Fts5IndexOpen(Fts5Config *pConfig, int bCreate, Fts5Index**, char**);
int sqlite3Fts5IndexClose(Fts5Index *p);
/*
** for(
** sqlite3Fts5IndexQuery(p, "token", 5, 0, 0, &pIter);
** 0==sqlite3Fts5IterEof(pIter);
** sqlite3Fts5IterNext(pIter)
** ){
** i64 iRowid = sqlite3Fts5IterRowid(pIter);
** }
** Return a simple checksum value based on the arguments.
*/
u64 sqlite3Fts5IndexEntryCksum(
i64 iRowid,
int iCol,
int iPos,
int iIdx,
const char *pTerm,
int nTerm
);
/*
** Argument p points to a buffer containing utf-8 text that is n bytes in
** size. Return the number of bytes in the nChar character prefix of the
** buffer, or 0 if there are less than nChar characters in total.
*/
int sqlite3Fts5IndexCharlenToBytelen(
const char *p,
int nByte,
int nChar
);
/*
** Open a new iterator to iterate though all rowids that match the
@@ -341,12 +395,8 @@ int sqlite3Fts5IndexQuery(
** The various operations on open token or token prefix iterators opened
** using sqlite3Fts5IndexQuery().
*/
int sqlite3Fts5IterEof(Fts5IndexIter*);
int sqlite3Fts5IterNext(Fts5IndexIter*);
int sqlite3Fts5IterNextFrom(Fts5IndexIter*, i64 iMatch);
i64 sqlite3Fts5IterRowid(Fts5IndexIter*);
int sqlite3Fts5IterPoslist(Fts5IndexIter*,Fts5Colset*, const u8**, int*, i64*);
int sqlite3Fts5IterPoslistBuffer(Fts5IndexIter *pIter, Fts5Buffer *pBuf);
/*
** Close an iterator opened by sqlite3Fts5IndexQuery().
@@ -410,7 +460,6 @@ int sqlite3Fts5IndexSetAverages(Fts5Index *p, const u8*, int);
/*
** Functions called by the storage module as part of integrity-check.
*/
u64 sqlite3Fts5IndexCksum(Fts5Config*,i64,int,int,const char*,int);
int sqlite3Fts5IndexIntegrityCheck(Fts5Index*, u64 cksum);
/*
@@ -475,7 +524,7 @@ int sqlite3Fts5GetTokenizer(
char **pzErr
);
Fts5Index *sqlite3Fts5IndexFromCsrid(Fts5Global*, i64, int*);
Fts5Index *sqlite3Fts5IndexFromCsrid(Fts5Global*, i64, Fts5Config **);
/*
** End of interface to code in fts5.c.
@@ -489,7 +538,7 @@ typedef struct Fts5Hash Fts5Hash;
/*
** Create a hash table, free a hash table.
*/
int sqlite3Fts5HashNew(Fts5Hash**, int *pnSize);
int sqlite3Fts5HashNew(Fts5Config*, Fts5Hash**, int *pnSize);
void sqlite3Fts5HashFree(Fts5Hash*);
int sqlite3Fts5HashWrite(
@@ -548,7 +597,7 @@ int sqlite3Fts5StorageRename(Fts5Storage*, const char *zName);
int sqlite3Fts5DropAll(Fts5Config*);
int sqlite3Fts5CreateTable(Fts5Config*, const char*, const char*, int, char **);
int sqlite3Fts5StorageDelete(Fts5Storage *p, i64);
int sqlite3Fts5StorageDelete(Fts5Storage *p, i64, sqlite3_value**);
int sqlite3Fts5StorageContentInsert(Fts5Storage *p, sqlite3_value**, i64*);
int sqlite3Fts5StorageIndexInsert(Fts5Storage *p, sqlite3_value**, i64);
@@ -568,8 +617,6 @@ int sqlite3Fts5StorageConfigValue(
Fts5Storage *p, const char*, sqlite3_value*, int
);
int sqlite3Fts5StorageSpecialDelete(Fts5Storage *p, i64 iDel, sqlite3_value**);
int sqlite3Fts5StorageDeleteAll(Fts5Storage *p);
int sqlite3Fts5StorageRebuild(Fts5Storage *p);
int sqlite3Fts5StorageOptimize(Fts5Storage *p);
@@ -626,7 +673,17 @@ int sqlite3Fts5ExprPhraseCount(Fts5Expr*);
int sqlite3Fts5ExprPhraseSize(Fts5Expr*, int iPhrase);
int sqlite3Fts5ExprPoslist(Fts5Expr*, int, const u8 **);
int sqlite3Fts5ExprClonePhrase(Fts5Config*, Fts5Expr*, int, Fts5Expr**);
typedef struct Fts5PoslistPopulator Fts5PoslistPopulator;
Fts5PoslistPopulator *sqlite3Fts5ExprClearPoslists(Fts5Expr*, int);
int sqlite3Fts5ExprPopulatePoslists(
Fts5Config*, Fts5Expr*, Fts5PoslistPopulator*, int, const char*, int
);
void sqlite3Fts5ExprCheckPoslists(Fts5Expr*, i64);
void sqlite3Fts5ExprClearEof(Fts5Expr*);
int sqlite3Fts5ExprClonePhrase(Fts5Expr*, int, Fts5Expr**);
int sqlite3Fts5ExprPhraseCollist(Fts5Expr *, int, const u8 **, int *);
/*******************************************
** The fts5_expr.c API above this point is used by the other hand-written
+5 -2
View File
@@ -137,7 +137,7 @@ static void fts5HighlightAppend(
const char *z, int n
){
if( *pRc==SQLITE_OK ){
if( n<0 ) n = strlen(z);
if( n<0 ) n = (int)strlen(z);
p->zOut = sqlite3_mprintf("%z%.*s", p->zOut, n, z);
if( p->zOut==0 ) *pRc = SQLITE_NOMEM;
}
@@ -158,6 +158,8 @@ static int fts5HighlightCb(
int rc = SQLITE_OK;
int iPos;
UNUSED_PARAM2(pToken, nToken);
if( tflags & FTS5_TOKEN_COLOCATED ) return SQLITE_OK;
iPos = p->iPos++;
@@ -391,6 +393,7 @@ static int fts5CountCb(
void *pUserData /* Pointer to sqlite3_int64 variable */
){
sqlite3_int64 *pn = (sqlite3_int64*)pUserData;
UNUSED_PARAM2(pApi, pFts);
(*pn)++;
return SQLITE_OK;
}
@@ -544,7 +547,7 @@ int sqlite3Fts5AuxInit(fts5_api *pApi){
int rc = SQLITE_OK; /* Return code */
int i; /* To iterate through builtin functions */
for(i=0; rc==SQLITE_OK && i<sizeof(aBuiltin)/sizeof(aBuiltin[0]); i++){
for(i=0; rc==SQLITE_OK && i<ArraySize(aBuiltin); i++){
rc = pApi->xCreateFunction(pApi,
aBuiltin[i].zFunc,
aBuiltin[i].pUserData,
+119 -33
View File
@@ -15,16 +15,11 @@
#include "fts5Int.h"
int sqlite3Fts5BufferGrow(int *pRc, Fts5Buffer *pBuf, int nByte){
if( (pBuf->n + nByte) > pBuf->nSpace ){
int sqlite3Fts5BufferSize(int *pRc, Fts5Buffer *pBuf, u32 nByte){
if( (u32)pBuf->nSpace<nByte ){
u32 nNew = pBuf->nSpace ? pBuf->nSpace : 64;
u8 *pNew;
int nNew = pBuf->nSpace ? pBuf->nSpace*2 : 64;
/* A no-op if an error has already occurred */
if( *pRc ) return 1;
while( nNew<(pBuf->n + nByte) ){
while( nNew<nByte ){
nNew = nNew * 2;
}
pNew = sqlite3_realloc(pBuf->p, nNew);
@@ -39,12 +34,13 @@ int sqlite3Fts5BufferGrow(int *pRc, Fts5Buffer *pBuf, int nByte){
return 0;
}
/*
** Encode value iVal as an SQLite varint and append it to the buffer object
** pBuf. If an OOM error occurs, set the error code in p.
*/
void sqlite3Fts5BufferAppendVarint(int *pRc, Fts5Buffer *pBuf, i64 iVal){
if( sqlite3Fts5BufferGrow(pRc, pBuf, 9) ) return;
if( fts5BufferGrow(pRc, pBuf, 9) ) return;
pBuf->n += sqlite3Fts5PutVarint(&pBuf->p[pBuf->n], iVal);
}
@@ -59,12 +55,6 @@ int sqlite3Fts5Get32(const u8 *aBuf){
return (aBuf[0] << 24) + (aBuf[1] << 16) + (aBuf[2] << 8) + aBuf[3];
}
void sqlite3Fts5BufferAppend32(int *pRc, Fts5Buffer *pBuf, int iVal){
if( sqlite3Fts5BufferGrow(pRc, pBuf, 4) ) return;
sqlite3Fts5Put32(&pBuf->p[pBuf->n], iVal);
pBuf->n += 4;
}
/*
** Append buffer nData/pData to buffer pBuf. If an OOM error occurs, set
** the error code in p. If an error has already occurred when this function
@@ -73,11 +63,11 @@ void sqlite3Fts5BufferAppend32(int *pRc, Fts5Buffer *pBuf, int iVal){
void sqlite3Fts5BufferAppendBlob(
int *pRc,
Fts5Buffer *pBuf,
int nData,
u32 nData,
const u8 *pData
){
assert( *pRc || nData>=0 );
if( sqlite3Fts5BufferGrow(pRc, pBuf, nData) ) return;
assert_nc( *pRc || nData>=0 );
if( fts5BufferGrow(pRc, pBuf, nData) ) return;
memcpy(&pBuf->p[pBuf->n], pData, nData);
pBuf->n += nData;
}
@@ -92,7 +82,7 @@ void sqlite3Fts5BufferAppendString(
Fts5Buffer *pBuf,
const char *zStr
){
int nStr = strlen(zStr);
int nStr = (int)strlen(zStr);
sqlite3Fts5BufferAppendBlob(pRc, pBuf, nStr+1, (const u8*)zStr);
pBuf->n--;
}
@@ -220,23 +210,36 @@ int sqlite3Fts5PoslistReaderInit(
return pIter->bEof;
}
/*
** Append position iPos to the position list being accumulated in buffer
** pBuf, which must be already be large enough to hold the new data.
** The previous position written to this list is *piPrev. *piPrev is set
** to iPos before returning.
*/
void sqlite3Fts5PoslistSafeAppend(
Fts5Buffer *pBuf,
i64 *piPrev,
i64 iPos
){
static const i64 colmask = ((i64)(0x7FFFFFFF)) << 32;
if( (iPos & colmask) != (*piPrev & colmask) ){
pBuf->p[pBuf->n++] = 1;
pBuf->n += sqlite3Fts5PutVarint(&pBuf->p[pBuf->n], (iPos>>32));
*piPrev = (iPos & colmask);
}
pBuf->n += sqlite3Fts5PutVarint(&pBuf->p[pBuf->n], (iPos-*piPrev)+2);
*piPrev = iPos;
}
int sqlite3Fts5PoslistWriterAppend(
Fts5Buffer *pBuf,
Fts5PoslistWriter *pWriter,
i64 iPos
){
static const i64 colmask = ((i64)(0x7FFFFFFF)) << 32;
int rc = SQLITE_OK;
if( 0==sqlite3Fts5BufferGrow(&rc, pBuf, 5+5+5) ){
if( (iPos & colmask) != (pWriter->iPrev & colmask) ){
pBuf->p[pBuf->n++] = 1;
pBuf->n += sqlite3Fts5PutVarint(&pBuf->p[pBuf->n], (iPos>>32));
pWriter->iPrev = (iPos & colmask);
}
pBuf->n += sqlite3Fts5PutVarint(&pBuf->p[pBuf->n], (iPos-pWriter->iPrev)+2);
pWriter->iPrev = iPos;
}
return rc;
int rc = 0; /* Initialized only to suppress erroneous warning from Clang */
if( fts5BufferGrow(&rc, pBuf, 5+5+5) ) return rc;
sqlite3Fts5PoslistSafeAppend(pBuf, &pWriter->iPrev, iPos);
return SQLITE_OK;
}
void *sqlite3Fts5MallocZero(int *pRc, int nByte){
@@ -264,7 +267,7 @@ char *sqlite3Fts5Strndup(int *pRc, const char *pIn, int nIn){
char *zRet = 0;
if( *pRc==SQLITE_OK ){
if( nIn<0 ){
nIn = strlen(pIn);
nIn = (int)strlen(pIn);
}
zRet = (char*)sqlite3_malloc(nIn+1);
if( zRet ){
@@ -304,3 +307,86 @@ int sqlite3Fts5IsBareword(char t){
}
/*************************************************************************
*/
typedef struct Fts5TermsetEntry Fts5TermsetEntry;
struct Fts5TermsetEntry {
char *pTerm;
int nTerm;
int iIdx; /* Index (main or aPrefix[] entry) */
Fts5TermsetEntry *pNext;
};
struct Fts5Termset {
Fts5TermsetEntry *apHash[512];
};
int sqlite3Fts5TermsetNew(Fts5Termset **pp){
int rc = SQLITE_OK;
*pp = sqlite3Fts5MallocZero(&rc, sizeof(Fts5Termset));
return rc;
}
int sqlite3Fts5TermsetAdd(
Fts5Termset *p,
int iIdx,
const char *pTerm, int nTerm,
int *pbPresent
){
int rc = SQLITE_OK;
*pbPresent = 0;
if( p ){
int i;
u32 hash = 13;
Fts5TermsetEntry *pEntry;
/* Calculate a hash value for this term. This is the same hash checksum
** used by the fts5_hash.c module. This is not important for correct
** operation of the module, but is necessary to ensure that some tests
** designed to produce hash table collisions really do work. */
for(i=nTerm-1; i>=0; i--){
hash = (hash << 3) ^ hash ^ pTerm[i];
}
hash = (hash << 3) ^ hash ^ iIdx;
hash = hash % ArraySize(p->apHash);
for(pEntry=p->apHash[hash]; pEntry; pEntry=pEntry->pNext){
if( pEntry->iIdx==iIdx
&& pEntry->nTerm==nTerm
&& memcmp(pEntry->pTerm, pTerm, nTerm)==0
){
*pbPresent = 1;
break;
}
}
if( pEntry==0 ){
pEntry = sqlite3Fts5MallocZero(&rc, sizeof(Fts5TermsetEntry) + nTerm);
if( pEntry ){
pEntry->pTerm = (char*)&pEntry[1];
pEntry->nTerm = nTerm;
pEntry->iIdx = iIdx;
memcpy(pEntry->pTerm, pTerm, nTerm);
pEntry->pNext = p->apHash[hash];
p->apHash[hash] = pEntry;
}
}
}
return rc;
}
void sqlite3Fts5TermsetFree(Fts5Termset *p){
if( p ){
u32 i;
for(i=0; i<ArraySize(p->apHash); i++){
Fts5TermsetEntry *pEntry = p->apHash[i];
while( pEntry ){
Fts5TermsetEntry *pDel = pEntry;
pEntry = pEntry->pNext;
sqlite3_free(pDel);
}
}
sqlite3_free(p);
}
}
+121 -44
View File
@@ -14,12 +14,12 @@
*/
#include "fts5Int.h"
#define FTS5_DEFAULT_PAGE_SIZE 4050
#define FTS5_DEFAULT_AUTOMERGE 4
#define FTS5_DEFAULT_CRISISMERGE 16
#define FTS5_DEFAULT_HASHSIZE (1024*1024)
/* Maximum allowed page size */
#define FTS5_MAX_PAGE_SIZE (128*1024)
@@ -194,6 +194,33 @@ void sqlite3Fts5Dequote(char *z){
}
}
struct Fts5Enum {
const char *zName;
int eVal;
};
typedef struct Fts5Enum Fts5Enum;
static int fts5ConfigSetEnum(
const Fts5Enum *aEnum,
const char *zEnum,
int *peVal
){
int nEnum = (int)strlen(zEnum);
int i;
int iVal = -1;
for(i=0; aEnum[i].zName; i++){
if( sqlite3_strnicmp(aEnum[i].zName, zEnum, nEnum)==0 ){
if( iVal>=0 ) return SQLITE_ERROR;
iVal = aEnum[i].eVal;
}
}
*peVal = iVal;
return iVal<0 ? SQLITE_ERROR : SQLITE_OK;
}
/*
** Parse a "special" CREATE VIRTUAL TABLE directive and update
** configuration object pConfig as appropriate.
@@ -211,44 +238,63 @@ static int fts5ConfigParseSpecial(
char **pzErr /* OUT: Error message */
){
int rc = SQLITE_OK;
int nCmd = strlen(zCmd);
int nCmd = (int)strlen(zCmd);
if( sqlite3_strnicmp("prefix", zCmd, nCmd)==0 ){
const int nByte = sizeof(int) * FTS5_MAX_PREFIX_INDEXES;
const char *p;
if( pConfig->aPrefix ){
*pzErr = sqlite3_mprintf("multiple prefix=... directives");
rc = SQLITE_ERROR;
}else{
int bFirst = 1;
if( pConfig->aPrefix==0 ){
pConfig->aPrefix = sqlite3Fts5MallocZero(&rc, nByte);
if( rc ) return rc;
}
p = zArg;
while( rc==SQLITE_OK && p[0] ){
while( 1 ){
int nPre = 0;
while( p[0]==' ' ) p++;
if( bFirst==0 && p[0]==',' ){
p++;
while( p[0]==' ' ) p++;
}else if( p[0]=='\0' ){
break;
}
if( p[0]<'0' || p[0]>'9' ){
*pzErr = sqlite3_mprintf("malformed prefix=... directive");
rc = SQLITE_ERROR;
break;
}
if( pConfig->nPrefix==FTS5_MAX_PREFIX_INDEXES ){
*pzErr = sqlite3_mprintf(
"too many prefix indexes (max %d)", FTS5_MAX_PREFIX_INDEXES
);
rc = SQLITE_ERROR;
break;
}
while( p[0]>='0' && p[0]<='9' && nPre<1000 ){
nPre = nPre*10 + (p[0] - '0');
p++;
}
while( p[0]==' ' ) p++;
if( p[0]==',' ){
p++;
}else if( p[0] ){
*pzErr = sqlite3_mprintf("malformed prefix=... directive");
rc = SQLITE_ERROR;
}
if( rc==SQLITE_OK && (nPre==0 || nPre>=1000) ){
*pzErr = sqlite3_mprintf("prefix length out of range: %d", nPre);
if( nPre<=0 || nPre>=1000 ){
*pzErr = sqlite3_mprintf("prefix length out of range (max 999)");
rc = SQLITE_ERROR;
break;
}
pConfig->aPrefix[pConfig->nPrefix] = nPre;
pConfig->nPrefix++;
bFirst = 0;
}
assert( pConfig->nPrefix<=FTS5_MAX_PREFIX_INDEXES );
return rc;
}
if( sqlite3_strnicmp("tokenize", zCmd, nCmd)==0 ){
const char *p = (const char*)zArg;
int nArg = strlen(zArg) + 1;
int nArg = (int)strlen(zArg) + 1;
char **azArg = sqlite3Fts5MallocZero(&rc, sizeof(char*) * nArg);
char *pDel = sqlite3Fts5MallocZero(&rc, nArg * 2);
char *pSpace = pDel;
@@ -325,6 +371,20 @@ static int fts5ConfigParseSpecial(
return rc;
}
if( sqlite3_strnicmp("detail", zCmd, nCmd)==0 ){
const Fts5Enum aDetail[] = {
{ "none", FTS5_DETAIL_NONE },
{ "full", FTS5_DETAIL_FULL },
{ "columns", FTS5_DETAIL_COLUMNS },
{ 0, 0 }
};
if( (rc = fts5ConfigSetEnum(aDetail, zArg, &pConfig->eDetail)) ){
*pzErr = sqlite3_mprintf("malformed detail=... directive");
}
return rc;
}
*pzErr = sqlite3_mprintf("unrecognized option: \"%.*s\"", nCmd, zCmd);
return SQLITE_ERROR;
}
@@ -364,7 +424,7 @@ static const char *fts5ConfigGobbleWord(
){
const char *zRet = 0;
int nIn = strlen(zIn);
int nIn = (int)strlen(zIn);
char *zOut = sqlite3_malloc(nIn+1);
assert( *pRc==SQLITE_OK );
@@ -480,6 +540,7 @@ int sqlite3Fts5ConfigParse(
pRet->zDb = sqlite3Fts5Strndup(&rc, azArg[1], -1);
pRet->zName = sqlite3Fts5Strndup(&rc, azArg[2], -1);
pRet->bColumnsize = 1;
pRet->eDetail = FTS5_DETAIL_FULL;
#ifdef SQLITE_DEBUG
pRet->bPrefixIndex = 1;
#endif
@@ -706,33 +767,37 @@ int sqlite3Fts5ConfigParseRank(
*pzRank = 0;
*pzRankArgs = 0;
p = fts5ConfigSkipWhitespace(p);
pRank = p;
p = fts5ConfigSkipBareword(p);
if( p ){
zRank = sqlite3Fts5MallocZero(&rc, 1 + p - pRank);
if( zRank ) memcpy(zRank, pRank, p-pRank);
}else{
if( p==0 ){
rc = SQLITE_ERROR;
}
}else{
p = fts5ConfigSkipWhitespace(p);
pRank = p;
p = fts5ConfigSkipBareword(p);
if( rc==SQLITE_OK ){
p = fts5ConfigSkipWhitespace(p);
if( *p!='(' ) rc = SQLITE_ERROR;
p++;
}
if( rc==SQLITE_OK ){
const char *pArgs;
p = fts5ConfigSkipWhitespace(p);
pArgs = p;
if( *p!=')' ){
p = fts5ConfigSkipArgs(p);
if( p==0 ){
rc = SQLITE_ERROR;
}else{
zRankArgs = sqlite3Fts5MallocZero(&rc, 1 + p - pArgs);
if( zRankArgs ) memcpy(zRankArgs, pArgs, p-pArgs);
if( p ){
zRank = sqlite3Fts5MallocZero(&rc, 1 + p - pRank);
if( zRank ) memcpy(zRank, pRank, p-pRank);
}else{
rc = SQLITE_ERROR;
}
if( rc==SQLITE_OK ){
p = fts5ConfigSkipWhitespace(p);
if( *p!='(' ) rc = SQLITE_ERROR;
p++;
}
if( rc==SQLITE_OK ){
const char *pArgs;
p = fts5ConfigSkipWhitespace(p);
pArgs = p;
if( *p!=')' ){
p = fts5ConfigSkipArgs(p);
if( p==0 ){
rc = SQLITE_ERROR;
}else{
zRankArgs = sqlite3Fts5MallocZero(&rc, 1 + p - pArgs);
if( zRankArgs ) memcpy(zRankArgs, pArgs, p-pArgs);
}
}
}
}
@@ -767,6 +832,18 @@ int sqlite3Fts5ConfigSetValue(
}
}
else if( 0==sqlite3_stricmp(zKey, "hashsize") ){
int nHashSize = -1;
if( SQLITE_INTEGER==sqlite3_value_numeric_type(pVal) ){
nHashSize = sqlite3_value_int(pVal);
}
if( nHashSize<=0 ){
*pbBadkey = 1;
}else{
pConfig->nHashSize = nHashSize;
}
}
else if( 0==sqlite3_stricmp(zKey, "automerge") ){
int nAutomerge = -1;
if( SQLITE_INTEGER==sqlite3_value_numeric_type(pVal) ){
@@ -827,6 +904,7 @@ int sqlite3Fts5ConfigLoad(Fts5Config *pConfig, int iCookie){
pConfig->pgsz = FTS5_DEFAULT_PAGE_SIZE;
pConfig->nAutomerge = FTS5_DEFAULT_AUTOMERGE;
pConfig->nCrisisMerge = FTS5_DEFAULT_CRISISMERGE;
pConfig->nHashSize = FTS5_DEFAULT_HASHSIZE;
zSql = sqlite3Fts5Mprintf(&rc, zSelect, pConfig->zDb, pConfig->zName);
if( zSql ){
@@ -865,4 +943,3 @@ int sqlite3Fts5ConfigLoad(Fts5Config *pConfig, int iCookie){
}
return rc;
}
+801 -477
View File
File diff suppressed because it is too large Load Diff
+118 -63
View File
@@ -26,6 +26,7 @@ typedef struct Fts5HashEntry Fts5HashEntry;
struct Fts5Hash {
int eDetail; /* Copy of Fts5Config.eDetail */
int *pnByte; /* Pointer to bytes counter */
int nEntry; /* Number of entries currently in hash */
int nSlot; /* Size of aSlot[] array */
@@ -61,9 +62,10 @@ struct Fts5HashEntry {
int nAlloc; /* Total size of allocation */
int iSzPoslist; /* Offset of space for 4-byte poslist size */
int nData; /* Total bytes of data (incl. structure) */
int nKey; /* Length of zKey[] in bytes */
u8 bDel; /* Set delete-flag @ iSzPoslist */
int iCol; /* Column of last value written */
u8 bContent; /* Set content-flag (detail=none mode) */
i16 iCol; /* Column of last value written */
int iPos; /* Position of last value written */
i64 iRowid; /* Rowid of last value written */
char zKey[8]; /* Nul-terminated entry key */
@@ -79,7 +81,7 @@ struct Fts5HashEntry {
/*
** Allocate a new hash table.
*/
int sqlite3Fts5HashNew(Fts5Hash **ppNew, int *pnByte){
int sqlite3Fts5HashNew(Fts5Config *pConfig, Fts5Hash **ppNew, int *pnByte){
int rc = SQLITE_OK;
Fts5Hash *pNew;
@@ -90,6 +92,7 @@ int sqlite3Fts5HashNew(Fts5Hash **ppNew, int *pnByte){
int nByte;
memset(pNew, 0, sizeof(Fts5Hash));
pNew->pnByte = pnByte;
pNew->eDetail = pConfig->eDetail;
pNew->nSlot = 1024;
nByte = sizeof(Fts5HashEntry*) * pNew->nSlot;
@@ -170,7 +173,7 @@ static int fts5HashResize(Fts5Hash *pHash){
int iHash;
Fts5HashEntry *p = apOld[i];
apOld[i] = p->pHashNext;
iHash = fts5HashKey(nNew, (u8*)p->zKey, strlen(p->zKey));
iHash = fts5HashKey(nNew, (u8*)p->zKey, (int)strlen(p->zKey));
p->pHashNext = apNew[iHash];
apNew[iHash] = p;
}
@@ -182,26 +185,46 @@ static int fts5HashResize(Fts5Hash *pHash){
return SQLITE_OK;
}
static void fts5HashAddPoslistSize(Fts5HashEntry *p){
static void fts5HashAddPoslistSize(Fts5Hash *pHash, Fts5HashEntry *p){
if( p->iSzPoslist ){
u8 *pPtr = (u8*)p;
int nSz = (p->nData - p->iSzPoslist - 1); /* Size in bytes */
int nPos = nSz*2 + p->bDel; /* Value of nPos field */
assert( p->bDel==0 || p->bDel==1 );
if( nPos<=127 ){
pPtr[p->iSzPoslist] = nPos;
if( pHash->eDetail==FTS5_DETAIL_NONE ){
assert( p->nData==p->iSzPoslist );
if( p->bDel ){
pPtr[p->nData++] = 0x00;
if( p->bContent ){
pPtr[p->nData++] = 0x00;
}
}
}else{
int nByte = sqlite3Fts5GetVarintLen((u32)nPos);
memmove(&pPtr[p->iSzPoslist + nByte], &pPtr[p->iSzPoslist + 1], nSz);
sqlite3Fts5PutVarint(&pPtr[p->iSzPoslist], nPos);
p->nData += (nByte-1);
int nSz = (p->nData - p->iSzPoslist - 1); /* Size in bytes */
int nPos = nSz*2 + p->bDel; /* Value of nPos field */
assert( p->bDel==0 || p->bDel==1 );
if( nPos<=127 ){
pPtr[p->iSzPoslist] = (u8)nPos;
}else{
int nByte = sqlite3Fts5GetVarintLen((u32)nPos);
memmove(&pPtr[p->iSzPoslist + nByte], &pPtr[p->iSzPoslist + 1], nSz);
sqlite3Fts5PutVarint(&pPtr[p->iSzPoslist], nPos);
p->nData += (nByte-1);
}
}
p->bDel = 0;
p->iSzPoslist = 0;
p->bDel = 0;
p->bContent = 0;
}
}
/*
** Add an entry to the in-memory hash table. The key is the concatenation
** of bByte and (pToken/nToken). The value is (iRowid/iCol/iPos).
**
** (bByte || pToken) -> (iRowid,iCol,iPos)
**
** Or, if iCol is negative, then the value is a delete marker.
*/
int sqlite3Fts5HashWrite(
Fts5Hash *pHash,
i64 iRowid, /* Rowid for this entry */
@@ -214,13 +237,16 @@ int sqlite3Fts5HashWrite(
Fts5HashEntry *p;
u8 *pPtr;
int nIncr = 0; /* Amount to increment (*pHash->pnByte) by */
int bNew; /* If non-delete entry should be written */
bNew = (pHash->eDetail==FTS5_DETAIL_FULL);
/* Attempt to locate an existing hash entry */
iHash = fts5HashKey2(pHash->nSlot, (u8)bByte, (const u8*)pToken, nToken);
for(p=pHash->aSlot[iHash]; p; p=p->pHashNext){
if( p->zKey[0]==bByte
&& p->nKey==nToken
&& memcmp(&p->zKey[1], pToken, nToken)==0
&& p->zKey[nToken+1]==0
){
break;
}
@@ -228,15 +254,18 @@ int sqlite3Fts5HashWrite(
/* If an existing hash entry cannot be found, create a new one. */
if( p==0 ){
/* Figure out how much space to allocate */
int nByte = FTS5_HASHENTRYSIZE + (nToken+1) + 1 + 64;
if( nByte<128 ) nByte = 128;
/* Grow the Fts5Hash.aSlot[] array if necessary. */
if( (pHash->nEntry*2)>=pHash->nSlot ){
int rc = fts5HashResize(pHash);
if( rc!=SQLITE_OK ) return rc;
iHash = fts5HashKey2(pHash->nSlot, (u8)bByte, (const u8*)pToken, nToken);
}
/* Allocate new Fts5HashEntry and add it to the hash table. */
p = (Fts5HashEntry*)sqlite3_malloc(nByte);
if( !p ) return SQLITE_NOMEM;
memset(p, 0, FTS5_HASHENTRYSIZE);
@@ -244,72 +273,98 @@ int sqlite3Fts5HashWrite(
p->zKey[0] = bByte;
memcpy(&p->zKey[1], pToken, nToken);
assert( iHash==fts5HashKey(pHash->nSlot, (u8*)p->zKey, nToken+1) );
p->nKey = nToken;
p->zKey[nToken+1] = '\0';
p->nData = nToken+1 + 1 + FTS5_HASHENTRYSIZE;
p->nData += sqlite3Fts5PutVarint(&((u8*)p)[p->nData], iRowid);
p->iSzPoslist = p->nData;
p->nData += 1;
p->iRowid = iRowid;
p->pHashNext = pHash->aSlot[iHash];
pHash->aSlot[iHash] = p;
pHash->nEntry++;
nIncr += p->nData;
}
/* Check there is enough space to append a new entry. Worst case scenario
** is:
**
** + 9 bytes for a new rowid,
** + 4 byte reserved for the "poslist size" varint.
** + 1 byte for a "new column" byte,
** + 3 bytes for a new column number (16-bit max) as a varint,
** + 5 bytes for the new position offset (32-bit max).
*/
if( (p->nAlloc - p->nData) < (9 + 4 + 1 + 3 + 5) ){
int nNew = p->nAlloc * 2;
Fts5HashEntry *pNew;
Fts5HashEntry **pp;
pNew = (Fts5HashEntry*)sqlite3_realloc(p, nNew);
if( pNew==0 ) return SQLITE_NOMEM;
pNew->nAlloc = nNew;
for(pp=&pHash->aSlot[iHash]; *pp!=p; pp=&(*pp)->pHashNext);
*pp = pNew;
p = pNew;
/* Add the first rowid field to the hash-entry */
p->nData += sqlite3Fts5PutVarint(&((u8*)p)[p->nData], iRowid);
p->iRowid = iRowid;
p->iSzPoslist = p->nData;
if( pHash->eDetail!=FTS5_DETAIL_NONE ){
p->nData += 1;
p->iCol = (pHash->eDetail==FTS5_DETAIL_FULL ? 0 : -1);
}
nIncr += p->nData;
}else{
/* Appending to an existing hash-entry. Check that there is enough
** space to append the largest possible new entry. Worst case scenario
** is:
**
** + 9 bytes for a new rowid,
** + 4 byte reserved for the "poslist size" varint.
** + 1 byte for a "new column" byte,
** + 3 bytes for a new column number (16-bit max) as a varint,
** + 5 bytes for the new position offset (32-bit max).
*/
if( (p->nAlloc - p->nData) < (9 + 4 + 1 + 3 + 5) ){
int nNew = p->nAlloc * 2;
Fts5HashEntry *pNew;
Fts5HashEntry **pp;
pNew = (Fts5HashEntry*)sqlite3_realloc(p, nNew);
if( pNew==0 ) return SQLITE_NOMEM;
pNew->nAlloc = nNew;
for(pp=&pHash->aSlot[iHash]; *pp!=p; pp=&(*pp)->pHashNext);
*pp = pNew;
p = pNew;
}
nIncr -= p->nData;
}
assert( (p->nAlloc - p->nData) >= (9 + 4 + 1 + 3 + 5) );
pPtr = (u8*)p;
nIncr -= p->nData;
/* If this is a new rowid, append the 4-byte size field for the previous
** entry, and the new rowid for this entry. */
if( iRowid!=p->iRowid ){
fts5HashAddPoslistSize(p);
fts5HashAddPoslistSize(pHash, p);
p->nData += sqlite3Fts5PutVarint(&pPtr[p->nData], iRowid - p->iRowid);
p->iSzPoslist = p->nData;
p->nData += 1;
p->iCol = 0;
p->iPos = 0;
p->iRowid = iRowid;
bNew = 1;
p->iSzPoslist = p->nData;
if( pHash->eDetail!=FTS5_DETAIL_NONE ){
p->nData += 1;
p->iCol = (pHash->eDetail==FTS5_DETAIL_FULL ? 0 : -1);
p->iPos = 0;
}
}
if( iCol>=0 ){
/* Append a new column value, if necessary */
assert( iCol>=p->iCol );
if( iCol!=p->iCol ){
pPtr[p->nData++] = 0x01;
p->nData += sqlite3Fts5PutVarint(&pPtr[p->nData], iCol);
p->iCol = iCol;
p->iPos = 0;
}
if( pHash->eDetail==FTS5_DETAIL_NONE ){
p->bContent = 1;
}else{
/* Append a new column value, if necessary */
assert( iCol>=p->iCol );
if( iCol!=p->iCol ){
if( pHash->eDetail==FTS5_DETAIL_FULL ){
pPtr[p->nData++] = 0x01;
p->nData += sqlite3Fts5PutVarint(&pPtr[p->nData], iCol);
p->iCol = iCol;
p->iPos = 0;
}else{
bNew = 1;
p->iCol = iPos = iCol;
}
}
/* Append the new position offset */
p->nData += sqlite3Fts5PutVarint(&pPtr[p->nData], iPos - p->iPos + 2);
p->iPos = iPos;
/* Append the new position offset, if necessary */
if( bNew ){
p->nData += sqlite3Fts5PutVarint(&pPtr[p->nData], iPos - p->iPos + 2);
p->iPos = iPos;
}
}
}else{
/* This is a delete. Set the delete flag. */
p->bDel = 1;
}
nIncr += p->nData;
nIncr += p->nData;
*pHash->pnByte += nIncr;
return SQLITE_OK;
}
@@ -423,7 +478,7 @@ int sqlite3Fts5HashQuery(
}
if( p ){
fts5HashAddPoslistSize(p);
fts5HashAddPoslistSize(pHash, p);
*ppDoclist = (const u8*)&p->zKey[nTerm+1];
*pnDoclist = p->nData - (FTS5_HASHENTRYSIZE + nTerm + 1);
}else{
@@ -458,8 +513,8 @@ void sqlite3Fts5HashScanEntry(
){
Fts5HashEntry *p;
if( (p = pHash->pScan) ){
int nTerm = strlen(p->zKey);
fts5HashAddPoslistSize(p);
int nTerm = (int)strlen(p->zKey);
fts5HashAddPoslistSize(pHash, p);
*pzTerm = p->zKey;
*ppDoclist = (const u8*)&p->zKey[nTerm+1];
*pnDoclist = p->nData - (FTS5_HASHENTRYSIZE + nTerm + 1);
+1451 -897
View File
File diff suppressed because it is too large Load Diff
+352 -131
View File
@@ -220,12 +220,13 @@ struct Fts5Cursor {
/*
** Values for Fts5Cursor.csrflags
*/
#define FTS5CSR_REQUIRE_CONTENT 0x01
#define FTS5CSR_REQUIRE_DOCSIZE 0x02
#define FTS5CSR_REQUIRE_INST 0x04
#define FTS5CSR_EOF 0x08
#define FTS5CSR_EOF 0x01
#define FTS5CSR_REQUIRE_CONTENT 0x02
#define FTS5CSR_REQUIRE_DOCSIZE 0x04
#define FTS5CSR_REQUIRE_INST 0x08
#define FTS5CSR_FREE_ZRANK 0x10
#define FTS5CSR_REQUIRE_RESEEK 0x20
#define FTS5CSR_REQUIRE_POSLIST 0x40
#define BitFlagAllTest(x,y) (((x) & (y))==(y))
#define BitFlagTest(x,y) (((x) & (y))!=0)
@@ -395,6 +396,15 @@ static int fts5InitVtab(
rc = sqlite3Fts5ConfigDeclareVtab(pConfig);
}
/* Load the initial configuration */
if( rc==SQLITE_OK ){
assert( pConfig->pzErrmsg==0 );
pConfig->pzErrmsg = pzErr;
rc = sqlite3Fts5IndexLoadConfig(pTab->pIndex);
sqlite3Fts5IndexRollback(pTab->pIndex);
pConfig->pzErrmsg = 0;
}
if( rc!=SQLITE_OK ){
fts5FreeVtab(pTab);
pTab = 0;
@@ -447,7 +457,10 @@ static int fts5CreateMethod(
*/
static void fts5SetUniqueFlag(sqlite3_index_info *pIdxInfo){
#if SQLITE_VERSION_NUMBER>=3008012
if( sqlite3_libversion_number()>=3008012 ){
#ifndef SQLITE_CORE
if( sqlite3_libversion_number()>=3008012 )
#endif
{
pIdxInfo->idxFlags |= SQLITE_INDEX_SCAN_UNIQUE;
}
#endif
@@ -525,7 +538,7 @@ static int fts5BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){
for(i=0; i<pInfo->nConstraint; i++){
struct sqlite3_index_constraint *p = &pInfo->aConstraint[i];
int j;
for(j=0; j<sizeof(aConstraint)/sizeof(aConstraint[0]); j++){
for(j=0; j<ArraySize(aConstraint); j++){
struct Constraint *pC = &aConstraint[j];
if( p->iColumn==aColMap[pC->iCol] && p->op & pC->op ){
if( p->usable ){
@@ -572,11 +585,11 @@ static int fts5BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){
/* Assign argvIndex values to each constraint in use. */
iNext = 1;
for(i=0; i<sizeof(aConstraint)/sizeof(aConstraint[0]); i++){
for(i=0; i<ArraySize(aConstraint); i++){
struct Constraint *pC = &aConstraint[i];
if( pC->iConsIndex>=0 ){
pInfo->aConstraintUsage[pC->iConsIndex].argvIndex = iNext++;
pInfo->aConstraintUsage[pC->iConsIndex].omit = pC->omit;
pInfo->aConstraintUsage[pC->iConsIndex].omit = (unsigned char)pC->omit;
}
}
@@ -627,6 +640,7 @@ static void fts5CsrNewrow(Fts5Cursor *pCsr){
FTS5CSR_REQUIRE_CONTENT
| FTS5CSR_REQUIRE_DOCSIZE
| FTS5CSR_REQUIRE_INST
| FTS5CSR_REQUIRE_POSLIST
);
}
@@ -709,15 +723,18 @@ static int fts5SorterNext(Fts5Cursor *pCsr){
nBlob = sqlite3_column_bytes(pSorter->pStmt, 1);
aBlob = a = sqlite3_column_blob(pSorter->pStmt, 1);
for(i=0; i<(pSorter->nIdx-1); i++){
int iVal;
a += fts5GetVarint32(a, iVal);
iOff += iVal;
pSorter->aIdx[i] = iOff;
/* nBlob==0 in detail=none mode. */
if( nBlob>0 ){
for(i=0; i<(pSorter->nIdx-1); i++){
int iVal;
a += fts5GetVarint32(a, iVal);
iOff += iVal;
pSorter->aIdx[i] = iOff;
}
pSorter->aIdx[i] = &aBlob[nBlob] - a;
pSorter->aPoslist = a;
}
pSorter->aIdx[i] = &aBlob[nBlob] - a;
pSorter->aPoslist = a;
fts5CsrNewrow(pCsr);
}
@@ -761,7 +778,7 @@ static int fts5CursorReseek(Fts5Cursor *pCsr, int *pbSkip){
i64 iRowid = sqlite3Fts5ExprRowid(pCsr->pExpr);
rc = sqlite3Fts5ExprFirst(pCsr->pExpr, pTab->pIndex, iRowid, bDesc);
if( rc==SQLITE_OK && iRowid!=sqlite3Fts5ExprRowid(pCsr->pExpr) ){
if( rc==SQLITE_OK && iRowid!=sqlite3Fts5ExprRowid(pCsr->pExpr) ){
*pbSkip = 1;
}
@@ -769,6 +786,7 @@ static int fts5CursorReseek(Fts5Cursor *pCsr, int *pbSkip){
fts5CsrNewrow(pCsr);
if( sqlite3Fts5ExprEof(pCsr->pExpr) ){
CsrFlagSet(pCsr, FTS5CSR_EOF);
*pbSkip = 1;
}
}
return rc;
@@ -785,24 +803,24 @@ static int fts5CursorReseek(Fts5Cursor *pCsr, int *pbSkip){
*/
static int fts5NextMethod(sqlite3_vtab_cursor *pCursor){
Fts5Cursor *pCsr = (Fts5Cursor*)pCursor;
int rc = SQLITE_OK;
int rc;
assert( (pCsr->ePlan<3)==
(pCsr->ePlan==FTS5_PLAN_MATCH || pCsr->ePlan==FTS5_PLAN_SOURCE)
);
assert( !CsrFlagTest(pCsr, FTS5CSR_EOF) );
if( pCsr->ePlan<3 ){
int bSkip = 0;
if( (rc = fts5CursorReseek(pCsr, &bSkip)) || bSkip ) return rc;
rc = sqlite3Fts5ExprNext(pCsr->pExpr, pCsr->iLastRowid);
if( sqlite3Fts5ExprEof(pCsr->pExpr) ){
CsrFlagSet(pCsr, FTS5CSR_EOF);
}
CsrFlagSet(pCsr, sqlite3Fts5ExprEof(pCsr->pExpr));
fts5CsrNewrow(pCsr);
}else{
switch( pCsr->ePlan ){
case FTS5_PLAN_SPECIAL: {
CsrFlagSet(pCsr, FTS5CSR_EOF);
rc = SQLITE_OK;
break;
}
@@ -826,13 +844,41 @@ static int fts5NextMethod(sqlite3_vtab_cursor *pCursor){
return rc;
}
static int fts5PrepareStatement(
sqlite3_stmt **ppStmt,
Fts5Config *pConfig,
const char *zFmt,
...
){
sqlite3_stmt *pRet = 0;
int rc;
char *zSql;
va_list ap;
va_start(ap, zFmt);
zSql = sqlite3_vmprintf(zFmt, ap);
if( zSql==0 ){
rc = SQLITE_NOMEM;
}else{
rc = sqlite3_prepare_v2(pConfig->db, zSql, -1, &pRet, 0);
if( rc!=SQLITE_OK ){
*pConfig->pzErrmsg = sqlite3_mprintf("%s", sqlite3_errmsg(pConfig->db));
}
sqlite3_free(zSql);
}
va_end(ap);
*ppStmt = pRet;
return rc;
}
static int fts5CursorFirstSorted(Fts5Table *pTab, Fts5Cursor *pCsr, int bDesc){
Fts5Config *pConfig = pTab->pConfig;
Fts5Sorter *pSorter;
int nPhrase;
int nByte;
int rc = SQLITE_OK;
char *zSql;
int rc;
const char *zRank = pCsr->zRank;
const char *zRankArgs = pCsr->zRankArgs;
@@ -850,17 +896,13 @@ static int fts5CursorFirstSorted(Fts5Table *pTab, Fts5Cursor *pCsr, int bDesc){
** table, saving it creates a circular reference.
**
** If SQLite a built-in statement cache, this wouldn't be a problem. */
zSql = sqlite3Fts5Mprintf(&rc,
rc = fts5PrepareStatement(&pSorter->pStmt, pConfig,
"SELECT rowid, rank FROM %Q.%Q ORDER BY %s(%s%s%s) %s",
pConfig->zDb, pConfig->zName, zRank, pConfig->zName,
(zRankArgs ? ", " : ""),
(zRankArgs ? zRankArgs : ""),
bDesc ? "DESC" : "ASC"
);
if( zSql ){
rc = sqlite3_prepare_v2(pConfig->db, zSql, -1, &pSorter->pStmt, 0);
sqlite3_free(zSql);
}
pCsr->pSorter = pSorter;
if( rc==SQLITE_OK ){
@@ -1054,7 +1096,7 @@ static i64 fts5GetRowidLimit(sqlite3_value *pVal, i64 iDefault){
static int fts5FilterMethod(
sqlite3_vtab_cursor *pCursor, /* The cursor used for this query */
int idxNum, /* Strategy index */
const char *idxStr, /* Unused */
const char *zUnused, /* Unused */
int nVal, /* Number of elements in apVal */
sqlite3_value **apVal /* Arguments for the indexing scheme */
){
@@ -1072,6 +1114,9 @@ static int fts5FilterMethod(
sqlite3_value *pRowidGe = 0; /* rowid >= ? expression (or NULL) */
char **pzErrmsg = pConfig->pzErrmsg;
UNUSED_PARAM(zUnused);
UNUSED_PARAM(nVal);
if( pCsr->ePlan ){
fts5FreeCursorComponents(pCsr);
memset(&pCsr->ePlan, 0, sizeof(Fts5Cursor) - ((u8*)&pCsr->ePlan-(u8*)pCsr));
@@ -1130,6 +1175,7 @@ static int fts5FilterMethod(
pCsr->ePlan = FTS5_PLAN_SOURCE;
pCsr->pExpr = pTab->pSortCsr->pExpr;
rc = fts5CursorFirst(pTab, pCsr, bDesc);
sqlite3Fts5ExprClearEof(pCsr->pExpr);
}else if( pMatch ){
const char *zExpr = (const char*)sqlite3_value_text(apVal[0]);
if( zExpr==0 ) zExpr = "";
@@ -1355,14 +1401,13 @@ static int fts5SpecialInsert(
static int fts5SpecialDelete(
Fts5Table *pTab,
sqlite3_value **apVal,
sqlite3_int64 *piRowid
sqlite3_value **apVal
){
int rc = SQLITE_OK;
int eType1 = sqlite3_value_type(apVal[1]);
if( eType1==SQLITE_INTEGER ){
sqlite3_int64 iDel = sqlite3_value_int64(apVal[1]);
rc = sqlite3Fts5StorageSpecialDelete(pTab->pStorage, iDel, &apVal[2]);
rc = sqlite3Fts5StorageDelete(pTab->pStorage, iDel, &apVal[2]);
}
return rc;
}
@@ -1432,7 +1477,7 @@ static int fts5UpdateMethod(
if( pConfig->eContent!=FTS5_CONTENT_NORMAL
&& 0==sqlite3_stricmp("delete", z)
){
rc = fts5SpecialDelete(pTab, apVal, pRowid);
rc = fts5SpecialDelete(pTab, apVal);
}else{
rc = fts5SpecialInsert(pTab, z, apVal[2 + pConfig->nCol + 1]);
}
@@ -1448,7 +1493,10 @@ static int fts5UpdateMethod(
**
** Cases 3 and 4 may violate the rowid constraint.
*/
int eConflict = sqlite3_vtab_on_conflict(pConfig->db);
int eConflict = SQLITE_ABORT;
if( pConfig->eContent==FTS5_CONTENT_NORMAL ){
eConflict = sqlite3_vtab_on_conflict(pConfig->db);
}
assert( eType0==SQLITE_INTEGER || eType0==SQLITE_NULL );
assert( nArg!=1 || eType0==SQLITE_INTEGER );
@@ -1466,7 +1514,7 @@ static int fts5UpdateMethod(
/* Case 1: DELETE */
else if( nArg==1 ){
i64 iDel = sqlite3_value_int64(apVal[0]); /* Rowid to delete */
rc = sqlite3Fts5StorageDelete(pTab->pStorage, iDel);
rc = sqlite3Fts5StorageDelete(pTab->pStorage, iDel, 0);
}
/* Case 2: INSERT */
@@ -1476,7 +1524,7 @@ static int fts5UpdateMethod(
&& sqlite3_value_type(apVal[1])==SQLITE_INTEGER
){
i64 iNew = sqlite3_value_int64(apVal[1]); /* Rowid to delete */
rc = sqlite3Fts5StorageDelete(pTab->pStorage, iNew);
rc = sqlite3Fts5StorageDelete(pTab->pStorage, iNew, 0);
}
fts5StorageInsert(&rc, pTab, apVal, pRowid);
}
@@ -1487,22 +1535,22 @@ static int fts5UpdateMethod(
i64 iNew = sqlite3_value_int64(apVal[1]); /* New rowid */
if( iOld!=iNew ){
if( eConflict==SQLITE_REPLACE ){
rc = sqlite3Fts5StorageDelete(pTab->pStorage, iOld);
rc = sqlite3Fts5StorageDelete(pTab->pStorage, iOld, 0);
if( rc==SQLITE_OK ){
rc = sqlite3Fts5StorageDelete(pTab->pStorage, iNew);
rc = sqlite3Fts5StorageDelete(pTab->pStorage, iNew, 0);
}
fts5StorageInsert(&rc, pTab, apVal, pRowid);
}else{
rc = sqlite3Fts5StorageContentInsert(pTab->pStorage, apVal, pRowid);
if( rc==SQLITE_OK ){
rc = sqlite3Fts5StorageDelete(pTab->pStorage, iOld);
rc = sqlite3Fts5StorageDelete(pTab->pStorage, iOld, 0);
}
if( rc==SQLITE_OK ){
rc = sqlite3Fts5StorageIndexInsert(pTab->pStorage, apVal, *pRowid);
}
}
}else{
rc = sqlite3Fts5StorageDelete(pTab->pStorage, iOld);
rc = sqlite3Fts5StorageDelete(pTab->pStorage, iOld, 0);
fts5StorageInsert(&rc, pTab, apVal, pRowid);
}
}
@@ -1530,6 +1578,7 @@ static int fts5SyncMethod(sqlite3_vtab *pVtab){
** Implementation of xBegin() method.
*/
static int fts5BeginMethod(sqlite3_vtab *pVtab){
UNUSED_PARAM(pVtab); /* Call below is a no-op for NDEBUG builds */
fts5CheckTransactionState((Fts5Table*)pVtab, FTS5_BEGIN, 0);
return SQLITE_OK;
}
@@ -1540,6 +1589,7 @@ static int fts5BeginMethod(sqlite3_vtab *pVtab){
** by fts5SyncMethod().
*/
static int fts5CommitMethod(sqlite3_vtab *pVtab){
UNUSED_PARAM(pVtab); /* Call below is a no-op for NDEBUG builds */
fts5CheckTransactionState((Fts5Table*)pVtab, FTS5_COMMIT, 0);
return SQLITE_OK;
}
@@ -1556,6 +1606,8 @@ static int fts5RollbackMethod(sqlite3_vtab *pVtab){
return rc;
}
static int fts5CsrPoslist(Fts5Cursor*, int, const u8**, int*);
static void *fts5ApiUserData(Fts5Context *pCtx){
Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
return pCsr->pAux->pUserData;
@@ -1605,17 +1657,72 @@ static int fts5ApiPhraseSize(Fts5Context *pCtx, int iPhrase){
return sqlite3Fts5ExprPhraseSize(pCsr->pExpr, iPhrase);
}
static int fts5CsrPoslist(Fts5Cursor *pCsr, int iPhrase, const u8 **pa){
int n;
if( pCsr->pSorter ){
static int fts5ApiColumnText(
Fts5Context *pCtx,
int iCol,
const char **pz,
int *pn
){
int rc = SQLITE_OK;
Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
if( fts5IsContentless((Fts5Table*)(pCsr->base.pVtab)) ){
*pz = 0;
*pn = 0;
}else{
rc = fts5SeekCursor(pCsr, 0);
if( rc==SQLITE_OK ){
*pz = (const char*)sqlite3_column_text(pCsr->pStmt, iCol+1);
*pn = sqlite3_column_bytes(pCsr->pStmt, iCol+1);
}
}
return rc;
}
static int fts5CsrPoslist(
Fts5Cursor *pCsr,
int iPhrase,
const u8 **pa,
int *pn
){
Fts5Config *pConfig = ((Fts5Table*)(pCsr->base.pVtab))->pConfig;
int rc = SQLITE_OK;
int bLive = (pCsr->pSorter==0);
if( CsrFlagTest(pCsr, FTS5CSR_REQUIRE_POSLIST) ){
if( pConfig->eDetail!=FTS5_DETAIL_FULL ){
Fts5PoslistPopulator *aPopulator;
int i;
aPopulator = sqlite3Fts5ExprClearPoslists(pCsr->pExpr, bLive);
if( aPopulator==0 ) rc = SQLITE_NOMEM;
for(i=0; i<pConfig->nCol && rc==SQLITE_OK; i++){
int n; const char *z;
rc = fts5ApiColumnText((Fts5Context*)pCsr, i, &z, &n);
if( rc==SQLITE_OK ){
rc = sqlite3Fts5ExprPopulatePoslists(
pConfig, pCsr->pExpr, aPopulator, i, z, n
);
}
}
sqlite3_free(aPopulator);
if( pCsr->pSorter ){
sqlite3Fts5ExprCheckPoslists(pCsr->pExpr, pCsr->pSorter->iRowid);
}
}
CsrFlagClear(pCsr, FTS5CSR_REQUIRE_POSLIST);
}
if( pCsr->pSorter && pConfig->eDetail==FTS5_DETAIL_FULL ){
Fts5Sorter *pSorter = pCsr->pSorter;
int i1 = (iPhrase==0 ? 0 : pSorter->aIdx[iPhrase-1]);
n = pSorter->aIdx[iPhrase] - i1;
*pn = pSorter->aIdx[iPhrase] - i1;
*pa = &pSorter->aPoslist[i1];
}else{
n = sqlite3Fts5ExprPoslist(pCsr->pExpr, iPhrase, pa);
*pn = sqlite3Fts5ExprPoslist(pCsr->pExpr, iPhrase, pa);
}
return n;
return rc;
}
/*
@@ -1640,43 +1747,48 @@ static int fts5CacheInstArray(Fts5Cursor *pCsr){
int i;
/* Initialize all iterators */
for(i=0; i<nIter; i++){
for(i=0; i<nIter && rc==SQLITE_OK; i++){
const u8 *a;
int n = fts5CsrPoslist(pCsr, i, &a);
sqlite3Fts5PoslistReaderInit(a, n, &aIter[i]);
int n;
rc = fts5CsrPoslist(pCsr, i, &a, &n);
if( rc==SQLITE_OK ){
sqlite3Fts5PoslistReaderInit(a, n, &aIter[i]);
}
}
while( 1 ){
int *aInst;
int iBest = -1;
for(i=0; i<nIter; i++){
if( (aIter[i].bEof==0)
&& (iBest<0 || aIter[i].iPos<aIter[iBest].iPos)
){
iBest = i;
if( rc==SQLITE_OK ){
while( 1 ){
int *aInst;
int iBest = -1;
for(i=0; i<nIter; i++){
if( (aIter[i].bEof==0)
&& (iBest<0 || aIter[i].iPos<aIter[iBest].iPos)
){
iBest = i;
}
}
}
if( iBest<0 ) break;
if( iBest<0 ) break;
nInst++;
if( nInst>=pCsr->nInstAlloc ){
pCsr->nInstAlloc = pCsr->nInstAlloc ? pCsr->nInstAlloc*2 : 32;
aInst = (int*)sqlite3_realloc(
pCsr->aInst, pCsr->nInstAlloc*sizeof(int)*3
);
if( aInst ){
pCsr->aInst = aInst;
}else{
rc = SQLITE_NOMEM;
break;
nInst++;
if( nInst>=pCsr->nInstAlloc ){
pCsr->nInstAlloc = pCsr->nInstAlloc ? pCsr->nInstAlloc*2 : 32;
aInst = (int*)sqlite3_realloc(
pCsr->aInst, pCsr->nInstAlloc*sizeof(int)*3
);
if( aInst ){
pCsr->aInst = aInst;
}else{
rc = SQLITE_NOMEM;
break;
}
}
}
aInst = &pCsr->aInst[3 * (nInst-1)];
aInst[0] = iBest;
aInst[1] = FTS5_POS2COLUMN(aIter[iBest].iPos);
aInst[2] = FTS5_POS2OFFSET(aIter[iBest].iPos);
sqlite3Fts5PoslistReaderNext(&aIter[iBest]);
aInst = &pCsr->aInst[3 * (nInst-1)];
aInst[0] = iBest;
aInst[1] = FTS5_POS2COLUMN(aIter[iBest].iPos);
aInst[2] = FTS5_POS2OFFSET(aIter[iBest].iPos);
sqlite3Fts5PoslistReaderNext(&aIter[iBest]);
}
}
pCsr->nInstCount = nInst;
@@ -1709,6 +1821,12 @@ static int fts5ApiInst(
){
if( iIdx<0 || iIdx>=pCsr->nInstCount ){
rc = SQLITE_RANGE;
#if 0
}else if( fts5IsOffsetless((Fts5Table*)pCsr->base.pVtab) ){
*piPhrase = pCsr->aInst[iIdx*3];
*piCol = pCsr->aInst[iIdx*3 + 2];
*piOff = -1;
#endif
}else{
*piPhrase = pCsr->aInst[iIdx*3];
*piCol = pCsr->aInst[iIdx*3 + 1];
@@ -1722,36 +1840,17 @@ static sqlite3_int64 fts5ApiRowid(Fts5Context *pCtx){
return fts5CursorRowid((Fts5Cursor*)pCtx);
}
static int fts5ApiColumnText(
Fts5Context *pCtx,
int iCol,
const char **pz,
int *pn
){
int rc = SQLITE_OK;
Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
if( fts5IsContentless((Fts5Table*)(pCsr->base.pVtab)) ){
*pz = 0;
*pn = 0;
}else{
rc = fts5SeekCursor(pCsr, 0);
if( rc==SQLITE_OK ){
*pz = (const char*)sqlite3_column_text(pCsr->pStmt, iCol+1);
*pn = sqlite3_column_bytes(pCsr->pStmt, iCol+1);
}
}
return rc;
}
static int fts5ColumnSizeCb(
void *pContext, /* Pointer to int */
int tflags,
const char *pToken, /* Buffer containing token */
int nToken, /* Size of token in bytes */
int iStart, /* Start offset of token */
int iEnd /* End offset of token */
const char *pUnused, /* Buffer containing token */
int nUnused, /* Size of token in bytes */
int iUnused1, /* Start offset of token */
int iUnused2 /* End offset of token */
){
int *pCnt = (int*)pContext;
UNUSED_PARAM2(pUnused, nUnused);
UNUSED_PARAM2(iUnused1, iUnused2);
if( (tflags & FTS5_TOKEN_COLOCATED)==0 ){
(*pCnt)++;
}
@@ -1867,10 +1966,11 @@ static void *fts5ApiGetAuxdata(Fts5Context *pCtx, int bClear){
}
static void fts5ApiPhraseNext(
Fts5Context *pCtx,
Fts5Context *pUnused,
Fts5PhraseIter *pIter,
int *piCol, int *piOff
){
UNUSED_PARAM(pUnused);
if( pIter->a>=pIter->b ){
*piCol = -1;
*piOff = -1;
@@ -1887,20 +1987,98 @@ static void fts5ApiPhraseNext(
}
}
static void fts5ApiPhraseFirst(
static int fts5ApiPhraseFirst(
Fts5Context *pCtx,
int iPhrase,
Fts5PhraseIter *pIter,
int *piCol, int *piOff
){
Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
int n = fts5CsrPoslist(pCsr, iPhrase, &pIter->a);
pIter->b = &pIter->a[n];
*piCol = 0;
*piOff = 0;
fts5ApiPhraseNext(pCtx, pIter, piCol, piOff);
int n;
int rc = fts5CsrPoslist(pCsr, iPhrase, &pIter->a, &n);
if( rc==SQLITE_OK ){
pIter->b = &pIter->a[n];
*piCol = 0;
*piOff = 0;
fts5ApiPhraseNext(pCtx, pIter, piCol, piOff);
}
return rc;
}
static void fts5ApiPhraseNextColumn(
Fts5Context *pCtx,
Fts5PhraseIter *pIter,
int *piCol
){
Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
Fts5Config *pConfig = ((Fts5Table*)(pCsr->base.pVtab))->pConfig;
if( pConfig->eDetail==FTS5_DETAIL_COLUMNS ){
if( pIter->a>=pIter->b ){
*piCol = -1;
}else{
int iIncr;
pIter->a += fts5GetVarint32(&pIter->a[0], iIncr);
*piCol += (iIncr-2);
}
}else{
while( 1 ){
int dummy;
if( pIter->a>=pIter->b ){
*piCol = -1;
return;
}
if( pIter->a[0]==0x01 ) break;
pIter->a += fts5GetVarint32(pIter->a, dummy);
}
pIter->a += 1 + fts5GetVarint32(&pIter->a[1], *piCol);
}
}
static int fts5ApiPhraseFirstColumn(
Fts5Context *pCtx,
int iPhrase,
Fts5PhraseIter *pIter,
int *piCol
){
int rc = SQLITE_OK;
Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
Fts5Config *pConfig = ((Fts5Table*)(pCsr->base.pVtab))->pConfig;
if( pConfig->eDetail==FTS5_DETAIL_COLUMNS ){
Fts5Sorter *pSorter = pCsr->pSorter;
int n;
if( pSorter ){
int i1 = (iPhrase==0 ? 0 : pSorter->aIdx[iPhrase-1]);
n = pSorter->aIdx[iPhrase] - i1;
pIter->a = &pSorter->aPoslist[i1];
}else{
rc = sqlite3Fts5ExprPhraseCollist(pCsr->pExpr, iPhrase, &pIter->a, &n);
}
if( rc==SQLITE_OK ){
pIter->b = &pIter->a[n];
*piCol = 0;
fts5ApiPhraseNextColumn(pCtx, pIter, piCol);
}
}else{
int n;
rc = fts5CsrPoslist(pCsr, iPhrase, &pIter->a, &n);
if( rc==SQLITE_OK ){
pIter->b = &pIter->a[n];
if( n<=0 ){
*piCol = -1;
}else if( pIter->a[0]==0x01 ){
pIter->a += 1 + fts5GetVarint32(&pIter->a[1], *piCol);
}else{
*piCol = 0;
}
}
}
return rc;
}
static int fts5ApiQueryPhrase(Fts5Context*, int, void*,
int(*)(const Fts5ExtensionApi*, Fts5Context*, void*)
);
@@ -1924,9 +2102,10 @@ static const Fts5ExtensionApi sFts5Api = {
fts5ApiGetAuxdata,
fts5ApiPhraseFirst,
fts5ApiPhraseNext,
fts5ApiPhraseFirstColumn,
fts5ApiPhraseNextColumn,
};
/*
** Implementation of API function xQueryPhrase().
*/
@@ -1943,12 +2122,11 @@ static int fts5ApiQueryPhrase(
rc = fts5OpenMethod(pCsr->base.pVtab, (sqlite3_vtab_cursor**)&pNew);
if( rc==SQLITE_OK ){
Fts5Config *pConf = pTab->pConfig;
pNew->ePlan = FTS5_PLAN_MATCH;
pNew->iFirstRowid = SMALLEST_INT64;
pNew->iLastRowid = LARGEST_INT64;
pNew->base.pVtab = (sqlite3_vtab*)pTab;
rc = sqlite3Fts5ExprClonePhrase(pConf, pCsr->pExpr, iPhrase, &pNew->pExpr);
rc = sqlite3Fts5ExprClonePhrase(pCsr->pExpr, iPhrase, &pNew->pExpr);
}
if( rc==SQLITE_OK ){
@@ -2018,20 +2196,20 @@ static void fts5ApiCallback(
** Given cursor id iId, return a pointer to the corresponding Fts5Index
** object. Or NULL If the cursor id does not exist.
**
** If successful, set *pnCol to the number of indexed columns in the
** table before returning.
** If successful, set *ppConfig to point to the associated config object
** before returning.
*/
Fts5Index *sqlite3Fts5IndexFromCsrid(
Fts5Global *pGlobal,
i64 iCsrId,
int *pnCol
Fts5Global *pGlobal, /* FTS5 global context for db handle */
i64 iCsrId, /* Id of cursor to find */
Fts5Config **ppConfig /* OUT: Configuration object */
){
Fts5Cursor *pCsr;
Fts5Table *pTab;
pCsr = fts5CursorFromCsrid(pGlobal, iCsrId);
pTab = (Fts5Table*)pCsr->base.pVtab;
*pnCol = pTab->pConfig->nCol;
*ppConfig = pTab->pConfig;
return pTab->pIndex;
}
@@ -2058,20 +2236,46 @@ static int fts5PoslistBlob(sqlite3_context *pCtx, Fts5Cursor *pCsr){
Fts5Buffer val;
memset(&val, 0, sizeof(Fts5Buffer));
switch( ((Fts5Table*)(pCsr->base.pVtab))->pConfig->eDetail ){
case FTS5_DETAIL_FULL:
/* Append the varints */
for(i=0; i<(nPhrase-1); i++){
const u8 *dummy;
int nByte = sqlite3Fts5ExprPoslist(pCsr->pExpr, i, &dummy);
sqlite3Fts5BufferAppendVarint(&rc, &val, nByte);
}
/* Append the varints */
for(i=0; i<(nPhrase-1); i++){
const u8 *dummy;
int nByte = sqlite3Fts5ExprPoslist(pCsr->pExpr, i, &dummy);
sqlite3Fts5BufferAppendVarint(&rc, &val, nByte);
}
/* Append the position lists */
for(i=0; i<nPhrase; i++){
const u8 *pPoslist;
int nPoslist;
nPoslist = sqlite3Fts5ExprPoslist(pCsr->pExpr, i, &pPoslist);
sqlite3Fts5BufferAppendBlob(&rc, &val, nPoslist, pPoslist);
/* Append the position lists */
for(i=0; i<nPhrase; i++){
const u8 *pPoslist;
int nPoslist;
nPoslist = sqlite3Fts5ExprPoslist(pCsr->pExpr, i, &pPoslist);
sqlite3Fts5BufferAppendBlob(&rc, &val, nPoslist, pPoslist);
}
break;
case FTS5_DETAIL_COLUMNS:
/* Append the varints */
for(i=0; rc==SQLITE_OK && i<(nPhrase-1); i++){
const u8 *dummy;
int nByte;
rc = sqlite3Fts5ExprPhraseCollist(pCsr->pExpr, i, &dummy, &nByte);
sqlite3Fts5BufferAppendVarint(&rc, &val, nByte);
}
/* Append the position lists */
for(i=0; rc==SQLITE_OK && i<nPhrase; i++){
const u8 *pPoslist;
int nPoslist;
rc = sqlite3Fts5ExprPhraseCollist(pCsr->pExpr, i, &pPoslist, &nPoslist);
sqlite3Fts5BufferAppendBlob(&rc, &val, nPoslist, pPoslist);
}
break;
default:
break;
}
sqlite3_result_blob(pCtx, val.p, val.n, sqlite3_free);
@@ -2135,7 +2339,7 @@ static int fts5ColumnMethod(
*/
static int fts5FindFunctionMethod(
sqlite3_vtab *pVtab, /* Virtual table handle */
int nArg, /* Number of SQL function arguments */
int nUnused, /* Number of SQL function arguments */
const char *zName, /* Name of SQL function */
void (**pxFunc)(sqlite3_context*,int,sqlite3_value**), /* OUT: Result */
void **ppArg /* OUT: User data for *pxFunc */
@@ -2143,6 +2347,7 @@ static int fts5FindFunctionMethod(
Fts5Table *pTab = (Fts5Table*)pVtab;
Fts5Auxiliary *pAux;
UNUSED_PARAM(nUnused);
pAux = fts5FindAuxiliary(pTab, zName);
if( pAux ){
*pxFunc = fts5ApiCallback;
@@ -2172,6 +2377,7 @@ static int fts5RenameMethod(
*/
static int fts5SavepointMethod(sqlite3_vtab *pVtab, int iSavepoint){
Fts5Table *pTab = (Fts5Table*)pVtab;
UNUSED_PARAM(iSavepoint); /* Call below is a no-op for NDEBUG builds */
fts5CheckTransactionState(pTab, FTS5_SAVEPOINT, iSavepoint);
fts5TripCursors(pTab);
return sqlite3Fts5StorageSync(pTab->pStorage, 0);
@@ -2184,6 +2390,7 @@ static int fts5SavepointMethod(sqlite3_vtab *pVtab, int iSavepoint){
*/
static int fts5ReleaseMethod(sqlite3_vtab *pVtab, int iSavepoint){
Fts5Table *pTab = (Fts5Table*)pVtab;
UNUSED_PARAM(iSavepoint); /* Call below is a no-op for NDEBUG builds */
fts5CheckTransactionState(pTab, FTS5_RELEASE, iSavepoint);
fts5TripCursors(pTab);
return sqlite3Fts5StorageSync(pTab->pStorage, 0);
@@ -2196,6 +2403,7 @@ static int fts5ReleaseMethod(sqlite3_vtab *pVtab, int iSavepoint){
*/
static int fts5RollbackToMethod(sqlite3_vtab *pVtab, int iSavepoint){
Fts5Table *pTab = (Fts5Table*)pVtab;
UNUSED_PARAM(iSavepoint); /* Call below is a no-op for NDEBUG builds */
fts5CheckTransactionState(pTab, FTS5_ROLLBACKTO, iSavepoint);
fts5TripCursors(pTab);
return sqlite3Fts5StorageRollback(pTab->pStorage);
@@ -2375,10 +2583,11 @@ static void fts5ModuleDestroy(void *pCtx){
static void fts5Fts5Func(
sqlite3_context *pCtx, /* Function call context */
int nArg, /* Number of args */
sqlite3_value **apVal /* Function arguments */
sqlite3_value **apUnused /* Function arguments */
){
Fts5Global *pGlobal = (Fts5Global*)sqlite3_user_data(pCtx);
char buf[8];
UNUSED_PARAM2(nArg, apUnused);
assert( nArg==0 );
assert( sizeof(buf)>=sizeof(pGlobal) );
memcpy(buf, (void*)&pGlobal, sizeof(pGlobal));
@@ -2391,9 +2600,10 @@ static void fts5Fts5Func(
static void fts5SourceIdFunc(
sqlite3_context *pCtx, /* Function call context */
int nArg, /* Number of args */
sqlite3_value **apVal /* Function arguments */
sqlite3_value **apUnused /* Function arguments */
){
assert( nArg==0 );
UNUSED_PARAM2(nArg, apUnused);
sqlite3_result_text(pCtx, "--FTS5-SOURCE-ID--", -1, SQLITE_TRANSIENT);
}
@@ -2455,6 +2665,17 @@ static int fts5Init(sqlite3 *db){
);
}
}
/* If SQLITE_FTS5_ENABLE_TEST_MI is defined, assume that the file
** fts5_test_mi.c is compiled and linked into the executable. And call
** its entry point to enable the matchinfo() demo. */
#ifdef SQLITE_FTS5_ENABLE_TEST_MI
if( rc==SQLITE_OK ){
extern int sqlite3Fts5TestRegisterMatchinfo(sqlite3*);
rc = sqlite3Fts5TestRegisterMatchinfo(db);
}
#endif
return rc;
}
+129 -115
View File
@@ -297,10 +297,10 @@ int sqlite3Fts5StorageOpen(
int i;
int iOff;
sqlite3_snprintf(nDefn, zDefn, "id INTEGER PRIMARY KEY");
iOff = strlen(zDefn);
iOff = (int)strlen(zDefn);
for(i=0; i<pConfig->nCol; i++){
sqlite3_snprintf(nDefn-iOff, &zDefn[iOff], ", c%d", i);
iOff += strlen(&zDefn[iOff]);
iOff += (int)strlen(&zDefn[iOff]);
}
rc = sqlite3Fts5CreateTable(pConfig, "content", zDefn, 0, pzErr);
}
@@ -362,11 +362,12 @@ static int fts5StorageInsertCallback(
int tflags,
const char *pToken, /* Buffer containing token */
int nToken, /* Size of token in bytes */
int iStart, /* Start offset of token */
int iEnd /* End offset of token */
int iUnused1, /* Start offset of token */
int iUnused2 /* End offset of token */
){
Fts5InsertCtx *pCtx = (Fts5InsertCtx*)pContext;
Fts5Index *pIdx = pCtx->pStorage->pIndex;
UNUSED_PARAM2(iUnused1, iUnused2);
if( (tflags & FTS5_TOKEN_COLOCATED)==0 || pCtx->szCol==0 ){
pCtx->szCol++;
}
@@ -378,39 +379,52 @@ static int fts5StorageInsertCallback(
** delete-markers to the FTS index necessary to delete it. Do not actually
** remove the %_content row at this time though.
*/
static int fts5StorageDeleteFromIndex(Fts5Storage *p, i64 iDel){
static int fts5StorageDeleteFromIndex(
Fts5Storage *p,
i64 iDel,
sqlite3_value **apVal
){
Fts5Config *pConfig = p->pConfig;
sqlite3_stmt *pSeek; /* SELECT to read row iDel from %_data */
sqlite3_stmt *pSeek = 0; /* SELECT to read row iDel from %_data */
int rc; /* Return code */
int rc2; /* sqlite3_reset() return code */
int iCol;
Fts5InsertCtx ctx;
rc = fts5StorageGetStmt(p, FTS5_STMT_LOOKUP, &pSeek, 0);
if( rc==SQLITE_OK ){
int rc2;
if( apVal==0 ){
rc = fts5StorageGetStmt(p, FTS5_STMT_LOOKUP, &pSeek, 0);
if( rc!=SQLITE_OK ) return rc;
sqlite3_bind_int64(pSeek, 1, iDel);
if( sqlite3_step(pSeek)==SQLITE_ROW ){
int iCol;
Fts5InsertCtx ctx;
ctx.pStorage = p;
ctx.iCol = -1;
rc = sqlite3Fts5IndexBeginWrite(p->pIndex, 1, iDel);
for(iCol=1; rc==SQLITE_OK && iCol<=pConfig->nCol; iCol++){
if( pConfig->abUnindexed[iCol-1] ) continue;
ctx.szCol = 0;
rc = sqlite3Fts5Tokenize(pConfig,
FTS5_TOKENIZE_DOCUMENT,
(const char*)sqlite3_column_text(pSeek, iCol),
sqlite3_column_bytes(pSeek, iCol),
(void*)&ctx,
fts5StorageInsertCallback
);
p->aTotalSize[iCol-1] -= (i64)ctx.szCol;
}
p->nTotalRow--;
if( sqlite3_step(pSeek)!=SQLITE_ROW ){
return sqlite3_reset(pSeek);
}
rc2 = sqlite3_reset(pSeek);
if( rc==SQLITE_OK ) rc = rc2;
}
ctx.pStorage = p;
ctx.iCol = -1;
rc = sqlite3Fts5IndexBeginWrite(p->pIndex, 1, iDel);
for(iCol=1; rc==SQLITE_OK && iCol<=pConfig->nCol; iCol++){
if( pConfig->abUnindexed[iCol-1]==0 ){
const char *zText;
int nText;
if( pSeek ){
zText = (const char*)sqlite3_column_text(pSeek, iCol);
nText = sqlite3_column_bytes(pSeek, iCol);
}else{
zText = (const char*)sqlite3_value_text(apVal[iCol-1]);
nText = sqlite3_value_bytes(apVal[iCol-1]);
}
ctx.szCol = 0;
rc = sqlite3Fts5Tokenize(pConfig, FTS5_TOKENIZE_DOCUMENT,
zText, nText, (void*)&ctx, fts5StorageInsertCallback
);
p->aTotalSize[iCol-1] -= (i64)ctx.szCol;
}
}
p->nTotalRow--;
rc2 = sqlite3_reset(pSeek);
if( rc==SQLITE_OK ) rc = rc2;
return rc;
}
@@ -490,16 +504,17 @@ static int fts5StorageSaveTotals(Fts5Storage *p){
/*
** Remove a row from the FTS table.
*/
int sqlite3Fts5StorageDelete(Fts5Storage *p, i64 iDel){
int sqlite3Fts5StorageDelete(Fts5Storage *p, i64 iDel, sqlite3_value **apVal){
Fts5Config *pConfig = p->pConfig;
int rc;
sqlite3_stmt *pDel = 0;
assert( pConfig->eContent!=FTS5_CONTENT_NORMAL || apVal==0 );
rc = fts5StorageLoadTotals(p, 1);
/* Delete the index records */
if( rc==SQLITE_OK ){
rc = fts5StorageDeleteFromIndex(p, iDel);
rc = fts5StorageDeleteFromIndex(p, iDel, apVal);
}
/* Delete the %_docsize record */
@@ -513,62 +528,9 @@ int sqlite3Fts5StorageDelete(Fts5Storage *p, i64 iDel){
}
/* Delete the %_content record */
if( rc==SQLITE_OK ){
rc = fts5StorageGetStmt(p, FTS5_STMT_DELETE_CONTENT, &pDel, 0);
}
if( rc==SQLITE_OK ){
sqlite3_bind_int64(pDel, 1, iDel);
sqlite3_step(pDel);
rc = sqlite3_reset(pDel);
}
/* Write the averages record */
if( rc==SQLITE_OK ){
rc = fts5StorageSaveTotals(p);
}
return rc;
}
int sqlite3Fts5StorageSpecialDelete(
Fts5Storage *p,
i64 iDel,
sqlite3_value **apVal
){
Fts5Config *pConfig = p->pConfig;
int rc;
sqlite3_stmt *pDel = 0;
assert( pConfig->eContent!=FTS5_CONTENT_NORMAL );
rc = fts5StorageLoadTotals(p, 1);
/* Delete the index records */
if( rc==SQLITE_OK ){
int iCol;
Fts5InsertCtx ctx;
ctx.pStorage = p;
ctx.iCol = -1;
rc = sqlite3Fts5IndexBeginWrite(p->pIndex, 1, iDel);
for(iCol=0; rc==SQLITE_OK && iCol<pConfig->nCol; iCol++){
if( pConfig->abUnindexed[iCol] ) continue;
ctx.szCol = 0;
rc = sqlite3Fts5Tokenize(pConfig,
FTS5_TOKENIZE_DOCUMENT,
(const char*)sqlite3_value_text(apVal[iCol]),
sqlite3_value_bytes(apVal[iCol]),
(void*)&ctx,
fts5StorageInsertCallback
);
p->aTotalSize[iCol] -= (i64)ctx.szCol;
}
p->nTotalRow--;
}
/* Delete the %_docsize record */
if( pConfig->bColumnsize ){
if( pConfig->eContent==FTS5_CONTENT_NORMAL ){
if( rc==SQLITE_OK ){
rc = fts5StorageGetStmt(p, FTS5_STMT_DELETE_DOCSIZE, &pDel, 0);
rc = fts5StorageGetStmt(p, FTS5_STMT_DELETE_CONTENT, &pDel, 0);
}
if( rc==SQLITE_OK ){
sqlite3_bind_int64(pDel, 1, iDel);
@@ -725,17 +687,7 @@ int sqlite3Fts5StorageContentInsert(
}else{
sqlite3_stmt *pInsert = 0; /* Statement to write %_content table */
int i; /* Counter variable */
#if 0
if( eConflict==SQLITE_REPLACE ){
eStmt = FTS5_STMT_REPLACE_CONTENT;
rc = fts5StorageDeleteFromIndex(p, sqlite3_value_int64(apVal[1]));
}else{
eStmt = FTS5_STMT_INSERT_CONTENT;
}
#endif
if( rc==SQLITE_OK ){
rc = fts5StorageGetStmt(p, FTS5_STMT_INSERT_CONTENT, &pInsert, 0);
}
rc = fts5StorageGetStmt(p, FTS5_STMT_INSERT_CONTENT, &pInsert, 0);
for(i=1; rc==SQLITE_OK && i<=pConfig->nCol+1; i++){
rc = sqlite3_bind_value(pInsert, i, apVal[i]);
}
@@ -833,28 +785,75 @@ struct Fts5IntegrityCtx {
int iCol;
int szCol;
u64 cksum;
Fts5Termset *pTermset;
Fts5Config *pConfig;
};
/*
** Tokenization callback used by integrity check.
*/
static int fts5StorageIntegrityCallback(
void *pContext, /* Pointer to Fts5InsertCtx object */
void *pContext, /* Pointer to Fts5IntegrityCtx object */
int tflags,
const char *pToken, /* Buffer containing token */
int nToken, /* Size of token in bytes */
int iStart, /* Start offset of token */
int iEnd /* End offset of token */
int iUnused1, /* Start offset of token */
int iUnused2 /* End offset of token */
){
Fts5IntegrityCtx *pCtx = (Fts5IntegrityCtx*)pContext;
Fts5Termset *pTermset = pCtx->pTermset;
int bPresent;
int ii;
int rc = SQLITE_OK;
int iPos;
int iCol;
UNUSED_PARAM2(iUnused1, iUnused2);
if( (tflags & FTS5_TOKEN_COLOCATED)==0 || pCtx->szCol==0 ){
pCtx->szCol++;
}
pCtx->cksum ^= sqlite3Fts5IndexCksum(
pCtx->pConfig, pCtx->iRowid, pCtx->iCol, pCtx->szCol-1, pToken, nToken
);
return SQLITE_OK;
switch( pCtx->pConfig->eDetail ){
case FTS5_DETAIL_FULL:
iPos = pCtx->szCol-1;
iCol = pCtx->iCol;
break;
case FTS5_DETAIL_COLUMNS:
iPos = pCtx->iCol;
iCol = 0;
break;
default:
assert( pCtx->pConfig->eDetail==FTS5_DETAIL_NONE );
iPos = 0;
iCol = 0;
break;
}
rc = sqlite3Fts5TermsetAdd(pTermset, 0, pToken, nToken, &bPresent);
if( rc==SQLITE_OK && bPresent==0 ){
pCtx->cksum ^= sqlite3Fts5IndexEntryCksum(
pCtx->iRowid, iCol, iPos, 0, pToken, nToken
);
}
for(ii=0; rc==SQLITE_OK && ii<pCtx->pConfig->nPrefix; ii++){
const int nChar = pCtx->pConfig->aPrefix[ii];
int nByte = sqlite3Fts5IndexCharlenToBytelen(pToken, nToken, nChar);
if( nByte ){
rc = sqlite3Fts5TermsetAdd(pTermset, ii+1, pToken, nByte, &bPresent);
if( bPresent==0 ){
pCtx->cksum ^= sqlite3Fts5IndexEntryCksum(
pCtx->iRowid, iCol, iPos, ii+1, pToken, nByte
);
}
}
}
return rc;
}
/*
@@ -890,22 +889,37 @@ int sqlite3Fts5StorageIntegrity(Fts5Storage *p){
if( pConfig->bColumnsize ){
rc = sqlite3Fts5StorageDocsize(p, ctx.iRowid, aColSize);
}
if( rc==SQLITE_OK && pConfig->eDetail==FTS5_DETAIL_NONE ){
rc = sqlite3Fts5TermsetNew(&ctx.pTermset);
}
for(i=0; rc==SQLITE_OK && i<pConfig->nCol; i++){
if( pConfig->abUnindexed[i] ) continue;
ctx.iCol = i;
ctx.szCol = 0;
rc = sqlite3Fts5Tokenize(pConfig,
FTS5_TOKENIZE_DOCUMENT,
(const char*)sqlite3_column_text(pScan, i+1),
sqlite3_column_bytes(pScan, i+1),
(void*)&ctx,
fts5StorageIntegrityCallback
);
if( pConfig->bColumnsize && ctx.szCol!=aColSize[i] ){
if( pConfig->eDetail==FTS5_DETAIL_COLUMNS ){
rc = sqlite3Fts5TermsetNew(&ctx.pTermset);
}
if( rc==SQLITE_OK ){
rc = sqlite3Fts5Tokenize(pConfig,
FTS5_TOKENIZE_DOCUMENT,
(const char*)sqlite3_column_text(pScan, i+1),
sqlite3_column_bytes(pScan, i+1),
(void*)&ctx,
fts5StorageIntegrityCallback
);
}
if( rc==SQLITE_OK && pConfig->bColumnsize && ctx.szCol!=aColSize[i] ){
rc = FTS5_CORRUPT;
}
aTotalSize[i] += ctx.szCol;
if( pConfig->eDetail==FTS5_DETAIL_COLUMNS ){
sqlite3Fts5TermsetFree(ctx.pTermset);
ctx.pTermset = 0;
}
}
sqlite3Fts5TermsetFree(ctx.pTermset);
ctx.pTermset = 0;
if( rc!=SQLITE_OK ) break;
}
rc2 = sqlite3_reset(pScan);
@@ -924,12 +938,12 @@ int sqlite3Fts5StorageIntegrity(Fts5Storage *p){
/* Check that the %_docsize and %_content tables contain the expected
** number of rows. */
if( rc==SQLITE_OK && pConfig->eContent==FTS5_CONTENT_NORMAL ){
i64 nRow;
i64 nRow = 0;
rc = fts5StorageCount(p, "content", &nRow);
if( rc==SQLITE_OK && nRow!=p->nTotalRow ) rc = FTS5_CORRUPT;
}
if( rc==SQLITE_OK && pConfig->bColumnsize ){
i64 nRow;
i64 nRow = 0;
rc = fts5StorageCount(p, "docsize", &nRow);
if( rc==SQLITE_OK && nRow!=p->nTotalRow ) rc = FTS5_CORRUPT;
}
+92 -2
View File
@@ -23,7 +23,8 @@
#include <assert.h>
extern int sqlite3_fts5_may_be_corrupt;
extern int sqlite3Fts5TestRegisterMatchinfo(sqlite3 *);
extern int sqlite3Fts5TestRegisterMatchinfo(sqlite3*);
extern int sqlite3Fts5TestRegisterTok(sqlite3*, fts5_api*);
/*************************************************************************
** This is a copy of the first part of the SqliteDb structure in
@@ -235,6 +236,8 @@ static int xF5tApi(
{ "xGetAuxdata", 1, "CLEAR" }, /* 13 */
{ "xSetAuxdataInt", 1, "INTEGER" }, /* 14 */
{ "xGetAuxdataInt", 1, "CLEAR" }, /* 15 */
{ "xPhraseForeach", 4, "IPHRASE COLVAR OFFVAR SCRIPT" }, /* 16 */
{ "xPhraseColumnForeach", 3, "IPHRASE COLVAR SCRIPT" }, /* 17 */
{ 0, 0, 0}
};
@@ -431,6 +434,66 @@ static int xF5tApi(
break;
}
CASE(16, "xPhraseForeach") {
int iPhrase;
int iCol;
int iOff;
const char *zColvar;
const char *zOffvar;
Tcl_Obj *pScript = objv[5];
Fts5PhraseIter iter;
if( Tcl_GetIntFromObj(interp, objv[2], &iPhrase) ) return TCL_ERROR;
zColvar = Tcl_GetString(objv[3]);
zOffvar = Tcl_GetString(objv[4]);
rc = p->pApi->xPhraseFirst(p->pFts, iPhrase, &iter, &iCol, &iOff);
if( rc!=SQLITE_OK ){
Tcl_AppendResult(interp, sqlite3ErrName(rc), 0);
return TCL_ERROR;
}
for( ;iCol>=0; p->pApi->xPhraseNext(p->pFts, &iter, &iCol, &iOff) ){
Tcl_SetVar2Ex(interp, zColvar, 0, Tcl_NewIntObj(iCol), 0);
Tcl_SetVar2Ex(interp, zOffvar, 0, Tcl_NewIntObj(iOff), 0);
rc = Tcl_EvalObjEx(interp, pScript, 0);
if( rc==TCL_CONTINUE ) rc = TCL_OK;
if( rc!=TCL_OK ){
if( rc==TCL_BREAK ) rc = TCL_OK;
break;
}
}
break;
}
CASE(17, "xPhraseColumnForeach") {
int iPhrase;
int iCol;
const char *zColvar;
Tcl_Obj *pScript = objv[4];
Fts5PhraseIter iter;
if( Tcl_GetIntFromObj(interp, objv[2], &iPhrase) ) return TCL_ERROR;
zColvar = Tcl_GetString(objv[3]);
rc = p->pApi->xPhraseFirstColumn(p->pFts, iPhrase, &iter, &iCol);
if( rc!=SQLITE_OK ){
Tcl_AppendResult(interp, sqlite3ErrName(rc), 0);
return TCL_ERROR;
}
for( ; iCol>=0; p->pApi->xPhraseNextColumn(p->pFts, &iter, &iCol)){
Tcl_SetVar2Ex(interp, zColvar, 0, Tcl_NewIntObj(iCol), 0);
rc = Tcl_EvalObjEx(interp, pScript, 0);
if( rc==TCL_CONTINUE ) rc = TCL_OK;
if( rc!=TCL_OK ){
if( rc==TCL_BREAK ) rc = TCL_OK;
break;
}
}
break;
}
default:
assert( 0 );
break;
@@ -1020,6 +1083,32 @@ static int f5tRegisterMatchinfo(
return TCL_OK;
}
static int f5tRegisterTok(
void * clientData,
Tcl_Interp *interp,
int objc,
Tcl_Obj *CONST objv[]
){
int rc;
sqlite3 *db = 0;
fts5_api *pApi = 0;
if( objc!=2 ){
Tcl_WrongNumArgs(interp, 1, objv, "DB");
return TCL_ERROR;
}
if( f5tDbAndApi(interp, objv[1], &db, &pApi) ){
return TCL_ERROR;
}
rc = sqlite3Fts5TestRegisterTok(db, pApi);
if( rc!=SQLITE_OK ){
Tcl_SetResult(interp, (char*)sqlite3ErrName(rc), TCL_VOLATILE);
return TCL_ERROR;
}
return TCL_OK;
}
/*
** Entry point.
*/
@@ -1035,7 +1124,8 @@ int Fts5tcl_Init(Tcl_Interp *interp){
{ "sqlite3_fts5_create_function", f5tCreateFunction, 0 },
{ "sqlite3_fts5_may_be_corrupt", f5tMayBeCorrupt, 0 },
{ "sqlite3_fts5_token_hash", f5tTokenHash, 0 },
{ "sqlite3_fts5_register_matchinfo", f5tRegisterMatchinfo, 0 }
{ "sqlite3_fts5_register_matchinfo", f5tRegisterMatchinfo, 0 },
{ "sqlite3_fts5_register_fts5tokenize", f5tRegisterTok, 0 }
};
int i;
F5tTokenizerContext *pContext;
+26 -17
View File
@@ -41,16 +41,17 @@
*/
#ifdef SQLITE_TEST
#ifdef SQLITE_ENABLE_FTS5
#include "fts5.h"
#include <tcl.h>
#include <assert.h>
#include <string.h>
typedef struct Fts5MatchinfoCtx Fts5MatchinfoCtx;
#ifndef SQLITE_AMALGAMATION
typedef unsigned int u32;
#endif
struct Fts5MatchinfoCtx {
int nCol; /* Number of cols in FTS5 table */
@@ -134,7 +135,7 @@ static int fts5MatchinfoXCb(
int iPrev = -1;
for(pApi->xPhraseFirst(pFts, 0, &iter, &iCol, &iOff);
iOff>=0;
iCol>=0;
pApi->xPhraseNext(pFts, &iter, &iCol, &iOff)
){
aOut[iCol*3+1]++;
@@ -211,18 +212,31 @@ static int fts5MatchinfoLocalCb(
int rc = SQLITE_OK;
switch( f ){
case 'b':
case 'b': {
int iPhrase;
int nInt = ((p->nCol + 31) / 32) * p->nPhrase;
for(i=0; i<nInt; i++) aOut[i] = 0;
for(iPhrase=0; iPhrase<p->nPhrase; iPhrase++){
Fts5PhraseIter iter;
int iCol;
for(pApi->xPhraseFirstColumn(pFts, iPhrase, &iter, &iCol);
iCol>=0;
pApi->xPhraseNextColumn(pFts, &iter, &iCol)
){
aOut[iPhrase * ((p->nCol+31)/32) + iCol/32] |= ((u32)1 << iCol%32);
}
}
break;
}
case 'x':
case 'y': {
int nMul = (f=='x' ? 3 : 1);
int iPhrase;
if( f=='b' ){
int nInt = ((p->nCol + 31) / 32) * p->nPhrase;
for(i=0; i<nInt; i++) aOut[i] = 0;
}else{
for(i=0; i<(p->nCol*p->nPhrase); i++) aOut[i*nMul] = 0;
}
for(i=0; i<(p->nCol*p->nPhrase); i++) aOut[i*nMul] = 0;
for(iPhrase=0; iPhrase<p->nPhrase; iPhrase++){
Fts5PhraseIter iter;
@@ -231,11 +245,7 @@ static int fts5MatchinfoLocalCb(
iOff>=0;
pApi->xPhraseNext(pFts, &iter, &iCol, &iOff)
){
if( f=='b' ){
aOut[iPhrase * ((p->nCol+31)/32) + iCol/32] |= ((u32)1 << iCol%32);
}else{
aOut[nMul * (iCol + iPhrase * p->nCol)]++;
}
aOut[nMul * (iCol + iPhrase * p->nCol)]++;
}
}
@@ -396,7 +406,7 @@ int sqlite3Fts5TestRegisterMatchinfo(sqlite3 *db){
**
** Also check that the fts5_api object is version 2 or newer.
*/
if( pApi==0 || pApi->iVersion<1 ){
if( pApi==0 || pApi->iVersion<2 ){
return SQLITE_ERROR;
}
@@ -407,5 +417,4 @@ int sqlite3Fts5TestRegisterMatchinfo(sqlite3 *db){
}
#endif /* SQLITE_ENABLE_FTS5 */
#endif /* SQLITE_TEST */
+482
View File
@@ -0,0 +1,482 @@
/*
** 2013 Apr 22
**
** The author disclaims copyright to this source code. In place of
** a legal notice, here is a blessing:
**
** May you do good and not evil.
** May you find forgiveness for yourself and forgive others.
** May you share freely, never taking more than you give.
**
******************************************************************************
**
** This file contains code for the "fts5tokenize" virtual table module.
** An fts5tokenize virtual table is created as follows:
**
** CREATE VIRTUAL TABLE <tbl> USING fts5tokenize(
** <tokenizer-name>, <arg-1>, ...
** );
**
** The table created has the following schema:
**
** CREATE TABLE <tbl>(input HIDDEN, token, start, end, position)
**
** When queried, the query must include a WHERE clause of type:
**
** input = <string>
**
** The virtual table module tokenizes this <string>, using the FTS3
** tokenizer specified by the arguments to the CREATE VIRTUAL TABLE
** statement and returns one row for each token in the result. With
** fields set as follows:
**
** input: Always set to a copy of <string>
** token: A token from the input.
** start: Byte offset of the token within the input <string>.
** end: Byte offset of the byte immediately following the end of the
** token within the input string.
** pos: Token offset of token within input.
**
*/
#if defined(SQLITE_TEST) && defined(SQLITE_ENABLE_FTS5)
#include <fts5.h>
#include <string.h>
#include <assert.h>
typedef struct Fts5tokTable Fts5tokTable;
typedef struct Fts5tokCursor Fts5tokCursor;
typedef struct Fts5tokRow Fts5tokRow;
/*
** Virtual table structure.
*/
struct Fts5tokTable {
sqlite3_vtab base; /* Base class used by SQLite core */
fts5_tokenizer tok; /* Tokenizer functions */
Fts5Tokenizer *pTok; /* Tokenizer instance */
};
/*
** A container for a rows values.
*/
struct Fts5tokRow {
char *zToken;
int iStart;
int iEnd;
int iPos;
};
/*
** Virtual table cursor structure.
*/
struct Fts5tokCursor {
sqlite3_vtab_cursor base; /* Base class used by SQLite core */
int iRowid; /* Current 'rowid' value */
char *zInput; /* Input string */
int nRow; /* Number of entries in aRow[] */
Fts5tokRow *aRow; /* Array of rows to return */
};
static void fts5tokDequote(char *z){
char q = z[0];
if( q=='[' || q=='\'' || q=='"' || q=='`' ){
int iIn = 1;
int iOut = 0;
if( q=='[' ) q = ']';
while( z[iIn] ){
if( z[iIn]==q ){
if( z[iIn+1]!=q ){
/* Character iIn was the close quote. */
iIn++;
break;
}else{
/* Character iIn and iIn+1 form an escaped quote character. Skip
** the input cursor past both and copy a single quote character
** to the output buffer. */
iIn += 2;
z[iOut++] = q;
}
}else{
z[iOut++] = z[iIn++];
}
}
z[iOut] = '\0';
}
}
/*
** The second argument, argv[], is an array of pointers to nul-terminated
** strings. This function makes a copy of the array and strings into a
** single block of memory. It then dequotes any of the strings that appear
** to be quoted.
**
** If successful, output parameter *pazDequote is set to point at the
** array of dequoted strings and SQLITE_OK is returned. The caller is
** responsible for eventually calling sqlite3_free() to free the array
** in this case. Or, if an error occurs, an SQLite error code is returned.
** The final value of *pazDequote is undefined in this case.
*/
static int fts5tokDequoteArray(
int argc, /* Number of elements in argv[] */
const char * const *argv, /* Input array */
char ***pazDequote /* Output array */
){
int rc = SQLITE_OK; /* Return code */
if( argc==0 ){
*pazDequote = 0;
}else{
int i;
int nByte = 0;
char **azDequote;
for(i=0; i<argc; i++){
nByte += (int)(strlen(argv[i]) + 1);
}
*pazDequote = azDequote = sqlite3_malloc(sizeof(char *)*argc + nByte);
if( azDequote==0 ){
rc = SQLITE_NOMEM;
}else{
char *pSpace = (char *)&azDequote[argc];
for(i=0; i<argc; i++){
int n = (int)strlen(argv[i]);
azDequote[i] = pSpace;
memcpy(pSpace, argv[i], n+1);
fts5tokDequote(pSpace);
pSpace += (n+1);
}
}
}
return rc;
}
/*
** Schema of the tokenizer table.
*/
#define FTS3_TOK_SCHEMA "CREATE TABLE x(input HIDDEN, token, start, end, position)"
/*
** This function does all the work for both the xConnect and xCreate methods.
** These tables have no persistent representation of their own, so xConnect
** and xCreate are identical operations.
**
** argv[0]: module name
** argv[1]: database name
** argv[2]: table name
** argv[3]: first argument (tokenizer name)
*/
static int fts5tokConnectMethod(
sqlite3 *db, /* Database connection */
void *pCtx, /* Pointer to fts5_api object */
int argc, /* Number of elements in argv array */
const char * const *argv, /* xCreate/xConnect argument array */
sqlite3_vtab **ppVtab, /* OUT: New sqlite3_vtab object */
char **pzErr /* OUT: sqlite3_malloc'd error message */
){
fts5_api *pApi = (fts5_api*)pCtx;
Fts5tokTable *pTab = 0;
int rc;
char **azDequote = 0;
int nDequote;
rc = sqlite3_declare_vtab(db,
"CREATE TABLE x(input HIDDEN, token, start, end, position)"
);
if( rc==SQLITE_OK ){
nDequote = argc-3;
rc = fts5tokDequoteArray(nDequote, &argv[3], &azDequote);
}
if( rc==SQLITE_OK ){
pTab = (Fts5tokTable*)sqlite3_malloc(sizeof(Fts5tokTable));
if( pTab==0 ){
rc = SQLITE_NOMEM;
}else{
memset(pTab, 0, sizeof(Fts5tokTable));
}
}
if( rc==SQLITE_OK ){
void *pTokCtx = 0;
const char *zModule = 0;
if( nDequote>0 ){
zModule = azDequote[0];
}
rc = pApi->xFindTokenizer(pApi, zModule, &pTokCtx, &pTab->tok);
if( rc==SQLITE_OK ){
const char **azArg = (const char **)&azDequote[1];
int nArg = nDequote>0 ? nDequote-1 : 0;
rc = pTab->tok.xCreate(pTokCtx, azArg, nArg, &pTab->pTok);
}
}
if( rc!=SQLITE_OK ){
sqlite3_free(pTab);
pTab = 0;
}
*ppVtab = (sqlite3_vtab*)pTab;
sqlite3_free(azDequote);
return rc;
}
/*
** This function does the work for both the xDisconnect and xDestroy methods.
** These tables have no persistent representation of their own, so xDisconnect
** and xDestroy are identical operations.
*/
static int fts5tokDisconnectMethod(sqlite3_vtab *pVtab){
Fts5tokTable *pTab = (Fts5tokTable *)pVtab;
if( pTab->pTok ){
pTab->tok.xDelete(pTab->pTok);
}
sqlite3_free(pTab);
return SQLITE_OK;
}
/*
** xBestIndex - Analyze a WHERE and ORDER BY clause.
*/
static int fts5tokBestIndexMethod(
sqlite3_vtab *pVTab,
sqlite3_index_info *pInfo
){
int i;
for(i=0; i<pInfo->nConstraint; i++){
if( pInfo->aConstraint[i].usable
&& pInfo->aConstraint[i].iColumn==0
&& pInfo->aConstraint[i].op==SQLITE_INDEX_CONSTRAINT_EQ
){
pInfo->idxNum = 1;
pInfo->aConstraintUsage[i].argvIndex = 1;
pInfo->aConstraintUsage[i].omit = 1;
pInfo->estimatedCost = 1;
return SQLITE_OK;
}
}
pInfo->idxNum = 0;
assert( pInfo->estimatedCost>1000000.0 );
return SQLITE_OK;
}
/*
** xOpen - Open a cursor.
*/
static int fts5tokOpenMethod(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCsr){
Fts5tokCursor *pCsr;
pCsr = (Fts5tokCursor *)sqlite3_malloc(sizeof(Fts5tokCursor));
if( pCsr==0 ){
return SQLITE_NOMEM;
}
memset(pCsr, 0, sizeof(Fts5tokCursor));
*ppCsr = (sqlite3_vtab_cursor *)pCsr;
return SQLITE_OK;
}
/*
** Reset the tokenizer cursor passed as the only argument. As if it had
** just been returned by fts5tokOpenMethod().
*/
static void fts5tokResetCursor(Fts5tokCursor *pCsr){
int i;
for(i=0; i<pCsr->nRow; i++){
sqlite3_free(pCsr->aRow[i].zToken);
}
sqlite3_free(pCsr->zInput);
sqlite3_free(pCsr->aRow);
pCsr->zInput = 0;
pCsr->aRow = 0;
pCsr->nRow = 0;
pCsr->iRowid = 0;
}
/*
** xClose - Close a cursor.
*/
static int fts5tokCloseMethod(sqlite3_vtab_cursor *pCursor){
Fts5tokCursor *pCsr = (Fts5tokCursor *)pCursor;
fts5tokResetCursor(pCsr);
sqlite3_free(pCsr);
return SQLITE_OK;
}
/*
** xNext - Advance the cursor to the next row, if any.
*/
static int fts5tokNextMethod(sqlite3_vtab_cursor *pCursor){
Fts5tokCursor *pCsr = (Fts5tokCursor *)pCursor;
pCsr->iRowid++;
return SQLITE_OK;
}
static int fts5tokCb(
void *pCtx, /* Pointer to Fts5tokCursor */
int tflags, /* Mask of FTS5_TOKEN_* flags */
const char *pToken, /* Pointer to buffer containing token */
int nToken, /* Size of token in bytes */
int iStart, /* Byte offset of token within input text */
int iEnd /* Byte offset of end of token within input text */
){
Fts5tokCursor *pCsr = (Fts5tokCursor*)pCtx;
Fts5tokRow *pRow;
if( (pCsr->nRow & (pCsr->nRow-1))==0 ){
int nNew = pCsr->nRow ? pCsr->nRow*2 : 32;
Fts5tokRow *aNew;
aNew = (Fts5tokRow*)sqlite3_realloc(pCsr->aRow, nNew*sizeof(Fts5tokRow));
if( aNew==0 ) return SQLITE_NOMEM;
memset(&aNew[pCsr->nRow], 0, sizeof(Fts5tokRow)*(nNew-pCsr->nRow));
pCsr->aRow = aNew;
}
pRow = &pCsr->aRow[pCsr->nRow];
pRow->iStart = iStart;
pRow->iEnd = iEnd;
if( pCsr->nRow ){
pRow->iPos = pRow[-1].iPos + ((tflags & FTS5_TOKEN_COLOCATED) ? 0 : 1);
}
pRow->zToken = sqlite3_malloc(nToken+1);
if( pRow->zToken==0 ) return SQLITE_NOMEM;
memcpy(pRow->zToken, pToken, nToken);
pRow->zToken[nToken] = 0;
pCsr->nRow++;
return SQLITE_OK;
}
/*
** xFilter - Initialize a cursor to point at the start of its data.
*/
static int fts5tokFilterMethod(
sqlite3_vtab_cursor *pCursor, /* The cursor used for this query */
int idxNum, /* Strategy index */
const char *idxStr, /* Unused */
int nVal, /* Number of elements in apVal */
sqlite3_value **apVal /* Arguments for the indexing scheme */
){
int rc = SQLITE_ERROR;
Fts5tokCursor *pCsr = (Fts5tokCursor *)pCursor;
Fts5tokTable *pTab = (Fts5tokTable *)(pCursor->pVtab);
fts5tokResetCursor(pCsr);
if( idxNum==1 ){
const char *zByte = (const char *)sqlite3_value_text(apVal[0]);
int nByte = sqlite3_value_bytes(apVal[0]);
pCsr->zInput = sqlite3_malloc(nByte+1);
if( pCsr->zInput==0 ){
rc = SQLITE_NOMEM;
}else{
memcpy(pCsr->zInput, zByte, nByte);
pCsr->zInput[nByte] = 0;
rc = pTab->tok.xTokenize(
pTab->pTok, (void*)pCsr, 0, zByte, nByte, fts5tokCb
);
}
}
if( rc!=SQLITE_OK ) return rc;
return fts5tokNextMethod(pCursor);
}
/*
** xEof - Return true if the cursor is at EOF, or false otherwise.
*/
static int fts5tokEofMethod(sqlite3_vtab_cursor *pCursor){
Fts5tokCursor *pCsr = (Fts5tokCursor *)pCursor;
return (pCsr->iRowid>pCsr->nRow);
}
/*
** xColumn - Return a column value.
*/
static int fts5tokColumnMethod(
sqlite3_vtab_cursor *pCursor, /* Cursor to retrieve value from */
sqlite3_context *pCtx, /* Context for sqlite3_result_xxx() calls */
int iCol /* Index of column to read value from */
){
Fts5tokCursor *pCsr = (Fts5tokCursor *)pCursor;
Fts5tokRow *pRow = &pCsr->aRow[pCsr->iRowid-1];
/* CREATE TABLE x(input, token, start, end, position) */
switch( iCol ){
case 0:
sqlite3_result_text(pCtx, pCsr->zInput, -1, SQLITE_TRANSIENT);
break;
case 1:
sqlite3_result_text(pCtx, pRow->zToken, -1, SQLITE_TRANSIENT);
break;
case 2:
sqlite3_result_int(pCtx, pRow->iStart);
break;
case 3:
sqlite3_result_int(pCtx, pRow->iEnd);
break;
default:
assert( iCol==4 );
sqlite3_result_int(pCtx, pRow->iPos);
break;
}
return SQLITE_OK;
}
/*
** xRowid - Return the current rowid for the cursor.
*/
static int fts5tokRowidMethod(
sqlite3_vtab_cursor *pCursor, /* Cursor to retrieve value from */
sqlite_int64 *pRowid /* OUT: Rowid value */
){
Fts5tokCursor *pCsr = (Fts5tokCursor *)pCursor;
*pRowid = (sqlite3_int64)pCsr->iRowid;
return SQLITE_OK;
}
/*
** Register the fts5tok module with database connection db. Return SQLITE_OK
** if successful or an error code if sqlite3_create_module() fails.
*/
int sqlite3Fts5TestRegisterTok(sqlite3 *db, fts5_api *pApi){
static const sqlite3_module fts5tok_module = {
0, /* iVersion */
fts5tokConnectMethod, /* xCreate */
fts5tokConnectMethod, /* xConnect */
fts5tokBestIndexMethod, /* xBestIndex */
fts5tokDisconnectMethod, /* xDisconnect */
fts5tokDisconnectMethod, /* xDestroy */
fts5tokOpenMethod, /* xOpen */
fts5tokCloseMethod, /* xClose */
fts5tokFilterMethod, /* xFilter */
fts5tokNextMethod, /* xNext */
fts5tokEofMethod, /* xEof */
fts5tokColumnMethod, /* xColumn */
fts5tokRowidMethod, /* xRowid */
0, /* xUpdate */
0, /* xBegin */
0, /* xSync */
0, /* xCommit */
0, /* xRollback */
0, /* xFindFunction */
0, /* xRename */
0, /* xSavepoint */
0, /* xRelease */
0 /* xRollbackTo */
};
int rc; /* Return code */
rc = sqlite3_create_module(db, "fts5tokenize", &fts5tok_module, (void*)pApi);
return rc;
}
#endif /* defined(SQLITE_TEST) && defined(SQLITE_ENABLE_FTS5) */
+14 -7
View File
@@ -62,12 +62,13 @@ static void fts5AsciiDelete(Fts5Tokenizer *p){
** Create an "ascii" tokenizer.
*/
static int fts5AsciiCreate(
void *pCtx,
void *pUnused,
const char **azArg, int nArg,
Fts5Tokenizer **ppOut
){
int rc = SQLITE_OK;
AsciiTokenizer *p = 0;
UNUSED_PARAM(pUnused);
if( nArg%2 ){
rc = SQLITE_ERROR;
}else{
@@ -116,7 +117,7 @@ static void asciiFold(char *aOut, const char *aIn, int nByte){
static int fts5AsciiTokenize(
Fts5Tokenizer *pTokenizer,
void *pCtx,
int flags,
int iUnused,
const char *pText, int nText,
int (*xToken)(void*, int, const char*, int nToken, int iStart, int iEnd)
){
@@ -130,6 +131,8 @@ static int fts5AsciiTokenize(
char *pFold = aFold;
unsigned char *a = p->aTokenChar;
UNUSED_PARAM(iUnused);
while( is<nText && rc==SQLITE_OK ){
int nByte;
@@ -242,7 +245,7 @@ static int fts5UnicodeAddExceptions(
int bTokenChars /* 1 for 'tokenchars', 0 for 'separators' */
){
int rc = SQLITE_OK;
int n = strlen(z);
int n = (int)strlen(z);
int *aNew;
if( n>0 ){
@@ -256,7 +259,7 @@ static int fts5UnicodeAddExceptions(
int bToken;
READ_UTF8(zCsr, zTerm, iCode);
if( iCode<128 ){
p->aTokenChar[iCode] = bTokenChars;
p->aTokenChar[iCode] = (unsigned char)bTokenChars;
}else{
bToken = sqlite3Fts5UnicodeIsalnum(iCode);
assert( (bToken==0 || bToken==1) );
@@ -323,13 +326,15 @@ static void fts5UnicodeDelete(Fts5Tokenizer *pTok){
** Create a "unicode61" tokenizer.
*/
static int fts5UnicodeCreate(
void *pCtx,
void *pUnused,
const char **azArg, int nArg,
Fts5Tokenizer **ppOut
){
int rc = SQLITE_OK; /* Return code */
Unicode61Tokenizer *p = 0; /* New tokenizer object */
UNUSED_PARAM(pUnused);
if( nArg%2 ){
rc = SQLITE_ERROR;
}else{
@@ -386,7 +391,7 @@ static int fts5UnicodeIsAlnum(Unicode61Tokenizer *p, int iCode){
static int fts5UnicodeTokenize(
Fts5Tokenizer *pTokenizer,
void *pCtx,
int flags,
int iUnused,
const char *pText, int nText,
int (*xToken)(void*, int, const char*, int nToken, int iStart, int iEnd)
){
@@ -402,6 +407,8 @@ static int fts5UnicodeTokenize(
int nFold = p->nFold;
const char *pEnd = &aFold[nFold-6];
UNUSED_PARAM(iUnused);
/* Each iteration of this loop gobbles up a contiguous run of separators,
** then the next token. */
while( rc==SQLITE_OK ){
@@ -1220,7 +1227,7 @@ int sqlite3Fts5TokenizerInit(fts5_api *pApi){
int rc = SQLITE_OK; /* Return code */
int i; /* To iterate through builtin functions */
for(i=0; rc==SQLITE_OK && i<sizeof(aBuiltin)/sizeof(aBuiltin[0]); i++){
for(i=0; rc==SQLITE_OK && i<ArraySize(aBuiltin); i++){
rc = pApi->xCreateTokenizer(pApi,
aBuiltin[i].zName,
(void*)pApi,
+2 -2
View File
@@ -125,9 +125,9 @@ int sqlite3Fts5UnicodeIsalnum(int c){
0xFFFFFFFF, 0xFC00FFFF, 0xF8000001, 0xF8000001,
};
if( c<128 ){
if( (unsigned int)c<128 ){
return ( (aAscii[c >> 5] & (1 << (c & 0x001F)))==0 );
}else if( c<(1<<22) ){
}else if( (unsigned int)c<(1<<22) ){
unsigned int key = (((unsigned int)c)<<10) | 0x000003FF;
int iRes = 0;
int iHi = sizeof(aEntry)/sizeof(aEntry[0]) - 1;
+3
View File
@@ -333,7 +333,10 @@ int sqlite3Fts5PutVarint(unsigned char *p, u64 v){
int sqlite3Fts5GetVarintLen(u32 iVal){
#if 0
if( iVal<(1 << 7 ) ) return 1;
#endif
assert( iVal>=(1 << 7) );
if( iVal<(1 << 14) ) return 2;
if( iVal<(1 << 21) ) return 3;
if( iVal<(1 << 28) ) return 4;
+212 -59
View File
@@ -55,16 +55,18 @@ struct Fts5VocabCursor {
int bEof; /* True if this cursor is at EOF */
Fts5IndexIter *pIter; /* Term/rowid iterator object */
int nLeTerm; /* Size of zLeTerm in bytes */
char *zLeTerm; /* (term <= $zLeTerm) paramater, or NULL */
/* These are used by 'col' tables only */
int nCol;
Fts5Config *pConfig; /* Fts5 table configuration */
int iCol;
i64 *aCnt;
i64 *aDoc;
/* Output values */
/* Output values used by 'row' and 'col' tables */
i64 rowid; /* This table's current rowid value */
Fts5Buffer term; /* Current value of 'term' column */
i64 aVal[3]; /* Up to three columns left of 'term' */
};
#define FTS5_VOCAB_COL 0
@@ -73,6 +75,14 @@ struct Fts5VocabCursor {
#define FTS5_VOCAB_COL_SCHEMA "term, col, doc, cnt"
#define FTS5_VOCAB_ROW_SCHEMA "term, doc, cnt"
/*
** Bits for the mask used as the idxNum value by xBestIndex/xFilter.
*/
#define FTS5_VOCAB_TERM_EQ 0x01
#define FTS5_VOCAB_TERM_GE 0x02
#define FTS5_VOCAB_TERM_LE 0x04
/*
** Translate a string containing an fts5vocab table type to an
** FTS5_VOCAB_XXX constant. If successful, set *peType to the output
@@ -168,13 +178,13 @@ static int fts5VocabInitVtab(
const char *zDb = bDb ? argv[3] : argv[1];
const char *zTab = bDb ? argv[4] : argv[3];
const char *zType = bDb ? argv[5] : argv[4];
int nDb = strlen(zDb)+1;
int nTab = strlen(zTab)+1;
int eType;
int nDb = (int)strlen(zDb)+1;
int nTab = (int)strlen(zTab)+1;
int eType = 0;
rc = fts5VocabTableType(zType, pzErr, &eType);
if( rc==SQLITE_OK ){
assert( eType>=0 && eType<sizeof(azSchema)/sizeof(azSchema[0]) );
assert( eType>=0 && eType<ArraySize(azSchema) );
rc = sqlite3_declare_vtab(db, azSchema[eType]);
}
@@ -227,9 +237,50 @@ static int fts5VocabCreateMethod(
** Implementation of the xBestIndex method.
*/
static int fts5VocabBestIndexMethod(
sqlite3_vtab *pVTab,
sqlite3_vtab *pUnused,
sqlite3_index_info *pInfo
){
int i;
int iTermEq = -1;
int iTermGe = -1;
int iTermLe = -1;
int idxNum = 0;
int nArg = 0;
UNUSED_PARAM(pUnused);
for(i=0; i<pInfo->nConstraint; i++){
struct sqlite3_index_constraint *p = &pInfo->aConstraint[i];
if( p->usable==0 ) continue;
if( p->iColumn==0 ){ /* term column */
if( p->op==SQLITE_INDEX_CONSTRAINT_EQ ) iTermEq = i;
if( p->op==SQLITE_INDEX_CONSTRAINT_LE ) iTermLe = i;
if( p->op==SQLITE_INDEX_CONSTRAINT_LT ) iTermLe = i;
if( p->op==SQLITE_INDEX_CONSTRAINT_GE ) iTermGe = i;
if( p->op==SQLITE_INDEX_CONSTRAINT_GT ) iTermGe = i;
}
}
if( iTermEq>=0 ){
idxNum |= FTS5_VOCAB_TERM_EQ;
pInfo->aConstraintUsage[iTermEq].argvIndex = ++nArg;
pInfo->estimatedCost = 100;
}else{
pInfo->estimatedCost = 1000000;
if( iTermGe>=0 ){
idxNum |= FTS5_VOCAB_TERM_GE;
pInfo->aConstraintUsage[iTermGe].argvIndex = ++nArg;
pInfo->estimatedCost = pInfo->estimatedCost / 2;
}
if( iTermLe>=0 ){
idxNum |= FTS5_VOCAB_TERM_LE;
pInfo->aConstraintUsage[iTermLe].argvIndex = ++nArg;
pInfo->estimatedCost = pInfo->estimatedCost / 2;
}
}
pInfo->idxNum = idxNum;
return SQLITE_OK;
}
@@ -242,12 +293,11 @@ static int fts5VocabOpenMethod(
){
Fts5VocabTable *pTab = (Fts5VocabTable*)pVTab;
Fts5Index *pIndex = 0;
int nCol = 0;
Fts5Config *pConfig = 0;
Fts5VocabCursor *pCsr = 0;
int rc = SQLITE_OK;
sqlite3_stmt *pStmt = 0;
char *zSql = 0;
int nByte;
zSql = sqlite3Fts5Mprintf(&rc,
"SELECT t.%Q FROM %Q.%Q AS t WHERE t.%Q MATCH '*id'",
@@ -262,7 +312,7 @@ static int fts5VocabOpenMethod(
if( pStmt && sqlite3_step(pStmt)==SQLITE_ROW ){
i64 iId = sqlite3_column_int64(pStmt, 0);
pIndex = sqlite3Fts5IndexFromCsrid(pTab->pGlobal, iId, &nCol);
pIndex = sqlite3Fts5IndexFromCsrid(pTab->pGlobal, iId, &pConfig);
}
if( rc==SQLITE_OK && pIndex==0 ){
@@ -276,14 +326,17 @@ static int fts5VocabOpenMethod(
}
}
nByte = nCol * sizeof(i64) * 2 + sizeof(Fts5VocabCursor);
pCsr = (Fts5VocabCursor*)sqlite3Fts5MallocZero(&rc, nByte);
if( rc==SQLITE_OK ){
int nByte = pConfig->nCol * sizeof(i64) * 2 + sizeof(Fts5VocabCursor);
pCsr = (Fts5VocabCursor*)sqlite3Fts5MallocZero(&rc, nByte);
}
if( pCsr ){
pCsr->pIndex = pIndex;
pCsr->pStmt = pStmt;
pCsr->nCol = nCol;
pCsr->pConfig = pConfig;
pCsr->aCnt = (i64*)&pCsr[1];
pCsr->aDoc = &pCsr->aCnt[nCol];
pCsr->aDoc = &pCsr->aCnt[pConfig->nCol];
}else{
sqlite3_finalize(pStmt);
}
@@ -296,6 +349,9 @@ static void fts5VocabResetCursor(Fts5VocabCursor *pCsr){
pCsr->rowid = 0;
sqlite3Fts5IterClose(pCsr->pIter);
pCsr->pIter = 0;
sqlite3_free(pCsr->zLeTerm);
pCsr->nLeTerm = -1;
pCsr->zLeTerm = 0;
}
/*
@@ -319,16 +375,17 @@ static int fts5VocabNextMethod(sqlite3_vtab_cursor *pCursor){
Fts5VocabCursor *pCsr = (Fts5VocabCursor*)pCursor;
Fts5VocabTable *pTab = (Fts5VocabTable*)pCursor->pVtab;
int rc = SQLITE_OK;
int nCol = pCsr->pConfig->nCol;
pCsr->rowid++;
if( pTab->eType==FTS5_VOCAB_COL ){
for(pCsr->iCol++; pCsr->iCol<pCsr->nCol; pCsr->iCol++){
if( pCsr->aCnt[pCsr->iCol] ) break;
for(pCsr->iCol++; pCsr->iCol<nCol; pCsr->iCol++){
if( pCsr->aDoc[pCsr->iCol] ) break;
}
}
if( pTab->eType==FTS5_VOCAB_ROW || pCsr->iCol>=pCsr->nCol ){
if( pTab->eType==FTS5_VOCAB_ROW || pCsr->iCol>=nCol ){
if( sqlite3Fts5IterEof(pCsr->pIter) ){
pCsr->bEof = 1;
}else{
@@ -336,53 +393,93 @@ static int fts5VocabNextMethod(sqlite3_vtab_cursor *pCursor){
int nTerm;
zTerm = sqlite3Fts5IterTerm(pCsr->pIter, &nTerm);
if( pCsr->nLeTerm>=0 ){
int nCmp = MIN(nTerm, pCsr->nLeTerm);
int bCmp = memcmp(pCsr->zLeTerm, zTerm, nCmp);
if( bCmp<0 || (bCmp==0 && pCsr->nLeTerm<nTerm) ){
pCsr->bEof = 1;
return SQLITE_OK;
}
}
sqlite3Fts5BufferSet(&rc, &pCsr->term, nTerm, (const u8*)zTerm);
memset(pCsr->aVal, 0, sizeof(pCsr->aVal));
memset(pCsr->aCnt, 0, pCsr->nCol * sizeof(i64));
memset(pCsr->aDoc, 0, pCsr->nCol * sizeof(i64));
memset(pCsr->aCnt, 0, nCol * sizeof(i64));
memset(pCsr->aDoc, 0, nCol * sizeof(i64));
pCsr->iCol = 0;
assert( pTab->eType==FTS5_VOCAB_COL || pTab->eType==FTS5_VOCAB_ROW );
while( rc==SQLITE_OK ){
i64 dummy;
const u8 *pPos; int nPos; /* Position list */
i64 iPos = 0; /* 64-bit position read from poslist */
int iOff = 0; /* Current offset within position list */
rc = sqlite3Fts5IterPoslist(pCsr->pIter, 0, &pPos, &nPos, &dummy);
if( rc==SQLITE_OK ){
if( pTab->eType==FTS5_VOCAB_ROW ){
while( 0==sqlite3Fts5PoslistNext64(pPos, nPos, &iOff, &iPos) ){
pCsr->aVal[1]++;
}
pCsr->aVal[0]++;
}else{
int iCol = -1;
while( 0==sqlite3Fts5PoslistNext64(pPos, nPos, &iOff, &iPos) ){
int ii = FTS5_POS2COLUMN(iPos);
pCsr->aCnt[ii]++;
if( iCol!=ii ){
pCsr->aDoc[ii]++;
iCol = ii;
pPos = pCsr->pIter->pData;
nPos = pCsr->pIter->nData;
switch( pCsr->pConfig->eDetail ){
case FTS5_DETAIL_FULL:
pPos = pCsr->pIter->pData;
nPos = pCsr->pIter->nData;
if( pTab->eType==FTS5_VOCAB_ROW ){
while( 0==sqlite3Fts5PoslistNext64(pPos, nPos, &iOff, &iPos) ){
pCsr->aCnt[0]++;
}
pCsr->aDoc[0]++;
}else{
int iCol = -1;
while( 0==sqlite3Fts5PoslistNext64(pPos, nPos, &iOff, &iPos) ){
int ii = FTS5_POS2COLUMN(iPos);
pCsr->aCnt[ii]++;
if( iCol!=ii ){
if( ii>=nCol ){
rc = FTS5_CORRUPT;
break;
}
pCsr->aDoc[ii]++;
iCol = ii;
}
}
}
}
break;
case FTS5_DETAIL_COLUMNS:
if( pTab->eType==FTS5_VOCAB_ROW ){
pCsr->aDoc[0]++;
}else{
while( 0==sqlite3Fts5PoslistNext64(pPos, nPos, &iOff,&iPos) ){
assert_nc( iPos>=0 && iPos<nCol );
if( iPos>=nCol ){
rc = FTS5_CORRUPT;
break;
}
pCsr->aDoc[iPos]++;
}
}
break;
default:
assert( pCsr->pConfig->eDetail==FTS5_DETAIL_NONE );
pCsr->aDoc[0]++;
break;
}
if( rc==SQLITE_OK ){
rc = sqlite3Fts5IterNextScan(pCsr->pIter);
}
if( rc==SQLITE_OK ){
zTerm = sqlite3Fts5IterTerm(pCsr->pIter, &nTerm);
if( nTerm!=pCsr->term.n || memcmp(zTerm, pCsr->term.p, nTerm) ) break;
if( nTerm!=pCsr->term.n || memcmp(zTerm, pCsr->term.p, nTerm) ){
break;
}
if( sqlite3Fts5IterEof(pCsr->pIter) ) break;
}
}
}
}
if( pCsr->bEof==0 && pTab->eType==FTS5_VOCAB_COL ){
while( pCsr->aCnt[pCsr->iCol]==0 ) pCsr->iCol++;
pCsr->aVal[0] = pCsr->iCol;
pCsr->aVal[1] = pCsr->aDoc[pCsr->iCol];
pCsr->aVal[2] = pCsr->aCnt[pCsr->iCol];
if( rc==SQLITE_OK && pCsr->bEof==0 && pTab->eType==FTS5_VOCAB_COL ){
while( pCsr->aDoc[pCsr->iCol]==0 ) pCsr->iCol++;
assert( pCsr->iCol<pCsr->pConfig->nCol );
}
return rc;
}
@@ -393,16 +490,54 @@ static int fts5VocabNextMethod(sqlite3_vtab_cursor *pCursor){
static int fts5VocabFilterMethod(
sqlite3_vtab_cursor *pCursor, /* The cursor used for this query */
int idxNum, /* Strategy index */
const char *idxStr, /* Unused */
int nVal, /* Number of elements in apVal */
const char *zUnused, /* Unused */
int nUnused, /* Number of elements in apVal */
sqlite3_value **apVal /* Arguments for the indexing scheme */
){
Fts5VocabCursor *pCsr = (Fts5VocabCursor*)pCursor;
int rc;
const int flags = FTS5INDEX_QUERY_SCAN;
int rc = SQLITE_OK;
int iVal = 0;
int f = FTS5INDEX_QUERY_SCAN;
const char *zTerm = 0;
int nTerm = 0;
sqlite3_value *pEq = 0;
sqlite3_value *pGe = 0;
sqlite3_value *pLe = 0;
UNUSED_PARAM2(zUnused, nUnused);
fts5VocabResetCursor(pCsr);
rc = sqlite3Fts5IndexQuery(pCsr->pIndex, 0, 0, flags, 0, &pCsr->pIter);
if( idxNum & FTS5_VOCAB_TERM_EQ ) pEq = apVal[iVal++];
if( idxNum & FTS5_VOCAB_TERM_GE ) pGe = apVal[iVal++];
if( idxNum & FTS5_VOCAB_TERM_LE ) pLe = apVal[iVal++];
if( pEq ){
zTerm = (const char *)sqlite3_value_text(pEq);
nTerm = sqlite3_value_bytes(pEq);
f = 0;
}else{
if( pGe ){
zTerm = (const char *)sqlite3_value_text(pGe);
nTerm = sqlite3_value_bytes(pGe);
}
if( pLe ){
const char *zCopy = (const char *)sqlite3_value_text(pLe);
pCsr->nLeTerm = sqlite3_value_bytes(pLe);
pCsr->zLeTerm = sqlite3_malloc(pCsr->nLeTerm+1);
if( pCsr->zLeTerm==0 ){
rc = SQLITE_NOMEM;
}else{
memcpy(pCsr->zLeTerm, zCopy, pCsr->nLeTerm+1);
}
}
}
if( rc==SQLITE_OK ){
rc = sqlite3Fts5IndexQuery(pCsr->pIndex, zTerm, nTerm, f, 0, &pCsr->pIter);
}
if( rc==SQLITE_OK ){
rc = fts5VocabNextMethod(pCursor);
}
@@ -425,18 +560,36 @@ static int fts5VocabColumnMethod(
int iCol /* Index of column to read value from */
){
Fts5VocabCursor *pCsr = (Fts5VocabCursor*)pCursor;
switch( iCol ){
case 0: /* term */
sqlite3_result_text(
pCtx, (const char*)pCsr->term.p, pCsr->term.n, SQLITE_TRANSIENT
);
break;
int eDetail = pCsr->pConfig->eDetail;
int eType = ((Fts5VocabTable*)(pCursor->pVtab))->eType;
i64 iVal = 0;
default:
assert( iCol<4 && iCol>0 );
sqlite3_result_int64(pCtx, pCsr->aVal[iCol-1]);
break;
if( iCol==0 ){
sqlite3_result_text(
pCtx, (const char*)pCsr->term.p, pCsr->term.n, SQLITE_TRANSIENT
);
}else if( eType==FTS5_VOCAB_COL ){
assert( iCol==1 || iCol==2 || iCol==3 );
if( iCol==1 ){
if( eDetail!=FTS5_DETAIL_NONE ){
const char *z = pCsr->pConfig->azCol[pCsr->iCol];
sqlite3_result_text(pCtx, z, -1, SQLITE_STATIC);
}
}else if( iCol==2 ){
iVal = pCsr->aDoc[pCsr->iCol];
}else{
iVal = pCsr->aCnt[pCsr->iCol];
}
}else{
assert( iCol==1 || iCol==2 );
if( iCol==1 ){
iVal = pCsr->aDoc[0];
}else{
iVal = pCsr->aCnt[0];
}
}
if( iVal>0 ) sqlite3_result_int64(pCtx, iVal);
return SQLITE_OK;
}
+14 -5
View File
@@ -28,12 +28,13 @@
// This code runs whenever there is a syntax error
//
%syntax_error {
UNUSED_PARAM(yymajor); /* Silence a compiler warning */
sqlite3Fts5ParseError(
pParse, "fts5: syntax error near \"%.*s\"",TOKEN.n,TOKEN.p
);
}
%stack_overflow {
assert( 0 );
sqlite3Fts5ParseError(pParse, "fts5: parser stack overflow");
}
// The name of the generated procedure that implements the parser
@@ -58,6 +59,18 @@
*/
#define yytestcase(X) testcase(X)
/*
** Indicate that sqlite3ParserFree() will never be called with a null
** pointer.
*/
#define YYPARSEFREENOTNULL 1
/*
** Alternative datatype for the argument to the malloc() routine passed
** into sqlite3ParserAlloc(). The default is size_t.
*/
#define YYMALLOCARGTYPE u64
} // end %include
%left OR.
@@ -168,7 +181,3 @@ phrase(A) ::= STRING(Y) star_opt(Z). {
star_opt(A) ::= STAR. { A = 1; }
star_opt(A) ::= . { A = 0; }
+331 -19
View File
@@ -15,6 +15,16 @@ if {![info exists testdir]} {
}
source $testdir/tester.tcl
ifcapable !fts5 {
proc return_if_no_fts5 {} {
finish_test
return -code return
}
return
} else {
proc return_if_no_fts5 {} {}
}
catch {
sqlite3_fts5_may_be_corrupt 0
reset_db
@@ -28,6 +38,29 @@ proc fts5_test_poslist {cmd} {
set res
}
proc fts5_test_poslist2 {cmd} {
set res [list]
for {set i 0} {$i < [$cmd xPhraseCount]} {incr i} {
$cmd xPhraseForeach $i c o {
lappend res $i.$c.$o
}
}
#set res
sort_poslist $res
}
proc fts5_test_collist {cmd} {
set res [list]
for {set i 0} {$i < [$cmd xPhraseCount]} {incr i} {
$cmd xPhraseColumnForeach $i c { lappend res $i.$c }
}
set res
}
proc fts5_test_columnsize {cmd} {
set res [list]
for {set i 0} {$i < [$cmd xColumnCount]} {incr i} {
@@ -113,6 +146,8 @@ proc fts5_aux_test_functions {db} {
fts5_test_columntext
fts5_test_columntotalsize
fts5_test_poslist
fts5_test_poslist2
fts5_test_collist
fts5_test_tokenize
fts5_test_rowcount
fts5_test_all
@@ -178,15 +213,24 @@ proc fts5_rnddoc {n} {
# -near N (NEAR distance. Default 10)
# -col C (List of column indexes to match against)
# -pc VARNAME (variable in caller frame to use for phrase numbering)
# -dict VARNAME (array in caller frame to use for synonyms)
#
proc nearset {aCol args} {
# Process the command line options.
#
set O(-near) 10
set O(-col) {}
set O(-pc) ""
set O(-dict) ""
set nOpt [lsearch -exact $args --]
if {$nOpt<0} { error "no -- option" }
# Set $lPhrase to be a list of phrases. $nPhrase its length.
set lPhrase [lrange $args [expr $nOpt+1] end]
set nPhrase [llength $lPhrase]
foreach {k v} [lrange $args 0 [expr $nOpt-1]] {
if {[info exists O($k)]==0} { error "unrecognized option $k" }
set O($k) $v
@@ -198,9 +242,7 @@ proc nearset {aCol args} {
upvar $O(-pc) counter
}
# Set $phraselist to be a list of phrases. $nPhrase its length.
set phraselist [lrange $args [expr $nOpt+1] end]
set nPhrase [llength $phraselist]
if {$O(-dict)!=""} { upvar $O(-dict) aDict }
for {set j 0} {$j < [llength $aCol]} {incr j} {
for {set i 0} {$i < $nPhrase} {incr i} {
@@ -208,27 +250,54 @@ proc nearset {aCol args} {
}
}
set iCol -1
foreach col $aCol {
incr iCol
if {$O(-col)!="" && [lsearch $O(-col) $iCol]<0} continue
set nToken [llength $col]
# Loop through each column of the current row.
for {set iCol 0} {$iCol < [llength $aCol]} {incr iCol} {
set iFL [expr $O(-near) >= $nToken ? $nToken - 1 : $O(-near)]
for { } {$iFL < $nToken} {incr iFL} {
for {set iPhrase 0} {$iPhrase<$nPhrase} {incr iPhrase} {
set B($iPhrase) [list]
}
# If there is a column filter, test whether this column is excluded. If
# so, skip to the next iteration of this loop. Otherwise, set zCol to the
# column value and nToken to the number of tokens that comprise it.
if {$O(-col)!="" && [lsearch $O(-col) $iCol]<0} continue
set zCol [lindex $aCol $iCol]
set nToken [llength $zCol]
# Each iteration of the following loop searches a substring of the
# column value for phrase matches. The last token of the substring
# is token $iLast of the column value. The first token is:
#
# iFirst = ($iLast - $O(-near) - 1)
#
# where $sz is the length of the phrase being searched for. A phrase
# counts as matching the substring if its first token lies on or before
# $iLast and its last token on or after $iFirst.
#
# For example, if the query is "NEAR(a+b c, 2)" and the column value:
#
# "x x x x A B x x C x"
# 0 1 2 3 4 5 6 7 8 9"
#
# when (iLast==8 && iFirst=5) the range will contain both phrases and
# so both instances can be added to the output poslists.
#
set iLast [expr $O(-near) >= $nToken ? $nToken - 1 : $O(-near)]
for { } {$iLast < $nToken} {incr iLast} {
catch { array unset B }
for {set iPhrase 0} {$iPhrase<$nPhrase} {incr iPhrase} {
set p [lindex $phraselist $iPhrase]
set p [lindex $lPhrase $iPhrase]
set nPm1 [expr {[llength $p] - 1}]
set iFirst [expr $iFL - $O(-near) - [llength $p]]
set iFirst [expr $iLast - $O(-near) - [llength $p]]
for {set i $iFirst} {$i <= $iFL} {incr i} {
if {[lrange $col $i [expr $i+$nPm1]] == $p} { lappend B($iPhrase) $i }
for {set i $iFirst} {$i <= $iLast} {incr i} {
set lCand [lrange $zCol $i [expr $i+$nPm1]]
set bMatch 1
foreach tok $p term $lCand {
if {[nearset_match aDict $tok $term]==0} { set bMatch 0 ; break }
}
if {$bMatch} { lappend B($iPhrase) $i }
}
if {[llength $B($iPhrase)] == 0} break
if {![info exists B($iPhrase)]} break
}
if {$iPhrase==$nPhrase} {
@@ -252,10 +321,22 @@ proc nearset {aCol args} {
incr counter
}
#puts $res
#puts "$aCol -> $res"
sort_poslist $res
}
proc nearset_match {aDictVar tok term} {
if {[string match $tok $term]} { return 1 }
upvar $aDictVar aDict
if {[info exists aDict($tok)]} {
foreach s $aDict($tok) {
if {[string match $s $term]} { return 1 }
}
}
return 0;
}
#-------------------------------------------------------------------------
# Usage:
#
@@ -327,3 +408,234 @@ proc fts5_tokenize_split {text} {
set ret
}
#-------------------------------------------------------------------------
#
proc foreach_detail_mode {prefix script} {
set saved $::testprefix
foreach d [list full col none] {
set s [string map [list %DETAIL% $d] $script]
set ::detail $d
set ::testprefix "$prefix-$d"
reset_db
uplevel $s
unset ::detail
}
set ::testprefix $saved
}
proc detail_check {} {
if {$::detail != "none" && $::detail!="full" && $::detail!="col"} {
error "not in foreach_detail_mode {...} block"
}
}
proc detail_is_none {} { detail_check ; expr {$::detail == "none"} }
proc detail_is_col {} { detail_check ; expr {$::detail == "col" } }
proc detail_is_full {} { detail_check ; expr {$::detail == "full"} }
#-------------------------------------------------------------------------
# Convert a poslist of the type returned by fts5_test_poslist() to a
# collist as returned by fts5_test_collist().
#
proc fts5_poslist2collist {poslist} {
set res [list]
foreach h $poslist {
regexp {(.*)\.[1234567890]+} $h -> cand
lappend res $cand
}
set res [lsort -command fts5_collist_elem_compare -unique $res]
return $res
}
# Comparison function used by fts5_poslist2collist to sort collist entries.
proc fts5_collist_elem_compare {a b} {
foreach {a1 a2} [split $a .] {}
foreach {b1 b2} [split $b .] {}
if {$a1==$b1} { return [expr $a2 - $b2] }
return [expr $a1 - $b1]
}
#--------------------------------------------------------------------------
# Construct and return a tcl list equivalent to that returned by the SQL
# query executed against database handle [db]:
#
# SELECT
# rowid,
# fts5_test_poslist($tbl),
# fts5_test_collist($tbl)
# FROM $tbl('$expr')
# ORDER BY rowid $order;
#
proc fts5_query_data {expr tbl {order ASC} {aDictVar ""}} {
# Figure out the set of columns in the FTS5 table. This routine does
# not handle tables with UNINDEXED columns, but if it did, it would
# have to be here.
db eval "PRAGMA table_info = $tbl" x { lappend lCols $x(name) }
set d ""
if {$aDictVar != ""} {
upvar $aDictVar aDict
set d aDict
}
set cols ""
foreach e $lCols { append cols ", '$e'" }
set tclexpr [db one [subst -novar {
SELECT fts5_expr_tcl( $expr, 'nearset $cols -dict $d -pc ::pc' [set cols] )
}]]
set res [list]
db eval "SELECT rowid, * FROM $tbl ORDER BY rowid $order" x {
set cols [list]
foreach col $lCols { lappend cols $x($col) }
set ::pc 0
set rowdata [eval $tclexpr]
if {$rowdata != ""} {
lappend res $x(rowid) $rowdata [fts5_poslist2collist $rowdata]
}
}
set res
}
#-------------------------------------------------------------------------
# Similar to [fts5_query_data], but omit the collist field.
#
proc fts5_poslist_data {expr tbl {order ASC} {aDictVar ""}} {
set res [list]
if {$aDictVar!=""} {
upvar $aDictVar aDict
set dict aDict
} else {
set dict ""
}
foreach {rowid poslist collist} [fts5_query_data $expr $tbl $order $dict] {
lappend res $rowid $poslist
}
set res
}
proc fts5_collist_data {expr tbl {order ASC} {aDictVar ""}} {
set res [list]
if {$aDictVar!=""} {
upvar $aDictVar aDict
set dict aDict
} else {
set dict ""
}
foreach {rowid poslist collist} [fts5_query_data $expr $tbl $order $dict] {
lappend res $rowid $collist
}
set res
}
#-------------------------------------------------------------------------
#
# This command will only work inside a [foreach_detail_mode] block. It tests
# whether or not expression $expr run on FTS5 table $tbl is supported by
# the current mode. If so, 1 is returned. If not, 0.
#
# detail=full (all queries supported)
# detail=col (all but phrase queries and NEAR queries)
# detail=none (all but phrase queries, NEAR queries, and column filters)
#
proc fts5_expr_ok {expr tbl} {
if {![detail_is_full]} {
set nearset "nearset_rc"
if {[detail_is_col]} { set nearset "nearset_rf" }
set ::expr_not_ok 0
db eval "PRAGMA table_info = $tbl" x { lappend lCols $x(name) }
set cols ""
foreach e $lCols { append cols ", '$e'" }
set ::pc 0
set tclexpr [db one [subst -novar {
SELECT fts5_expr_tcl( $expr, '[set nearset] $cols -pc ::pc' [set cols] )
}]]
eval $tclexpr
if {$::expr_not_ok} { return 0 }
}
return 1
}
# Helper for [fts5_expr_ok]
proc nearset_rf {aCol args} {
set idx [lsearch -exact $args --]
if {$idx != [llength $args]-2 || [llength [lindex $args end]]!=1} {
set ::expr_not_ok 1
}
list
}
# Helper for [fts5_expr_ok]
proc nearset_rc {aCol args} {
nearset_rf $aCol {*}$args
if {[lsearch $args -col]>=0} {
set ::expr_not_ok 1
}
list
}
#-------------------------------------------------------------------------
# Code for a simple Tcl tokenizer that supports synonyms at query time.
#
proc tclnum_tokenize {mode tflags text} {
foreach {w iStart iEnd} [fts5_tokenize_split $text] {
sqlite3_fts5_token $w $iStart $iEnd
if {$tflags == $mode && [info exists ::tclnum_syn($w)]} {
foreach s $::tclnum_syn($w) { sqlite3_fts5_token -colo $s $iStart $iEnd }
}
}
}
proc tclnum_create {args} {
set mode query
if {[llength $args]} {
set mode [lindex $args 0]
}
if {$mode != "query" && $mode != "document"} { error "bad mode: $mode" }
return [list tclnum_tokenize $mode]
}
proc fts5_tclnum_register {db} {
foreach SYNDICT {
{zero 0}
{one 1 i}
{two 2 ii}
{three 3 iii}
{four 4 iv}
{five 5 v}
{six 6 vi}
{seven 7 vii}
{eight 8 viii}
{nine 9 ix}
{a1 a2 a3 a4 a5 a6 a7 a8 a9}
{b1 b2 b3 b4 b5 b6 b7 b8 b9}
{c1 c2 c3 c4 c5 c6 c7 c8 c9}
} {
foreach s $SYNDICT {
set o [list]
foreach x $SYNDICT {if {$x!=$s} {lappend o $x}}
set ::tclnum_syn($s) $o
}
}
sqlite3_fts5_create_tokenizer db tclnum tclnum_create
}
#
# End of tokenizer code.
#-------------------------------------------------------------------------
+48 -27
View File
@@ -15,12 +15,14 @@
source [file join [file dirname [info script]] fts5_common.tcl]
set testprefix fts5aa
# If SQLITE_ENABLE_FTS3 is defined, omit this file.
# If SQLITE_ENABLE_FTS5 is not defined, omit this file.
ifcapable !fts5 {
finish_test
return
}
foreach_detail_mode $::testprefix {
do_execsql_test 1.0 {
CREATE VIRTUAL TABLE t1 USING fts5(a, b, c);
SELECT name, sql FROM sqlite_master;
@@ -41,9 +43,9 @@ do_execsql_test 1.1 {
#-------------------------------------------------------------------------
#
reset_db
do_execsql_test 2.0 {
CREATE VIRTUAL TABLE t1 USING fts5(x,y);
CREATE VIRTUAL TABLE t1 USING fts5(x, y, detail=%DETAIL%);
}
do_execsql_test 2.1 {
INSERT INTO t1 VALUES('a b c', 'd e f');
@@ -66,11 +68,12 @@ do_execsql_test 2.4 {
INSERT INTO t1(t1) VALUES('integrity-check');
}
#-------------------------------------------------------------------------
#
reset_db
do_execsql_test 3.0 {
CREATE VIRTUAL TABLE t1 USING fts5(x,y);
CREATE VIRTUAL TABLE t1 USING fts5(x,y, detail=%DETAIL%);
}
foreach {i x y} {
1 {g f d b f} {h h e i a}
@@ -93,7 +96,7 @@ foreach {i x y} {
#
reset_db
do_execsql_test 4.0 {
CREATE VIRTUAL TABLE t1 USING fts5(x,y);
CREATE VIRTUAL TABLE t1 USING fts5(x,y, detail=%DETAIL%);
INSERT INTO t1(t1, rank) VALUES('pgsz', 32);
}
foreach {i x y} {
@@ -117,7 +120,7 @@ foreach {i x y} {
#
reset_db
do_execsql_test 5.0 {
CREATE VIRTUAL TABLE t1 USING fts5(x,y);
CREATE VIRTUAL TABLE t1 USING fts5(x,y, detail=%DETAIL%);
INSERT INTO t1(t1, rank) VALUES('pgsz', 32);
}
foreach {i x y} {
@@ -141,7 +144,7 @@ foreach {i x y} {
#
reset_db
do_execsql_test 6.0 {
CREATE VIRTUAL TABLE t1 USING fts5(x,y);
CREATE VIRTUAL TABLE t1 USING fts5(x,y, detail=%DETAIL%);
INSERT INTO t1(t1, rank) VALUES('pgsz', 32);
}
@@ -159,9 +162,20 @@ do_execsql_test 6.3 {
}
do_execsql_test 6.4 {
REPLACE INTO t1(x, y) VALUES('x y z', 'x y z');
}
do_execsql_test 6.5 {
INSERT INTO t1(t1) VALUES('integrity-check')
}
do_execsql_test 6.6 {
SELECT rowid, * FROM t1;
} {
22 {l l l} {l l l}
23 {x y z} {x y z}
}
#-------------------------------------------------------------------------
#
reset_db
@@ -265,7 +279,7 @@ for {set i 1} {$i <= 10} {incr i} {
#
reset_db
do_execsql_test 10.0 {
CREATE VIRTUAL TABLE t1 USING fts5(x,y);
CREATE VIRTUAL TABLE t1 USING fts5(x,y, detail=%DETAIL%);
}
set d10 {
1 {g f d b f} {h h e i a}
@@ -298,19 +312,19 @@ do_execsql_test 10.4.2 { INSERT INTO t1(t1) VALUES('integrity-check') }
#-------------------------------------------------------------------------
#
do_catchsql_test 11.1 {
CREATE VIRTUAL TABLE t2 USING fts5(a, b, c, rank);
CREATE VIRTUAL TABLE t2 USING fts5(a, b, c, rank, detail=%DETAIL%);
} {1 {reserved fts5 column name: rank}}
do_catchsql_test 11.2 {
CREATE VIRTUAL TABLE rank USING fts5(a, b, c);
CREATE VIRTUAL TABLE rank USING fts5(a, b, c, detail=%DETAIL%);
} {1 {reserved fts5 table name: rank}}
do_catchsql_test 11.3 {
CREATE VIRTUAL TABLE t2 USING fts5(a, b, c, rowid);
CREATE VIRTUAL TABLE t2 USING fts5(a, b, c, rowid, detail=%DETAIL%);
} {1 {reserved fts5 column name: rowid}}
#-------------------------------------------------------------------------
#
do_execsql_test 12.1 {
CREATE VIRTUAL TABLE t2 USING fts5(x,y);
CREATE VIRTUAL TABLE t2 USING fts5(x,y, detail=%DETAIL%);
} {}
do_catchsql_test 12.2 {
@@ -326,7 +340,7 @@ do_test 12.3 {
#
reset_db
do_execsql_test 13.1 {
CREATE VIRTUAL TABLE t1 USING fts5(x);
CREATE VIRTUAL TABLE t1 USING fts5(x, detail=%DETAIL%);
INSERT INTO t1(rowid, x) VALUES(1, 'o n e'), (2, 't w o');
} {}
@@ -350,7 +364,7 @@ do_execsql_test 13.6 {
#
reset_db
do_execsql_test 14.1 {
CREATE VIRTUAL TABLE t1 USING fts5(x, y);
CREATE VIRTUAL TABLE t1 USING fts5(x, y, detail=%DETAIL%);
INSERT INTO t1(t1, rank) VALUES('pgsz', 32);
WITH d(x,y) AS (
SELECT NULL, 'xyz xyz xyz xyz xyz xyz'
@@ -360,6 +374,10 @@ do_execsql_test 14.1 {
INSERT INTO t1 SELECT * FROM d LIMIT 200;
}
do_execsql_test 15.x {
INSERT INTO t1(t1) VALUES('integrity-check');
}
do_test 14.2 {
set nRow 0
db eval { SELECT * FROM t1 WHERE t1 MATCH 'xyz' } {
@@ -406,11 +424,11 @@ do_execsql_test 16.1 {
}
proc funk {} {
db eval { UPDATE n1_config SET v=50 WHERE k='version' }
set fd [db incrblob main n1_data block 10]
fconfigure $fd -encoding binary -translation binary
puts -nonewline $fd "\x44\x45"
close $fd
db eval { UPDATE n1_config SET v=50 WHERE k='version' }
}
db func funk funk
@@ -422,7 +440,7 @@ do_catchsql_test 16.2 {
#
reset_db
do_execsql_test 17.1 {
CREATE VIRTUAL TABLE b2 USING fts5(x);
CREATE VIRTUAL TABLE b2 USING fts5(x, detail=%DETAIL%);
INSERT INTO b2 VALUES('a');
INSERT INTO b2 VALUES('b');
INSERT INTO b2 VALUES('c');
@@ -436,18 +454,20 @@ do_test 17.2 {
set res
} {{a b c} {a b c} {a b c}}
reset_db
do_execsql_test 18.1 {
CREATE VIRTUAL TABLE c2 USING fts5(x, y);
INSERT INTO c2 VALUES('x x x', 'x x x');
SELECT rowid FROM c2 WHERE c2 MATCH 'y:x';
} {1}
if {[string match n* %DETAIL%]==0} {
reset_db
do_execsql_test 17.3 {
CREATE VIRTUAL TABLE c2 USING fts5(x, y, detail=%DETAIL%);
INSERT INTO c2 VALUES('x x x', 'x x x');
SELECT rowid FROM c2 WHERE c2 MATCH 'y:x';
} {1}
}
#-------------------------------------------------------------------------
#
reset_db
do_execsql_test 17.1 {
CREATE VIRTUAL TABLE uio USING fts5(ttt);
CREATE VIRTUAL TABLE uio USING fts5(ttt, detail=%DETAIL%);
INSERT INTO uio VALUES(NULL);
INSERT INTO uio SELECT NULL FROM uio;
INSERT INTO uio SELECT NULL FROM uio;
@@ -494,8 +514,8 @@ do_execsql_test 17.9 {
#--------------------------------------------------------------------
#
do_execsql_test 18.1 {
CREATE VIRTUAL TABLE t1 USING fts5(a, b);
CREATE VIRTUAL TABLE t2 USING fts5(c, d);
CREATE VIRTUAL TABLE t1 USING fts5(a, b, detail=%DETAIL%);
CREATE VIRTUAL TABLE t2 USING fts5(c, d, detail=%DETAIL%);
INSERT INTO t1 VALUES('abc*', NULL);
INSERT INTO t2 VALUES(1, 'abcdefg');
}
@@ -511,7 +531,7 @@ do_execsql_test 18.3 {
#
reset_db
do_execsql_test 19.0 {
CREATE VIRTUAL TABLE temp.t1 USING fts5(x);
CREATE VIRTUAL TABLE temp.t1 USING fts5(x, detail=%DETAIL%);
INSERT INTO t1 VALUES('x y z');
INSERT INTO t1 VALUES('w x 1');
SELECT rowid FROM t1 WHERE t1 MATCH 'x';
@@ -522,7 +542,7 @@ do_execsql_test 19.0 {
#
reset_db
do_execsql_test 20.0 {
CREATE VIRTUAL TABLE temp.tmp USING fts5(x);
CREATE VIRTUAL TABLE temp.tmp USING fts5(x, detail=%DETAIL%);
}
set ::ids [list \
0 [expr 1<<36] [expr 2<<36] [expr 1<<43] [expr 2<<43]
@@ -534,6 +554,7 @@ do_test 20.1 {
execsql { SELECT rowid FROM tmp WHERE tmp MATCH 'y' }
} $::ids
}
finish_test
+18 -10
View File
@@ -22,8 +22,10 @@ ifcapable !fts5 {
return
}
foreach_detail_mode $testprefix {
do_execsql_test 1.0 {
CREATE VIRTUAL TABLE t1 USING fts5(a, b);
CREATE VIRTUAL TABLE t1 USING fts5(a, b, detail=%DETAIL%);
INSERT INTO t1 VALUES('hello', 'world');
INSERT INTO t1 VALUES('one two', 'three four');
INSERT INTO t1(rowid, a, b) VALUES(45, 'forty', 'five');
@@ -57,7 +59,7 @@ do_execsql_test 1.6 {
reset_db
do_execsql_test 2.1 {
CREATE VIRTUAL TABLE t1 USING fts5(x);
CREATE VIRTUAL TABLE t1 USING fts5(x, detail=%DETAIL%);
INSERT INTO t1(t1, rank) VALUES('pgsz', 32);
INSERT INTO t1 VALUES('one');
INSERT INTO t1 VALUES('two');
@@ -159,7 +161,7 @@ foreach {tn expr res} {
#
do_execsql_test 4.0 {
CREATE VIRTUAL TABLE s1 USING fts5(x);
CREATE VIRTUAL TABLE s1 USING fts5(x, detail=%DETAIL%);
}
foreach {tn doc} [list \
1 [string repeat {a x } 1500000] \
@@ -172,8 +174,14 @@ do_execsql_test 4.3 {
SELECT rowid FROM s1 WHERE s1 MATCH 'x'
} {1 2}
do_execsql_test 4.4 {
SELECT rowid FROM s1 WHERE s1 MATCH '"a x"'
if {[detail_is_full]} {
do_execsql_test 4.4 {
SELECT rowid FROM s1 WHERE s1 MATCH '"a x"'
} {1 2}
}
do_execsql_test 4.5 {
SELECT rowid FROM s1 WHERE s1 MATCH 'a x'
} {1 2}
#-------------------------------------------------------------------------
@@ -182,7 +190,7 @@ do_execsql_test 4.4 {
# (L-2) is larger than it.
#
do_execsql_test 5.0 {
CREATE VIRTUAL TABLE s2 USING fts5(x);
CREATE VIRTUAL TABLE s2 USING fts5(x, detail=%DETAIL%);
INSERT INTO s2(s2, rank) VALUES('pgsz', 32);
INSERT INTO s2(s2, rank) VALUES('automerge', 0);
}
@@ -222,7 +230,7 @@ do_test 5.2 {
do_test 5.3 {
execsql {
DROP TABLE s2;
CREATE VIRTUAL TABLE s2 USING fts5(x);
CREATE VIRTUAL TABLE s2 USING fts5(x, detail=%DETAIL%);
INSERT INTO s2(s2, rank) VALUES('pgsz', 32);
INSERT INTO s2(s2, rank) VALUES('automerge', 0);
}
@@ -241,7 +249,7 @@ do_test 5.4 {
#-------------------------------------------------------------------------
#
do_execsql_test 6.0 {
CREATE VIRTUAL TABLE s3 USING fts5(x);
CREATE VIRTUAL TABLE s3 USING fts5(x, detail=%DETAIL%);
BEGIN;
INSERT INTO s3 VALUES('a b c');
INSERT INTO s3 VALUES('A B C');
@@ -276,13 +284,13 @@ do_test 6.4 {
#-------------------------------------------------------------------------
#
set doc [string repeat "a b c " 500]
breakpoint
do_execsql_test 7.0 {
CREATE VIRTUAL TABLE x1 USING fts5(x);
CREATE VIRTUAL TABLE x1 USING fts5(x, detail=%DETAIL%);
INSERT INTO x1(x1, rank) VALUES('pgsz', 32);
INSERT INTO x1 VALUES($doc);
}
} ;# foreach_detail_mode...
finish_test
+113 -193
View File
@@ -22,6 +22,8 @@ ifcapable !fts5 {
return
}
foreach_detail_mode $testprefix {
set data {
0 {p o q e z k z p n f y u z y n y} {l o o l v v k}
1 {p k h h p y l l h i p v n} {p p l u r i f a j g e r r x w}
@@ -125,80 +127,21 @@ set data {
99 {r c v w i v h a t a c v c r e} {h h u m g o f b a e o}
}
# Argument $expr is an FTS5 match expression designed to be executed against
# an FTS5 table with the following schema:
#
# CREATE VIRTUAL TABLE xy USING fts5(x, y);
#
# Assuming the table contains the same records as stored int the global
# $::data array (see above), this function returns a list containing one
# element for each match in the dataset. The elements are themselves lists
# formatted as follows:
#
# <rowid> {<phrase 0 matches> <phrase 1 matches>...}
#
# where each <phrase X matches> element is a list of phrase matches in the
# same form as returned by auxiliary scalar function fts5_test().
#
proc matchdata {bPos expr {bAsc 1}} {
set tclexpr [db one {
SELECT fts5_expr_tcl($expr, 'nearset $cols -pc ::pc', 'x', 'y')
}]
set res [list]
#puts $tclexpr
foreach {id x y} $::data {
set cols [list $x $y]
set ::pc 0
#set hits [lsort -command instcompare [eval $tclexpr]]
set hits [eval $tclexpr]
if {[llength $hits]>0} {
if {$bPos} {
lappend res [list $id $hits]
} else {
lappend res $id
}
}
}
if {$bAsc} {
set res [lsort -integer -increasing -index 0 $res]
} else {
set res [lsort -integer -decreasing -index 0 $res]
}
return [concat {*}$res]
}
#
# End of test code
#-------------------------------------------------------------------------
proc fts5_test_poslist {cmd} {
set res [list]
for {set i 0} {$i < [$cmd xInstCount]} {incr i} {
lappend res [string map {{ } .} [$cmd xInst $i]]
}
set res
}
foreach {tn2 sql} {
1 {}
2 {BEGIN}
} {
reset_db
sqlite3_fts5_create_function db fts5_test_poslist fts5_test_poslist
fts5_aux_test_functions db
do_execsql_test 1.0 {
CREATE VIRTUAL TABLE xx USING fts5(x,y);
do_execsql_test 1.$tn2.0 {
CREATE VIRTUAL TABLE xx USING fts5(x,y, detail=%DETAIL%);
INSERT INTO xx(xx, rank) VALUES('pgsz', 32);
}
execsql $sql
do_test $tn2.1.1 {
do_test 1.$tn2.1.1 {
foreach {id x y} $data {
execsql { INSERT INTO xx(rowid, x, y) VALUES($id, $x, $y) }
}
@@ -207,153 +150,130 @@ foreach {tn2 sql} {
#-------------------------------------------------------------------------
# Test phrase queries.
#
foreach {tn phrase} {
1 "o"
2 "b q"
3 "e a e"
4 "m d g q q b k b w f q q p p"
5 "l o o l v v k"
6 "a"
7 "b"
8 "c"
9 "no"
10 "L O O L V V K"
} {
set expr "\"$phrase\""
set res [matchdata 1 $expr]
do_execsql_test $tn2.1.2.$tn.[llength $res] {
SELECT rowid, fts5_test_poslist(xx) FROM xx WHERE xx match $expr
} $res
do_execsql_test 1.$tn2.integrity {
INSERT INTO xx(xx) VALUES('integrity-check');
}
#-------------------------------------------------------------------------
# Test some AND and OR queries.
#
foreach {tn expr} {
1.1 "a AND b"
1.2 "a+b AND c"
1.3 "d+c AND u"
1.4 "d+c AND u+d"
1.2 "a OR b"
1.3 "o"
1.4 "b q"
1.5 "e a e"
1.6 "m d g q q b k b w f q q p p"
1.7 "l o o l v v k"
1.8 "a"
1.9 "b"
1.10 "c"
1.11 "no"
1.12 "L O O L V V K"
1.13 "a AND b AND c"
1.14 "x:a"
2.1 "a OR b"
2.2 "a+b OR c"
2.3 "d+c OR u"
2.4 "d+c OR u+d"
2.1 "x:a"
2.2 "y:a"
2.3 "x:b"
2.4 "y:b"
3.1 { a AND b AND c }
3.1 "{x}:a"
3.2 "{y}:a"
3.3 "{x}:b"
3.4 "{y}:b"
4.1 "{x y}:a"
4.2 "{y x}:a"
4.3 "{x x}:b"
4.4 "{y y}:b"
5.1 {{"x" "y"}:a}
5.2 {{"y" x}:a}
5.3 {{x "x"}:b}
5.4 {{"y" y}:b}
6.1 "b + q"
6.2 "e + a + e"
6.3 "m + d + g + q + q + b + k + b + w + f + q + q + p + p"
6.4 "l + o + o + l + v + v + k"
6.5 "L + O + O + L + V + V + K"
7.1 "a+b AND c"
7.2 "d+c AND u"
7.3 "d+c AND u+d"
7.4 "a+b OR c"
7.5 "d+c OR u"
7.6 "d+c OR u+d"
8.1 "NEAR(a b)"
8.2 "NEAR(r c)"
8.2 { NEAR(r c, 5) }
8.3 { NEAR(r c, 3) }
8.4 { NEAR(r c, 2) }
8.5 { NEAR(r c, 0) }
8.6 { NEAR(a b c) }
8.7 { NEAR(a b c, 8) }
8.8 { x : NEAR(r c) }
8.9 { y : NEAR(r c) }
9.1 { NEAR(r c) }
9.2 { NEAR(r c, 5) }
9.3 { NEAR(r c, 3) }
9.4 { NEAR(r c, 2) }
9.5 { NEAR(r c, 0) }
9.6 { NEAR(a b c) }
9.7 { NEAR(a b c, 8) }
9.8 { x : NEAR(r c) }
9.9 { y : NEAR(r c) }
9.10 { x : "r c" }
9.11 { y : "r c" }
9.12 { a AND b }
9.13 { a AND b AND c }
9.14a { a }
9.14b { a OR b }
9.15 { a OR b AND c }
9.16 { c AND b OR a }
9.17 { c AND (b OR a) }
9.18 { c NOT (b OR a) }
9.19 { (c NOT b) OR (a AND d) }
} {
set res [matchdata 1 $expr]
do_execsql_test $tn2.2.$tn.[llength $res] {
SELECT rowid, fts5_test_poslist(xx) FROM xx WHERE xx match $expr
} $res
}
#-------------------------------------------------------------------------
# Queries on a specific column.
#
foreach {tn expr} {
1.1 "x:a"
1.2 "y:a"
1.3 "x:b"
1.4 "y:b"
2.1 "{x}:a"
2.2 "{y}:a"
2.3 "{x}:b"
2.4 "{y}:b"
3.1 "{x y}:a"
3.2 "{y x}:a"
3.3 "{x x}:b"
3.4 "{y y}:b"
4.1 {{"x" "y"}:a}
4.2 {{"y" x}:a}
4.3 {{x "x"}:b}
4.4 {{"y" y}:b}
} {
set res [matchdata 1 $expr]
do_execsql_test $tn2.3.$tn.[llength $res] {
SELECT rowid, fts5_test_poslist(xx) FROM xx WHERE xx match $expr
} $res
}
#-------------------------------------------------------------------------
# Some NEAR queries.
#
foreach {tn expr} {
1 "NEAR(a b)"
2 "NEAR(r c)"
2 { NEAR(r c, 5) }
3 { NEAR(r c, 3) }
4 { NEAR(r c, 2) }
5 { NEAR(r c, 0) }
6 { NEAR(a b c) }
7 { NEAR(a b c, 8) }
8 { x : NEAR(r c) }
9 { y : NEAR(r c) }
} {
set res [matchdata 1 $expr]
do_execsql_test $tn2.4.1.$tn.[llength $res] {
SELECT rowid, fts5_test_poslist(xx) FROM xx WHERE xx match $expr
} $res
}
do_test $tn2.4.1 { nearset {{a b c}} -- a } {0.0.0}
do_test $tn2.4.2 { nearset {{a b c}} -- c } {0.0.2}
foreach {tn expr tclexpr} {
1 {a b} {AND [N $x -- {a}] [N $x -- {b}]}
} {
do_execsql_test $tn2.5.$tn {
SELECT fts5_expr_tcl($expr, 'N $x')
} [list $tclexpr]
}
#-------------------------------------------------------------------------
#
do_execsql_test $tn2.6.integrity {
INSERT INTO xx(xx) VALUES('integrity-check');
}
#db eval {SELECT rowid, fts5_decode(rowid, block) aS r FROM xx_data} {puts $r}
foreach {bAsc sql} {
1 {SELECT rowid FROM xx WHERE xx MATCH $expr}
0 {SELECT rowid FROM xx WHERE xx MATCH $expr ORDER BY rowid DESC}
} {
foreach {tn expr} {
0.1 x
1 { NEAR(r c) }
2 { NEAR(r c, 5) }
3 { NEAR(r c, 3) }
4 { NEAR(r c, 2) }
5 { NEAR(r c, 0) }
6 { NEAR(a b c) }
7 { NEAR(a b c, 8) }
8 { x : NEAR(r c) }
9 { y : NEAR(r c) }
10 { x : "r c" }
11 { y : "r c" }
12 { a AND b }
13 { a AND b AND c }
14a { a }
14b { a OR b }
15 { a OR b AND c }
16 { c AND b OR a }
17 { c AND (b OR a) }
18 { c NOT (b OR a) }
19 { c NOT b OR a AND d }
} {
set res [matchdata 0 $expr $bAsc]
do_execsql_test $tn2.6.$bAsc.$tn.[llength $res] $sql $res
if {[fts5_expr_ok $expr xx]==0} {
do_test 1.$tn2.$tn.OMITTED { list } [list]
continue
}
set res [fts5_query_data $expr xx]
do_execsql_test 1.$tn2.$tn.[llength $res].asc {
SELECT rowid, fts5_test_poslist(xx), fts5_test_collist(xx)
FROM xx WHERE xx match $expr
} $res
set res [fts5_query_data $expr xx DESC]
do_execsql_test 1.$tn2.$tn.[llength $res].desc {
SELECT rowid, fts5_test_poslist(xx), fts5_test_collist(xx)
FROM xx WHERE xx match $expr ORDER BY 1 DESC
} $res
}
}
do_execsql_test 3.1 {
}
do_execsql_test 2.1 {
SELECT fts5_expr_tcl('a AND b');
} {{AND [nearset -- {a}] [nearset -- {b}]}}
do_test 2.2.1 { nearset {{a b c}} -- a } {0.0.0}
do_test 2.2.2 { nearset {{a b c}} -- c } {0.0.2}
foreach {tn expr tclexpr} {
1 {a b} {AND [N $x -- {a}] [N $x -- {b}]}
} {
do_execsql_test 2.3.$tn {
SELECT fts5_expr_tcl($expr, 'N $x')
} [list $tclexpr]
}
finish_test
+11 -5
View File
@@ -11,6 +11,8 @@
# This file implements regression tests for SQLite library. The
# focus of this script is testing the FTS5 module.
#
# More specifically, the focus is on testing prefix queries, both with and
# without prefix indexes.
#
source [file join [file dirname [info script]] fts5_common.tcl]
@@ -22,8 +24,10 @@ ifcapable !fts5 {
return
}
foreach_detail_mode $testprefix {
do_execsql_test 1.0 {
CREATE VIRTUAL TABLE yy USING fts5(x, y);
CREATE VIRTUAL TABLE yy USING fts5(x, y, detail=%DETAIL%);
INSERT INTO yy VALUES('Changes the result to be', 'the list of all matching');
INSERT INTO yy VALUES('indices (or all matching', 'values if -inline is');
INSERT INTO yy VALUES('specified as well.) If', 'indices are returned, the');
@@ -53,23 +57,23 @@ foreach {tn match res} {
foreach {T create} {
2 {
CREATE VIRTUAL TABLE t1 USING fts5(a, b);
CREATE VIRTUAL TABLE t1 USING fts5(a, b, detail=%DETAIL%);
INSERT INTO t1(t1, rank) VALUES('pgsz', 32);
}
3 {
CREATE VIRTUAL TABLE t1 USING fts5(a, b, prefix=1,2,3,4,5);
CREATE VIRTUAL TABLE t1 USING fts5(a, b, prefix="1,2,3,4", detail=%DETAIL%);
INSERT INTO t1(t1, rank) VALUES('pgsz', 32);
}
4 {
CREATE VIRTUAL TABLE t1 USING fts5(a, b);
CREATE VIRTUAL TABLE t1 USING fts5(a, b, detail=%DETAIL%);
INSERT INTO t1(t1, rank) VALUES('pgsz', 32);
BEGIN;
}
5 {
CREATE VIRTUAL TABLE t1 USING fts5(a, b, prefix=1,2,3,4,5);
CREATE VIRTUAL TABLE t1 USING fts5(a, b, prefix="1,2,3,4", detail=%DETAIL%);
INSERT INTO t1(t1, rank) VALUES('pgsz', 32);
BEGIN;
}
@@ -235,5 +239,7 @@ foreach {T create} {
catchsql COMMIT
}
}
finish_test
+30 -22
View File
@@ -22,8 +22,10 @@ ifcapable !fts5 {
return
}
foreach_detail_mode $testprefix {
do_execsql_test 1.0 {
CREATE VIRTUAL TABLE t1 USING fts5(a, b);
CREATE VIRTUAL TABLE t1 USING fts5(a, b, detail=%DETAIL%);
INSERT INTO t1(t1, rank) VALUES('pgsz', 32);
}
@@ -55,7 +57,7 @@ fts5_aux_test_functions db
#-------------------------------------------------------------------------
#
do_execsql_test 2.0 {
CREATE VIRTUAL TABLE t2 USING fts5(x, y);
CREATE VIRTUAL TABLE t2 USING fts5(x, y, detail=%DETAIL%);
INSERT INTO t2 VALUES('u t l w w m s', 'm f m o l t k o p e');
INSERT INTO t2 VALUES('f g q e l n d m z x q', 'z s i i i m f w w f n g p');
}
@@ -76,31 +78,35 @@ do_execsql_test 2.2 {
2 {1.0.2 1.0.10}
}
do_execsql_test 2.3 {
SELECT rowid, fts5_test_poslist(t2) FROM t2
WHERE t2 MATCH 'y:o' ORDER BY rowid;
} {
1 {0.1.3 0.1.7}
if {[detail_is_full]} {
do_execsql_test 2.3 {
SELECT rowid, fts5_test_poslist(t2) FROM t2
WHERE t2 MATCH 'y:o' ORDER BY rowid;
} {
1 {0.1.3 0.1.7}
}
}
#-------------------------------------------------------------------------
#
do_execsql_test 3.0 {
CREATE VIRTUAL TABLE t3 USING fts5(x, y);
CREATE VIRTUAL TABLE t3 USING fts5(x, y, detail=%DETAIL%);
INSERT INTO t3 VALUES( 'j f h o x x a z g b a f a m i b', 'j z c z y x w t');
INSERT INTO t3 VALUES( 'r c', '');
}
do_execsql_test 3.1 {
SELECT rowid, fts5_test_poslist(t3) FROM t3 WHERE t3 MATCH 'NEAR(a b)';
} {
1 {0.0.6 1.0.9 0.0.10 0.0.12 1.0.15}
}
if {[detail_is_full]} {
do_execsql_test 3.1 {
SELECT rowid, fts5_test_poslist(t3) FROM t3 WHERE t3 MATCH 'NEAR(a b)';
} {
1 {0.0.6 1.0.9 0.0.10 0.0.12 1.0.15}
}
do_execsql_test 3.2 {
SELECT rowid, fts5_test_poslist(t3) FROM t3 WHERE t3 MATCH 'NEAR(r c)';
} {
2 {0.0.0 1.0.1}
do_execsql_test 3.2 {
SELECT rowid, fts5_test_poslist(t3) FROM t3 WHERE t3 MATCH 'NEAR(r c)';
} {
2 {0.0.0 1.0.1}
}
}
do_execsql_test 3.3 {
@@ -116,7 +122,7 @@ do_execsql_test 3.3 {
#-------------------------------------------------------------------------
#
do_execsql_test 4.0 {
CREATE VIRTUAL TABLE t4 USING fts5(x, y);
CREATE VIRTUAL TABLE t4 USING fts5(x, y, detail=%DETAIL%);
INSERT INTO t4
VALUES('k x j r m a d o i z j', 'r t t t f e b r x i v j v g o');
}
@@ -134,7 +140,7 @@ reset_db
fts5_aux_test_functions db
do_execsql_test 5.1 {
CREATE VIRTUAL TABLE t5 USING fts5(x, y);
CREATE VIRTUAL TABLE t5 USING fts5(x, y, detail=%DETAIL%);
INSERT INTO t5 VALUES('a b c d', 'e f g h i j');
INSERT INTO t5 VALUES('', 'a');
INSERT INTO t5 VALUES('a', '');
@@ -182,7 +188,7 @@ do_execsql_test 5.5 {
reset_db
fts5_aux_test_functions db
do_execsql_test 6.1 {
CREATE VIRTUAL TABLE t6 USING fts5(x, y);
CREATE VIRTUAL TABLE t6 USING fts5(x, y, detail=%DETAIL%);
INSERT INTO t6 VALUES('There are more', 'things in heaven and earth');
INSERT INTO t6 VALUES(', Horatio, Than are', 'dreamt of in your philosophy.');
}
@@ -200,7 +206,7 @@ do_execsql_test 6.2 {
reset_db
fts5_aux_test_functions db
do_execsql_test 7.1 {
CREATE VIRTUAL TABLE t7 USING fts5(x, y);
CREATE VIRTUAL TABLE t7 USING fts5(x, y, detail=%DETAIL%);
}
do_test 7.2 {
foreach {x y} {
@@ -240,7 +246,7 @@ do_execsql_test 7.4 {
#-------------------------------------------------------------------------
#
do_test 8.1 {
execsql { CREATE VIRTUAL TABLE t8 USING fts5(x, y) }
execsql { CREATE VIRTUAL TABLE t8 USING fts5(x, y, detail=%DETAIL%) }
foreach {rowid x y} {
0 {A o} {o o o C o o o o o o o o}
1 {o o B} {o o o C C o o o o o o o}
@@ -300,5 +306,7 @@ foreach {tn q cnt} {
} $cnt
}
}
finish_test
+30 -26
View File
@@ -24,9 +24,10 @@ ifcapable !fts5 {
return
}
foreach_detail_mode $testprefix {
do_execsql_test 1.0 {
CREATE VIRTUAL TABLE t1 USING fts5(x, y);
CREATE VIRTUAL TABLE t1 USING fts5(x, y, detail=%DETAIL%);
}
proc do_snippet_test {tn doc match res} {
@@ -111,34 +112,37 @@ foreach {tn doc res} {
do_snippet_test 1.$tn $doc X $res
}
foreach {tn doc res} {
1.1 {X Y o o o o o} {[X Y] o o o o o}
1.2 {o X Y o o o o} {o [X Y] o o o o}
1.3 {o o X Y o o o} {o o [X Y] o o o}
1.4 {o o o X Y o o} {o o o [X Y] o o}
1.5 {o o o o X Y o} {o o o o [X Y] o}
1.6 {o o o o o X Y} {o o o o o [X Y]}
if {[detail_is_full]} {
foreach {tn doc res} {
1.1 {X Y o o o o o} {[X Y] o o o o o}
1.2 {o X Y o o o o} {o [X Y] o o o o}
1.3 {o o X Y o o o} {o o [X Y] o o o}
1.4 {o o o X Y o o} {o o o [X Y] o o}
1.5 {o o o o X Y o} {o o o o [X Y] o}
1.6 {o o o o o X Y} {o o o o o [X Y]}
2.1 {X Y o o o o o o} {[X Y] o o o o o...}
2.2 {o X Y o o o o o} {o [X Y] o o o o...}
2.3 {o o X Y o o o o} {o o [X Y] o o o...}
2.4 {o o o X Y o o o} {...o o [X Y] o o o}
2.5 {o o o o X Y o o} {...o o o [X Y] o o}
2.6 {o o o o o X Y o} {...o o o o [X Y] o}
2.7 {o o o o o o X Y} {...o o o o o [X Y]}
2.1 {X Y o o o o o o} {[X Y] o o o o o...}
2.2 {o X Y o o o o o} {o [X Y] o o o o...}
2.3 {o o X Y o o o o} {o o [X Y] o o o...}
2.4 {o o o X Y o o o} {...o o [X Y] o o o}
2.5 {o o o o X Y o o} {...o o o [X Y] o o}
2.6 {o o o o o X Y o} {...o o o o [X Y] o}
2.7 {o o o o o o X Y} {...o o o o o [X Y]}
3.1 {X Y o o o o o o o} {[X Y] o o o o o...}
3.2 {o X Y o o o o o o} {o [X Y] o o o o...}
3.3 {o o X Y o o o o o} {o o [X Y] o o o...}
3.4 {o o o X Y o o o o} {...o o [X Y] o o o...}
3.5 {o o o o X Y o o o} {...o o [X Y] o o o}
3.6 {o o o o o X Y o o} {...o o o [X Y] o o}
3.7 {o o o o o o X Y o} {...o o o o [X Y] o}
3.8 {o o o o o o o X Y} {...o o o o o [X Y]}
} {
do_snippet_test 2.$tn $doc "X + Y" $res
3.1 {X Y o o o o o o o} {[X Y] o o o o o...}
3.2 {o X Y o o o o o o} {o [X Y] o o o o...}
3.3 {o o X Y o o o o o} {o o [X Y] o o o...}
3.4 {o o o X Y o o o o} {...o o [X Y] o o o...}
3.5 {o o o o X Y o o o} {...o o [X Y] o o o}
3.6 {o o o o o X Y o o} {...o o o [X Y] o o}
3.7 {o o o o o o X Y o} {...o o o o [X Y] o}
3.8 {o o o o o o o X Y} {...o o o o o [X Y]}
} {
do_snippet_test 2.$tn $doc "X + Y" $res
}
}
} ;# foreach_detail_mode
finish_test
+14 -7
View File
@@ -33,8 +33,10 @@ ifcapable !fts5 {
# ... WHERE fts MATCH ? ORDER BY rank [ASC|DESC]
#
foreach_detail_mode $testprefix {
do_execsql_test 1.0 {
CREATE VIRTUAL TABLE t1 USING fts5(x, y, z);
CREATE VIRTUAL TABLE t1 USING fts5(x, y, z, detail=%DETAIL%);
}
do_test 1.1 {
@@ -119,19 +121,24 @@ foreach {tn expr} {
2.3 c
2.4 d
2.5 {"m m"}
2.6 {e + s}
3.0 {a AND b}
3.1 {a OR b}
3.2 {b OR c AND d}
3.3 {NEAR(c d)}
} {
do_fts5ag_test $tn $expr
if {[set_test_counter errors]} break
}
if {[detail_is_full]} {
foreach {tn expr} {
4.1 {"m m"}
4.2 {e + s}
4.3 {NEAR(c d)}
} {
do_fts5ag_test $tn $expr
}
}
} ;# foreach_detail_mode
finish_test
+33 -13
View File
@@ -21,12 +21,16 @@ ifcapable !fts5 {
return
}
foreach_detail_mode $testprefix {
#-------------------------------------------------------------------------
# This file contains tests for very large doclists.
#
set Y [list]
set W [list]
do_test 1.0 {
execsql { CREATE VIRTUAL TABLE t1 USING fts5(a) }
execsql { CREATE VIRTUAL TABLE t1 USING fts5(a, detail=%DETAIL%) }
execsql { INSERT INTO t1(t1, rank) VALUES('pgsz', 128) }
set v {w w w w w w w w w w w w w w w w w w w w}
execsql { INSERT INTO t1(rowid, a) VALUES(0, $v) }
@@ -70,7 +74,12 @@ do_test 1.4 {
set nRead [reads]
execsql { SELECT rowid FROM t1 WHERE t1 MATCH 'x' }
set nReadX [expr [reads] - $nRead]
expr $nReadX>1000
#puts -nonewline "(nReadX=$nReadX)"
if {[detail_is_full]} { set expect 1000 }
if {[detail_is_col]} { set expect 250 }
if {[detail_is_none]} { set expect 80 }
expr $nReadX>$expect
} {1}
do_test 1.5 {
@@ -87,17 +96,22 @@ foreach {tn q res} "
3 { SELECT rowid FROM t1 WHERE t1 MATCH 'x AND w' } [list $W]
4 { SELECT rowid FROM t1 WHERE t1 MATCH 'y AND x' } [list $Y]
" {
if {[detail_is_full]==0 && ($tn==1 || $tn==2)} continue
if {[detail_is_full]} { set ratio 8 }
if {[detail_is_col]} { set ratio 4 }
if {[detail_is_none]} { set ratio 2 }
do_test 1.6.$tn.1 {
set n [execsql_reads $q]
#puts -nonewline "(n=$n nReadX=$nReadX)"
expr {$n < ($nReadX / 8)}
expr {$n < ($nReadX / $ratio)}
} {1}
do_test 1.6.$tn.2 {
set n [execsql_reads "$q ORDER BY rowid DESC"]
#puts -nonewline "(n=$n nReadX=$nReadX)"
expr {$n < ($nReadX / 8)}
expr {$n < ($nReadX / $ratio)}
} {1}
do_execsql_test 1.6.$tn.3 $q [lsort -int -incr $res]
@@ -109,21 +123,26 @@ foreach {tn q res} "
# number of pages loaded from disk.
#
foreach {tn fraction tail cnt} {
1 0.6 {rowid > 5000} 5000
2 0.2 {rowid > 9000} 1000
3 0.2 {rowid < 1000} 999
4 0.2 {rowid BETWEEN 4000 AND 5000} 1001
5 0.6 {rowid >= 5000} 5001
6 0.2 {rowid >= 9000} 1001
7 0.2 {rowid <= 1000} 1000
8 0.6 {rowid > '5000'} 5000
9 0.2 {rowid > '9000'} 1000
1 0.6 {rowid > 5000} 5000
2 0.2 {rowid > 9000} 1000
3 0.2 {rowid < 1000} 999
4 0.2 {rowid BETWEEN 4000 AND 5000} 1001
5 0.6 {rowid >= 5000} 5001
6 0.2 {rowid >= 9000} 1001
7 0.2 {rowid <= 1000} 1000
8 0.6 {rowid > '5000'} 5000
9 0.2 {rowid > '9000'} 1000
10 0.1 {rowid = 444} 1
} {
set q "SELECT rowid FROM t1 WHERE t1 MATCH 'x' AND $tail"
set n [execsql_reads $q]
set ret [llength [execsql $q]]
# Because the position lists for 'x' are quite long in this db, the
# advantage is a bit smaller in detail=none mode. Update $fraction to
# reflect this.
if {[detail_is_none] && $fraction<0.5} { set fraction [expr $fraction*2] }
do_test "1.7.$tn.asc.(n=$n ret=$ret)" {
expr {$n < ($fraction*$nReadX) && $ret==$cnt}
} {1}
@@ -143,6 +162,7 @@ do_execsql_test 1.8.2 {
SELECT count(*) FROM t1 WHERE t1 MATCH 'x' AND rowid < 'text';
} {10000}
} ;# foreach_detail_mode
#db eval {SELECT rowid, fts5_decode(rowid, block) aS r FROM t1_data} {puts $r}
+4 -1
View File
@@ -23,8 +23,10 @@ ifcapable !fts5 {
return
}
foreach_detail_mode $testprefix {
do_execsql_test 1.0 {
CREATE VIRTUAL TABLE t1 USING fts5(a);
CREATE VIRTUAL TABLE t1 USING fts5(a, detail=%DETAIL%);
} {}
do_execsql_test 1.1 {
@@ -49,6 +51,7 @@ do_execsql_test 1.1 {
do_execsql_test 1.2 {
INSERT INTO t1(t1) VALUES('integrity-check');
}
}
finish_test
+57 -50
View File
@@ -23,8 +23,10 @@ ifcapable !fts5 {
return
}
foreach_detail_mode $testprefix {
do_execsql_test 1.1 {
CREATE VIRTUAL TABLE ft1 USING fts5(x);
CREATE VIRTUAL TABLE ft1 USING fts5(x, detail=%DETAIL%);
INSERT INTO ft1 VALUES('i d d a g i b g d d');
INSERT INTO ft1 VALUES('h d b j c c g a c a');
INSERT INTO ft1 VALUES('e j a e f h b f h h');
@@ -35,6 +37,9 @@ do_execsql_test 1.1 {
INSERT INTO ft1 VALUES('i c c f a d g h j e');
INSERT INTO ft1 VALUES('i d i g c d c h b f');
INSERT INTO ft1 VALUES('g d a e h a b c f j');
CREATE VIRTUAL TABLE ft2 USING fts5(x, detail=%DETAIL%);
INSERT INTO ft2 VALUES('a b c d e f g h i j');
}
do_execsql_test 1.2 {
@@ -49,19 +54,6 @@ do_execsql_test 1.2 {
}
do_execsql_test 1.3 {
SELECT highlight(ft1, 0, '[', ']') FROM ft1 WHERE ft1 MATCH 'h + d';
} {
{[h d] b j c c g a c a}
{j f [h d] g h i b d f}
}
do_execsql_test 1.4 {
SELECT highlight(ft1, 0, '[', ']') FROM ft1 WHERE ft1 MATCH 'd + d';
} {
{i [d d] a g i b g [d d]}
}
do_execsql_test 1.5 {
SELECT highlight(ft1, 0, '[', ']') FROM ft1 WHERE ft1 MATCH 'e e e'
} {
{[e] j a [e] f h b f h h}
@@ -72,57 +64,71 @@ do_execsql_test 1.5 {
{g d a [e] h a b c f j}
}
do_execsql_test 1.6 {
SELECT highlight(ft1, 0, '[', ']') FROM ft1 WHERE ft1 MATCH 'd + d d + d';
} {
{i [d d] a g i b g [d d]}
}
do_execsql_test 2.1 {
CREATE VIRTUAL TABLE ft2 USING fts5(x);
INSERT INTO ft2 VALUES('a b c d e f g h i j');
}
do_execsql_test 2.2 {
SELECT highlight(ft2, 0, '[', ']') FROM ft2 WHERE ft2 MATCH 'b+c+d c+d+e'
} {{a [b c d e] f g h i j}}
do_execsql_test 2.3 {
SELECT highlight(ft2, 0, '[', ']') FROM ft2 WHERE ft2 MATCH 'b+c+d e+f+g'
} {
{a [b c d] [e f g] h i j}
}
do_execsql_test 2.4 {
SELECT highlight(ft2, 0, '[', ']') FROM ft2 WHERE ft2 MATCH 'b+c+d c'
} {
{a [b c d] e f g h i j}
}
do_execsql_test 2.5 {
SELECT highlight(ft2, 0, '[', ']') FROM ft2 WHERE ft2 MATCH 'b+c c+d+e'
} {
{a [b c d e] f g h i j}
}
do_execsql_test 2.6.1 {
do_execsql_test 1.4 {
SELECT highlight(ft2, 0, '[', ']') FROM ft2 WHERE ft2 MATCH 'f d'
} {
{a b c [d] e [f] g h i j}
}
do_execsql_test 2.6.2 {
do_execsql_test 1.5 {
SELECT highlight(ft2, 0, '[', ']') FROM ft2 WHERE ft2 MATCH 'd f'
} {
{a b c [d] e [f] g h i j}
}
#-------------------------------------------------------------------------
# Tests below this point require detail=full.
#-------------------------------------------------------------------------
if {[detail_is_full]==0} continue
do_execsql_test 2.1 {
SELECT highlight(ft1, 0, '[', ']') FROM ft1 WHERE ft1 MATCH 'h + d';
} {
{[h d] b j c c g a c a}
{j f [h d] g h i b d f}
}
do_execsql_test 2.2 {
SELECT highlight(ft1, 0, '[', ']') FROM ft1 WHERE ft1 MATCH 'd + d';
} {
{i [d d] a g i b g [d d]}
}
do_execsql_test 2.3 {
SELECT highlight(ft1, 0, '[', ']') FROM ft1 WHERE ft1 MATCH 'd + d d + d';
} {
{i [d d] a g i b g [d d]}
}
do_execsql_test 2.4 {
SELECT highlight(ft2, 0, '[', ']') FROM ft2 WHERE ft2 MATCH 'b+c+d c+d+e'
} {{a [b c d e] f g h i j}}
do_execsql_test 2.5 {
SELECT highlight(ft2, 0, '[', ']') FROM ft2 WHERE ft2 MATCH 'b+c+d e+f+g'
} {
{a [b c d] [e f g] h i j}
}
do_execsql_test 2.6 {
SELECT highlight(ft2, 0, '[', ']') FROM ft2 WHERE ft2 MATCH 'b+c+d c'
} {
{a [b c d] e f g h i j}
}
do_execsql_test 2.7 {
SELECT highlight(ft2, 0, '[', ']') FROM ft2 WHERE ft2 MATCH 'b+c c+d+e'
} {
{a [b c d e] f g h i j}
}
#-------------------------------------------------------------------------
# The example from the docs.
#
do_execsql_test 3.1 {
-- Assuming this:
CREATE VIRTUAL TABLE ft USING fts5(a);
CREATE VIRTUAL TABLE ft USING fts5(a, detail=%DETAIL%);
INSERT INTO ft VALUES('a b c x c d e');
INSERT INTO ft VALUES('a b c c d e');
INSERT INTO ft VALUES('a b c d e');
@@ -138,6 +144,7 @@ do_execsql_test 3.1 {
{[a b c d e]}
}
}
finish_test
+33 -26
View File
@@ -23,8 +23,10 @@ ifcapable !fts5 {
return
}
foreach_detail_mode $testprefix {
do_execsql_test 1.1 {
CREATE VIRTUAL TABLE ft1 USING fts5(x);
CREATE VIRTUAL TABLE ft1 USING fts5(x, detail=%DETAIL%);
SELECT * FROM ft1_config;
} {version 4}
@@ -83,7 +85,7 @@ foreach {tn defn} {
#
do_execsql_test 3.1 {
CREATE VIRTUAL TABLE t1 USING fts5(x);
CREATE VIRTUAL TABLE t1 USING fts5(x, detail=%DETAIL%);
INSERT INTO t1 VALUES('q w e r t y');
INSERT INTO t1 VALUES('y t r e w q');
}
@@ -122,11 +124,13 @@ do_execsql_test 3.4.1 {
{{0 0 5}}
}
do_execsql_test 3.4.2 {
SELECT insttest(t1) FROM t1 WHERE t1 MATCH 'r+e OR w'
} {
{{1 0 1}}
{{0 0 2} {1 0 4}}
if {[detail_is_full]} {
do_execsql_test 3.4.2 {
SELECT insttest(t1) FROM t1 WHERE t1 MATCH 'r+e OR w'
} {
{{1 0 1}}
{{0 0 2} {1 0 4}}
}
}
proc coltest {cmd} {
@@ -149,7 +153,7 @@ do_execsql_test 3.5.1 {
#
do_execsql_test 4.0 {
CREATE VIRTUAL TABLE t2 USING fts5(a, b);
CREATE VIRTUAL TABLE t2 USING fts5(a, b, detail=%DETAIL%);
INSERT INTO t2 VALUES('a s h g s b j m r h', 's b p a d b b a o e');
INSERT INTO t2 VALUES('r h n t a g r d d i', 'l d n j r c f t o q');
INSERT INTO t2 VALUES('q k n i k c a a e m', 'c h n j p g s c i t');
@@ -218,24 +222,26 @@ proc rowidplus {cmd ival} {
}
sqlite3_fts5_create_function db rowidplus rowidplus
do_execsql_test 4.2.1 {
INSERT INTO t2(t2, rank) VALUES('rank', 'rowidplus(100) ');
SELECT rowid, rank FROM t2 WHERE t2 MATCH 'o + q + g'
} {
10 110
}
do_execsql_test 4.2.2 {
INSERT INTO t2(t2, rank) VALUES('rank', 'rowidplus(111) ');
SELECT rowid, rank FROM t2 WHERE t2 MATCH 'o + q + g'
} {
10 121
}
if {[detail_is_full]} {
do_execsql_test 4.2.1 {
INSERT INTO t2(t2, rank) VALUES('rank', 'rowidplus(100) ');
SELECT rowid, rank FROM t2 WHERE t2 MATCH 'o + q + g'
} {
10 110
}
do_execsql_test 4.2.2 {
INSERT INTO t2(t2, rank) VALUES('rank', 'rowidplus(111) ');
SELECT rowid, rank FROM t2 WHERE t2 MATCH 'o + q + g'
} {
10 121
}
do_execsql_test 4.2.3 {
SELECT rowid, rank FROM t2
WHERE t2 MATCH 'o + q + g' AND rank MATCH 'rowidplus(112)'
} {
10 122
do_execsql_test 4.2.3 {
SELECT rowid, rank FROM t2
WHERE t2 MATCH 'o + q + g' AND rank MATCH 'rowidplus(112)'
} {
10 122
}
}
proc rowidmod {cmd imod} {
@@ -243,7 +249,7 @@ proc rowidmod {cmd imod} {
}
sqlite3_fts5_create_function db rowidmod rowidmod
do_execsql_test 4.3.1 {
CREATE VIRTUAL TABLE t3 USING fts5(x);
CREATE VIRTUAL TABLE t3 USING fts5(x, detail=%DETAIL%);
INSERT INTO t3 VALUES('a one');
INSERT INTO t3 VALUES('a two');
INSERT INTO t3 VALUES('a three');
@@ -287,6 +293,7 @@ do_catchsql_test 4.4.4 {
SELECT *, rank FROM t3 WHERE t3 MATCH 'a' AND rank MATCH NULL
} {1 {parse error in rank function: }}
} ;# foreach_detail_mode
finish_test
+4 -38
View File
@@ -22,7 +22,6 @@ ifcapable !fts5 {
return
}
set data {
-4026076
{n x w k b p x b n t t d s} {f j j s p j o}
@@ -232,37 +231,9 @@ do_execsql_test 1.0 {
fts5_aux_test_functions db
proc matchdata {expr tbl collist {order ASC}} {
set cols ""
foreach e $collist {
append cols ", '$e'"
}
set tclexpr [db one [subst -novar {
SELECT fts5_expr_tcl(
$expr, 'nearset $cols -pc ::pc' [set cols]
)
}]]
set res [list]
db eval "SELECT rowid, * FROM $tbl ORDER BY rowid $order" x {
set cols [list]
foreach col $x(*) {
if {$col != "rowid"} { lappend cols $x($col) }
}
# set cols [list $a $b $c $d $e $f]
set ::pc 0
set rowdata [eval $tclexpr]
if {$rowdata != ""} { lappend res $x(rowid) $rowdata }
}
set res
}
proc do_auto_test {tn tbl cols expr} {
proc do_auto_test {tn tbl expr} {
foreach order {asc desc} {
set res [matchdata $expr $tbl $cols $order]
set res [fts5_poslist_data $expr $tbl $order]
set testname "$tn.[string range $order 0 0].rows=[expr [llength $res]/2]"
set ::autotest_expr $expr
@@ -271,8 +242,6 @@ proc do_auto_test {tn tbl cols expr} {
WHERE [set tbl] MATCH $::autotest_expr ORDER BY rowid [set order]
}] $res
}
}
#-------------------------------------------------------------------------
@@ -332,7 +301,7 @@ for {set fold 0} {$fold < 3} {incr fold} {
C.1 { a OR (b AND "b c") }
C.2 { a OR (b AND "z c") }
} {
do_auto_test 3.$fold.$tn tt {a b c d e f} $expr
do_auto_test 3.$fold.$tn tt $expr
}
}
@@ -366,11 +335,8 @@ foreach {tn expr} {
4 {c1 : x} 5 {c2 : x} 6 {c3 : x}
7 {c1 : y} 8 {c2 : y} 9 {c3 : y}
10 {c1 : z} 11 {c2 : z} 12 {c3 : z}
} {
breakpoint
do_auto_test 4.$tn yy {c1 c2 c3} $expr
do_auto_test 4.$tn yy $expr
}
+68
View File
@@ -0,0 +1,68 @@
# 2016 Jan 19
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
# May you find forgiveness for yourself and forgive others.
# May you share freely, never taking more than you give.
#
#*************************************************************************
# This file implements regression tests for SQLite library. The
# focus of this script is testing the FTS5 module.
#
source [file join [file dirname [info script]] fts5_common.tcl]
set testprefix fts5bigtok
return_if_no_fts5
proc rndterm {} {
set L [list a b c d e f g h i j k l m n o p q r s t u v w x y z]
set l [lindex $L [expr int(rand() * [llength $L])]]
string repeat $l [expr int(rand() * 5) + 60]
}
proc rnddoc {n} {
set res [list]
for {set i 0} {$i < $n} {incr i} {
lappend res [rndterm]
}
set res
}
foreach_detail_mode $::testprefix {
db func rnddoc rnddoc
do_execsql_test 1.0 {
CREATE VIRTUAL TABLE t1 USING fts5(x, detail=%DETAIL%);
INSERT INTO t1(t1, rank) VALUES('pgsz', 32);
CREATE VIRTUAL TABLE t1vocab USING fts5vocab(t1, row);
WITH s(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<10 )
INSERT INTO t1 SELECT rnddoc(3) FROM s;
WITH s(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<10 )
INSERT INTO t1 SELECT rnddoc(3) FROM s;
}
foreach v [db eval {SELECT term FROM t1vocab}] {
set res [db eval {SELECT rowid FROM t1($v)}]
do_execsql_test 1.[string range $v 0 0] {
SELECT rowid FROM t1($v) ORDER BY rowid DESC
} [lsort -integer -decr $res]
}
do_execsql_test 2.0 {
INSERT INTO t1(t1) VALUES('optimize');
}
foreach v [db eval {SELECT term FROM t1vocab}] {
set res [db eval {SELECT rowid FROM t1($v)}]
do_execsql_test 2.[string range $v 0 0] {
SELECT rowid FROM t1($v) ORDER BY rowid DESC
} [lsort -integer -decr $res]
}
}
finish_test
+49 -6
View File
@@ -42,6 +42,10 @@ foreach {tn opt} {
1 {prefix=x}
2 {prefix='x'}
3 {prefix='$'}
4 {prefix='1,2,'}
5 {prefix=',1'}
6 {prefix='1,2,3...'}
7 {prefix='1,2,3xyz'}
} {
set res [list 1 {malformed prefix=... directive}]
do_catchsql_test 2.$tn "CREATE VIRTUAL TABLE f1 USING fts5(x, $opt)" $res
@@ -118,18 +122,15 @@ do_catchsql_test 5.3 {
#-------------------------------------------------------------------------
# Errors in prefix= directives.
#
do_catchsql_test 6.1 {
CREATE VIRTUAL TABLE abc USING fts5(a, prefix=1, prefix=2);
} {1 {multiple prefix=... directives}}
do_catchsql_test 6.2 {
CREATE VIRTUAL TABLE abc USING fts5(a, prefix='1, 2, 1001');
} {1 {prefix length out of range: 1001}}
} {1 {prefix length out of range (max 999)}}
do_catchsql_test 6.3 {
CREATE VIRTUAL TAbLE abc USING fts5(a, prefix='1, 2, 0000');
} {1 {prefix length out of range: 0}}
} {1 {prefix length out of range (max 999)}}
do_catchsql_test 6.4 {
CREATE VIRTUAL TABLE abc USING fts5(a, prefix='1 , 1000000');
} {1 {malformed prefix=... directive}}
} {1 {prefix length out of range (max 999)}}
#-------------------------------------------------------------------------
# Duplicate tokenize= and other options.
@@ -160,6 +161,8 @@ do_catchsql_test 8.1 {
# 9.1.* 'pgsz' options.
# 9.2.* 'automerge' options.
# 9.3.* 'crisismerge' options.
# 9.4.* a non-existant option.
# 9.5.* 'hashsize' options.
#
do_execsql_test 9.0 {
CREATE VIRTUAL TABLE abc USING fts5(a, b);
@@ -204,5 +207,45 @@ do_catchsql_test 9.4.1 {
INSERT INTO abc(abc, rank) VALUES('nosuchoption', 1);
} {1 {SQL logic error or missing database}}
do_catchsql_test 9.5.1 {
INSERT INTO abc(abc, rank) VALUES('hashsize', 'not an integer');
} {1 {SQL logic error or missing database}}
do_catchsql_test 9.5.2 {
INSERT INTO abc(abc, rank) VALUES('hashsize', -500000);
} {1 {SQL logic error or missing database}}
do_catchsql_test 9.5.3 {
INSERT INTO abc(abc, rank) VALUES('hashsize', 500000);
} {0 {}}
#-------------------------------------------------------------------------
# Too many prefix indexes. Maximum allowed is 31.
#
foreach {tn spec} {
1 {prefix="1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32"}
2 {prefix="1 2 3 4", prefix="5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32"}
} {
set sql "CREATE VIRTUAL TABLE xyz USING fts5(x, $spec)"
do_catchsql_test 10.$tn $sql {1 {too many prefix indexes (max 31)}}
}
#-------------------------------------------------------------------------
# errors in the detail= option.
#
foreach {tn opt} {
1 {detail=x}
2 {detail='x'}
3 {detail='$'}
4 {detail='1,2,'}
5 {detail=',1'}
6 {detail=''}
} {
set res [list 1 {malformed detail=... directive}]
do_catchsql_test 11.$tn "CREATE VIRTUAL TABLE f1 USING fts5(x, $opt)" $res
}
do_catchsql_test 12.1 {
INSERT INTO t1(t1, rank) VALUES('rank', NULL);;
} {1 {SQL logic error or missing database}}
finish_test
+70
View File
@@ -0,0 +1,70 @@
# 2015 October 27
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
# May you find forgiveness for yourself and forgive others.
# May you share freely, never taking more than you give.
#
#*************************************************************************
# This file implements regression tests for SQLite library. The
# focus of this script is testing the FTS5 module.
#
source [file join [file dirname [info script]] fts5_common.tcl]
set testprefix fts5conflict
# If SQLITE_ENABLE_FTS5 is not defined, omit this file.
ifcapable !fts5 {
finish_test
return
}
do_execsql_test 1.0 {
CREATE TABLE t1(x INTEGER PRIMARY KEY, a, b);
CREATE VIRTUAL TABLE ft USING fts5(a, b, content=t1, content_rowid=x);
}
do_execsql_test 1.1 {
REPLACE INTO ft(rowid, a, b) VALUES(1, 'a b c', 'a b c');
REPLACE INTO t1 VALUES(1, 'a b c', 'a b c');
}
do_execsql_test 1.2 {
INSERT INTO ft(ft) VALUES('integrity-check');
}
do_execsql_test 2.0 {
CREATE TABLE tbl(a INTEGER PRIMARY KEY, b, c);
CREATE VIRTUAL TABLE fts_idx USING fts5(b, c, content=tbl, content_rowid=a);
CREATE TRIGGER tbl_ai AFTER INSERT ON tbl BEGIN
INSERT INTO fts_idx(rowid, b, c) VALUES (new.a, new.b, new.c);
END;
CREATE TRIGGER tbl_ad AFTER DELETE ON tbl BEGIN
INSERT INTO fts_idx(fts_idx, rowid, b, c)
VALUES('delete', old.a, old.b, old.c);
END;
CREATE TRIGGER tbl_au AFTER UPDATE ON tbl BEGIN
INSERT INTO fts_idx(fts_idx, rowid, b, c)
VALUES('delete', old.a, old.b, old.c);
INSERT INTO fts_idx(rowid, b, c) VALUES (new.a, new.b, new.c);
END;
}
do_execsql_test 2.1 {
PRAGMA recursive_triggers = 1;
INSERT INTO tbl VALUES(1, 'x y z', '1 2 3');
INSERT INTO tbl VALUES(10, 'x y z', '1 2 3');
INSERT INTO tbl VALUES(100, 'x 1 z', '1 y 3');
UPDATE tbl SET b = '1 2 x' WHERE rowid=10;
REPLACE INTO tbl VALUES(1, '4 5 6', '3 2 1');
DELETE FROM tbl WHERE a=100;
INSERT INTO fts_idx(fts_idx) VALUES('integrity-check');
}
finish_test
+70 -2
View File
@@ -250,8 +250,6 @@ foreach rowid [db eval {SELECT rowid FROM x1_data WHERE rowid>100}] {
}
}
}
#------------------------------------------------------------------------
#
reset_db
@@ -335,6 +333,76 @@ do_catchsql_test 6.3.5 {
INSERT INTO t1(t1) VALUES('integrity-check');
} {1 {database disk image is malformed}}
#------------------------------------------------------------------------
#
reset_db
proc rnddoc {n} {
set map [list a b c d]
set doc [list]
for {set i 0} {$i < $n} {incr i} {
lappend doc "x[lindex $map [expr int(rand()*4)]]"
}
set doc
}
db func rnddoc rnddoc
do_test 7.0 {
execsql {
CREATE VIRTUAL TABLE t5 USING fts5(x);
INSERT INTO t5 VALUES( rnddoc(10000) );
INSERT INTO t5 VALUES( rnddoc(10000) );
INSERT INTO t5 VALUES( rnddoc(10000) );
INSERT INTO t5 VALUES( rnddoc(10000) );
INSERT INTO t5(t5) VALUES('optimize');
}
} {}
do_test 7.1 {
foreach i [db eval { SELECT rowid FROM t5_data WHERE rowid>100 }] {
db eval BEGIN
db eval {DELETE FROM t5_data WHERE rowid = $i}
set r [catchsql { INSERT INTO t5(t5) VALUES('integrity-check')} ]
if {$r != "1 {database disk image is malformed}"} { error $r }
db eval ROLLBACK
}
} {}
}
#------------------------------------------------------------------------
# Corruption within the structure record.
#
reset_db
do_execsql_test 8.1 {
CREATE VIRTUAL TABLE t1 USING fts5(x, y);
INSERT INTO t1 VALUES('one', 'two');
}
do_test 9.1.1 {
set blob "12345678" ;# cookie
append blob "0105" ;# 1 level, total of 5 segments
append blob "06" ;# write counter
append blob "0002" ;# first level has 0 segments merging, 2 other.
append blob "450108" ;# first segment
execsql "REPLACE INTO t1_data VALUES(10, X'$blob')"
} {}
do_catchsql_test 9.1.2 {
SELECT * FROM t1('one AND two');
} {1 {database disk image is malformed}}
do_test 9.2.1 {
set blob "12345678" ;# cookie
append blob "0205" ;# 2 levels, total of 5 segments
append blob "06" ;# write counter
append blob "0001" ;# first level has 0 segments merging, 1 other.
append blob "450108" ;# first segment
execsql "REPLACE INTO t1_data VALUES(10, X'$blob')"
} {}
do_catchsql_test 9.2.2 {
SELECT * FROM t1('one AND two');
} {1 {database disk image is malformed}}
sqlite3_fts5_may_be_corrupt 0
finish_test
+244
View File
@@ -0,0 +1,244 @@
# 2015 December 18
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
# May you find forgiveness for yourself and forgive others.
# May you share freely, never taking more than you give.
#
#*************************************************************************
# This file implements regression tests for SQLite library. The
# focus of this script is testing the FTS5 module.
#
source [file join [file dirname [info script]] fts5_common.tcl]
set testprefix fts5detail
# If SQLITE_ENABLE_FTS5 is not defined, omit this file.
ifcapable !fts5 {
finish_test
return
}
fts5_aux_test_functions db
#--------------------------------------------------------------------------
# Simple tests.
#
do_execsql_test 1.0 {
CREATE VIRTUAL TABLE t1 USING fts5(a, b, c, detail=col);
INSERT INTO t1 VALUES('h d g', 'j b b g b', 'i e i d h g g'); -- 1
INSERT INTO t1 VALUES('h j d', 'j h d a h', 'f d d g g f b'); -- 2
INSERT INTO t1 VALUES('j c i', 'f f h e f', 'c j i j c h f'); -- 3
INSERT INTO t1 VALUES('e g g', 'g e d h i', 'e d b e g d c'); -- 4
INSERT INTO t1 VALUES('b c c', 'd i h a f', 'd i j f a b c'); -- 5
INSERT INTO t1 VALUES('e d e', 'b c j g d', 'a i f d h b d'); -- 6
INSERT INTO t1 VALUES('g h e', 'b c d i d', 'e f c i f i c'); -- 7
INSERT INTO t1 VALUES('c f j', 'j j i e a', 'h a c f d h e'); -- 8
INSERT INTO t1 VALUES('a h i', 'c i a f a', 'c f d h g d g'); -- 9
INSERT INTO t1 VALUES('j g g', 'e f e f f', 'h j b i c g e'); -- 10
}
do_execsql_test 1.1 {
INSERT INTO t1(t1) VALUES('integrity-check');
}
foreach {tn match res} {
1 "a:a" {9}
2 "b:g" {1 4 6}
3 "c:h" {1 3 6 8 9 10}
} {
do_execsql_test 1.2.$tn.1 {
SELECT rowid FROM t1($match);
} $res
do_execsql_test 1.2.$tn.2 {
SELECT rowid FROM t1($match || '*');
} $res
}
do_catchsql_test 1.3.1 {
SELECT rowid FROM t1('h + d');
} {1 {fts5: phrase queries are not supported (detail!=full)}}
do_catchsql_test 1.3.2 {
SELECT rowid FROM t1('NEAR(h d)');
} {1 {fts5: NEAR queries are not supported (detail!=full)}}
#-------------------------------------------------------------------------
# integrity-check with both detail= and prefix= options.
#
do_execsql_test 2.0 {
CREATE VIRTUAL TABLE t2 USING fts5(a, detail=col, prefix="1");
INSERT INTO t2(a) VALUES('aa ab');
}
#db eval {SELECT rowid, fts5_decode(rowid, block) aS r FROM t2_data} {puts $r}
do_execsql_test 2.1 {
INSERT INTO t2(t2) VALUES('integrity-check');
}
do_execsql_test 2.2 {
SELECT fts5_test_poslist(t2) FROM t2('aa');
} {0.0.0}
do_execsql_test 2.3 {
SELECT fts5_test_collist(t2) FROM t2('aa');
} {0.0}
set ::pc 0
#puts [nearset {{ax bx cx}} -pc ::pc -near 10 -- b*]
#exit
#-------------------------------------------------------------------------
# Check that the xInstCount, xInst, xPhraseFirst and xPhraseNext APIs
# work with detail=col tables.
#
set data {
1 {abb aca aca} {aba bab aab aac caa} {abc cbc ccb bcc bab ccb aca}
2 {bca aca acb} {ccb bcc bca aab bcc} {bab aaa aac cbb bba aca abc}
3 {cca abc cab} {aab aba bcc cac baa} {bab cbb acb aba aab ccc cca}
4 {ccb bcb aba} {aba bbb bcc cac bbb} {cbb aaa bca bcc aab cac aca}
5 {bca bbc cac} {aba cbb cac cca aca} {cab acb cbc ccb cac bbb bcb}
6 {acc bba cba} {bab bbc bbb bcb aca} {bca ccc cbb aca bac ccc ccb}
7 {aba bab aaa} {abb bca aac bcb bcc} {bcb bbc aba aaa cba abc acc}
8 {cab aba aaa} {ccb aca caa bbc bcc} {aaa abc ccb bbb cac cca abb}
9 {bcb bab bac} {bcb cba cac bbb abc} {aba aca cbb acb abb ccc ccb}
10 {aba aab ccc} {abc ccc bcc cab bbb} {aab bcc cbb ccc aaa bac baa}
11 {bab acb cba} {aac cab cab bca cbc} {aab cbc aac baa ccb acc cac}
12 {ccc cbb cbc} {aaa aab bcc aac bbc} {cbc cbc bac bac ccc bbc acc}
13 {cab bbc abc} {bbb bab bba aca bab} {baa bbb aab bbb ccb bbb ccc}
14 {bbc cab caa} {acb aac abb cba acc} {cba bba bba acb abc abb baa}
15 {aba cca bcc} {aaa acb abc aab ccb} {cca bcb acc aaa caa cca cbc}
16 {bcb bba aba} {cbc acb cab caa ccb} {aac aaa bbc cab cca cba abc}
17 {caa cbb acc} {ccb bcb bca aaa bcc} {bbb aca bcb bca cbc cbc cca}
18 {cbb bbc aac} {ccc bbc aaa aab baa} {cab cab cac cca bbc abc bbc}
19 {ccc acc aaa} {aab cbb bca cca caa} {bcb aca aca cab acc bac bcc}
20 {aab ccc bcb} {bbc cbb bbc aaa bcc} {cbc aab ccc aaa bcb bac cbc}
21 {aba cab ccc} {bbc cbc cba acc bbb} {acc aab aac acb aca bca acb}
22 {bcb bca baa} {cca bbc aca ccb cbb} {aab abc bbc aaa cab bcc bcc}
23 {cac cbb caa} {bbc aba bbb bcc ccb} {bbc bbb cab bbc cac abb acc}
24 {ccb acb caa} {cab bba cac bbc aac} {aac bca abc cab bca cab bcb}
25 {bbb aca bca} {bcb acc ccc cac aca} {ccc acb acc cac cac bba bbc}
26 {bab acc caa} {caa cab cac bac aca} {aba cac caa acc bac ccc aaa}
27 {bca bca aaa} {ccb aca bca aaa baa} {bab acc aaa cca cba cca bac}
28 {ccb cac cac} {bca abb bba bbc baa} {aca ccb aac cab ccc cab caa}
29 {abc bca cab} {cac cbc cbb ccc bcc} {bcc aaa aaa acc aac cac aac}
30 {aca acc acb} {aab aac cbb caa acb} {acb bbc bbc acc cbb bbc aac}
31 {aba aca baa} {aca bcc cab bab acb} {bcc acb baa bcb bbc acc aba}
32 {abb cbc caa} {cba abb bbb cbb aca} {bac aca caa cac caa ccb bbc}
33 {bcc bcb bcb} {cca cab cbc abb bab} {caa bbc aac bbb cab cba aaa}
34 {caa cab acc} {ccc ccc bcc acb bcc} {bac bba aca bcb bba bcb cac}
35 {bac bcb cba} {bcc acb bbc cba bab} {abb cbb abc abc bac acc cbb}
36 {cab bab ccb} {bca bba bab cca acc} {acc aab bcc bac acb cbb caa}
37 {aca cbc cab} {bba aac aca aac aaa} {baa cbb cba aba cab bca bcb}
38 {acb aab baa} {baa bab bca bbc bbb} {abc baa acc aba cab baa cac}
39 {bcb aac cba} {bcb baa caa cac bbc} {cbc ccc bab ccb bbb caa aba}
40 {cba ccb abc} {cbb caa cba aac bab} {cbb bbb bca bbb bac cac bca}
}
set data {
1 {abb aca aca} {aba bab aab aac caa} {abc cbc ccb bcc bab ccb aca}
}
proc matchdata {expr {bAsc 1}} {
set tclexpr [db one {
SELECT fts5_expr_tcl($expr, 'nearset $cols -pc ::pc', 'x', 'y', 'z')
}]
set res [list]
#puts "$expr -> $tclexpr"
foreach {id x y z} $::data {
set cols [list $x $y $z]
set ::pc 0
#set hits [lsort -command instcompare [eval $tclexpr]]
set hits [eval $tclexpr]
if {[llength $hits]>0} {
lappend res [list $id $hits]
}
}
if {$bAsc} {
set res [lsort -integer -increasing -index 0 $res]
} else {
set res [lsort -integer -decreasing -index 0 $res]
}
return [concat {*}$res]
}
foreach {tn tbl} {
1 { CREATE VIRTUAL TABLE t3 USING fts5(x, y, z, detail=col) }
2 { CREATE VIRTUAL TABLE t3 USING fts5(x, y, z, detail=none) }
} {
reset_db
fts5_aux_test_functions db
execsql $tbl
foreach {id x y z} $data {
execsql { INSERT INTO t3(rowid, x, y, z) VALUES($id, $x, $y, $z) }
}
foreach {tn2 expr} {
1 aaa 2 ccc 3 bab 4 aac
5 aa* 6 cc* 7 ba* 8 aa*
9 a* 10 b* 11 c*
} {
set res [matchdata $expr]
do_execsql_test 3.$tn.$tn2.1 {
SELECT rowid, fts5_test_poslist(t3) FROM t3($expr)
} $res
do_execsql_test 3.$tn.$tn2.2 {
SELECT rowid, fts5_test_poslist2(t3) FROM t3($expr)
} $res
}
}
#-------------------------------------------------------------------------
# Simple tests for detail=none tables.
#
do_execsql_test 4.0 {
CREATE VIRTUAL TABLE t4 USING fts5(a, b, c, detail=none);
INSERT INTO t4 VALUES('a b c', 'b c d', 'e f g');
INSERT INTO t4 VALUES('1 2 3', '4 5 6', '7 8 9');
}
do_catchsql_test 4.1 {
SELECT * FROM t4('a:a')
} {1 {fts5: column queries are not supported (detail=none)}}
#-------------------------------------------------------------------------
# Test that for the same content detail=none uses less space than
# detail=col, and that detail=col uses less space than detail=full
#
reset_db
do_test 5.1 {
foreach {tbl detail} {t1 none t2 col t3 full} {
execsql "CREATE VIRTUAL TABLE $tbl USING fts5(x, y, z, detail=$detail)"
foreach {rowid x y z} $::data {
execsql "INSERT INTO $tbl (rowid, x, y, z) VALUES(\$rowid, \$x, \$y, \$z)"
}
}
} {}
do_execsql_test 5.2 {
SELECT
(SELECT sum(length(block)) from t1_data) <
(SELECT sum(length(block)) from t2_data)
} {1}
do_execsql_test 5.3 {
SELECT
(SELECT sum(length(block)) from t2_data) <
(SELECT sum(length(block)) from t3_data)
} {1}
finish_test
+14 -11
View File
@@ -26,7 +26,7 @@ if { $tcl_platform(wordSize)<8 } {
return
}
if 1 {
foreach_detail_mode $testprefix {
proc do_fb_test {tn sql res} {
set res2 [lsort -integer -decr $res]
@@ -34,7 +34,7 @@ proc do_fb_test {tn sql res} {
uplevel [list do_execsql_test $tn.2 "$sql ORDER BY rowid DESC" $res2]
}
# This test populates the FTS5 table containing $nEntry entries. Rows are
# This test populates the FTS5 table with $nEntry entries. Rows are
# numbered from 0 to ($nEntry-1). The rowid for row $i is:
#
# ($iFirst + $i*$nStep)
@@ -77,10 +77,12 @@ proc do_dlidx_test1 {tn spc1 spc2 nEntry iFirst nStep} {
do_fb_test $tn.4.1 { SELECT rowid FROM t1 WHERE t1 MATCH 'a AND y' } $ydoc
do_fb_test $tn.4.2 { SELECT rowid FROM t1 WHERE t1 MATCH 'y AND a' } $ydoc
do_fb_test $tn.5.1 {
SELECT rowid FROM t1 WHERE t1 MATCH 'a + b + c + x' } $xdoc
do_fb_test $tn.5.2 {
SELECT rowid FROM t1 WHERE t1 MATCH 'b + c + x + y' } $ydoc
if {[detail_is_full]} {
do_fb_test $tn.5.1 {
SELECT rowid FROM t1 WHERE t1 MATCH 'a + b + c + x' } $xdoc
do_fb_test $tn.5.2 {
SELECT rowid FROM t1 WHERE t1 MATCH 'b + c + x + y' } $ydoc
}
}
@@ -90,7 +92,7 @@ foreach {tn pgsz} {
} {
do_execsql_test $tn.0 {
DROP TABLE IF EXISTS t1;
CREATE VIRTUAL TABLE t1 USING fts5(x);
CREATE VIRTUAL TABLE t1 USING fts5(x, detail=%DETAIL%);
INSERT INTO t1(t1, rank) VALUES('pgsz', $pgsz);
}
@@ -107,7 +109,7 @@ proc do_dlidx_test2 {tn nEntry iFirst nStep} {
execsql {
BEGIN;
DROP TABLE IF EXISTS t1;
CREATE VIRTUAL TABLE t1 USING fts5(x);
CREATE VIRTUAL TABLE t1 USING fts5(x, detail=%DETAIL%);
INSERT INTO t1(t1, rank) VALUES('pgsz', 64);
INSERT INTO t1 VALUES('b a');
@@ -130,8 +132,6 @@ proc do_dlidx_test2 {tn nEntry iFirst nStep} {
do_dlidx_test2 2.1 [expr 20] [expr 1<<57] [expr (1<<57) + 128]
}
#--------------------------------------------------------------------
#
reset_db
@@ -158,7 +158,7 @@ proc rnddoc {} {
db func rnddoc rnddoc
do_execsql_test 3.1 {
CREATE VIRTUAL TABLE abc USING fts5(a);
CREATE VIRTUAL TABLE abc USING fts5(a, detail=%DETAIL%);
INSERT INTO abc(abc, rank) VALUES('pgsz', 32);
INSERT INTO abc VALUES ( rnddoc() );
@@ -192,6 +192,9 @@ foreach v $vocab {
} {1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16}
}
} ;# foreach_detail_mode
finish_test
+9
View File
@@ -42,6 +42,15 @@ foreach {tn expr res} {
10 {abc + "" + def} {"abc" + "def"}
11 {abc "" def} {"abc" AND "def"}
12 {r+e OR w} {"r" + "e" OR "w"}
13 {a AND b NOT c} {"a" AND ("b" NOT "c")}
14 {a OR b NOT c} {"a" OR ("b" NOT "c")}
15 {a NOT b AND c} {("a" NOT "b") AND "c"}
16 {a NOT b OR c} {("a" NOT "b") OR "c"}
17 {a AND b OR c} {("a" AND "b") OR "c"}
18 {a OR b AND c} {"a" OR ("b" AND "c")}
} {
do_execsql_test 1.$tn {SELECT fts5_expr($expr)} [list $res]
}
+5 -4
View File
@@ -52,7 +52,7 @@ do_faultsim_test 2 -prep {
INSERT INTO t1 VALUES('a b c', 'a bc def ghij klmno');
}
} -test {
faultsim_test_result {0 {}}
faultsim_test_result {0 {}} {1 {vtable constructor failed: t1}}
}
reset_db
@@ -66,13 +66,13 @@ do_faultsim_test 3 -prep {
} -body {
execsql { DELETE FROM t1 }
} -test {
faultsim_test_result {0 {}}
faultsim_test_result {0 {}} {1 {vtable constructor failed: t1}}
}
reset_db
do_execsql_test 4.0 {
CREATE VIRTUAL TABLE t2 USING fts5(a, b);
INSERT INTO t2 VALUES('m f a jj th q jr ar', 'hj n h h sg j i m');
INSERT INTO t2 VALUES('m f a jj th q gi ar', 'hj n h h sg j i m');
INSERT INTO t2 VALUES('nr s t g od j kf h', 'sb h aq rg op rb n nl');
INSERT INTO t2 VALUES('do h h pb p p q fr', 'c rj qs or cr a l i');
INSERT INTO t2 VALUES('lk gp t i lq mq qm p', 'h mr g f op ld aj h');
@@ -95,13 +95,14 @@ foreach {tn expr res} {
7 { NEAR(r a, 5) } {9}
8 { m* f* } {1 4 6 8 9 10}
9 { m* + f* } {1 8}
10 { c NOT p } {5 6 7 10}
} {
do_faultsim_test 4.$tn -prep {
faultsim_restore_and_reopen
} -body "
execsql { SELECT rowid FROM t2 WHERE t2 MATCH '$expr' }
" -test "
faultsim_test_result {[list 0 $res]}
faultsim_test_result {[list 0 $res]} {1 {vtable constructor failed: t2}}
"
}
+1 -1
View File
@@ -16,7 +16,7 @@ source [file join [file dirname [info script]] fts5_common.tcl]
source $testdir/malloc_common.tcl
set testprefix fts5fault2
# If SQLITE_ENABLE_FTS3 is defined, omit this file.
# If SQLITE_ENABLE_FTS5 is not defined, omit this file.
ifcapable !fts5 {
finish_test
return
+1 -22
View File
@@ -40,27 +40,6 @@ do_faultsim_test 1 -faults oom-* -prep {
faultsim_test_result [list 0 {}]
}
#-------------------------------------------------------------------------
# An OOM within an "ORDER BY rank" query.
#
db func rnddoc fts5_rnddoc
do_execsql_test 2.0 {
CREATE VIRTUAL TABLE xx USING fts5(x);
INSERT INTO xx VALUES ('abc ' || rnddoc(10));
INSERT INTO xx VALUES ('abc abc' || rnddoc(9));
INSERT INTO xx VALUES ('abc abc abc' || rnddoc(8));
} {}
faultsim_save_and_close
do_faultsim_test 2 -faults oom-* -prep {
faultsim_restore_and_reopen
execsql { SELECT * FROM xx }
} -body {
execsql { SELECT rowid FROM xx WHERE xx MATCH 'abc' ORDER BY rank }
} -test {
faultsim_test_result [list 0 {3 2 1}]
}
#-------------------------------------------------------------------------
# An OOM while "reseeking" an FTS cursor.
#
@@ -107,7 +86,7 @@ set ::res [db eval {SELECT rowid, x1 FROM x1 WHERE x1 MATCH '*reads'}]
do_faultsim_test 4 -faults oom-* -body {
db eval {SELECT rowid, x, x1 FROM x1 WHERE x1 MATCH '*reads'}
} -test {
faultsim_test_result {0 {0 {} 3}}
faultsim_test_result {0 {0 {} 4}}
}
#-------------------------------------------------------------------------
+38 -1
View File
@@ -65,19 +65,26 @@ do_faultsim_test 2.2 -faults oom-t* -body {
}
#-------------------------------------------------------------------------
# OOM while scanning an fts5vocab table.
# OOM while scanning fts5vocab tables.
#
reset_db
do_test 3.0 {
execsql {
CREATE VIRTUAL TABLE tt USING fts5(x);
CREATE VIRTUAL TABLE tv USING fts5vocab(tt, 'row');
CREATE VIRTUAL TABLE tt2 USING fts5(x, detail=col);
CREATE VIRTUAL TABLE tv2 USING fts5vocab(tt2, 'col');
INSERT INTO tt(tt, rank) VALUES('pgsz', 32);
INSERT INTO tt2(tt2, rank) VALUES('pgsz', 32);
BEGIN;
}
for {set i 0} {$i < 20} {incr i} {
set str [string repeat "$i " 50]
execsql { INSERT INTO tt VALUES($str) }
execsql { INSERT INTO tt2 VALUES($str) }
}
execsql COMMIT
} {}
@@ -90,6 +97,36 @@ do_faultsim_test 3.1 -faults oom-t* -body {
faultsim_test_result {0 {0 1 10 11 12 13 14 15 16 17 18 19 2 3 4 5 6 7 8 9}}
}
do_faultsim_test 3.2 -faults oom-t* -body {
db eval {
SELECT term FROM tv WHERE term BETWEEN '1' AND '2';
}
} -test {
faultsim_test_result {0 {1 10 11 12 13 14 15 16 17 18 19 2}}
}
breakpoint
do_execsql_test 3.3.0 {
SELECT * FROM tv2;
} {
0 x 1 {} 1 x 1 {} 10 x 1 {} 11 x 1 {} 12 x 1 {} 13 x 1 {}
14 x 1 {} 15 x 1 {} 16 x 1 {} 17 x 1 {} 18 x 1 {} 19 x 1 {}
2 x 1 {} 3 x 1 {} 4 x 1 {} 5 x 1 {} 6 x 1 {} 7 x 1 {} 8 x 1 {}
9 x 1 {}
}
do_faultsim_test 3.3 -faults oom-t* -body {
db eval {
SELECT * FROM tv2;
}
} -test {
faultsim_test_result [list 0 [list \
0 x 1 {} 1 x 1 {} 10 x 1 {} 11 x 1 {} 12 x 1 {} 13 x 1 {} \
14 x 1 {} 15 x 1 {} 16 x 1 {} 17 x 1 {} 18 x 1 {} 19 x 1 {} \
2 x 1 {} 3 x 1 {} 4 x 1 {} 5 x 1 {} 6 x 1 {} 7 x 1 {} 8 x 1 {} \
9 x 1 {}
]]
}
finish_test
+28
View File
@@ -87,5 +87,33 @@ do_faultsim_test 1 -faults oom-t* -prep {
faultsim_test_result {0 {}}
}
#-------------------------------------------------------------------------
# Test fault-injection when a segment is promoted.
#
reset_db
do_execsql_test 2.0 {
CREATE VIRTUAL TABLE xy USING fts5(x);
INSERT INTO xy(rowid, x) VALUES(1, '1 2 3');
INSERT INTO xy(rowid, x) VALUES(2, '2 3 4');
INSERT INTO xy(rowid, x) VALUES(3, '3 4 5');
}
faultsim_save_and_close
do_faultsim_test 2.1 -faults oom-* -prep {
faultsim_restore_and_reopen
} -body {
db eval { UPDATE OR REPLACE xy SET rowid=3 WHERE rowid = 2 }
} -test {
faultsim_test_result {0 {}}
}
# Test fault-injection when an empty expression is parsed.
#
do_faultsim_test 2.2 -faults oom-* -body {
db eval { SELECT * FROM xy('""') }
} -test {
faultsim_test_result {0 {}}
}
finish_test
+60
View File
@@ -0,0 +1,60 @@
# 2015 September 3
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
# May you find forgiveness for yourself and forgive others.
# May you share freely, never taking more than you give.
#
#*************************************************************************
#
# This file is focused on OOM errors.
#
source [file join [file dirname [info script]] fts5_common.tcl]
source $testdir/malloc_common.tcl
set testprefix fts5fault8
# If SQLITE_ENABLE_FTS3 is defined, omit this file.
ifcapable !fts5 {
finish_test
return
}
foreach_detail_mode $testprefix {
fts5_aux_test_functions db
do_execsql_test 1.0 {
CREATE VIRTUAL TABLE t1 USING fts5(a, b, detail=%DETAIL%);
INSERT INTO t1 VALUES('a b c d', '1 2 3 4');
INSERT INTO t1 VALUES('a b a b', NULL);
INSERT INTO t1 VALUES(NULL, '1 2 1 2');
}
do_faultsim_test 1 -faults oom-* -body {
execsql {
SELECT rowid, fts5_test_poslist(t1) FROM t1 WHERE t1 MATCH 'b OR 2'
}
} -test {
faultsim_test_result {0 {1 {0.0.1 1.1.1} 2 {0.0.1 0.0.3} 3 {1.1.1 1.1.3}}} \
{1 SQLITE_NOMEM}
}
do_faultsim_test 2 -faults oom-* -body {
execsql { INSERT INTO t1(t1) VALUES('integrity-check') }
} -test {
faultsim_test_result {0 {}} {1 SQLITE_NOMEM}
}
if {[detail_is_none]==0} {
do_faultsim_test 3 -faults oom-* -body {
execsql { SELECT rowid FROM t1('b:2') }
} -test {
faultsim_test_result {0 {1 3}} {1 SQLITE_NOMEM}
}
}
} ;# foreach_detail_mode...
finish_test
+156
View File
@@ -0,0 +1,156 @@
# 2015 September 3
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
# May you find forgiveness for yourself and forgive others.
# May you share freely, never taking more than you give.
#
#*************************************************************************
#
# This file is focused on OOM errors.
#
source [file join [file dirname [info script]] fts5_common.tcl]
source $testdir/malloc_common.tcl
set testprefix fts5fault9
# If SQLITE_ENABLE_FTS3 is defined, omit this file.
ifcapable !fts5 {
finish_test
return
}
foreach_detail_mode $testprefix {
fts5_aux_test_functions db
do_execsql_test 1.0 {
CREATE VIRTUAL TABLE t1 USING fts5(a, b, detail=%DETAIL%);
INSERT INTO t1(t1, rank) VALUES('pgsz', 32);
WITH seq(s) AS ( SELECT 1 UNION ALL SELECT s+1 FROM seq WHERE s<50)
INSERT INTO t1 SELECT 'x x x y y y', 'a b c d e f' FROM seq;
}
do_faultsim_test 1 -faults oom-* -body {
execsql { SELECT count(*) FROM t1('x AND y') }
} -test {
faultsim_test_result {0 50}
}
do_execsql_test 2.0 {
CREATE VIRTUAL TABLE t2 USING fts5(a, b, detail=%DETAIL%);
INSERT INTO t2(t2, rank) VALUES('pgsz', 32);
INSERT INTO t2 VALUES('abc cba', 'cba abc');
INSERT INTO t2 VALUES('abc cba', 'cba abc');
INSERT INTO t2 VALUES('abc cba', 'cba abc');
INSERT INTO t2 VALUES('axy cyx', 'cyx axy');
INSERT INTO t2 VALUES('axy cyx', 'cyx axy');
INSERT INTO t2 VALUES('axy cyx', 'cyx axy');
}
do_faultsim_test 2 -faults oom-* -body {
execsql { SELECT count(*) FROM t2('a* AND c*') }
} -test {
faultsim_test_result {0 6}
}
do_execsql_test 3.0 {
CREATE VIRTUAL TABLE t3 USING fts5(a, detail=%DETAIL%);
INSERT INTO t3 VALUES('a x x a x a a a');
INSERT INTO t3 VALUES('x a a x a x x x');
}
do_faultsim_test 3.1 -faults oom-* -body {
execsql { SELECT highlight(t3, 0, '[', ']') FROM t3('a') }
} -test {
faultsim_test_result {0 {{[a] x x [a] x [a] [a] [a]} {x [a] [a] x [a] x x x}}}
}
do_faultsim_test 3.2 -faults oom-t* -body {
execsql { SELECT fts5_test_poslist2(t3) FROM t3('x') }
} -test {
faultsim_test_result \
{0 {{0.0.1 0.0.2 0.0.4} {0.0.0 0.0.3 0.0.5 0.0.6 0.0.7}}} \
{1 SQLITE_NOMEM}
}
#-------------------------------------------------------------------------
# Test OOM injection with the xPhraseFirstColumn() API and a tokenizer
# uses query synonyms.
#
fts5_tclnum_register db
do_execsql_test 4.0 {
CREATE VIRTUAL TABLE t4 USING fts5(x, y, z, detail=%DETAIL%, tokenize=tclnum);
INSERT INTO t4 VALUES('one two three', '1 2 3', 'i ii iii');
INSERT INTO t4 VALUES('1 2 3', 'i ii iii', 'one two three');
INSERT INTO t4 VALUES('i ii iii', 'one two three', 'i ii iii');
INSERT INTO t4 VALUES('a1 a2 a3', 'a4 a5 a6', 'a7 a8 a9');
INSERT INTO t4 VALUES('b1 b2 b3', 'b4 b5 b6', 'b7 b8 b9');
INSERT INTO t4 VALUES('c1 c2 c3', 'c4 c5 c6', 'c7 c8 c9');
}
do_faultsim_test 4.1 -faults oom-t* -body {
execsql { SELECT rowid, fts5_test_collist(t4) FROM t4('2') }
} -test {
faultsim_test_result \
{0 {1 {0.0 0.1 0.2} 2 {0.0 0.1 0.2} 3 {0.0 0.1 0.2}}} {1 SQLITE_NOMEM}
}
do_faultsim_test 4.2 -faults oom-t* -body {
execsql { SELECT rowid, fts5_test_collist(t4) FROM t4('a5 OR b5 OR c5') }
} -test {
faultsim_test_result \
{0 {4 {0.0 0.1 0.2} 5 {1.0 1.1 1.2} 6 {2.0 2.1 2.2}}} {1 SQLITE_NOMEM}
}
#-------------------------------------------------------------------------
# An OOM within an "ORDER BY rank" query.
#
db func rnddoc fts5_rnddoc
do_execsql_test 5.0 {
CREATE VIRTUAL TABLE xx USING fts5(x, y, detail=%DETAIL%);
INSERT INTO xx VALUES ('def', 'abc ' || rnddoc(10));
INSERT INTO xx VALUES ('def', 'abc abc' || rnddoc(9));
INSERT INTO xx VALUES ('def', 'abc abc abc' || rnddoc(8));
} {}
faultsim_save_and_close
do_faultsim_test 5 -faults oom-* -prep {
faultsim_restore_and_reopen
execsql { SELECT * FROM xx }
} -body {
execsql { SELECT rowid FROM xx('abc AND def') ORDER BY rank }
} -test {
faultsim_test_result [list 0 {3 2 1}]
}
set doc [string repeat "xyz " 500]
do_execsql_test 6.0 {
CREATE VIRTUAL TABLE yy USING fts5(y, detail=%DETAIL%);
INSERT INTO yy(yy, rank) VALUES('pgsz', 64);
INSERT INTO yy VALUES ($doc);
INSERT INTO yy VALUES ('1 2 3');
INSERT INTO yy VALUES ('xyz');
UPDATE yy SET y = y WHERE rowid = 1;
UPDATE yy SET y = y WHERE rowid = 1;
UPDATE yy SET y = y WHERE rowid = 1;
UPDATE yy SET y = y WHERE rowid = 1;
} {}
do_faultsim_test 6 -faults oom-* -body {
execsql { SELECT rowid FROM yy('xyz') }
} -test {
faultsim_test_result [list 0 {1 3}]
}
} ;# foreach_detail_mode...
finish_test
+64
View File
@@ -0,0 +1,64 @@
# 2016 February 2
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
# May you find forgiveness for yourself and forgive others.
# May you share freely, never taking more than you give.
#
#*************************************************************************
#
# This file is focused on OOM errors.
#
source [file join [file dirname [info script]] fts5_common.tcl]
source $testdir/malloc_common.tcl
set testprefix fts5faultA
# If SQLITE_ENABLE_FTS3 is defined, omit this file.
ifcapable !fts5 {
finish_test
return
}
foreach_detail_mode $testprefix {
do_execsql_test 1.0 {
CREATE VIRTUAL TABLE o1 USING fts5(a, detail=%DETAIL%);
INSERT INTO o1(o1, rank) VALUES('pgsz', 32);
WITH s(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<300 )
INSERT INTO o1 SELECT 'A B C' FROM s;
INSERT INTO o1 VALUES('A X C');
WITH s(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<300 )
INSERT INTO o1 SELECT 'A B C' FROM s;
}
do_faultsim_test 1 -faults oom* -prep {
sqlite3 db test.db
} -body {
execsql { SELECT rowid FROM o1('a NOT b') }
} -test {
faultsim_test_result {0 301}
}
}
do_execsql_test 2.0 {
CREATE VIRTUAL TABLE o2 USING fts5(a);
INSERT INTO o2 VALUES('A B C');
WITH s(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<300 )
INSERT INTO o2 SELECT group_concat('A B C ') FROM s;
}
do_faultsim_test 2 -faults oom* -prep {
sqlite3 db test.db
} -body {
execsql { SELECT rowid FROM o2('a+b+c NOT xyz') }
} -test {
faultsim_test_result {0 {1 2}}
}
finish_test
+83
View File
@@ -0,0 +1,83 @@
# 2016 February 17
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
# May you find forgiveness for yourself and forgive others.
# May you share freely, never taking more than you give.
#
#*************************************************************************
#
# This file is focused on OOM errors.
#
source [file join [file dirname [info script]] fts5_common.tcl]
source $testdir/malloc_common.tcl
set testprefix fts5faultB
# If SQLITE_ENABLE_FTS3 is defined, omit this file.
ifcapable !fts5 {
finish_test
return
}
proc mit {blob} {
set scan(littleEndian) i*
set scan(bigEndian) I*
binary scan $blob $scan($::tcl_platform(byteOrder)) r
return $r
}
db func mit mit
#-------------------------------------------------------------------------
# Errors while registering the matchinfo() demo function.
#
do_faultsim_test 1 -faults oom* -prep {
sqlite3 db test.db
} -body {
sqlite3_fts5_register_matchinfo db
} -test {
faultsim_test_result {0 {}} {1 SQLITE_ERROR} {1 SQLITE_NOMEM}
}
#-------------------------------------------------------------------------
# Errors while executing the matchinfo() demo function.
#
reset_db
sqlite3_fts5_register_matchinfo db
db func mit mit
do_execsql_test 2 {
CREATE VIRTUAL TABLE t1 USING fts5(a, b);
INSERT INTO t1 VALUES('x y z', '1 2 3');
INSERT INTO t1 VALUES('x', '1 2 3 4 5 6 7');
}
do_faultsim_test 2.1 -faults oom* -body {
execsql { SELECT mit(matchinfo(t1, 'a')) FROM t1('x') }
} -test {
faultsim_test_result {0 {{2 5} {2 5}}}
}
do_faultsim_test 2.2 -faults oom* -body {
execsql { SELECT mit(matchinfo(t1, 'l')) FROM t1('x') }
} -test {
faultsim_test_result {0 {{3 3} {1 7}}}
}
do_execsql_test 2.3 {
INSERT INTO t1 VALUES('a b c d e f', 'a b d e f c');
INSERT INTO t1 VALUES('l m b c a', 'n o a b c z');
}
do_faultsim_test 2.4 -faults oom* -body {
execsql { SELECT mit(matchinfo(t1, 's')) FROM t1('a b c') }
} -test {
faultsim_test_result {0 {{3 2} {2 3}}}
}
finish_test
+60 -35
View File
@@ -64,45 +64,70 @@ proc random_doc {vocab nWord} {
return $doc
}
set vocab [build_vocab1]
db func r random_doc
foreach_detail_mode $testprefix {
do_execsql_test 1.0 {
CREATE VIRTUAL TABLE eee USING fts5(e, ee);
BEGIN;
WITH ii(i) AS (SELECT 1 UNION ALL SELECT i+1 FROM ii WHERE i<100)
INSERT INTO eee SELECT r($vocab, 5), r($vocab, 7) FROM ii;
set vocab [build_vocab1]
db func r random_doc
do_execsql_test 1.0 {
CREATE VIRTUAL TABLE eee USING fts5(e, ee, detail=%DETAIL%);
BEGIN;
WITH ii(i) AS (SELECT 1 UNION ALL SELECT i+1 FROM ii WHERE i<100)
INSERT INTO eee SELECT r($vocab, 5), r($vocab, 7) FROM ii;
INSERT INTO eee(eee) VALUES('integrity-check');
COMMIT;
INSERT INTO eee(eee) VALUES('integrity-check');
}
set hash [sqlite3_fts5_token_hash 1024 xyz]
set vocab [build_vocab1 -prefix xyz -hash $hash]
lappend vocab xyz
do_execsql_test 1.1 {
CREATE VIRTUAL TABLE vocab USING fts5vocab(eee, 'row');
BEGIN;
}
do_test 1.2 {
for {set i 1} {$i <= 100} {incr i} {
execsql { INSERT INTO eee VALUES( r($vocab, 5), r($vocab, 7) ) }
}
} {}
do_test 1.3 {
db eval { SELECT term, doc FROM vocab } {
set nRow [db one {SELECT count(*) FROM eee WHERE eee MATCH $term}]
if {$nRow != $doc} {
error "term=$term fts5vocab=$doc cnt=$nRow"
}
}
set {} {}
} {}
do_execsql_test 1.4 {
COMMIT;
INSERT INTO eee(eee) VALUES('integrity-check');
COMMIT;
INSERT INTO eee(eee) VALUES('integrity-check');
}
set hash [sqlite3_fts5_token_hash 1024 xyz]
set vocab [build_vocab1 -prefix xyz -hash $hash]
lappend vocab xyz
do_execsql_test 1.1 {
CREATE VIRTUAL TABLE vocab USING fts5vocab(eee, 'row');
BEGIN;
WITH ii(i) AS (SELECT 1 UNION ALL SELECT i+1 FROM ii WHERE i<100)
INSERT INTO eee SELECT r($vocab, 5), r($vocab, 7) FROM ii;
INSERT INTO eee(eee) VALUES('integrity-check');
}
do_test 1.2 {
db eval { SELECT term, doc FROM vocab } {
set nRow [db one {SELECT count(*) FROM eee WHERE eee MATCH $term}]
if {$nRow != $doc} {
error "term=$term fts5vocab=$doc cnt=$nRow"
}
}
set {} {}
} {}
do_execsql_test 1.3 {
COMMIT;
INSERT INTO eee(eee) VALUES('integrity-check');
}
#-----------------------------------------------------------------------
# Add a small and very large token with the same hash value to an
# empty table. At one point this would provoke an asan error.
#
do_test 2.0 {
set big [string repeat 12345 40]
set hash [sqlite3_fts5_token_hash 1024 $big]
while {1} {
set small [random_token]
if {[sqlite3_fts5_token_hash 1024 $small]==$hash} break
}
execsql { CREATE VIRTUAL TABLE t2 USING fts5(x, detail=%DETAIL%) }
breakpoint
execsql {
INSERT INTO t2 VALUES($small || ' ' || $big);
}
} {}
} ;# foreach_detail_mode
finish_test
+107 -1
View File
@@ -9,7 +9,7 @@
#
#***********************************************************************
#
# This file containst tests focused on the integrity-check procedure.
# This file contains tests focused on the integrity-check procedure.
#
source [file join [file dirname [info script]] fts5_common.tcl]
@@ -102,6 +102,112 @@ do_catchsql_test 4.5 {
#db eval {SELECT rowid, fts5_decode(rowid, block) aS r FROM zz_data} {puts $r}
#exit
execsql { ROLLBACK }
#-------------------------------------------------------------------------
# Test that integrity-check works on a reasonably large db with many
# different terms.
# Document generator command.
proc rnddoc {n} {
set doc [list]
for {set i 0} {$i<$n} {incr i} {
lappend doc [format %.5d [expr int(rand()*10000)]]
}
return $doc
}
db func rnddoc rnddoc
expr srand(0)
do_execsql_test 5.0 {
CREATE VIRTUAL TABLE gg USING fts5(a, prefix="1,2,3");
INSERT INTO gg(gg, rank) VALUES('pgsz', 256);
INSERT INTO gg VALUES(rnddoc(20));
INSERT INTO gg SELECT rnddoc(20) FROM gg;
INSERT INTO gg SELECT rnddoc(20) FROM gg;
INSERT INTO gg SELECT rnddoc(20) FROM gg;
INSERT INTO gg SELECT rnddoc(20) FROM gg;
INSERT INTO gg SELECT rnddoc(20) FROM gg;
INSERT INTO gg SELECT rnddoc(20) FROM gg;
INSERT INTO gg SELECT rnddoc(20) FROM gg;
INSERT INTO gg SELECT rnddoc(20) FROM gg;
INSERT INTO gg SELECT rnddoc(20) FROM gg;
INSERT INTO gg SELECT rnddoc(20) FROM gg;
INSERT INTO gg SELECT rnddoc(20) FROM gg;
}
do_execsql_test 5.1 {
INSERT INTO gg(gg) VALUES('integrity-check');
}
do_execsql_test 5.2 {
INSERT INTO gg(gg) VALUES('optimize');
}
do_execsql_test 5.3 {
INSERT INTO gg(gg) VALUES('integrity-check');
}
do_test 5.4.1 {
set ok 0
for {set i 0} {$i < 10000} {incr i} {
set T [format %.5d $i]
set res [db eval { SELECT rowid FROM gg($T) ORDER BY rowid ASC }]
set res2 [db eval { SELECT rowid FROM gg($T) ORDER BY rowid DESC }]
if {$res == [lsort -integer $res2]} { incr ok }
}
set ok
} {10000}
do_test 5.4.2 {
set ok 0
for {set i 0} {$i < 100} {incr i} {
set T "[format %.3d $i]*"
set res [db eval { SELECT rowid FROM gg($T) ORDER BY rowid ASC }]
set res2 [db eval { SELECT rowid FROM gg($T) ORDER BY rowid DESC }]
if {$res == [lsort -integer $res2]} { incr ok }
}
set ok
} {100}
#-------------------------------------------------------------------------
# Similar to 5.*.
#
foreach {tn pgsz} {
1 32
2 36
3 40
4 44
5 48
} {
do_execsql_test 6.$tn.1 {
DROP TABLE IF EXISTS hh;
CREATE VIRTUAL TABLE hh USING fts5(y);
INSERT INTO hh(hh, rank) VALUES('pgsz', $pgsz);
WITH s(i) AS (SELECT 0 UNION ALL SELECT i+1 FROM s WHERE i<999)
INSERT INTO hh SELECT printf("%.3d%.3d%.3d %.3d%.3d%.3d",i,i,i,i+1,i+1,i+1)
FROM s;
WITH s(i) AS (SELECT 0 UNION ALL SELECT i+1 FROM s WHERE i<999)
INSERT INTO hh SELECT printf("%.3d%.3d%.3d %.3d%.3d%.3d",i,i,i,i+1,i+1,i+1)
FROM s;
INSERT INTO hh(hh) VALUES('optimize');
}
do_test 6.$tn.2 {
set ok 0
for {set i 0} {$i < 1000} {incr i} {
set T [format %.3d%.3d%.3d $i $i $i]
set res [db eval { SELECT rowid FROM hh($T) ORDER BY rowid ASC }]
set res2 [db eval { SELECT rowid FROM hh($T) ORDER BY rowid DESC }]
if {$res == [lsort -integer $res2]} { incr ok }
}
set ok
} {1000}
}
finish_test
+72 -32
View File
@@ -16,6 +16,8 @@ set testprefix fts5matchinfo
# If SQLITE_ENABLE_FTS5 is not defined, omit this file.
ifcapable !fts5 { finish_test ; return }
foreach_detail_mode $testprefix {
proc mit {blob} {
set scan(littleEndian) i*
set scan(bigEndian) I*
@@ -27,7 +29,7 @@ db func mit mit
sqlite3_fts5_register_matchinfo db
do_execsql_test 1.0 {
CREATE VIRTUAL TABLE t1 USING fts5(content);
CREATE VIRTUAL TABLE t1 USING fts5(content, detail=%DETAIL%);
}
do_execsql_test 1.1 {
@@ -41,7 +43,7 @@ do_execsql_test 1.1 {
# Now create an FTS4 table that does not specify matchinfo=fts3.
#
do_execsql_test 1.2 {
CREATE VIRTUAL TABLE t2 USING fts5(content);
CREATE VIRTUAL TABLE t2 USING fts5(content, detail=%DETAIL%);
INSERT INTO t2 SELECT * FROM t1;
SELECT mit(matchinfo(t2)) FROM t2 WHERE t2 MATCH 'I';
} {{1 1 1 2 2} {1 1 1 2 2}}
@@ -149,9 +151,17 @@ proc normalize2 {list_of_lists} {
return $res
}
# Similar to [do_matchinfo_test], except that this is a no-op if the FTS5
# mode is not detail=full.
#
proc do_matchinfo_p_test {tn tbl expr results} {
if {[detail_is_full]} {
uplevel [list do_matchinfo_test $tn $tbl $expr $results]
}
}
do_execsql_test 4.1.0 {
CREATE VIRTUAL TABLE t4 USING fts5(x, y);
CREATE VIRTUAL TABLE t4 USING fts5(x, y, detail=%DETAIL%);
INSERT INTO t4 VALUES('a b c d e', 'f g h i j');
INSERT INTO t4 VALUES('f g h i j', 'a b c d e');
}
@@ -185,7 +195,7 @@ do_matchinfo_test 4.1.1 t4 {t4 MATCH 'a b c'} {
xpxsscplax -
}
do_matchinfo_test 4.1.2 t4 {t4 MATCH '"g h i"'} {
do_matchinfo_p_test 4.1.2 t4 {t4 MATCH '"g h i"'} {
p {1 1}
c {2 2}
x {
@@ -203,8 +213,8 @@ do_matchinfo_test 4.1.2 t4 {t4 MATCH '"g h i"'} {
}
do_matchinfo_test 4.1.3 t4 {t4 MATCH 'a b'} { s {{2 0} {0 2}} }
do_matchinfo_test 4.1.4 t4 {t4 MATCH '"a b" c'} { s {{2 0} {0 2}} }
do_matchinfo_test 4.1.5 t4 {t4 MATCH 'a "b c"'} { s {{2 0} {0 2}} }
do_matchinfo_p_test 4.1.4 t4 {t4 MATCH '"a b" c'} { s {{2 0} {0 2}} }
do_matchinfo_p_test 4.1.5 t4 {t4 MATCH 'a "b c"'} { s {{2 0} {0 2}} }
do_matchinfo_test 4.1.6 t4 {t4 MATCH 'd d'} { s {{1 0} {0 1}} }
do_matchinfo_test 4.1.7 t4 {t4 MATCH 'f OR abcd'} {
x {
@@ -220,7 +230,7 @@ do_matchinfo_test 4.1.8 t4 {t4 MATCH 'f NOT abcd'} {
}
do_execsql_test 4.2.0 {
CREATE VIRTUAL TABLE t5 USING fts5(content);
CREATE VIRTUAL TABLE t5 USING fts5(content, detail=%DETAIL%);
INSERT INTO t5 VALUES('a a a a a');
INSERT INTO t5 VALUES('a b a b a');
INSERT INTO t5 VALUES('c b c b c');
@@ -233,7 +243,7 @@ do_matchinfo_test 4.2.1 t5 {t5 MATCH 'a a'} {
do_matchinfo_test 4.2.2 t5 {t5 MATCH 'a b'} { s {2} }
do_matchinfo_test 4.2.3 t5 {t5 MATCH 'a b a'} { s {3} }
do_matchinfo_test 4.2.4 t5 {t5 MATCH 'a a a'} { s {3 1} }
do_matchinfo_test 4.2.5 t5 {t5 MATCH '"a b" "a b"'} { s {2} }
do_matchinfo_p_test 4.2.5 t5 {t5 MATCH '"a b" "a b"'} { s {2} }
do_matchinfo_test 4.2.6 t5 {t5 MATCH 'a OR b'} { s {1 2 1} }
do_execsql_test 4.3.0 "INSERT INTO t5 VALUES('x y [string repeat {b } 50000]')";
@@ -250,7 +260,7 @@ if 0 {
do_matchinfo_test 4.3.2 t5 {t5 MATCH 'a b'} { s {2} }
do_matchinfo_test 4.3.3 t5 {t5 MATCH 'a b a'} { s {3} }
do_matchinfo_test 4.3.4 t5 {t5 MATCH 'a a a'} { s {3 1} }
do_matchinfo_test 4.3.5 t5 {t5 MATCH '"a b" "a b"'} { s {2} }
do_matchinfo_p_test 4.3.5 t5 {t5 MATCH '"a b" "a b"'} { s {2} }
do_matchinfo_test 4.3.6 t5 {t5 MATCH 'a OR b'} { s {1 2 1 1} }
do_execsql_test 4.4.0.1 { INSERT INTO t5(t5) VALUES('optimize') }
@@ -260,10 +270,10 @@ do_matchinfo_test 4.4.1 t5 {t5 MATCH 'a a'} { s {2 1} }
do_matchinfo_test 4.4.2 t5 {t5 MATCH 'a b'} { s {2} }
do_matchinfo_test 4.4.3 t5 {t5 MATCH 'a b a'} { s {3} }
do_matchinfo_test 4.4.4 t5 {t5 MATCH 'a a a'} { s {3 1} }
do_matchinfo_test 4.4.5 t5 {t5 MATCH '"a b" "a b"'} { s {2} }
do_matchinfo_p_test 4.4.5 t5 {t5 MATCH '"a b" "a b"'} { s {2} }
do_execsql_test 4.5.0 {
CREATE VIRTUAL TABLE t6 USING fts5(a, b, c);
CREATE VIRTUAL TABLE t6 USING fts5(a, b, c, detail=%DETAIL%);
INSERT INTO t6 VALUES('a', 'b', 'c');
}
do_matchinfo_test 4.5.1 t6 {t6 MATCH 'a b c'} { s {{1 1 1}} }
@@ -274,7 +284,7 @@ do_matchinfo_test 4.5.1 t6 {t6 MATCH 'a b c'} { s {{1 1 1}} }
# use the full-text index (i.e. lookup by rowid or full-table scan).
#
do_execsql_test 7.1 {
CREATE VIRTUAL TABLE t10 USING fts5(content);
CREATE VIRTUAL TABLE t10 USING fts5(content, detail=%DETAIL%);
INSERT INTO t10 VALUES('first record');
INSERT INTO t10 VALUES('second record');
}
@@ -299,7 +309,7 @@ do_execsql_test 7.4 {
# SELECT sum(length(content)) < count(*) FROM fts4table;
#
do_execsql_test 8.1 {
CREATE VIRTUAL TABLE t11 USING fts5(content);
CREATE VIRTUAL TABLE t11 USING fts5(content, detail=%DETAIL%);
INSERT INTO t11(t11, rank) VALUES('pgsz', 32);
INSERT INTO t11 VALUES('quitealongstringoftext');
INSERT INTO t11 VALUES('anotherquitealongstringoftext');
@@ -318,22 +328,24 @@ do_execsql_test 8.3 {
#-------------------------------------------------------------------------
do_execsql_test 9.1 {
CREATE VIRTUAL TABLE t12 USING fts5(content);
INSERT INTO t12 VALUES('a b c d');
SELECT mit(matchinfo(t12, 'x')) FROM t12 WHERE t12 MATCH 'NEAR(a d, 1) OR a';
} {{0 1 1 0 1 1 1 1 1}}
do_execsql_test 9.2 {
INSERT INTO t12 VALUES('a d c d');
SELECT mit(matchinfo(t12, 'x')) FROM t12 WHERE t12 MATCH 'NEAR(a d, 1) OR a';
} {
{0 2 2 0 3 2 1 2 2} {1 2 2 1 3 2 1 2 2}
}
do_execsql_test 9.3 {
INSERT INTO t12 VALUES('a d d a');
SELECT mit(matchinfo(t12, 'x')) FROM t12 WHERE t12 MATCH 'NEAR(a d, 1) OR a';
} {
{0 4 3 0 5 3 1 4 3} {1 4 3 1 5 3 1 4 3} {2 4 3 2 5 3 2 4 3}
if {[detail_is_full]} {
do_execsql_test 9.1 {
CREATE VIRTUAL TABLE t12 USING fts5(content, detail=%DETAIL%);
INSERT INTO t12 VALUES('a b c d');
SELECT mit(matchinfo(t12,'x')) FROM t12 WHERE t12 MATCH 'NEAR(a d, 1) OR a';
} {{0 1 1 0 1 1 1 1 1}}
do_execsql_test 9.2 {
INSERT INTO t12 VALUES('a d c d');
SELECT mit(matchinfo(t12,'x')) FROM t12 WHERE t12 MATCH 'NEAR(a d, 1) OR a';
} {
{0 2 2 0 3 2 1 2 2} {1 2 2 1 3 2 1 2 2}
}
do_execsql_test 9.3 {
INSERT INTO t12 VALUES('a d d a');
SELECT mit(matchinfo(t12,'x')) FROM t12 WHERE t12 MATCH 'NEAR(a d, 1) OR a';
} {
{0 4 3 0 5 3 1 4 3} {1 4 3 1 5 3 1 4 3} {2 4 3 2 5 3 2 4 3}
}
}
#---------------------------------------------------------------------------
@@ -341,7 +353,7 @@ do_execsql_test 9.3 {
#
do_execsql_test 10.1 {
DROP TABLE t10;
CREATE VIRTUAL TABLE t10 USING fts5(idx, value);
CREATE VIRTUAL TABLE t10 USING fts5(idx, value, detail=%DETAIL%);
INSERT INTO t10 values (1, 'one'),(2, 'two'),(3, 'three');
SELECT t10.rowid, t10.*
FROM t10
@@ -358,7 +370,7 @@ do_execsql_test 10.1 {
reset_db
sqlite3_fts5_register_matchinfo db
do_execsql_test 11.0 {
CREATE VIRTUAL TABLE tt USING fts5(x, y);
CREATE VIRTUAL TABLE tt USING fts5(x, y, detail=%DETAIL%);
INSERT INTO tt VALUES('c d a c d d', 'e a g b d a'); -- 1
INSERT INTO tt VALUES('c c g a e b', 'c g d g e c'); -- 2
INSERT INTO tt VALUES('b e f d e g', 'b a c b c g'); -- 3
@@ -410,6 +422,8 @@ foreach {tn expr res} {
}
} {
if {[string match *:* $expr] && [detail_is_none]} continue
do_execsql_test 11.1.$tn.1 {
SELECT rowid, mit(matchinfo(tt, 'y')) FROM tt WHERE tt MATCH $expr
} $res
@@ -443,7 +457,7 @@ db func mit mit
do_test 12.0 {
set cols [list]
for {set i 0} {$i < 50} {incr i} { lappend cols "c$i" }
execsql "CREATE VIRTUAL TABLE tt USING fts5([join $cols ,])"
execsql "CREATE VIRTUAL TABLE tt USING fts5([join $cols ,], detail=%DETAIL%)"
} {}
do_execsql_test 12.1 {
@@ -451,5 +465,31 @@ do_execsql_test 12.1 {
SELECT mit(matchinfo(tt, 'b')) FROM tt WHERE tt MATCH 'abc';
} [list [list [expr 1<<4] [expr 1<<(45-32)]]]
} ;# foreach_detail_mode
#-------------------------------------------------------------------------
# Test that a bad fts5() return is detected
#
reset_db
proc xyz {} {}
db func fts5 -argcount 0 xyz
do_test 13.1 {
list [catch { sqlite3_fts5_register_matchinfo db } msg] $msg
} {1 SQLITE_ERROR}
#-------------------------------------------------------------------------
# Test that an invalid matchinfo() flag is detected
#
reset_db
sqlite3_fts5_register_matchinfo db
do_execsql_test 14.1 {
CREATE VIRTUAL TABLE x1 USING fts5(z);
INSERT INTO x1 VALUES('a b c a b c a b c');
} {}
do_catchsql_test 14.2 {
SELECT matchinfo(x1, 'd') FROM x1('a b c');
} {1 {unrecognized matchinfo flag: d}}
finish_test
+58
View File
@@ -0,0 +1,58 @@
# 2014 Dec 20
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
# May you find forgiveness for yourself and forgive others.
# May you share freely, never taking more than you give.
#
#***********************************************************************
#
# Test that focus on incremental merges of segments.
#
source [file join [file dirname [info script]] fts5_common.tcl]
set testprefix fts5merge2
return_if_no_fts5
proc dump_structure {} {
db eval {SELECT fts5_decode(id, block) AS t FROM t1_data WHERE id=10} {
foreach lvl [lrange $t 1 end] {
set seg [string repeat . [expr [llength $lvl]-2]]
puts "[lrange $lvl 0 1] $seg"
}
}
}
foreach_detail_mode $testprefix {
do_execsql_test 1.0 {
CREATE VIRTUAL TABLE t1 USING fts5(x, detail=%DETAIL%);
INSERT INTO t1(t1, rank) VALUES('pgsz', 32);
INSERT INTO t1(t1, rank) VALUES('crisismerge', 2);
INSERT INTO t1 VALUES('1 2 3 4');
}
expr srand(0)
db func rnddoc fts5_rnddoc
do_test 1.1 {
for {set i 0} {$i < 100} {incr i} {
execsql {
BEGIN;
DELETE FROM t1 WHERE rowid = 1;
INSERT INTO t1(rowid, x) VALUES(1, '1 2 3 4');
INSERT INTO t1 VALUES(rnddoc(10));
COMMIT;
}
}
} {}
do_execsql_test 1.2 {
INSERT INTO t1(t1) VALUES('integrity-check');
}
}
finish_test
+144
View File
@@ -195,6 +195,150 @@ for {set x 0} {$x<2} {incr x} {
execsql { INSERT INTO t3(t3) VALUES('integrity-check') }
}
#-------------------------------------------------------------------------
#
reset_db
do_execsql_test 4.0 {
CREATE VIRTUAL TABLE t2 USING fts5(c1, c2);
INSERT INTO t2 VALUES('xa xb', 'xb xa');
INSERT INTO t2 SELECT c1||' '||c1, c2||' '||c2 FROM t2; -- 2
INSERT INTO t2 SELECT c1||' '||c1, c2||' '||c2 FROM t2; -- 4
INSERT INTO t2 SELECT c1||' '||c1, c2||' '||c2 FROM t2; -- 8
INSERT INTO t2 SELECT c1||' '||c1, c2||' '||c2 FROM t2; -- 16
INSERT INTO t2 SELECT c1||' '||c1, c2||' '||c2 FROM t2; -- 32
INSERT INTO t2 SELECT c1||' '||c1, c2||' '||c2 FROM t2; -- 64
INSERT INTO t2 SELECT c1||' '||c1, c2||' '||c2 FROM t2; -- 128
INSERT INTO t2 SELECT c1||' '||c1, c2||' '||c2 FROM t2; -- 256
INSERT INTO t2 SELECT c1||' '||c1, c2||' '||c2 FROM t2; -- 512
INSERT INTO t2 SELECT c1||' '||c1, c2||' '||c2 FROM t2; -- 1024
INSERT INTO t2 SELECT c1||' '||c1, c2||' '||c2 FROM t2; -- 2048
INSERT INTO t2 SELECT c1||' '||c1, c2||' '||c2 FROM t2; -- 4096
SELECT count(*) FROM t2('x*');
} {4096}
do_execsql_test 4.1 {
UPDATE t2 SET c2 = 'ya yb';
SELECT count(*) FROM t2('c1:x*');
SELECT count(*) FROM t2('c2:x*');
} {4096 0}
do_execsql_test 4.2 {
UPDATE t2 SET c2 = 'xa';
SELECT count(*) FROM t2('c1:x*');
SELECT count(*) FROM t2('c2:x*');
} {4096 4096}
#-------------------------------------------------------------------------
#
reset_db
proc rnddoc {n} {
set map [list a b c d]
set doc [list]
for {set i 0} {$i < $n} {incr i} {
lappend doc "x[lindex $map [expr int(rand()*4)]]"
}
set doc
}
set cols [list]
for {set i 1} {$i<250} {incr i} {
lappend cols "c$i"
lappend vals "'[rnddoc 10]'"
}
do_test 5.0 {
execsql "CREATE VIRTUAL TABLE t4 USING fts5([join $cols ,])"
execsql {INSERT INTO t4(t4, rank) VALUES('pgsz', 32)}
execsql "INSERT INTO t4 VALUES([join $vals ,])"
execsql "INSERT INTO t4 VALUES([join $vals ,])"
execsql "INSERT INTO t4 VALUES([join $vals ,])"
execsql "INSERT INTO t4 VALUES([join $vals ,])"
} {}
proc gmatch {col pattern} {
expr {[lsearch -glob $col $pattern]>=0}
}
db func gmatch gmatch
foreach {tn col pattern} {
1 c100 {xa*}
2 c200 {xb*}
} {
set res [db eval "SELECT rowid FROM t4 WHERE gmatch($col, \$pattern)"]
set query "$col : $pattern"
do_execsql_test 5.$tn { SELECT rowid FROM t4($query) } $res
}
reset_db
db func fts5_rnddoc fts5_rnddoc
do_test 6.0 {
execsql {
CREATE VIRTUAL TABLE t5 USING fts5(x, y);
INSERT INTO t5 VALUES( fts5_rnddoc(10000), fts5_rnddoc(10000) );
INSERT INTO t5 VALUES( fts5_rnddoc(10000), fts5_rnddoc(10000) );
INSERT INTO t5 VALUES( fts5_rnddoc(10000), fts5_rnddoc(10000) );
INSERT INTO t5 VALUES( fts5_rnddoc(10000), fts5_rnddoc(10000) );
}
} {}
proc gmatch {col pattern} {
expr {[lsearch -glob $col $pattern]>=0}
}
db func gmatch gmatch
foreach {tn col pattern} {
1 y {xa*}
2 y {xb*}
3 y {xc*}
4 x {xa*}
5 x {xb*}
6 x {xc*}
} {
set res [db eval "SELECT rowid FROM t5 WHERE gmatch($col, \$pattern)"]
set query "$col : $pattern"
do_execsql_test 6.$tn { SELECT rowid FROM t5($query) } $res
}
#-------------------------------------------------------------------------
# Check that the various ways of creating prefix indexes produce the
# same database on disk.
#
save_prng_state
foreach {tn create} {
1 { CREATE VIRTUAL TABLE tt USING fts5(x, y, prefix="1,2,3") }
2 { CREATE VIRTUAL TABLE tt USING fts5(x, y, prefix="1 2 3") }
3 { CREATE VIRTUAL TABLE tt USING fts5(x, y, prefix=1, prefix=2, prefix=3) }
4 { CREATE VIRTUAL TABLE tt USING fts5(x, y, prefix="1 2", prefix=3) }
} {
execsql { DROP TABLE IF EXISTS tt }
restore_prng_state
execsql $create
execsql {
INSERT INTO tt VALUES('cc b ggg ccc aa eee hh', 'aa g b hh a e');
INSERT INTO tt VALUES('cc bb cc gg j g cc', 'ii jjj ggg jjj cc cc');
INSERT INTO tt VALUES('h eee cc h iii', 'aaa iii dd iii dd');
INSERT INTO tt VALUES('jjj hh eee c e b gg', 'j bbb jj ddd jj');
INSERT INTO tt VALUES('ii hhh aaa ff c hhh iii', 'j cc hh bb e');
INSERT INTO tt VALUES('e fff hhh i aaa', 'g b aa gg c aa dd');
INSERT INTO tt VALUES('i aaa ccc gg hhh aa h', 'j bbb bbb d ff');
INSERT INTO tt VALUES('g f gg ff ff jjj d', 'jjj d j fff fff ee j');
INSERT INTO tt VALUES('a cc e ccc jjj c', 'ccc iii d bb a eee g');
INSERT INTO tt VALUES('jj hh hh bb bbb gg', 'j c jjj bb iii f');
INSERT INTO tt VALUES('a ggg g cc ccc aa', 'jjj j j aaa c');
INSERT INTO tt VALUES('ddd j dd b i', 'aaa bbb iii ggg ff ccc ddd');
INSERT INTO tt VALUES('jj ii hh c ii h gg', 'hhh bbb ddd bbb hh g ggg');
INSERT INTO tt VALUES('aa hhh ccc h ggg ccc', 'iii d jj a ff ii');
}
#db eval {SELECT rowid, fts5_decode(rowid, block) aS r FROM tt_data} {puts $r}
if {$tn==1} {
set ::checksum [execsql {SELECT md5sum(id, block) FROM tt_data}]
} else {
do_execsql_test 7.$tn {
SELECT md5sum(id, block) FROM tt_data
} [list $::checksum]
}
}
finish_test
+83
View File
@@ -0,0 +1,83 @@
# 2015 October 27
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
# May you find forgiveness for yourself and forgive others.
# May you share freely, never taking more than you give.
#
#*************************************************************************
# This file implements regression tests for SQLite library. The
# focus of this script is testing the FTS5 module.
#
source [file join [file dirname [info script]] fts5_common.tcl]
set testprefix fts5query
# If SQLITE_ENABLE_FTS5 is defined, omit this file.
ifcapable !fts5 {
finish_test
return
}
for {set tn 1 ; set pgsz 64} {$tn<32} {incr tn; incr pgsz 16} {
reset_db
do_test 1.$tn.1 {
execsql {
CREATE VIRTUAL TABLE t1 USING fts5(x);
INSERT INTO t1(t1, rank) VALUES('pgsz', $pgsz);
BEGIN;
}
foreach x [list aaa bbb ccc ddd eee fff ggg hhh iii jjj] {
set doc [string repeat "$x " 30]
execsql { INSERT INTO t1 VALUES($doc) }
}
execsql COMMIT
} {}
do_execsql_test 1.$tn.2 {
INSERT INTO t1(t1) VALUES('integrity-check');
}
set ret 1
foreach x [list a b c d e f g h i j] {
do_execsql_test 1.$tn.3.$ret {
SELECT rowid FROM t1 WHERE t1 MATCH $x || '*';
} $ret
incr ret
}
}
for {set tn 1 ; set pgsz 64} {$tn<32} {incr tn; incr pgsz 16} {
reset_db
do_test 2.$tn.1 {
execsql {
CREATE VIRTUAL TABLE t1 USING fts5(x);
INSERT INTO t1(t1, rank) VALUES('pgsz', $pgsz);
BEGIN;
}
foreach x [list bbb ddd fff hhh jjj lll nnn ppp rrr ttt] {
set doc [string repeat "$x " 30]
execsql { INSERT INTO t1 VALUES($doc) }
}
execsql COMMIT
} {}
do_execsql_test 1.$tn.2 {
INSERT INTO t1(t1) VALUES('integrity-check');
}
set ret 1
foreach x [list a c e g i k m o q s u] {
do_execsql_test 2.$tn.3.$ret {
SELECT rowid FROM t1 WHERE t1 MATCH $x || '*';
} {}
incr ret
}
}
finish_test
+55
View File
@@ -41,5 +41,60 @@ do_execsql_test 1.3 {
WHERE xyz MATCH 'x AND y' ORDER BY rank
} [list [string map {x [x] y [y]} $doc]]
#-------------------------------------------------------------------------
# Check that the 'rank' option really is persistent.
#
do_execsql_test 2.0 {
CREATE VIRTUAL TABLE tt USING fts5(a);
INSERT INTO tt VALUES('a x x x x');
INSERT INTO tt VALUES('x x a a a');
INSERT INTO tt VALUES('x a a x x');
}
proc firstinst {cmd} {
foreach {p c o} [$cmd xInst 0] {}
return $o
}
sqlite3_fts5_create_function db firstinst firstinst
do_execsql_test 2.1 {
SELECT rowid FROM tt('a') ORDER BY rank;
} {2 3 1}
do_execsql_test 2.2 {
SELECT rowid FROM tt('a', 'firstinst()') ORDER BY rank;
} {1 3 2}
do_execsql_test 2.3 {
INSERT INTO tt(tt, rank) VALUES('rank', 'firstinst()');
SELECT rowid FROM tt('a') ORDER BY rank;
} {1 3 2}
do_test 2.4 {
sqlite3 db2 test.db
catchsql { SELECT rowid FROM tt('a') ORDER BY rank; } db2
} {1 {no such function: firstinst}}
do_test 2.5 {
db2 close
sqlite3 db2 test.db
sqlite3_fts5_create_function db2 firstinst firstinst
execsql { SELECT rowid FROM tt('a') ORDER BY rank; } db2
} {1 3 2}
do_test 2.6 {
execsql { SELECT rowid FROM tt('a') ORDER BY rank; } db2
} {1 3 2}
do_test 2.7 {
execsql { SELECT rowid FROM tt('a') ORDER BY rank; } db
} {1 3 2}
finish_test
+33 -2
View File
@@ -63,6 +63,7 @@ do_execsql_test 2.2 {
SELECT rnddoc(6), rnddoc(6) FROM r
)
INSERT INTO x1 SELECT * FROM r LIMIT 10000;
DELETE FROM x1 WHERE (rowid%2);
}
set res [db one {SELECT count(*) FROM x1_data}]
@@ -71,8 +72,7 @@ do_execsql_test 2.3 {
} $res
do_execsql_test 2.4 {
UPDATE x1_data SET block = X'';
-- SELECT count(fts5_decode(rowid, block)) FROM x1_data;
SELECT count(*) FROM x1_data;
SELECT count(fts5_decode(rowid, block)) FROM x1_data;
} $res
do_execsql_test 2.5 {
@@ -184,5 +184,36 @@ do_execsql_test 5.2 {
SELECT count(fts5_decode(rowid, block)) FROM x4_data;
} $res
#-------------------------------------------------------------------------
#
do_execsql_test 6.0 {
CREATE VIRTUAL TABLE x5 USING fts5(x, detail=none);
INSERT INTO x5(x5, rank) VALUES('pgsz', 32);
INSERT INTO x5 VALUES('a b c d e f');
INSERT INTO x5 VALUES('a b c d e f');
INSERT INTO x5 VALUES('a b c d e f');
BEGIN;
WITH s(i) AS (
SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<100
) INSERT INTO x5 SELECT 'a b c d e f' FROM s;
COMMIT;
SELECT count(fts5_decode_none(rowid, block)) FROM x5_data;
} {32}
do_execsql_test 6.1 {
DELETE FROM x5 WHERE rowid <= 2;
SELECT count(fts5_decode_none(rowid, block)) FROM x5_data;
} {34}
do_execsql_test 6.2 {
UPDATE x5 SET x='a b c d e f' WHERE rowid=3;
SELECT count(fts5_decode_none(rowid, block)) FROM x5_data;
} {36}
#db eval {SELECT rowid, fts5_decode_none(rowid, block) aS r FROM x5_data} {puts $r}
finish_test
+148 -1
View File
@@ -19,6 +19,8 @@ ifcapable !fts5 {
return
}
if 1 {
#-------------------------------------------------------------------------
#
set doc "x x [string repeat {y } 50]z z"
@@ -300,5 +302,150 @@ do_execsql_test 12.2 {
COMMIT;
} {}
finish_test
#-------------------------------------------------------------------------
# Try an UPDATE OR REPLACE query.
#
do_execsql_test 13.1 {
CREATE VIRTUAL TABLE xy USING fts5(x);
INSERT INTO xy(rowid, x) VALUES(1, '1 2 3');
INSERT INTO xy(rowid, x) VALUES(2, '2 3 4');
INSERT INTO xy(rowid, x) VALUES(3, '3 4 5');
}
do_execsql_test 13.2 {
UPDATE OR REPLACE xy SET rowid=3 WHERE rowid = 2;
SELECT rowid, x FROM xy;
} {
1 {1 2 3}
3 {2 3 4}
}
do_execsql_test 13.3 {
INSERT INTO xy(xy) VALUES('integrity-check');
}
#-------------------------------------------------------------------------
#
do_execsql_test 14.1 {
CREATE VIRTUAL TABLE ttt USING fts5(x);
BEGIN;
INSERT INTO ttt(rowid, x) VALUES(1, 'a b c');
INSERT INTO ttt(rowid, x) VALUES(2, 'a b c');
INSERT INTO ttt(rowid, x) VALUES(3, 'a b c');
COMMIT;
}
do_test 14.2 {
fts5_level_segs ttt
} {1}
#-------------------------------------------------------------------------
db func rnddoc fts5_rnddoc
do_execsql_test 4.0 {
CREATE VIRTUAL TABLE x1 USING fts5(x);
INSERT INTO x1(x1, rank) VALUES('pgsz', 32);
WITH ii(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM ii WHERE i<10 )
INSERT INTO x1 SELECT rnddoc(5) FROM ii;
}
do_execsql_test 4.1 {
SELECT rowid, x, x1 FROM x1 WHERE x1 MATCH '*reads'
} {0 {} 4}
#-------------------------------------------------------------------------
reset_db
do_execsql_test 15.0 {
CREATE VIRTUAL TABLE x2 USING fts5(x, prefix=1);
INSERT INTO x2 VALUES('ab');
}
do_execsql_test 15.1 {
INSERT INTO x2(x2) VALUES('integrity-check');
}
#-------------------------------------------------------------------------
foreach_detail_mode $testprefix {
reset_db
fts5_aux_test_functions db
do_execsql_test 16.0 {
CREATE VIRTUAL TABLE x3 USING fts5(x, detail=%DETAIL%);
INSERT INTO x3 VALUES('a b c d e f');
}
do_execsql_test 16.1 {
SELECT fts5_test_poslist(x3) FROM x3('(a NOT b) OR c');
} {2.0.2}
do_execsql_test 16.1 {
SELECT fts5_test_poslist(x3) FROM x3('a OR c');
} {{0.0.0 1.0.2}}
}
}
#-------------------------------------------------------------------------
reset_db
do_execsql_test 17.0 {
CREATE VIRTUAL TABLE x3 USING fts5(x);
INSERT INTO x3 VALUES('a b c');
}
do_execsql_test 17.1 {
SELECT rowid FROM x3('b AND d');
}
#-------------------------------------------------------------------------
do_execsql_test 18.1 {
CREATE VIRTUAL TABLE x4 USING fts5(x);
SELECT rowid FROM x4('""');
}
#-------------------------------------------------------------------------
reset_db
do_execsql_test 19.1 {
CREATE VIRTUAL TABLE x1 USING fts5(a,b,c);
}
do_catchsql_test 19.2 {
SELECT * FROM x1 WHERE x1 MATCH 'c0 AND (c1 AND (c2 AND (c3 AND (c4 AND (c5 AND (c6 AND (c7 AND (c8 AND (c9 AND (c10 AND (c11 AND (c12 AND (c13 AND (c14 AND (c15 AND (c16 AND (c17 AND (c18 AND (c19 AND (c20 AND (c21 AND (c22 AND (c23 AND (c24 AND (c25 AND (c26 AND (c27 AND (c28 AND (c29 AND (c30 AND (c31 AND (c32 AND (c33 AND (c34 AND (c35 AND (c36 AND (c37 AND (c38 AND (c39 AND (c40 AND (c41 AND (c42 AND (c43 AND (c44 AND (c45 AND (c46 AND (c47 AND (c48 AND (c49 AND (c50 AND (c51 AND (c52 AND (c53 AND (c54 AND (c55 AND (c56 AND (c57 AND (c58 AND (c59 AND (c60 AND (c61 AND (c62 AND (c63 AND (c64 AND (c65 AND (c66 AND (c67 AND (c68 AND (c69 AND (c70 AND (c71 AND (c72 AND (c73 AND (c74 AND (c75 AND (c76 AND (c77 AND (c78 AND (c79 AND (c80 AND (c81 AND (c82 AND (c83 AND (c84 AND (c85 AND (c86 AND (c87 AND (c88 AND (c89 AND (c90 AND (c91 AND (c92 AND (c93 AND (c94 AND (c95 AND (c96 AND (c97 AND (c98 AND (c99 AND (c100 AND (c101 AND (c102 AND (c103 AND (c104 AND (c105 AND (c106 AND (c107 AND (c108 AND (c109 AND (c110 AND (c111 AND (c112 AND (c113 AND (c114 AND (c115 AND (c116 AND (c117 AND (c118 AND (c119 AND (c120 AND (c121 AND (c122 AND (c123 AND (c124 AND (c125 AND (c126 AND (c127 AND (c128 AND (c129 AND (c130 AND (c131 AND (c132 AND (c133 AND (c134 AND (c135 AND (c136 AND (c137 AND (c138 AND (c139 AND (c140 AND (c141 AND (c142 AND (c143 AND (c144 AND (c145 AND (c146 AND (c147 AND (c148 AND (c149 AND (c150 AND (c151 AND (c152 AND (c153 AND (c154 AND (c155 AND (c156 AND (c157 AND (c158 AND (c159 AND (c160 AND (c161 AND (c162 AND (c163 AND (c164 AND (c165 AND (c166 AND (c167 AND (c168 AND (c169 AND (c170 AND (c171 AND (c172 AND (c173 AND (c174 AND (c175 AND (c176 AND (c177 AND (c178 AND (c179 AND (c180 AND (c181 AND (c182 AND (c183 AND (c184 AND (c185 AND (c186 AND (c187 AND (c188 AND (c189 AND (c190 AND (c191 AND (c192 AND (c193 AND (c194 AND (c195 AND (c196 AND (c197 AND (c198 AND (c199 AND c200)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))';
} {1 {fts5: parser stack overflow}}
#-------------------------------------------------------------------------
reset_db
breakpoint
do_execsql_test 20.0 {
CREATE VIRTUAL TABLE x1 USING fts5(x);
INSERT INTO x1(x1, rank) VALUES('pgsz', 32);
INSERT INTO x1(rowid, x) VALUES(11111, 'onetwothree');
}
do_test 20.1 {
for {set i 1} {$i <= 200} {incr i} {
execsql { INSERT INTO x1(rowid, x) VALUES($i, 'one two three'); }
}
execsql { INSERT INTO x1(x1) VALUES('optimize'); }
execsql { DELETE FROM x1 WHERE rowid = 4; }
} {}
do_execsql_test 20.2 {
INSERT INTO x1(x1) VALUES('optimize');
INSERT INTO x1(x1) VALUES('integrity-check');
} {}
#-------------------------------------------------------------------------
reset_db
do_execsql_test 20.0 {
CREATE VIRTUAL TABLE x1 USING fts5(x);
INSERT INTO x1(x1, rank) VALUES('pgsz', 32);
INSERT INTO x1(rowid, x) VALUES(11111, 'onetwothree');
}
do_test 20.1 {
for {set i 1} {$i <= 200} {incr i} {
execsql { INSERT INTO x1(rowid, x) VALUES($i, 'one two three'); }
}
execsql { INSERT INTO x1(x1) VALUES('optimize'); }
execsql { DELETE FROM x1 WHERE rowid = 4; }
} {}
do_execsql_test 20.2 {
INSERT INTO x1(x1) VALUES('optimize');
INSERT INTO x1(x1) VALUES('integrity-check');
} {}
finish_test
+338
View File
@@ -0,0 +1,338 @@
# 2015 September 05
#
# 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.
#
#*************************************************************************
#
source [file join [file dirname [info script]] fts5_common.tcl]
set testprefix fts5simple2
# If SQLITE_ENABLE_FTS5 is defined, omit this file.
ifcapable !fts5 {
finish_test
return
}
do_execsql_test 1.0 {
CREATE VIRTUAL TABLE t1 USING fts5(a, detail=none);
INSERT INTO t1 VALUES('a b c');
}
do_execsql_test 1.1 {
SELECT rowid FROM t1('c a b')
} {1}
#-------------------------------------------------------------------------
#
reset_db
do_execsql_test 2.0 {
CREATE VIRTUAL TABLE t1 USING fts5(a, detail=none);
BEGIN;
INSERT INTO t1 VALUES('b c d');
INSERT INTO t1 VALUES('b c d');
COMMIT;
}
do_execsql_test 2.1 {
SELECT rowid FROM t1('b c d')
} {1 2}
#-------------------------------------------------------------------------
#
reset_db
do_execsql_test 3.0 {
CREATE VIRTUAL TABLE t1 USING fts5(a, detail=none);
BEGIN;
INSERT INTO t1 VALUES('b c d');
INSERT INTO t1 VALUES('b c d');
}
do_execsql_test 3.1 {
SELECT rowid FROM t1('b c d'); COMMIT;
} {1 2}
#-------------------------------------------------------------------------
#
reset_db
do_execsql_test 4.0 {
CREATE VIRTUAL TABLE t1 USING fts5(a, detail=none);
BEGIN;
INSERT INTO t1 VALUES('a1 b1 c1');
INSERT INTO t1 VALUES('a2 b2 c2');
INSERT INTO t1 VALUES('a3 b3 c3');
COMMIT;
}
do_execsql_test 4.1 {
SELECT rowid FROM t1('b*');
} {1 2 3}
#-------------------------------------------------------------------------
#
reset_db
do_execsql_test 5.0 {
CREATE VIRTUAL TABLE t1 USING fts5(a, detail=none);
BEGIN;
INSERT INTO t1 VALUES('a1 b1 c1');
INSERT INTO t1 VALUES('a2 b2 c2');
INSERT INTO t1 VALUES('a1 b1 c1');
COMMIT;
}
do_execsql_test 5.1 { SELECT rowid FROM t1('b*') } {1 2 3}
#-------------------------------------------------------------------------
#
reset_db
do_execsql_test 6.0 {
CREATE VIRTUAL TABLE t1 USING fts5(a, detail=full);
BEGIN;
INSERT INTO t1 VALUES('a1 b1 c1');
INSERT INTO t1 VALUES('a1 b1 c1');
INSERT INTO t1 VALUES('a1 b1 c1');
COMMIT;
}
do_execsql_test 6.1 { SELECT rowid FROM t1('a1') ORDER BY rowid DESC } {3 2 1}
do_execsql_test 6.2 { SELECT rowid FROM t1('b1') ORDER BY rowid DESC } {3 2 1}
do_execsql_test 6.3 { SELECT rowid FROM t1('c1') ORDER BY rowid DESC } {3 2 1}
#-------------------------------------------------------------------------
#
reset_db
do_execsql_test 7.0 {
CREATE VIRTUAL TABLE t1 USING fts5(a, detail=none);
BEGIN;
INSERT INTO t1 VALUES('a1 b1');
INSERT INTO t1 VALUES('a1 b2');
COMMIT;
}
do_execsql_test 7.1 { SELECT rowid FROM t1('b*') ORDER BY rowid DESC } {2 1}
do_execsql_test 7.2 { SELECT rowid FROM t1('a1') ORDER BY rowid DESC } {2 1}
#-------------------------------------------------------------------------
#
reset_db
do_execsql_test 8.0 {
CREATE VIRTUAL TABLE t1 USING fts5(a, detail=none);
INSERT INTO t1 VALUES('a1 b1 c1');
INSERT INTO t1 VALUES('a2 b2 c2');
INSERT INTO t1 VALUES('a1 b1 c1');
}
do_execsql_test 8.0.1 { SELECT rowid FROM t1('b*') } {1 2 3}
do_execsql_test 8.0.2 { SELECT rowid FROM t1('a1') } {1 3}
do_execsql_test 8.0.3 { SELECT rowid FROM t1('c2') } {2}
do_execsql_test 8.0.4 { SELECT rowid FROM t1('b*') ORDER BY rowid DESC } {3 2 1}
do_execsql_test 8.0.5 { SELECT rowid FROM t1('a1') ORDER BY rowid DESC } {3 1}
do_execsql_test 8.0.8 { SELECT rowid FROM t1('c2') ORDER BY rowid DESC } {2}
do_execsql_test 8.1.0 { INSERT INTO t1(t1) VALUES('optimize') }
do_execsql_test 8.1.1 { SELECT rowid FROM t1('b*') } {1 2 3}
do_execsql_test 8.1.2 { SELECT rowid FROM t1('a1') } {1 3}
do_execsql_test 8.1.3 { SELECT rowid FROM t1('c2') } {2}
do_execsql_test 8.2.1 { SELECT rowid FROM t1('b*') ORDER BY rowid DESC} {3 2 1}
do_execsql_test 8.2.2 { SELECT rowid FROM t1('a1') ORDER BY rowid DESC} {3 1}
do_execsql_test 8.2.3 { SELECT rowid FROM t1('c2') ORDER BY rowid DESC} {2}
#--------------------------------------------------------------------------
#
reset_db
do_execsql_test 9.0.0 {
CREATE VIRTUAL TABLE t1 USING fts5(a, detail=none);
INSERT INTO t1 VALUES('a1 b1 c1');
INSERT INTO t1 VALUES('a2 b2 c2');
INSERT INTO t1 VALUES('a1 b1 c1');
}
do_execsql_test 9.0.1 {
INSERT INTO t1(t1) VALUES('integrity-check');
} {}
reset_db
do_execsql_test 9.1.0 {
CREATE VIRTUAL TABLE t1 USING fts5(a, b, detail=none);
INSERT INTO t1 VALUES('a1 b1 c1', 'x y z');
INSERT INTO t1 VALUES('a2 b2 c2', '1 2 3');
INSERT INTO t1 VALUES('a1 b1 c1', 'x 2 z');
}
do_execsql_test 9.2.1 {
INSERT INTO t1(t1) VALUES('integrity-check');
} {}
#--------------------------------------------------------------------------
#
reset_db
do_execsql_test 10.0 {
CREATE VIRTUAL TABLE t1 USING fts5(a, detail=none);
INSERT INTO t1 VALUES('b1');
INSERT INTO t1 VALUES('b1');
DELETE FROM t1 WHERE rowid=1;
}
do_execsql_test 10.1 {
SELECT rowid FROM t1('b1');
} {2}
do_execsql_test 10.2 {
SELECT rowid FROM t1('b1') ORDER BY rowid DESC;
} {2}
do_execsql_test 10.3 {
INSERT INTO t1(t1) VALUES('integrity-check');
} {}
#--------------------------------------------------------------------------
#
reset_db
do_execsql_test 11.1 {
CREATE VIRTUAL TABLE t1 USING fts5(x, y, detail=none);
INSERT INTO t1(t1, rank) VALUES('pgsz', 32);
WITH d(x,y) AS (
SELECT NULL, 'xyz' UNION ALL SELECT NULL, 'xyz' FROM d
)
INSERT INTO t1 SELECT * FROM d LIMIT 23;
}
#db eval { SELECT rowid AS r, quote(block) AS b FROM t1_data } { puts "$r: $b" }
do_execsql_test 11.2 {
SELECT rowid FROM t1;
} {1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23}
do_execsql_test 11.3 {
SELECT rowid FROM t1('xyz');
} {1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23}
do_execsql_test 11.4 {
INSERT INTO t1(t1) VALUES('integrity-check');
}
#-------------------------------------------------------------------------
#
reset_db
do_execsql_test 12.0 {
CREATE VIRTUAL TABLE yy USING fts5(x, detail=none);
INSERT INTO yy VALUES('in if');
INSERT INTO yy VALUES('if');
} {}
do_execsql_test 12.1 {
SELECT rowid FROM yy('i*');
} {1 2}
#-------------------------------------------------------------------------
#
reset_db
do_execsql_test 13.0 {
CREATE VIRTUAL TABLE t1 USING fts5(a, prefix=1, detail=none);
} {}
foreach {rowid a} {
0 {f}
1 {u}
2 {k}
3 {a}
4 {a}
5 {u}
6 {u}
7 {u}
8 {f}
9 {f}
10 {a}
11 {p}
12 {f}
13 {u}
14 {a}
15 {a}
} {
do_execsql_test 13.1.$rowid {
INSERT INTO t1(rowid, a) VALUES($rowid, $a);
}
}
#-------------------------------------------------------------------------
#
reset_db
fts5_aux_test_functions db
do_execsql_test 14.0 {
CREATE VIRTUAL TABLE t1 USING fts5(a, detail=none);
INSERT INTO t1 VALUES('a b c d');
} {}
do_execsql_test 14.1 {
SELECT fts5_test_poslist(t1) FROM t1('b') ORDER BY rank;
} {0.0.1}
#-------------------------------------------------------------------------
#
reset_db
do_execsql_test 15.1 {
CREATE VIRTUAL TABLE t1 USING fts5(x, detail=none);
BEGIN;
INSERT INTO t1(rowid, x) VALUES(1, 'sqlite');
INSERT INTO t1(rowid, x) VALUES(2, 'sqlite');
COMMIT;
} {}
do_test 15.1 {
execsql { INSERT INTO t1(t1) VALUES('integrity-check') }
} {}
do_test 15.2 {
execsql { DELETE FROM t1 }
} {}
do_execsql_test 15.3.1 {
SELECT rowid FROM t1('sqlite');
} {}
do_execsql_test 15.3.2 {
SELECT rowid FROM t1('sqlite') ORDER BY rowid DESC;
} {}
do_test 15.4 {
execsql { INSERT INTO t1(t1) VALUES('integrity-check') }
} {}
#-------------------------------------------------------------------------
#
reset_db
do_execsql_test 16.0 {
CREATE VIRTUAL TABLE t2 USING fts5(x, detail=none);
BEGIN;
INSERT INTO t2(rowid, x) VALUES(1, 'a b c');
INSERT INTO t2(rowid, x) VALUES(456, 'a b c');
INSERT INTO t2(rowid, x) VALUES(1000, 'a b c');
COMMIT;
UPDATE t2 SET x=x;
}
do_execsql_test 16.1 {
INSERT INTO t2(t2) VALUES('integrity-check');
} {}
do_execsql_test 16.2 {
SELECT rowid FROM t2('b') ORDER BY rowid DESC
} {1000 456 1}
#-------------------------------------------------------------------------
#
reset_db
do_execsql_test 16.0 {
CREATE VIRTUAL TABLE t2 USING fts5(x, detail=none);
BEGIN;
INSERT INTO t2(rowid, x) VALUES(1, 'a b c');
INSERT INTO t2(rowid, x) VALUES(456, 'a b c');
INSERT INTO t2(rowid, x) VALUES(1000, 'a b c');
COMMIT;
UPDATE t2 SET x=x;
DELETE FROM t2;
}
#db eval {SELECT rowid, fts5_decode_none(rowid, block) aS r FROM t2_data} {puts $r}
finish_test
+85
View File
@@ -0,0 +1,85 @@
# 2015 September 05
#
# 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.
#
#*************************************************************************
#
source [file join [file dirname [info script]] fts5_common.tcl]
set testprefix fts5simple3
# If SQLITE_ENABLE_FTS5 is defined, omit this file.
ifcapable !fts5 {
finish_test
return
}
fts5_aux_test_functions db
do_execsql_test 1.0 {
CREATE VIRTUAL TABLE t1 USING fts5(a, b, c, detail=col);
INSERT INTO t1 VALUES('a', 'b', 'c');
INSERT INTO t1 VALUES('x', 'x', 'x');
}
do_execsql_test 1.1 {
SELECT rowid, fts5_test_collist(t1) FROM t1('a:a');
} {1 0.0}
do_execsql_test 1.2 {
SELECT rowid, fts5_test_collist(t1) FROM t1('b:x');
} {2 0.1}
do_execsql_test 1.3 {
SELECT rowid, fts5_test_collist(t1) FROM t1('b:a');
} {}
#-------------------------------------------------------------------------
# Create detail=col and detail=full tables with 998 columns.
#
foreach_detail_mode $testprefix {
if {[detail_is_none]} continue
do_test 2.1 {
execsql { DROP TABLE IF EXISTS t2 }
set cols [list]
set vals [list]
for {set i 1} {$i <= 998} {incr i} {
lappend cols "c$i"
lappend vals "'val$i'"
}
execsql "CREATE VIRTUAL TABLE t2 USING fts5(detail=%DETAIL%,[join $cols ,])"
} {}
do_test 2.2 {
execsql "INSERT INTO t2 VALUES([join $vals ,])"
} {}
foreach {tn q res} {
1 { c1:val1 } 1
2 { c300:val300 } 1
3 { c300:val1 } {}
4 { c1:val300 } {}
} {
do_execsql_test 2.3.$tn {
SELECT rowid FROM t2($q)
} $res
}
}
do_execsql_test 3.0 {
CREATE VIRTUAL TABLE x3 USING fts5(one);
INSERT INTO x3 VALUES('a b c');
INSERT INTO x3 VALUES('c b a');
INSERT INTO x3 VALUES('o t t');
SELECT * FROM x3('x OR y OR z');
}
finish_test
+29 -65
View File
@@ -21,42 +21,16 @@ ifcapable !fts5 {
return
}
foreach S {
{zero 0}
{one 1 i}
{two 2 ii}
{three 3 iii}
{four 4 iv}
{five 5 v}
{six 6 vi}
{seven 7 vii}
{eight 8 viii}
{nine 9 ix}
} {
foreach s $S {
set o [list]
foreach x $S {if {$x!=$s} {lappend o $x}}
set ::syn($s) $o
}
}
proc tcl_create {args} { return "tcl_tokenize" }
proc tcl_tokenize {tflags text} {
foreach {w iStart iEnd} [fts5_tokenize_split $text] {
sqlite3_fts5_token $w $iStart $iEnd
}
}
proc tcl_create {args} {
return "tcl_tokenize"
}
sqlite3_fts5_create_tokenizer db tcl tcl_create
foreach_detail_mode $testprefix {
#-------------------------------------------------------------------------
# Warm body test for the code in fts5_tcl.c.
#
fts5_tclnum_register db
do_execsql_test 1.0 {
CREATE VIRTUAL TABLE ft USING fts5(x, tokenize = tcl);
CREATE VIRTUAL TABLE ft USING fts5(x, tokenize = "tclnum document", detail=%DETAIL%);
INSERT INTO ft VALUES('abc def ghi');
INSERT INTO ft VALUES('jkl mno pqr');
SELECT rowid, x FROM ft WHERE ft MATCH 'def';
@@ -67,22 +41,13 @@ do_execsql_test 1.0 {
# Test a tokenizer that supports synonyms by adding extra entries to the
# FTS index.
#
proc tcl_tokenize {tflags text} {
foreach {w iStart iEnd} [fts5_tokenize_split $text] {
sqlite3_fts5_token $w $iStart $iEnd
if {$tflags=="document" && [info exists ::syn($w)]} {
foreach s $::syn($w) {
sqlite3_fts5_token -colo $s $iStart $iEnd
}
}
}
}
reset_db
sqlite3_fts5_create_tokenizer db tcl tcl_create
fts5_tclnum_register db
do_execsql_test 2.0 {
CREATE VIRTUAL TABLE ft USING fts5(x, tokenize = tcl);
CREATE VIRTUAL TABLE ft USING fts5(
x, tokenize = "tclnum document", detail=%DETAIL%
);
INSERT INTO ft VALUES('one two three');
INSERT INTO ft VALUES('four five six');
INSERT INTO ft VALUES('eight nine ten');
@@ -95,6 +60,7 @@ foreach {tn expr res} {
4 "1*" {1}
5 "1 + 2" {1}
} {
if {![fts5_expr_ok $expr ft]} continue
do_execsql_test 2.1.$tn {
SELECT rowid FROM ft WHERE ft MATCH $expr
} $res
@@ -180,17 +146,7 @@ do_execsql_test 3.2.5 {
# Check that expressions with synonyms can be parsed and executed.
#
reset_db
sqlite3_fts5_create_tokenizer db tcl tcl_create
proc tcl_tokenize {tflags text} {
foreach {w iStart iEnd} [fts5_tokenize_split $text] {
sqlite3_fts5_token $w $iStart $iEnd
if {$tflags=="query" && [info exists ::syn($w)]} {
foreach s $::syn($w) {
sqlite3_fts5_token -colo $s $iStart $iEnd
}
}
}
}
fts5_tclnum_register db
foreach {tn expr res} {
1 {abc} {"abc"}
@@ -198,11 +154,13 @@ foreach {tn expr res} {
3 {3} {"3"|"iii"|"three"}
4 {3*} {"3"|"iii"|"three" *}
} {
do_execsql_test 4.1.$tn {SELECT fts5_expr($expr, 'tokenize=tcl')} [list $res]
do_execsql_test 4.1.$tn {
SELECT fts5_expr($expr, 'tokenize=tclnum')
} [list $res]
}
do_execsql_test 4.2.1 {
CREATE VIRTUAL TABLE xx USING fts5(x, tokenize=tcl);
CREATE VIRTUAL TABLE xx USING fts5(x, tokenize=tclnum, detail=%DETAIL%);
INSERT INTO xx VALUES('one two');
INSERT INTO xx VALUES('three four');
}
@@ -217,7 +175,7 @@ do_execsql_test 4.2.3 {
do_test 5.0 {
execsql {
CREATE VIRTUAL TABLE t1 USING fts5(a, b, tokenize=tcl)
CREATE VIRTUAL TABLE t1 USING fts5(a, b, tokenize=tclnum, detail=%DETAIL%)
}
foreach {rowid a b} {
1 {four v 4 i three} {1 3 five five 4 one}
@@ -285,6 +243,7 @@ foreach {tn q res} {
5 {three i v i four 4 1} {ii [five five five] iii}
}
} {
if {![fts5_expr_ok $q t1]} continue
do_execsql_test 5.1.$tn {
SELECT rowid, highlight(t1, 0, '[', ']'), highlight(t1, 1, '[', ']')
FROM t1 WHERE t1 MATCH $q
@@ -316,7 +275,6 @@ foreach {tn q res} {
} $res
}
#-------------------------------------------------------------------------
# Test terms with more than 4 synonyms.
#
@@ -334,17 +292,19 @@ proc tcl_tokenize {tflags text} {
}
do_execsql_test 6.0.1 {
CREATE VIRTUAL TABLE t1 USING fts5(x, tokenize=tcl);
CREATE VIRTUAL TABLE t1 USING fts5(x, tokenize=tcl, detail=%DETAIL%);
INSERT INTO t1 VALUES('yy xx qq');
INSERT INTO t1 VALUES('yy xx xx');
}
do_execsql_test 6.0.2 {
SELECT * FROM t1 WHERE t1 MATCH 'NEAR(y q)';
} {{yy xx qq}}
if {[fts5_expr_ok "NEAR(y q)" t1]} {
do_execsql_test 6.0.2 {
SELECT * FROM t1 WHERE t1 MATCH 'NEAR(y q)';
} {{yy xx qq}}
}
do_test 6.0.3 {
execsql {
CREATE VIRTUAL TABLE t2 USING fts5(a, b, tokenize=tcl)
CREATE VIRTUAL TABLE t2 USING fts5(a, b, tokenize=tcl, detail=%DETAIL%)
}
foreach {rowid a b} {
1 {yyyy vvvvv qq oo yyyyyy vvvv eee} {ffff uu r qq aaaa}
@@ -387,6 +347,8 @@ foreach {tn q res} {
2 {ww oooooo bbbbb ssssss mm} {ffffff [yy] iiii rr s ccc [qqqqq]}
}
} {
if {![fts5_expr_ok $q t2]} continue
do_execsql_test 6.1.$tn.asc {
SELECT rowid, highlight(t2, 0, '[', ']'), highlight(t2, 1, '[', ']')
FROM t2 WHERE t2 MATCH $q
@@ -435,7 +397,7 @@ proc tcl_tokenize {tflags text} {
}
do_execsql_test 7.0.1 {
CREATE VIRTUAL TABLE t1 USING fts5(a, b, columnsize=1, tokenize=tcl);
CREATE VIRTUAL TABLE t1 USING fts5(a, b, columnsize=1, tokenize=tcl, detail=%DETAIL%);
INSERT INTO t1 VALUES('0 2 3', '4 5 6 7');
INSERT INTO t1 VALUES('8 9', '0 0 0 0 0 0 0 0 0 0');
SELECT fts5_test_columnsize(t1) FROM t1 WHERE t1 MATCH '000 AND 00 AND 0';
@@ -446,7 +408,7 @@ do_execsql_test 7.0.2 {
}
do_execsql_test 7.1.1 {
CREATE VIRTUAL TABLE t2 USING fts5(a, b, columnsize=0, tokenize=tcl);
CREATE VIRTUAL TABLE t2 USING fts5(a, b, columnsize=0, tokenize=tcl, detail=%DETAIL%);
INSERT INTO t2 VALUES('0 2 3', '4 5 6 7');
INSERT INTO t2 VALUES('8 9', '0 0 0 0 0 0 0 0 0 0');
SELECT fts5_test_columnsize(t2) FROM t2 WHERE t2 MATCH '000 AND 00 AND 0';
@@ -456,5 +418,7 @@ do_execsql_test 7.1.2 {
INSERT INTO t2(t2) VALUES('integrity-check');
}
} ;# foreach_detail_mode
finish_test
+164
View File
@@ -0,0 +1,164 @@
# 2014 Dec 20
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
# May you find forgiveness for yourself and forgive others.
# May you share freely, never taking more than you give.
#
#***********************************************************************
#
# Tests focusing on custom tokenizers that support synonyms.
#
source [file join [file dirname [info script]] fts5_common.tcl]
set testprefix fts5synonym2
# If SQLITE_ENABLE_FTS5 is defined, omit this file.
ifcapable !fts5 {
finish_test
return
}
foreach tok {query document} {
foreach_detail_mode $testprefix {
fts5_tclnum_register db
fts5_aux_test_functions db
proc fts5_test_bothlist {cmd} {
for {set i 0} {$i < [$cmd xPhraseCount]} {incr i} {
set bFirst 1
$cmd xPhraseColumnForeach $i c {
lappend CL $i.$c
if {$bFirst} { $cmd xPhraseForeach $i c o { lappend PL $i.$c.$o } }
set bFirst 0
}
}
list [sort_poslist $PL] $CL
}
sqlite3_fts5_create_function db fts5_test_bothlist fts5_test_bothlist
proc fts5_rowid {cmd} { expr [$cmd xColumnText -1] }
sqlite3_fts5_create_function db fts5_rowid fts5_rowid
do_execsql_test 1.$tok.0.1 "
CREATE VIRTUAL TABLE ss USING fts5(a, b,
tokenize='tclnum $tok', detail=%DETAIL%);
INSERT INTO ss(ss, rank) VALUES('rank', 'fts5_rowid()');
"
do_execsql_test 1.$tok.0.2 {
INSERT INTO ss VALUES('5 5 five seven 3 seven i', '2 1 5 0 two 1 i');
INSERT INTO ss VALUES('six ix iii 7 i vii iii', 'one seven nine 4 9 1 vi');
INSERT INTO ss VALUES('6 viii i five six zero seven', '5 v iii iv iv 3');
INSERT INTO ss VALUES('9 ii six 8 1 6', 'six 4 iv iv 7');
INSERT INTO ss VALUES('1 5 4 eight ii iv iii', 'nine 2 eight ix v vii');
INSERT INTO ss VALUES('one 7 seven six 2 two', '1 2 four 7 4 3 4');
INSERT INTO ss VALUES('eight iv 4 nine vii six 1', '5 6 v one zero 4');
INSERT INTO ss VALUES('v 9 8 iii 4', '9 4 seven two vi vii');
INSERT INTO ss VALUES('3 ix two 9 0 nine i', 'five ii nine two viii i five');
INSERT INTO ss VALUES('six iii 9 two eight 2', 'nine i nine vii nine');
INSERT INTO ss VALUES('6 three zero seven vii five', '8 vii ix 0 7 seven');
INSERT INTO ss VALUES('8 vii 8 7 3 4', 'eight iii four viii nine iv three');
INSERT INTO ss VALUES('4 v 7 two 0 one 8', 'vii 1 two five i zero 9');
INSERT INTO ss VALUES('3 ii vii vi eight', '8 4 ix one three eight');
INSERT INTO ss VALUES('iv eight seven 6 9 seven', 'one vi two five seven');
INSERT INTO ss VALUES('i i 5 i v vii eight', '2 seven i 2 2 four');
INSERT INTO ss VALUES('0 i iii nine 3 ix five', '0 eight iv 0 six 2');
INSERT INTO ss VALUES('iv vii three 3 9 one 8', '2 ii 6 eight ii six six');
INSERT INTO ss VALUES('eight one two nine six', '8 9 3 viii vi');
INSERT INTO ss VALUES('one 0 four ii eight one 3', 'iii eight vi vi vi');
INSERT INTO ss VALUES('4 0 eight 0 0', '1 four one vii seven ii');
INSERT INTO ss VALUES('1 zero nine 2 2', 'viii iv two vi nine v iii');
INSERT INTO ss VALUES('5 five viii four four vi', '8 five 7 vii 6 4');
INSERT INTO ss VALUES('7 ix four 8 vii', 'nine three nine ii ix vii');
INSERT INTO ss VALUES('nine iv v i 0 v', 'two iv vii six i ix 4');
INSERT INTO ss VALUES('one v v one viii 3 8', '2 1 3 five iii');
INSERT INTO ss VALUES('six ii 5 nine 4 viii seven', 'eight i ix ix 7 four');
INSERT INTO ss VALUES('9 ii two seven three 7 0', 'six viii seven 7 five');
INSERT INTO ss VALUES('five two 4 viii nine', '9 7 nine zero 1 two one');
INSERT INTO ss VALUES('viii 8 iii i ii 8 3', '4 2 7 v 8 8');
INSERT INTO ss VALUES('four vii 4 iii zero 0 vii', '3 viii iii zero 9 i');
INSERT INTO ss VALUES('0 seven v five i five v', 'one 4 2 ix 9');
INSERT INTO ss VALUES('two 5 two two ix 4 1', '3 nine ii v nine 3 five');
INSERT INTO ss VALUES('five 5 7 4 6 vii', 'three 2 ix 2 8 6');
INSERT INTO ss VALUES('six iii vi iv seven eight', '8 six 7 0 4');
INSERT INTO ss VALUES('vi vi iv 3 0 one one', '9 6 eight ix iv');
INSERT INTO ss VALUES('7 2 2 iii 0', '0 0 seven 1 nine');
INSERT INTO ss VALUES('8 6 iv six ii', 'iv 6 3 4 ii five');
INSERT INTO ss VALUES('0 two two seven ii', 'vii ix four 4 zero vi vi');
INSERT INTO ss VALUES('2 one eight 8 9 7', 'vi 3 0 3 vii');
INSERT INTO ss VALUES('iii ii ix iv three', 'vi i 6 1 two');
INSERT INTO ss VALUES('eight four nine 8 seven', 'one three i nine iii one');
INSERT INTO ss VALUES('iii seven five ix 8', 'ii 7 seven 0 four ii');
INSERT INTO ss VALUES('four 0 1 5 two', 'iii 9 5 ii ii 2 4');
INSERT INTO ss VALUES('iii nine four vi 8 five six', 'i i ii seven vi vii');
INSERT INTO ss VALUES('eight vii eight six 3', 'i vii 1 six 9 vii');
INSERT INTO ss VALUES('9 0 viii viii five', 'i 1 viii ix 3 4');
INSERT INTO ss VALUES('three nine 5 nine viii four zero', 'ii i 1 5 2 viii');
INSERT INTO ss VALUES('5 vii three 9 four', 'three five one 7 2 eight one');
}
foreach {tn expr} {
2.1 "one OR two OR three OR four"
1.1 "one" 1.2 "two" 1.3 "three" 1.4 "four"
1.5 "v" 1.6 "vi" 1.7 "vii" 1.8 "viii"
1.9 "9" 1.10 "0" 1.11 "1" 1.12 "2"
2.1 "one OR two OR three OR four"
2.2 "(one AND two) OR (three AND four)"
2.3 "(one AND two) OR (three AND four) NOT five"
2.4 "(one AND two) NOT 6"
3.1 "b:one AND a:two"
3.2 "b:one OR a:two"
3.3 "a:one OR b:1 OR {a b} : i"
4.1 "NEAR(one two, 2)"
4.2 "NEAR(one two three, 2)"
4.3 "NEAR(eight nine, 1) OR NEAR(six seven, 1)"
} {
if {[fts5_expr_ok $expr ss]==0} {
do_test 1.$tok.$tn.OMITTED { list } [list]
continue
}
set res [fts5_query_data $expr ss ASC ::tclnum_syn]
do_execsql_test 1.$tok.$tn.[llength $res].asc.1 {
SELECT rowid, fts5_test_poslist2(ss), fts5_test_collist(ss) FROM ss($expr)
} $res
do_execsql_test 1.$tok.$tn.[llength $res].asc.2 {
SELECT rowid, fts5_test_poslist(ss), fts5_test_collist(ss) FROM ss($expr)
} $res
do_execsql_test 1.$tok.$tn.[llength $res].asc.2 {
SELECT rowid, fts5_test_poslist2(ss), fts5_test_collist(ss) FROM ss($expr)
ORDER BY rank ASC
} $res
set res2 [list]
foreach {a b c} $res { lappend res2 $a $c $b }
do_execsql_test 1.$tok.$tn.[llength $res].asc.3 {
SELECT rowid, fts5_test_collist(ss), fts5_test_poslist2(ss) FROM ss($expr)
} $res2
set res3 [list]
foreach {a b c} $res { lappend res3 $a [list $b $c] }
do_execsql_test 1.$tok.$tn.[llength $res].asc.3 {
SELECT rowid, fts5_test_bothlist(ss) FROM ss($expr)
} $res3
}
}
}
finish_test
+115
View File
@@ -0,0 +1,115 @@
# 2016 Jan 15
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
# May you find forgiveness for yourself and forgive others.
# May you share freely, never taking more than you give.
#
#*************************************************************************
#
source [file join [file dirname [info script]] fts5_common.tcl]
ifcapable !fts5 { finish_test ; return }
set ::testprefix fts5tok1
sqlite3_fts5_register_fts5tokenize db
#-------------------------------------------------------------------------
# Simple test cases. Using the default (ascii) tokenizer.
#
do_execsql_test 1.0 {
CREATE VIRTUAL TABLE t1 USING fts5tokenize(ascii);
CREATE VIRTUAL TABLE t2 USING fts5tokenize();
CREATE VIRTUAL TABLE t3 USING fts5tokenize(
ascii, 'separators', 'xyz', tokenchars, ''''
);
}
foreach {tn tbl} {1 t1 2 t2 3 t3} {
do_execsql_test 1.$tn.1 "SELECT input, * FROM $tbl ('one two three')" {
{one two three} one 0 3 0
{one two three} two 4 7 1
{one two three} three 8 13 2
}
do_execsql_test 1.$tn.2 "
SELECT token FROM $tbl WHERE input = 'OnE tWo tHrEe'
" {
one two three
}
}
do_execsql_test 1.4 {
SELECT token FROM t3 WHERE input = '1x2x3x'
} {1 2 3}
do_execsql_test 1.5 {
SELECT token FROM t1 WHERE input = '1x2x3x'
} {1x2x3x}
do_execsql_test 1.6 {
SELECT token FROM t3 WHERE input = '1''2x3x'
} {1'2 3}
do_execsql_test 1.7 {
SELECT token FROM t3 WHERE input = ''
} {}
do_execsql_test 1.8 {
SELECT token FROM t3 WHERE input = NULL
} {}
do_execsql_test 1.9 {
SELECT input, * FROM t3 WHERE input = 123
} {123 123 0 3 0}
do_execsql_test 1.10 {
SELECT input, * FROM t1 WHERE input = 'a b c' AND token = 'b';
} {
{a b c} b 2 3 1
}
do_execsql_test 1.11 {
SELECT input, * FROM t1 WHERE token = 'b' AND input = 'a b c';
} {
{a b c} b 2 3 1
}
do_execsql_test 1.12 {
SELECT input, * FROM t1 WHERE input < 'b' AND input = 'a b c';
} {
{a b c} a 0 1 0
{a b c} b 2 3 1
{a b c} c 4 5 2
}
do_execsql_test 1.13.1 {
CREATE TABLE c1(x);
INSERT INTO c1(x) VALUES('a b c');
INSERT INTO c1(x) VALUES('d e f');
}
do_execsql_test 1.13.2 {
SELECT c1.*, input, t1.* FROM c1, t1 WHERE input = x AND c1.rowid=t1.rowid;
} {
{a b c} {a b c} a 0 1 0
{d e f} {d e f} e 2 3 1
}
#-------------------------------------------------------------------------
# Error cases.
#
do_catchsql_test 2.0 {
CREATE VIRTUAL TABLE tX USING fts5tokenize(nosuchtokenizer);
} {1 {vtable constructor failed: tX}}
do_catchsql_test 2.1 {
CREATE VIRTUAL TABLE t4 USING fts5tokenize;
SELECT * FROM t4;
} {1 {SQL logic error or missing database}}
finish_test
+47
View File
@@ -0,0 +1,47 @@
# 2016 Jan 15
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
# May you find forgiveness for yourself and forgive others.
# May you share freely, never taking more than you give.
#
#*************************************************************************
#
source [file join [file dirname [info script]] fts5_common.tcl]
ifcapable !fts5||!fts3 { finish_test ; return }
set ::testprefix fts5tok2
sqlite3_fts5_register_fts5tokenize db
#-------------------------------------------------------------------------
# Simple test cases. Using the default (ascii) tokenizer.
#
do_execsql_test 1.0 {
CREATE VIRTUAL TABLE t5 USING fts5tokenize(unicode61);
CREATE VIRTUAL TABLE t3 USING fts3tokenize(unicode61);
}
do_test 1.1 {
array unset -nocomplain A
for {set i 1} {$i < 65536} {incr i} {
set input [format "abc%cxyz" $i]
set expect [execsql {
SELECT input, token, start, end FROM t3 WHERE input=$input
}]
incr A([llength $expect])
set res [execsql {
SELECT input, token, start, end FROM t5($input)
}]
if {$res != $expect} {error "failed at i=$i"}
}
} {}
do_test 1.1.nTokenChars=$A(4).nSeparators=$A(8) {} {}
finish_test
+121
View File
@@ -0,0 +1,121 @@
# 2016 Jan 16
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
# May you find forgiveness for yourself and forgive others.
# May you share freely, never taking more than you give.
#
#*************************************************************************
# This file implements regression tests for SQLite library. The
# focus of this script is testing the FTS5 module.
#
source [file join [file dirname [info script]] fts5_common.tcl]
set testprefix fts5update
# If SQLITE_ENABLE_FTS5 is not defined, omit this file.
ifcapable !fts5 {
finish_test
return
}
set docs {
"eight zero iv eight 7" "ix one 8 one three ii one"
"1 9 9 three viii" "5 zero ii 6 nine ix 3"
"3 zero 5 2 seven nine" "two eight viii eight 1"
"4 six two 5 9 vii" "viii ii four 8 i i iv"
"vii 0 iv seven 7 viii" "five 1 nine vi seven"
"1 zero zero iii 1" "one one six 6 nine seven"
"one v 4 zero 4 iii ii" "2 3 eight six ix"
"six iv 7 three 5" "ix zero 0 8 ii 7 3"
"four six nine 2 vii 3" "five viii 5 8 0 7"
}
foreach_detail_mode $::testprefix {
do_execsql_test 1.0 {
CREATE VIRTUAL TABLE t1 USING fts5(a, b, detail=%DETAIL%);
} {}
do_test 1.1 {
foreach {a b} $docs {
execsql {INSERT INTO t1 VALUES($a, $b)}
}
} {}
proc update {iRowid iA iB} {
set a [lindex $::docs $iA]
set b [lindex $::docs $iB]
execsql { UPDATE t1 SET a=$a, b=$b WHERE rowid=$iRowid }
}
set nDoc [llength $::docs]
foreach n {1 5 10 50 100} {
do_test 1.2.$n {
execsql BEGIN
for {set i 1} {$i <= 1000} {incr i} {
set iRowid [expr {int(rand() * ($nDoc/2)) + 1}]
set iA [expr {int(rand() * $nDoc)}]
set iB [expr {int(rand() * $nDoc)}]
update $iRowid $iA $iB
if {($i % $n)==0} {
execsql { COMMIT; BEGIN }
}
if {($i % $n)==100} {
execsql { INSERT INTO t1(t1) VALUES('integrity-check') }
}
}
execsql COMMIT
execsql { INSERT INTO t1(t1) VALUES('integrity-check') }
} {}
}
do_execsql_test 1.3 {
UPDATE t1 SET a=a AND b=b;
INSERT INTO t1(t1) VALUES('integrity-check');
}
do_test 1.4 {
execsql { INSERT INTO t1(t1, rank) VALUES('pgsz', 32) }
for {set i 0} {$i < 50} {incr i} {
execsql { UPDATE t1 SET a=a AND b=b }
execsql { INSERT INTO t1(t1) VALUES('integrity-check') }
}
} {}
#-------------------------------------------------------------------------
# Lots of deletes/inserts of the same document with the same rowid.
#
do_execsql_test 2.0 {
CREATE VIRTUAL TABLE x2 USING fts5(x, detail=%DETAIL%);
INSERT INTO x2(x2, rank) VALUES('crisismerge', 2);
INSERT INTO x2 VALUES('a b c');
INSERT INTO x2 VALUES('a b c');
}
do_test 2.1 {
for {set i 0} {$i < 1000} {incr i} {
execsql { DELETE FROM x2 WHERE rowid = 2 }
execsql { INSERT INTO x2(rowid, x) VALUES(2, 'a b c') }
}
} {}
do_execsql_test 2.1.integrity {
INSERT INTO x2(x2) VALUES('integrity-check');
}
do_test 2.2 {
for {set i 0} {$i < 1000} {incr i} {
execsql { UPDATE x2 SET x=x WHERE rowid=2 }
}
} {}
do_execsql_test 2.2.integrity {
INSERT INTO x2(x2) VALUES('integrity-check');
}
}
finish_test
+261 -29
View File
@@ -21,9 +21,46 @@ ifcapable !fts5 {
return
}
foreach_detail_mode $testprefix {
proc null_list_entries {iFirst nInterval L} {
for {set i $iFirst} {$i < [llength $L]} {incr i $nInterval} {
lset L $i {}
}
return $L
}
proc star_from_row {L} {
if {[detail_is_full]==0} {
set L [null_list_entries 2 3 $L]
}
return $L
}
proc star_from_col {L} {
if {[detail_is_col]} {
set L [null_list_entries 3 4 $L]
}
if {[detail_is_none]} {
set L [null_list_entries 1 4 $L]
set L [null_list_entries 3 4 $L]
}
return $L
}
proc row_to_col {L} {
if {[detail_is_none]==0} { error "this is for detail=none mode" }
set ret [list]
foreach {a b c} $L {
lappend ret $a {} $b {}
}
set ret
}
if 1 {
do_execsql_test 1.1.1 {
CREATE VIRTUAL TABLE t1 USING fts5(one, prefix=1);
CREATE VIRTUAL TABLE t1 USING fts5(one, prefix=1, detail=%DETAIL%);
CREATE VIRTUAL TABLE v1 USING fts5vocab(t1, 'row');
PRAGMA table_info = v1;
} {
@@ -52,32 +89,32 @@ do_execsql_test 1.3 {
do_execsql_test 1.4.1 {
SELECT * FROM v1;
} {x 2 4 y 1 1 z 1 1}
} [star_from_row {x 2 4 y 1 1 z 1 1}]
do_execsql_test 1.4.2 {
SELECT * FROM v2;
} {x 0 2 4 y 0 1 1 z 0 1 1}
} [star_from_col {x one 2 4 y one 1 1 z one 1 1}]
do_execsql_test 1.5.1 {
BEGIN;
INSERT INTO t1 VALUES('a b c');
SELECT * FROM v1 WHERE term<'d';
} {a 1 1 b 1 1 c 1 1}
} [star_from_row {a 1 1 b 1 1 c 1 1}]
do_execsql_test 1.5.2 {
SELECT * FROM v2 WHERE term<'d';
COMMIT;
} {a 0 1 1 b 0 1 1 c 0 1 1}
} [star_from_col {a one 1 1 b one 1 1 c one 1 1}]
do_execsql_test 1.6 {
DELETE FROM t1 WHERE one = 'a b c';
SELECT * FROM v1;
} {x 2 4 y 1 1 z 1 1}
} [star_from_row {x 2 4 y 1 1 z 1 1}]
#-------------------------------------------------------------------------
#
do_execsql_test 2.0 {
CREATE VIRTUAL TABLE tt USING fts5(a, b);
CREATE VIRTUAL TABLE tt USING fts5(a, b, detail=%DETAIL%);
INSERT INTO tt VALUES('d g b f d f', 'f c e c d a');
INSERT INTO tt VALUES('f a e a a b', 'e d c f d d');
INSERT INTO tt VALUES('b c a a a b', 'f f c c b c');
@@ -90,20 +127,23 @@ do_execsql_test 2.0 {
INSERT INTO tt VALUES('c c a a c f', 'd g a e b g');
}
set res_col {
a 0 6 11 a 1 7 9
b 0 6 7 b 1 7 7
c 0 6 12 c 1 5 8
d 0 4 6 d 1 9 13
e 0 6 7 e 1 6 6
f 0 9 10 f 1 7 10
g 0 5 7 g 1 5 7
x 0 1 1 y 1 1 1
}
set res_row {
set res_row [star_from_row {
a 10 20 b 9 14 c 9 20 d 9 19
e 8 13 f 10 20 g 7 14 x 1 1
y 1 1
}]
set res_col [star_from_col {
a a 6 11 a b 7 9
b a 6 7 b b 7 7
c a 6 12 c b 5 8
d a 4 6 d b 9 13
e a 6 7 e b 6 6
f a 9 10 f b 7 10
g a 5 7 g b 5 7
x a 1 1 y b 1 1
}]
if {[detail_is_none]} {
set res_col [row_to_col $res_row]
}
foreach {tn tbl resname} {
@@ -153,9 +193,9 @@ reset_db
forcedelete test.db2
do_execsql_test 5.0 {
ATTACH 'test.db2' AS aux;
CREATE VIRTUAL TABLE t1 USING fts5(x);
CREATE VIRTUAL TABLE temp.t1 USING fts5(x);
CREATE VIRTUAL TABLE aux.t1 USING fts5(x);
CREATE VIRTUAL TABLE t1 USING fts5(x, detail=%DETAIL%);
CREATE VIRTUAL TABLE temp.t1 USING fts5(x, detail=%DETAIL%);
CREATE VIRTUAL TABLE aux.t1 USING fts5(x, detail=%DETAIL%);
INSERT INTO main.t1 VALUES('a b c');
INSERT INTO main.t1 VALUES('d e f');
@@ -178,18 +218,18 @@ do_execsql_test 5.1 {
CREATE VIRTUAL TABLE temp.va USING fts5vocab(aux, t1, row);
}
do_execsql_test 5.2 { SELECT * FROM vm } {
do_execsql_test 5.2 { SELECT * FROM vm } [star_from_row {
a 2 2 b 1 1 c 2 2 d 1 1 e 2 2 f 1 1
}
do_execsql_test 5.3 { SELECT * FROM vt1 } {
}]
do_execsql_test 5.3 { SELECT * FROM vt1 } [star_from_row {
1 2 2 2 1 1 3 2 2 4 1 1 5 2 2 6 1 1
}
do_execsql_test 5.4 { SELECT * FROM vt2 } {
}]
do_execsql_test 5.4 { SELECT * FROM vt2 } [star_from_row {
1 2 2 2 1 1 3 2 2 4 1 1 5 2 2 6 1 1
}
do_execsql_test 5.5 { SELECT * FROM va } {
}]
do_execsql_test 5.5 { SELECT * FROM va } [star_from_row {
m 1 1 n 2 2 o 1 1 x 2 2 y 1 1 z 2 2
}
}]
#-------------------------------------------------------------------------
#
@@ -213,5 +253,197 @@ do_catchsql_test 6.2 {
SELECT * FROM vocab3;
} {1 {no such fts5 table: main.lll}}
#-------------------------------------------------------------------------
# Test single term queries on fts5vocab tables (i.e. those with term=?
# constraints in the WHERE clause).
#
do_execsql_test 7.0 {
CREATE VIRTUAL TABLE tx USING fts5(one, two, detail=%DETAIL%);
INSERT INTO tx VALUES('g a ggg g a b eee', 'cc d aa ff g ee');
INSERT INTO tx VALUES('dd fff i a i jjj', 'f fff hh jj e f');
INSERT INTO tx VALUES('ggg a f f fff dd aa', 'd ggg f f j gg ddd');
INSERT INTO tx VALUES('e bb h jjj ii gg', 'e aa e f c fff');
INSERT INTO tx VALUES('j ff aa a h', 'h a j bbb bb');
INSERT INTO tx VALUES('cc i ff c d f', 'dd ii fff f c cc d');
INSERT INTO tx VALUES('jjj g i bb cc eee', 'hhh iii aaa b bbb aaa');
INSERT INTO tx VALUES('hhh hhh hhh bb fff f', 'fff gg aa ii h a');
INSERT INTO tx VALUES('b c cc aaa iii ggg f', 'iii ff ee a ff c cc');
INSERT INTO tx VALUES('hhh b hhh aaa j i i', 'dd ee ee aa bbb iii');
INSERT INTO tx VALUES('hh dd h b g ff i', 'ccc bb cc ccc f a d');
INSERT INTO tx VALUES('g d b ggg jj', 'fff jj ff jj g gg ee');
INSERT INTO tx VALUES('g ee ggg ggg cc bb eee', 'aa j jjj bbb dd eee ff');
INSERT INTO tx VALUES('c jjj hh ddd dd h', 'e aaa h jjj gg');
CREATE VIRTUAL TABLE txr USING fts5vocab(tx, row);
CREATE VIRTUAL TABLE txc USING fts5vocab(tx, col);
}
proc cont {L elem} {
set n 0
foreach e $L { if {$elem==$e} {incr n} }
set n
}
db func cont cont
foreach {term} {
a aa aaa
b bb bbb
c cc ccc
d dd ddd
e ee eee
f ff fff
g gg ggg
h hh hhh
i ii iii
j jj jjj
} {
set resr [db eval {
SELECT $term,
sum(cont(one || ' ' || two, $term) > 0),
sum(cont(one || ' ' || two, $term))
FROM tx
}]
if {[lindex $resr 1]==0} {set resr [list]}
set r1 [db eval {
SELECT $term, 'one', sum(cont(one, $term)>0), sum(cont(one, $term)) FROM tx
}]
if {[lindex $r1 2]==0} {set r1 [list]}
set r2 [db eval {
SELECT $term, 'two', sum(cont(two, $term)>0), sum(cont(two, $term)) FROM tx
}]
if {[lindex $r2 2]==0} {set r2 [list]}
set resc [concat $r1 $r2]
set resc [star_from_col $resc]
set resr [star_from_row $resr]
if {[detail_is_none]} { set resc [row_to_col $resr] }
do_execsql_test 7.$term.1 {SELECT * FROM txc WHERE term=$term} $resc
do_execsql_test 7.$term.2 {SELECT * FROM txr WHERE term=$term} $resr
}
do_execsql_test 7.1 {
CREATE TABLE txr_c AS SELECT * FROM txr;
CREATE TABLE txc_c AS SELECT * FROM txc;
}
# Test range queries on the fts5vocab tables created above.
#
foreach {tn a b} {
1 a jjj
2 bb j
3 ccc ddd
4 dd xyz
5 xzy dd
6 h hh
} {
do_execsql_test 7.2.$tn.1 {
SELECT * FROM txr WHERE term>=$a
} [db eval {SELECT * FROM txr_c WHERE term>=$a}]
do_execsql_test 7.2.$tn.2 {
SELECT * FROM txr WHERE term<=$b
} [db eval {SELECT * FROM txr_c WHERE term <=$b}]
do_execsql_test 7.2.$tn.3 {
SELECT * FROM txr WHERE term>=$a AND term<=$b
} [db eval {SELECT * FROM txr_c WHERE term>=$a AND term <=$b}]
do_execsql_test 7.2.$tn.4 {
SELECT * FROM txc WHERE term>=$a
} [db eval {SELECT * FROM txc_c WHERE term>=$a}]
do_execsql_test 7.2.$tn.5 {
SELECT * FROM txc WHERE term<=$b
} [db eval {SELECT * FROM txc_c WHERE term <=$b}]
do_execsql_test 7.2.$tn.6 {
SELECT * FROM txc WHERE term>=$a AND term<=$b
} [db eval {SELECT * FROM txc_c WHERE term>=$a AND term <=$b}]
do_execsql_test 7.2.$tn.7 {
SELECT * FROM txr WHERE term>$a
} [db eval {SELECT * FROM txr_c WHERE term>$a}]
do_execsql_test 7.2.$tn.8 {
SELECT * FROM txr WHERE term<$b
} [db eval {SELECT * FROM txr_c WHERE term<$b}]
do_execsql_test 7.2.$tn.9 {
SELECT * FROM txr WHERE term>$a AND term<$b
} [db eval {SELECT * FROM txr_c WHERE term>$a AND term <$b}]
do_execsql_test 7.2.$tn.10 {
SELECT * FROM txc WHERE term>$a
} [db eval {SELECT * FROM txc_c WHERE term>$a}]
do_execsql_test 7.2.$tn.11 {
SELECT * FROM txc WHERE term<$b
} [db eval {SELECT * FROM txc_c WHERE term<$b}]
do_execsql_test 7.2.$tn.12 {
SELECT * FROM txc WHERE term>$a AND term<$b
} [db eval {SELECT * FROM txc_c WHERE term>$a AND term <$b}]
}
do_execsql_test 7.3.1 {
SELECT count(*) FROM txr, txr_c WHERE txr.term = txr_c.term;
} {30}
if {![detail_is_none]} {
do_execsql_test 7.3.2 {
SELECT count(*) FROM txc, txc_c
WHERE txc.term = txc_c.term AND txc.col=txc_c.col;
} {57}
}
}
#-------------------------------------------------------------------------
# Test the fts5vocab tables response to a specific types of corruption:
# where the fts5 index contains hits for columns that do not exist.
#
do_execsql_test 8.0 {
CREATE VIRTUAL TABLE x1 USING fts5(a, b, c, detail=%DETAIL%);
INSERT INTO x1 VALUES('a b c', 'd e f', 'g h i');
INSERT INTO x1 VALUES('g h i', 'a b c', 'd e f');
INSERT INTO x1 VALUES('d e f', 'g h i', 'a b c');
CREATE VIRTUAL TABLE x1_r USING fts5vocab(x1, row);
CREATE VIRTUAL TABLE x1_c USING fts5vocab(x1, col);
}
set resr [star_from_row {a 3 3 b 3 3 c 3 3 d 3 3 e 3 3 f 3 3 g 3 3 h 3 3 i 3 3}]
set resc [star_from_col {
a a 1 1 a b 1 1 a c 1 1 b a 1 1
b b 1 1 b c 1 1 c a 1 1 c b 1 1
c c 1 1 d a 1 1 d b 1 1 d c 1 1
e a 1 1 e b 1 1 e c 1 1 f a 1 1
f b 1 1 f c 1 1 g a 1 1 g b 1 1
g c 1 1 h a 1 1 h b 1 1 h c 1 1
i a 1 1 i b 1 1 i c 1 1
}]
if {[detail_is_none]} { set resc [row_to_col $resr] }
do_execsql_test 8.1.1 { SELECT * FROM x1_r; } $resr
do_execsql_test 8.1.2 { SELECT * FROM x1_c } $resc
do_execsql_test 8.2 {
PRAGMA writable_schema = 1;
UPDATE sqlite_master
SET sql = 'CREATE VIRTUAL TABLE x1 USING fts5(a, detail=%DETAIL%)'
WHERE name = 'x1';
}
db close
sqlite3 db test.db
sqlite3_fts5_may_be_corrupt 1
do_execsql_test 8.2.1 { SELECT * FROM x1_r } $resr
if {[detail_is_none]} {
do_execsql_test 8.2.2 { SELECT * FROM x1_c } $resc
} else {
do_catchsql_test 8.2.2 {
SELECT * FROM x1_c
} {1 {database disk image is malformed}}
}
sqlite3_fts5_may_be_corrupt 0
}
finish_test
+64
View File
@@ -0,0 +1,64 @@
set Q {
{1 "SELECT count(*) FROM t1 WHERE t1 MATCH 'enron'"}
{25 "SELECT count(*) FROM t1 WHERE t1 MATCH 'hours'"}
{300 "SELECT count(*) FROM t1 WHERE t1 MATCH 'acid'"}
{100 "SELECT count(*) FROM t1 WHERE t1 MATCH 'loaned OR mobility OR popcore OR sunk'"}
{100 "SELECT count(*) FROM t1 WHERE t1 MATCH 'enron AND myapps'"}
{1 "SELECT count(*) FROM t1 WHERE t1 MATCH 'en* AND my*'"}
{1 "SELECT count(*) FROM t1 WHERE t1 MATCH 'c:t*'"}
{1 "SELECT count(*) FROM t1 WHERE t1 MATCH 'a:t* OR b:t* OR c:t* OR d:t* OR e:t* OR f:t* OR g:t*'"}
{1 "SELECT count(*) FROM t1 WHERE t1 MATCH 'a:t*'"}
{2 "SELECT count(*) FROM t1 WHERE t1 MATCH 'c:the'"}
{2 "SELECT count(*) FROM t1 WHERE t1 MATCH 'd:holmes OR e:holmes OR f:holmes OR g:holmes'" }
{2 "SELECT count(*) FROM t1 WHERE t1 MATCH 'd:holmes AND e:holmes AND f:holmes AND g:holmes'" }
{4 "SELECT count(*) FROM t1 WHERE t1 MATCH 'd:holmes NOT e:holmes'" }
}
proc usage {} {
global Q
puts stderr "Usage: $::argv0 DATABASE QUERY"
puts stderr ""
for {set i 1} {$i <= [llength $Q]} {incr i} {
puts stderr " $i. [lindex $Q [expr $i-1]]"
}
puts stderr ""
exit -1
}
set nArg [llength $argv]
if {$nArg!=2 && $nArg!=3} usage
set database [lindex $argv 0]
set iquery [lindex $argv 1]
if {$iquery<1 || $iquery>[llength $Q]} usage
set nRepeat 0
if {$nArg==3} { set nRepeat [lindex $argv 2] }
sqlite3 db $database
catch { load_static_extension db fts5 }
incr iquery -1
set sql [lindex $Q $iquery 1]
if {$nRepeat==0} {
set nRepeat [lindex $Q $iquery 0]
}
puts "sql: $sql"
puts "nRepeat: $nRepeat"
if {[regexp matchinfo $sql]} {
sqlite3_fts5_register_matchinfo db
db eval $sql
} else {
puts "result: [db eval $sql]"
}
for {set i 1} {$i < $nRepeat} {incr i} {
db eval $sql
}
+173 -80
View File
@@ -1,95 +1,180 @@
proc usage {} {
puts stderr "$::argv0 ?OPTIONS? DATABASE FILE1..."
puts stderr ""
puts stderr "Options are"
puts stderr " -fts5"
puts stderr " -fts4"
puts stderr " -colsize <list of column sizes>"
puts stderr {
This script is designed to create fts4/5 tables with more than one column.
The -colsize option should be set to a Tcl list of integer values, one for
each column in the table. Each value is the number of tokens that will be
inserted into the column value for each row. For example, setting the -colsize
option to "5 10" creates an FTS table with 2 columns, with roughly 5 and 10
tokens per row in each, respectively.
Each "FILE" argument should be a text file. The contents of these text files is
split on whitespace characters to form a list of tokens. The first N1 tokens
are used for the first column of the first row, where N1 is the first element
of the -colsize list. The next N2 are used for the second column of the first
row, and so on. Rows are added to the table until the entire list of tokens
is exhausted.
}
exit -1
}
set O(aColsize) [list 10 10 10]
set O(tblname) t1
set O(fts) fts5
set options_with_values {-colsize}
for {set i 0} {$i < [llength $argv]} {incr i} {
set opt [lindex $argv $i]
if {[string range $opt 0 0]!="-"} break
if {[lsearch $options_with_values $opt]>=0} {
incr i
if {$i==[llength $argv]} usage
set val [lindex $argv $i]
}
switch -- $opt {
-colsize {
set O(aColSize) $val
}
-fts4 {
set O(fts) fts4
}
-fts5 {
set O(fts) fts5
}
##########################################################################
# 2016 Jan 27
#
# 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.
#
proc process_cmdline {} {
cmdline::process ::A $::argv {
{fts5 "use fts5 (this is the default)"}
{fts4 "use fts4"}
{colsize "10 10 10" "list of column sizes"}
{tblname "t1" "table name to create"}
{detail "full" "Fts5 detail mode to use"}
{repeat 1 "Load each file this many times"}
{prefix "" "Fts prefix= option"}
database
file...
} {
This script is designed to create fts4/5 tables with more than one column.
The -colsize option should be set to a Tcl list of integer values, one for
each column in the table. Each value is the number of tokens that will be
inserted into the column value for each row. For example, setting the -colsize
option to "5 10" creates an FTS table with 2 columns, with roughly 5 and 10
tokens per row in each, respectively.
Each "FILE" argument should be a text file. The contents of these text files
is split on whitespace characters to form a list of tokens. The first N1
tokens are used for the first column of the first row, where N1 is the first
element of the -colsize list. The next N2 are used for the second column of
the first row, and so on. Rows are added to the table until the entire list
of tokens is exhausted.
}
}
if {$i > [llength $argv]-2} usage
set O(db) [lindex $argv $i]
set O(files) [lrange $argv [expr $i+1] end]
foreach {k v} [lrange $argv 0 end-2] {
switch -- $k {
-colsize {
set O(aColSize) $v
###########################################################################
###########################################################################
# Command line options processor. This is generic code that can be copied
# between scripts.
#
namespace eval cmdline {
proc cmdline_error {O E {msg ""}} {
if {$msg != ""} {
puts stderr "Error: $msg"
puts stderr ""
}
-colsize {
set O(aColSize) $v
set L [list]
foreach o $O {
if {[llength $o]==1} {
lappend L [string toupper $o]
}
}
puts stderr "Usage: $::argv0 ?SWITCHES? $L"
puts stderr ""
puts stderr "Switches are:"
foreach o $O {
if {[llength $o]==3} {
foreach {a b c} $o {}
puts stderr [format " -%-15s %s (default \"%s\")" "$a VAL" $c $b]
} elseif {[llength $o]==2} {
foreach {a b} $o {}
puts stderr [format " -%-15s %s" $a $b]
}
}
puts stderr ""
puts stderr $E
exit -1
}
proc process {avar lArgs O E} {
upvar $avar A
set zTrailing "" ;# True if ... is present in $O
set lPosargs [list]
# Populate A() with default values. Also, for each switch in the command
# line spec, set an entry in the idx() array as follows:
#
# {tblname t1 "table name to use"}
# -> [set idx(-tblname) {tblname t1 "table name to use"}
#
# For each position parameter, append its name to $lPosargs. If the ...
# specifier is present, set $zTrailing to the name of the prefix.
#
foreach o $O {
set nm [lindex $o 0]
set nArg [llength $o]
switch -- $nArg {
1 {
if {[string range $nm end-2 end]=="..."} {
set zTrailing [string range $nm 0 end-3]
} else {
lappend lPosargs $nm
}
}
2 {
set A($nm) 0
set idx(-$nm) $o
}
3 {
set A($nm) [lindex $o 1]
set idx(-$nm) $o
}
default {
error "Error in command line specification"
}
}
}
# Set explicitly specified option values
#
set nArg [llength $lArgs]
for {set i 0} {$i < $nArg} {incr i} {
set opt [lindex $lArgs $i]
if {[string range $opt 0 0]!="-" || $opt=="--"} break
set c [array names idx "${opt}*"]
if {[llength $c]==0} { cmdline_error $O $E "Unrecognized option: $opt"}
if {[llength $c]>1} { cmdline_error $O $E "Ambiguous option: $opt"}
if {[llength $idx($c)]==3} {
if {$i==[llength $lArgs]-1} {
cmdline_error $O $E "Option requires argument: $c"
}
incr i
set A([lindex $idx($c) 0]) [lindex $lArgs $i]
} else {
set A([lindex $idx($c) 0]) 1
}
}
# Deal with position arguments.
#
set nPosarg [llength $lPosargs]
set nRem [expr $nArg - $i]
if {$nRem < $nPosarg || ($zTrailing=="" && $nRem > $nPosarg)} {
cmdline_error $O $E
}
for {set j 0} {$j < $nPosarg} {incr j} {
set A([lindex $lPosargs $j]) [lindex $lArgs [expr $j+$i]]
}
if {$zTrailing!=""} {
set A($zTrailing) [lrange $lArgs [expr $j+$i] end]
}
}
} ;# namespace eval cmdline
# End of command line options processor.
###########################################################################
###########################################################################
process_cmdline
# If -fts4 was specified, use fts4. Otherwise, fts5.
if {$A(fts4)} {
set A(fts) fts4
} else {
set A(fts) fts5
}
sqlite3 db $O(db)
load_static_extension db fts5
sqlite3 db $A(database)
# Create the FTS table in the db. Return a list of the table columns.
#
proc create_table {} {
global O
global A
set cols [list a b c d e f g h i j k l m n o p q r s t u v w x y z]
set nCol [llength $O(aColsize)]
set nCol [llength $A(colsize)]
set cols [lrange $cols 0 [expr $nCol-1]]
set sql "CREATE VIRTUAL TABLE IF NOT EXISTS $O(tblname) USING $O(fts) ("
set sql "CREATE VIRTUAL TABLE IF NOT EXISTS $A(tblname) USING $A(fts) ("
append sql [join $cols ,]
append sql ");"
if {$A(fts)=="fts5"} { append sql ",detail=$A(detail)" }
append sql ", prefix='$A(prefix)');"
db eval $sql
return $cols
@@ -104,27 +189,35 @@ proc readfile {file} {
split $data
}
proc repeat {L n} {
set res [list]
for {set i 0} {$i < $n} {incr i} {
set res [concat $res $L]
}
set res
}
# Load all the data into a big list of tokens.
#
set tokens [list]
foreach f $O(files) {
set tokens [concat $tokens [readfile $f]]
foreach f $A(file) {
set tokens [concat $tokens [repeat [readfile $f] $A(repeat)]]
}
set N [llength $tokens]
set i 0
set cols [create_table]
set sql "INSERT INTO $O(tblname) VALUES(\$[lindex $cols 0]"
set sql "INSERT INTO $A(tblname) VALUES(\$R([lindex $cols 0])"
foreach c [lrange $cols 1 end] {
append sql ", \$$c"
append sql ", \$R($c)"
}
append sql ")"
db eval BEGIN
while {$i < $N} {
foreach c $cols s $O(aColsize) {
set $c [lrange $tokens $i [expr $i+$s-1]]
foreach c $cols s $A(colsize) {
set R($c) [lrange $tokens $i [expr $i+$s-1]]
incr i $s
}
db eval $sql
+26
View File
@@ -48,6 +48,8 @@ proc usage {} {
puts stderr " -crisismerge N (set the crisismerge parameter to N)"
puts stderr " -prefix PREFIX (comma separated prefix= argument)"
puts stderr " -trans N (commit after N inserts - 0 == never)"
puts stderr " -hashsize N (set the fts5 hashsize parameter to N)"
puts stderr " -detail MODE (detail mode for fts5 tables)"
exit 1
}
@@ -59,6 +61,8 @@ set O(automerge) -1
set O(crisismerge) -1
set O(prefix) ""
set O(trans) 0
set O(hashsize) -1
set O(detail) full
if {[llength $argv]<2} usage
set nOpt [expr {[llength $argv]-2}]
@@ -106,6 +110,16 @@ for {set i 0} {$i < $nOpt} {incr i} {
set O(prefix) [lindex $argv $i]
}
-hashsize {
if { [incr i]>=$nOpt } usage
set O(hashsize) [lindex $argv $i]
}
-detail {
if { [incr i]>=$nOpt } usage
set O(detail) [lindex $argv $i]
}
default {
usage
}
@@ -122,10 +136,21 @@ db eval "PRAGMA page_size=4096"
db eval BEGIN
set pref ""
if {$O(prefix)!=""} { set pref ", prefix='$O(prefix)'" }
if {$O(vtab)=="fts5"} {
append pref ", detail=$O(detail)"
}
catch {
db eval "CREATE VIRTUAL TABLE t1 USING $O(vtab) (path, content$O(tok)$pref)"
db eval "INSERT INTO t1(t1, rank) VALUES('pgsz', 4050);"
}
if {$O(hashsize)>=0} {
catch {
db eval "INSERT INTO t1(t1, rank) VALUES('hashsize', $O(hashsize));"
}
}
if {$O(automerge)>=0} {
if {$O(vtab) == "fts5"} {
db eval { INSERT INTO t1(t1, rank) VALUES('automerge', $O(automerge)) }
@@ -141,6 +166,7 @@ db eval BEGIN
}
load_hierachy [lindex $argv end]
db eval COMMIT
puts ""
+5 -3
View File
@@ -78,7 +78,7 @@ proc fts5c_printfile {zIn} {
global G
set data [readfile $zIn]
set zTail [file tail $zIn]
puts $G(fd) "#line 2 \"$zTail\""
puts $G(fd) "#line 1 \"$zTail\""
set sub_map [list --FTS5-SOURCE-ID-- [fts5_source_id $::srcdir]]
if {$zTail=="fts5parse.c"} {
@@ -86,8 +86,10 @@ proc fts5c_printfile {zIn} {
}
foreach line [split $data "\n"] {
if {[regexp {^#include.*fts5} $line]} continue
if { ![regexp { sqlite3Fts5Init\(} $line]
if {[regexp {^#include.*fts5} $line]} {
set line "/* $line */"
} elseif {
![regexp { sqlite3Fts5Init\(} $line]
&& [regexp {^(const )?[a-zA-Z][a-zA-Z0-9]* [*]?sqlite3Fts5} $line]
} {
set line "static $line"
+13
View File
@@ -8,11 +8,13 @@ proc usage {} {
puts stderr "usage: $::argv0 ?OPTIONS? database table"
puts stderr ""
puts stderr " -nterm (count number of terms in each segment)"
puts stderr " -segments (output segment contents)"
puts stderr ""
exit 1
}
set O(nterm) 0
set O(segments) 0
if {[llength $argv]<2} usage
foreach a [lrange $argv 0 end-2] {
@@ -21,6 +23,10 @@ foreach a [lrange $argv 0 end-2] {
set O(nterm) 1
}
-segments {
set O(segments) 1
}
default {
usage
}
@@ -78,6 +84,13 @@ db eval "SELECT fts5_decode(rowid, block) AS d FROM ${tbl}_data WHERE id=10" {
}
}
if {$O(segments)} {
puts ""
db eval "SELECT fts5_decode(rowid, block) AS d FROM ${tbl}_data WHERE id>10" {
puts $d
}
}
+75 -37
View File
@@ -60,6 +60,38 @@ static void xFree(void *p){
sqlite3_free(p);
}
/*
** This lookup table is used to help decode the first byte of
** a multi-byte UTF8 character. It is copied here from SQLite source
** code file utf8.c.
*/
static const unsigned char icuUtf8Trans1[] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x00, 0x00,
};
#define SQLITE_ICU_READ_UTF8(zIn, c) \
c = *(zIn++); \
if( c>=0xc0 ){ \
c = icuUtf8Trans1[c-0xc0]; \
while( (*zIn & 0xc0)==0x80 ){ \
c = (c<<6) + (0x3f & *(zIn++)); \
} \
}
#define SQLITE_ICU_SKIP_UTF8(zIn) \
assert( *zIn ); \
if( *(zIn++)>=0xc0 ){ \
while( (*zIn & 0xc0)==0x80 ){zIn++;} \
}
/*
** Compare two UTF-8 strings for equality where the first string is
** a "LIKE" expression. Return true (1) if they are the same and
@@ -73,16 +105,14 @@ static int icuLikeCompare(
static const int MATCH_ONE = (UChar32)'_';
static const int MATCH_ALL = (UChar32)'%';
int iPattern = 0; /* Current byte index in zPattern */
int iString = 0; /* Current byte index in zString */
int prevEscape = 0; /* True if the previous character was uEsc */
while( zPattern[iPattern]!=0 ){
while( 1 ){
/* Read (and consume) the next character from the input pattern. */
UChar32 uPattern;
U8_NEXT_UNSAFE(zPattern, iPattern, uPattern);
SQLITE_ICU_READ_UTF8(zPattern, uPattern);
if( uPattern==0 ) break;
/* There are now 4 possibilities:
**
@@ -99,28 +129,28 @@ static int icuLikeCompare(
** MATCH_ALL. For each MATCH_ONE, skip one character in the
** test string.
*/
while( (c=zPattern[iPattern]) == MATCH_ALL || c == MATCH_ONE ){
while( (c=*zPattern) == MATCH_ALL || c == MATCH_ONE ){
if( c==MATCH_ONE ){
if( zString[iString]==0 ) return 0;
U8_FWD_1_UNSAFE(zString, iString);
if( *zString==0 ) return 0;
SQLITE_ICU_SKIP_UTF8(zString);
}
iPattern++;
zPattern++;
}
if( zPattern[iPattern]==0 ) return 1;
if( *zPattern==0 ) return 1;
while( zString[iString] ){
if( icuLikeCompare(&zPattern[iPattern], &zString[iString], uEsc) ){
while( *zString ){
if( icuLikeCompare(zPattern, zString, uEsc) ){
return 1;
}
U8_FWD_1_UNSAFE(zString, iString);
SQLITE_ICU_SKIP_UTF8(zString);
}
return 0;
}else if( !prevEscape && uPattern==MATCH_ONE ){
/* Case 2. */
if( zString[iString]==0 ) return 0;
U8_FWD_1_UNSAFE(zString, iString);
if( *zString==0 ) return 0;
SQLITE_ICU_SKIP_UTF8(zString);
}else if( !prevEscape && uPattern==uEsc){
/* Case 3. */
@@ -129,7 +159,7 @@ static int icuLikeCompare(
}else{
/* Case 4. */
UChar32 uString;
U8_NEXT_UNSAFE(zString, iString, uString);
SQLITE_ICU_READ_UTF8(zString, uString);
uString = u_foldCase(uString, U_FOLD_CASE_DEFAULT);
uPattern = u_foldCase(uPattern, U_FOLD_CASE_DEFAULT);
if( uString!=uPattern ){
@@ -139,7 +169,7 @@ static int icuLikeCompare(
}
}
return zString[iString]==0;
return *zString==0;
}
/*
@@ -325,11 +355,11 @@ static void icuRegexpFunc(sqlite3_context *p, int nArg, sqlite3_value **apArg){
*/
static void icuCaseFunc16(sqlite3_context *p, int nArg, sqlite3_value **apArg){
const UChar *zInput;
UChar *zOutput;
UChar *zOutput = 0;
int nInput;
int nOutput;
UErrorCode status = U_ZERO_ERROR;
int nOut;
int cnt;
UErrorCode status;
const char *zLocale = 0;
assert(nArg==1 || nArg==2);
@@ -341,26 +371,34 @@ static void icuCaseFunc16(sqlite3_context *p, int nArg, sqlite3_value **apArg){
if( !zInput ){
return;
}
nInput = sqlite3_value_bytes16(apArg[0]);
nOutput = nInput * 2 + 2;
zOutput = sqlite3_malloc(nOutput);
if( !zOutput ){
nOut = nInput = sqlite3_value_bytes16(apArg[0]);
if( nOut==0 ){
sqlite3_result_text16(p, "", 0, SQLITE_STATIC);
return;
}
if( sqlite3_user_data(p) ){
u_strToUpper(zOutput, nOutput/2, zInput, nInput/2, zLocale, &status);
}else{
u_strToLower(zOutput, nOutput/2, zInput, nInput/2, zLocale, &status);
for(cnt=0; cnt<2; cnt++){
UChar *zNew = sqlite3_realloc(zOutput, nOut);
if( zNew==0 ){
sqlite3_free(zOutput);
sqlite3_result_error_nomem(p);
return;
}
zOutput = zNew;
status = U_ZERO_ERROR;
if( sqlite3_user_data(p) ){
nOut = 2*u_strToUpper(zOutput,nOut/2,zInput,nInput/2,zLocale,&status);
}else{
nOut = 2*u_strToLower(zOutput,nOut/2,zInput,nInput/2,zLocale,&status);
}
if( !U_SUCCESS(status) ){
if( status==U_BUFFER_OVERFLOW_ERROR ) continue;
icuFunctionError(p,
sqlite3_user_data(p) ? "u_strToUpper" : "u_strToLower", status);
return;
}
}
if( !U_SUCCESS(status) ){
icuFunctionError(p, "u_strToLower()/u_strToUpper", status);
return;
}
sqlite3_result_text16(p, zOutput, -1, xFree);
sqlite3_result_text16(p, zOutput, nOut, xFree);
}
/*

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