Compare commits

...

522 Commits

Author SHA1 Message Date
dan 4a372fa888 Fix OOM handling in sqlite3NestedParse().
FossilOrigin-Name: e6e9dd5c17405a3e5547076d4004455621a318de46233312557ed9e48ebc821d
2019-02-21 18:11:12 +00:00
drh dbdddc99d8 Detect oversized strings in the OP_String opcode even if the P4 argument
is originally UTF8 and has to be converted to UTF16 to match the database
file and that conversion causes the string to become shorter and cross
below SQLITE_LIMIT_LENGTH threshold.  This might fix an OSSFuzz problem
that we have been so far unable to reproduce.

FossilOrigin-Name: c13d563925db12bc2c91ff9432050261e5bd39d960e2739777a66bf804df2e31
2019-02-21 16:41:34 +00:00
drh 6a1bfc9a6d Changes to the unix VFS that allegedly enable it to build of Fuchsia.
We have no way of testing this.

FossilOrigin-Name: be21a6416d47ff7db995006a0422b745044d9b8bb5bad3c53342aa6e2e524771
2019-02-20 19:20:16 +00:00
drh 7e85e9033f Disable unix-specific features of dbfuzz2 when compiling on windows.
FossilOrigin-Name: af84774d1eebcfe6a61b564b4edf280ad3c3a93f39b7f70b6fcc56f7bbdfb9eb
2019-02-20 19:06:16 +00:00
drh 8cf92890f2 Avoid the use of function pointers in columnName(), as function pointers
appear to be a source of consternation to LLVM.

FossilOrigin-Name: c48f6f39c5f89a338fed7153553a27a5d882d4d8db8221e911b96e0dd57c53d9
2019-02-20 18:13:57 +00:00
drh b1af9c603c Progress handler improvements:
(1) Invoke the callback after OP_Program opcodes
(2) Invoke the callback multiple times in a row to catch up after a
long run of no progress checks.

FossilOrigin-Name: 0c5db18d79366d9c23925ce3ed835500311f32a10aa7dbfdd09148b1e8a2507b
2019-02-20 13:55:45 +00:00
drh 042666e4fa When an IN operator drives a query loop, mark it as "CODED" so that it
will not be used afterwards for a (pointless) membership test.  This is
a better fix for ticket [df46dfb631f75694] than the previous fix that is
now on a branch as it preserves the full optimization of
check-in [e130319317e76119].

FossilOrigin-Name: fa792714ae62fa980f1767acc6d622a6727ceb677870243c88548423795dcb5b
2019-02-20 12:52:47 +00:00
drh 2a98b586c8 Enhance the xBestIndex method on delta_parse() to return SQLITE_CONSTRAINT if
no delta argument is supplied.

FossilOrigin-Name: f16d127c3b4a735afae1fc236bcf90f31adff079c7d3a896f901d908ff8b8532
2019-02-19 20:29:05 +00:00
drh 2d441ce3f3 Add the delta_parse(DELTA) table-valued function to the fossildelta
extension.

FossilOrigin-Name: d91fcc267bf1be795dfdb1fbfb40c2aea79ddff247a51d26462136c325b7a6d3
2019-02-19 20:19:51 +00:00
drh 4bec44bdfa Add the fossildelta.c extension in ext/misc with implementations of the Fossil
delta functions.

FossilOrigin-Name: b80cafa6f8a5c6ff1dc9efd2f670777ab131ace2df1eb431cedc8cfa901baf18
2019-02-19 18:39:16 +00:00
drh 6d7f18d60c Fix a potential memory leak in RBU if the rbu_fossil_delta() SQL function is
misused.  Misuse never happens in a working RBU system, so this is not a 
particularly important fix.

FossilOrigin-Name: 12517d1b15da46bc90bd95bb9c161d7f2ecdd7f28b1b3a5ed4397939ef986061
2019-02-19 17:45:31 +00:00
drh 12fe9a0d25 Fix an assert() that might not be true if the database file is corrupt.
FossilOrigin-Name: f2d400db4dbfb05e2540178ed3662f97f8c57a95f8129886c7081c35e53adf0d
2019-02-19 16:42:54 +00:00
drh 3cbd2b7245 New assert() to verify the TF_HasprimaryKey flag.
FossilOrigin-Name: 0abace8a7aecca01c8677d07f3ec1bafb289ceffe5bcd60284701a7bf813f415
2019-02-19 13:51:58 +00:00
drh 9df385ec3d Always use the symbolic name SQLITE_IDXTYPE_PRIMARYKEY rather than a hard-coded
magic number 2.

FossilOrigin-Name: 55d43adc894a6b1e0f77bf481dad6dd604a0dc0022e72bbf2e3037f97351971e
2019-02-19 13:08:35 +00:00
drh b43ac0021f Fix an assert() that might not be true if the %_segdir table of FTS3 contains
corrupt entries.

FossilOrigin-Name: a6509ca3dc2602c7d0376230ee63c1bb4c4066f007e77e9ac20d8eee966e5e13
2019-02-18 12:16:03 +00:00
drh 56785a0a80 Fix an assert() that might be false for a corrupt database.
FossilOrigin-Name: 0cfb888723fb8ff0763bbc23acb7d21a53f6d1c40661d8468248644281b29d85
2019-02-16 22:45:55 +00:00
drh 9c7e44cddd Improved oversized cell detection when updating ptrmap pages in
balance_nonroot().

FossilOrigin-Name: aa61435a4c3800f023788081c1342ad6a05a41449a424fa6c039d5ca46072256
2019-02-14 15:27:12 +00:00
drh 82642f815b Ensure that the nProgressLimit variable is always initialized in
sqlite3VdbeExec(), even if the routine jumps to its exit processing early.

FossilOrigin-Name: 167b91df77fff1a84791f6ab5f72239b90475475be690a838248119b6dd312f0
2019-02-12 22:58:32 +00:00
drh c332e04310 Enhancement the progress callback mechanism so that the progress callback
is always invoked at least once at the end of a prepared statement if the 
opcode count has been exceeded.  This makes the progress callback more
effective at limiting run times.  This check-in also includes and unrelated
performance enhancement to OP_Column.

FossilOrigin-Name: 68cce272e7f7cbc0c319ee8b7ff674d652cb1e95e903d99d848c41dff2b5d304
2019-02-12 21:04:33 +00:00
drh 5860a61d59 Further performance improvements to btreeInitPage().
FossilOrigin-Name: 93ae382e97c23c90312739481e47ef7f9bc475a8382c063a2de2986c950c0aec
2019-02-12 16:58:26 +00:00
drh 83acc14ad4 Increase the version number to 3.28.0 for the next release cycle.
FossilOrigin-Name: 6eb38c59a81d27b7c1f3edad84b27a1114df6f1607282b2be1b5de9c7decc512
2019-02-12 15:51:36 +00:00
drh f9101623a3 Register the "vfsstat" virtual table immediately when loading the vfsstat.c
extension.

FossilOrigin-Name: 9bd92afd0cb0a958441e861c7006b77027125b1ceea0868958ec948b6b3c7bc9
2019-02-12 12:25:34 +00:00
drh 62e009f3d8 New test cases in test/fuzzdata8.db.
FossilOrigin-Name: ab2356f580384e4b40d128fc04fd6bc4dfcf50109df77d05d59adcc20f339066
2019-02-12 01:28:24 +00:00
drh 3e7800a9db Defer computing the number of bytes of free space on a btree page until that
value is actually needed.

FossilOrigin-Name: 177f5f40eabfcfd229ac7f291dfed9e9ee35762e86923a0f356915f389da177d
2019-02-12 01:04:49 +00:00
drh a941ff712d Change an assert() into a NEVER(), since the condition is difficult to prove
with certainty.  Improved comment on the MemPage.nFree field.

FossilOrigin-Name: fec071b89df2cbafda365077bb54bc9999e12086f36d6cea8d125662b36638dc
2019-02-12 00:58:10 +00:00
drh 8357c662b3 Do not invoke btreeComputeFreeSpace() when not necessary.
FossilOrigin-Name: f11b0ed47402034378ded2c60b82841b81cd1319cdb72d1ef052faef29a5294d
2019-02-11 22:50:01 +00:00
drh d4a6744b50 Improvements to comments. No changes to code.
FossilOrigin-Name: 16eb0fc8f8cce51eaa5305ebc9f3bd8c8d935dd3ebebab6820e5629f9292eec2
2019-02-11 19:27:36 +00:00
drh 6813350966 Fix test cases. Avoid unnecessary tests for MemPage.nFree less than zero.
FossilOrigin-Name: 480a5090befdc29eaeb6f0b22831c980d6ee92438d9b2e766de68b037ded38b8
2019-02-11 17:22:30 +00:00
dan 43a6e4d3df Fix another segfault that could occur in fts5 with a corrupted database.
FossilOrigin-Name: 09e337386beb2008eba969f79601d1b8ed953951ce6e43782586e168140d78d2
2019-02-11 16:12:09 +00:00
dan 47a30159e5 Fix typos in comments in fts5.h. No changes to code.
FossilOrigin-Name: c19e97bc927074915a3ac8307bf89d30580cf90edd75f4001bcf589b2dfefe58
2019-02-11 13:25:33 +00:00
drh c01f41cfa6 Updates to a comment to keep it in alignment to the changes on this branch.
FossilOrigin-Name: 7499f74351415e601eb48eff6b6fccd3a78d137f5ea9cd7cac46b904772966de
2019-02-11 12:51:39 +00:00
dan 8cd2e4ae03 Build and test fixes for SQLITE_OMIT_WINDOWFUNC builds.
FossilOrigin-Name: 8824115a9776e876a3677f0cb479e311ee65584d43872b37766a146afec72d8f
2019-02-11 11:34:01 +00:00
dan 3fd7eaf3f2 Avoid using non-ANSI return statement in void function sqlite3WalSnapshotUnlock().
FossilOrigin-Name: 4a4952d38e8177ed8d59aaa575410bebf76787dd6d801fdbdb809d4f8c670da0
2019-02-11 11:04:17 +00:00
drh f0c48b1cd8 Add an assert() in an attempt to repro an ASAN warning from OSSFuzz.
FossilOrigin-Name: 7b41222428dcebaae2e9a0e8192e091b6fdee5b1163a5fa14ca1cd4f06354983
2019-02-11 01:58:34 +00:00
drh 85a379b74b Fix a page-cache reference leak in the btree balancer when there is a corrupt
database.

FossilOrigin-Name: 9285899120dec24ff2944431ad455d7ae217ef408ae2f1a3e7bdfb897099028c
2019-02-09 22:33:44 +00:00
drh b0ea9432a1 Defer computing the MemPage.nFree value of an in-memory btree page
until it is actually needed, since for many pages it is never needed.
This checkin works sufficiently to prove the concept, but still has issues
with exception handling.

FossilOrigin-Name: 1d43ee4000b71f5c6d49244dee96358c567f09ba3451b9d22895a796d3f61ad6
2019-02-09 21:06:40 +00:00
dan 2fa619a3a8 Change a few assert() statements in fts3 that might fail if the database is corrupt.
FossilOrigin-Name: db74a56af73d92b7a9d43ceda7e4540915c580c68a0266b4ddefb9e0d5cbcbeb
2019-02-09 19:23:54 +00:00
drh 298f45c641 Small performance improvement and size reduction for pageFindSlot() - the
routine in btree.c that locates a free slot for a cell on a btree page.

FossilOrigin-Name: 1969372ac72d25cc642a0268f4bb0ae4b59f2dca568c119ef61b67183b3a8bd9
2019-02-08 22:34:59 +00:00
drh 16d7e87caa Further simplifications to sqlite3VdbeMemSetStr().
FossilOrigin-Name: 1d212957079a2caa30f3c9d80f43464781bc9634c2b5181a5814efbddae31711
2019-02-08 17:28:20 +00:00
drh 6ff7427733 Change the sqlite3VdbeMemGrow() routine so that it no longer guarantees a
minimum size of 32 bytes.  That minimum is no longer required, and without
the extra check for the minimum size, the routine runs faster.

FossilOrigin-Name: 5c499da8a4d0babc56883aa362ae124772fd9214a51169a88a5dee523d051658
2019-02-08 15:59:20 +00:00
drh 1cf197583d Give the sqlite3 object a pointer to the current Parse so that if an OOM
occurs, it can automatically set the Parse.rc value to SQLITE_NOMEM.  This
avoids a frequent extra test of db.mallocFailed in the innermost parser loop.

FossilOrigin-Name: 5c6638040b3017c6be016441422d965a3ca00dd6ae1f78cadc0b54562978f64e
2019-02-08 14:55:30 +00:00
drh 8851e10017 Do not do the optimization that attempts to pull expression values from
an index on that expression when processing a multi-index OR
(see check-in [a47efb7c8520a0111]) because the expression transformations
that are applied become invalid when the processing moves off of the current
index and on to the next index.  Fix for ticket [4e8e4857d32d401f].

FossilOrigin-Name: 440a7cda000164d3b46109caf2e1dde80681ba9b0d94ba9be6847d2b917445cf
2019-02-08 04:15:19 +00:00
drh 1e30c7f369 Change VACUUM so that it preserves ROWID values.
FossilOrigin-Name: 49e5d11d463de078c2b8a963f5ed436210937e6dfddf06942132db9ec685bfd8
2019-02-07 19:07:11 +00:00
drh c9912d1706 Version 3.27.0
FossilOrigin-Name: 97744701c3bd414e6c9d7182639d8c2ce7cf124c4fce625071ae65658ac61713
2019-02-07 17:02:52 +00:00
drh 24bfecab3c Experimental change to VACUUM so that it preserves existing ROWID values.
FossilOrigin-Name: f264015f84de51d74f681ba62a5f26bd859480d93e1eaf9e1018b3e9b4e0bea3
2019-02-07 15:09:44 +00:00
drh af63892337 In the fuzzcheck test program, make sure the isspace() and related routines
are not given values outside the range of -1 to 255.

FossilOrigin-Name: f298328771d5aaba798d05f50c77ac239c7c72422ff35953463d6876a9659f74
2019-02-07 00:17:36 +00:00
dan e385d33a29 Ensure all bytes of the PgHdr1 structure are initialized. This avoids a valgrind error when running corruptI.test.
FossilOrigin-Name: a505e34d4ec31159a4508ec827fcffed0cf3bd5ea5ef0ac293016da02367a53a
2019-02-06 20:49:49 +00:00
dan 922b35801d Update an assert() in test_journal.c to take the new "VACUUM INTO" functionality into account.
FossilOrigin-Name: 0e6249cb958a40ead0edf6e75a2c46e8657db3d358c5fe78a9dc0fa5ed7ad929
2019-02-06 20:12:00 +00:00
dan 9c5f734339 Avoid attempting to delete a file while it is still open in walfault2.test.
FossilOrigin-Name: 9d54a63d6e3cd47b483cf0ee868a5e7f638bcb0e3cbdeaecc667f293b87a3e99
2019-02-06 19:42:02 +00:00
dan 6e08c4a5e6 Update test file dbfuzz001.test so that it works with SQLITE_ENABLE_OVERSIZE_CELL_CHECK builds.
FossilOrigin-Name: 4371a0c46ee7bfbc0a1507796bd9eefd3371adad81b8dda214d018854316727b
2019-02-06 18:08:42 +00:00
dan 531230d006 Add -DSQLITE_ENABLE_DESERIALIZE to the default testing configuration in test/releasetest.tcl.
FossilOrigin-Name: 433d6ef637a10ee017b5d8cadd125a162cfedc9895ae862b8dde6dddb7eda59b
2019-02-06 15:23:43 +00:00
dan fbf6136c78 Do not attempt to test the shell ".trace" command in SQLITE_OMIT_TRACE builds.
FossilOrigin-Name: 3839e9098107604e1526c2b1e813c019607077dfe39d7eeb92f3466518dec3b1
2019-02-06 13:48:04 +00:00
dan 871b13492d Fix a problem preventing testfixture from being built with SQLITE_OMIT_VIRTUALTABLE.
FossilOrigin-Name: d2cca36adc69d2c8e7707d70cbd75c497eae6a1a3f8a9dd18249ca6804c9db5f
2019-02-06 13:41:19 +00:00
drh d0ee3a1e6d When extending the size of SrcList objects, do not attempt to use
extra space on the end of the allocation, as that provides scarcely any
performance benefit but does greatly complicate cross-platform testing.

FossilOrigin-Name: 3087a0c31e9fbfaedb7cf10a2fda59bc22318ff178614aefcc00ac83d9a7bb14
2019-02-06 01:18:36 +00:00
drh 4acd754c79 If the query flattener detects an error, cause the SELECT code generator
to abort immediately.

FossilOrigin-Name: 3d3b142f1045080beb775a9cfe88ec143aa460750132e20059fd510291449850
2019-02-06 00:55:47 +00:00
drh 01996dae49 Back out check-in [008112bcef561a8], reenabling deprecated PRAGMAs when the
SQLITE_OMIT_DEPRECATED compile-time option is used, because way too many
TH3 tests depend on those deprecated PRAGMAs.

FossilOrigin-Name: 9dbf512d1c4627a28d60f4e7238cb100d7a4e11f976139b07ad1c59e9b584c7d
2019-02-06 00:11:13 +00:00
drh 569b1d9119 Omit the ".progress" command from the shell if it is compiled with the
SQLITE_OMIT_PROGRESS_CALLBACK option.

FossilOrigin-Name: 4d0a949fd92e19fbf243a2e3a1a7c2cdb111f9a6943949d2420dd846bc7d9285
2019-02-05 20:51:41 +00:00
drh d46b6f57c9 Fix a harmless compiler warning in the memtrace.c extension.
FossilOrigin-Name: 2f468da4e9fb3edb5e902fa5d3c528726d1fb64d749d29e558ba3243c76bcb95
2019-02-05 19:52:39 +00:00
drh fc4eeef9e7 Fix compiler warnings on Windows.
FossilOrigin-Name: 4978ee8b5405f958723b4ebbd4288bd08bff2b453da2d1c032d1ae904c2a3821
2019-02-05 19:48:46 +00:00
dan dee9be9b3b Update the tester.tcl --malloctrace option so that it uses eu-addr2line instead of addr2line.
FossilOrigin-Name: 79c073878d56fc638b751b0e61295df182f7ee6f8ebd7319c1eeac1608abbac8
2019-02-05 16:53:26 +00:00
drh d57936721b The IS NOT NULL operator does not imply that the operand is never NULL.
Fix for ticket [5948e09b8c415bc45da5cf]

FossilOrigin-Name: d840e9bb023a1e84a7739d764a0f6cf608fc3183ff8c366fcdb486ebd932f0c1
2019-02-05 14:36:33 +00:00
drh 24545d2300 Keep the temp_store_directory and data_store_directory pragmas even when
compiling with SQLITE_OMIT_DEPRECATED.

FossilOrigin-Name: 93386a7c97f27df69f79052ef4d80143bb6832a806885249c315d226b2a256b2
2019-02-05 12:16:53 +00:00
dan 41e0717bcb Update test file "resetdb.test" so that it works with the "prepare" permutation.
FossilOrigin-Name: 95d338124be2e0e18f17354b28f4320336202f1a4ec1177df753b2800e954bfb
2019-02-05 08:55:43 +00:00
drh 53d30dd371 Early detection of implausibly sized records to avoid unnecessary
large memory allocations.

FossilOrigin-Name: 2c8769c69f301307db6663adb8b7c0b89f5959516bf6110cb8ff4b21bd903f70
2019-02-04 21:10:24 +00:00
drh af48257bc9 Mention the new -memtrace command-line option in the -help output of the CLI.
FossilOrigin-Name: ada91aefe37efe3c009691b5599e4d6acf182e5ec3cf28dda0871d09858498b3
2019-02-04 19:52:39 +00:00
drh a790882d63 Add the -memtrace option to dbfuzz2.
FossilOrigin-Name: 67fecbc79d3e927a7e22f3589be3184114322635874e4b3170666e352d0bfe9d
2019-02-04 19:50:44 +00:00
drh 88862d49a6 Enhance dbfuzz2 so that with the -v option it shows the return code and
error message for any failing SQL statements.

FossilOrigin-Name: 3a127ef9f7feafe6ba8c75e4eb29e28aa61a30249082cc8767ada1ec0cc0b7f1
2019-02-04 19:45:26 +00:00
drh f2305414cd Ensure that the sqlite3_exec() callback gets the correct number of columns
for a query, even if the schema changes out from under it.

FossilOrigin-Name: a16ffb5a4b30f1ac4a8384fccde0a0f69e49545b6f9be9267928609328c4a151
2019-02-04 19:12:54 +00:00
dan 4fc4ba771c Do not run shmlock.test as part of the inmemory_journal permutation.
FossilOrigin-Name: d3fea69cbb071867a90ad56ca05123ebf8e44689a92577a525a883c176c791bd
2019-02-04 16:42:57 +00:00
drh e2d2ad6ece Update the test/fuzzdata8.db database with new interesting cases from
dbsqlfuzz.

FossilOrigin-Name: e467e4c8fa256ddd6c26c1f21bc26289a21f18b781737eaf706bc813ed8234fa
2019-02-04 16:36:24 +00:00
dan 83a635a267 Fix problems with SAVEPOINT and related commands within transactions on a corrupt database that include fts5 or some other virtual tables.
FossilOrigin-Name: b0da6e0dd1f9a9ba7646ee6bb3c14945e570303c9a42d20fa8a653570e12c3f9
2019-02-04 16:25:40 +00:00
drh 3f83f59154 Add the ".progress" command to the CLI.
FossilOrigin-Name: ad84ca24ff760f7a2b128f2eeb4d799a97f84b8b8a8bb8d9657c4c555f6ccf47
2019-02-04 14:53:18 +00:00
dan 0062ddd4c9 Fix another potential buffer overread in fts5.
FossilOrigin-Name: 14fba4cc5db2bc206f024bfa5dd82fffdbc7577162da2c3b15a91cc1c91f3846
2019-02-04 14:00:20 +00:00
dan 81f44cdbfb Fix another corruption case in fts5.
FossilOrigin-Name: e608085d3f7e3cc0015fde626e205ee9842ef3cd06dc879fbbc7f2067c592965
2019-02-04 11:54:22 +00:00
dan 41fc545147 Fix an assertion failure in fts3 triggered by a corrupt database.
FossilOrigin-Name: 560ebd4269fad07b8e988d070454017123593eb6762597d08e8c32d7b4fb92ac
2019-02-03 07:46:07 +00:00
drh 150edadf58 New testcase added to test/fuzzdata8.db.
FossilOrigin-Name: 2f5c1925b94d85489533549c58191feb1d803ad9d58b43f47fef42b72c531a38
2019-02-02 18:24:28 +00:00
drh e5989723ba Honor key query parameters for SEE on the URI filename for ATTACH
and VACUUM INTO.

FossilOrigin-Name: 2e01096b8933a2315e3dffcd7d0de84c744c1b4be1d909388c61f0fd636ddb99
2019-02-02 15:59:49 +00:00
drh 9b2bd91d9a Give a link to the URI Filename document in the documentation to the
various sqlite3_uri_parameter() interfaces.

FossilOrigin-Name: 69b0b2ee536fda8975f60643f7f1891db4649958aca476822ea2a632ce731992
2019-02-02 15:05:25 +00:00
dan 8f5b14a5c2 Fix a buffer overread in fts5 debugging scalar function fts5_decode().
FossilOrigin-Name: 54f2399fb2a626602d405c857297f2da833f9f048cbc478f9110bed2e9bda299
2019-02-02 13:47:25 +00:00
mistachkin 844b900491 Fix harmless compiler warning.
FossilOrigin-Name: dddda685f3443d8a38901f758543fcde73d7b8cfe72b0ad5f419cd7459343bf5
2019-02-02 01:27:45 +00:00
drh 7ba03ea15a Slight adjustment to the printf formatter large memory allocation detector
so that it does not overestimate the amount of space needed for
oversize %d conversions.

FossilOrigin-Name: 1aee70d6de8a9b17ebb74a7cb1dad65139cde1b615dcce4d15d3a476fda8676b
2019-02-01 21:08:27 +00:00
drh 2964225247 Prevent the printf formatter from doing large memory allocations - larger
than either the size of the static buffer for interfaces like
sqlite3_snprintf(), or larger than SQLITE_LIMIT_LENGTH for interfaces that
are associated with a database connection.  This helps to prevent DOS
attacks on products that let hostile sources inject arbitrary SQL.  It also
helps fuzzers run faster and more effectively.

FossilOrigin-Name: 179e5d46054e5c86f53a79b7a0823d9a383da8391ad1d3c3b22645927a1e052b
2019-02-01 20:29:04 +00:00
drh 9a6d01bff5 Performance improvement in the parsing of options to %-formats in the
printf implementation.

FossilOrigin-Name: 40d8f8ae87abf928542c4e558a4c3a3eab18776a3e8db7ca1c5e5f744ca0bce3
2019-02-01 18:46:41 +00:00
drh 9c46c66c46 Ensure that the Walker.pParse structure is initialized when walking the
source tree to gather the WINDOW clauses on a query with window functions.

FossilOrigin-Name: 4ca9d5d53d41d08fbce29f9da8cc0948df9c4c3136210af88b499cf889b5ccb8
2019-02-01 15:06:27 +00:00
drh 38a28a7434 New test cases added to test/fuzzdata8.db.
FossilOrigin-Name: e5924939c9c8f39367900360fa294cdb1220e9f68d183e32882e0926f775869d
2019-02-01 14:54:18 +00:00
drh 26b7ec8b24 Improve the strict enforcement of cell sizes in balancing from
check-in [12713f320b2c1def] so that it also works with table-btrees
in addition to index-btrees.

FossilOrigin-Name: ef27e7a08728aa7447ae19812803ac5c4a9d80c97541014bd292485792005a3e
2019-02-01 14:50:43 +00:00
dan 1c7d389a23 Fix an assert() in fts5 that could fail if the database is corrupt.
FossilOrigin-Name: 55f06aa3f890dc1dc5c2ed0e6777e46d609a6f9d223d1d4b5813097ce4f4e797
2019-02-01 14:40:44 +00:00
dan abd7449478 Fix another corrupt-database-handling problem in fts5.
FossilOrigin-Name: 9876ae1b802a449aacbbdd42778653edc19e29315dc627c23ab7493d6492c800
2019-02-01 13:34:00 +00:00
drh 3bf0d7a881 Remove an incorrect assert() from the deserialize in-memory database VFS.
FossilOrigin-Name: 80151d7e3b9fd84086874a1cebed024b9e14005ea2d0108cf6efcd07373fcf51
2019-01-31 16:09:48 +00:00
drh 23a885956e Add the SQLITE_CONFIG_MEMDB_MAXSIZE configuration option for configuring
the default maximum size of an in-memory database created using
sqlite3_deserialize().  This is necessary to make the interface reasonably
testable.

FossilOrigin-Name: cb72ee0478ce98c48aae059fd5de4e36caf2b8c953e08fcb799bfd119ad46b73
2019-01-31 15:38:53 +00:00
dan b92b019fe3 Fix another buffer overrun that could occur when quering a corrupt database using an fts5vocab table.
FossilOrigin-Name: b80119bd6044c0993210115732b6ae7b4b0b29c1471b0723bef24f2052c8e671
2019-01-31 14:37:18 +00:00
drh 6a0db87a2f If the amalgamation file "sqlite3.c" is generated using the
SQLITE_ENABLE_UPDATE_DELETE_LIMIT option, but then subsequently (mis-)compiled
without that option, and then a particular syntax error could cause
a memory leak, but for this fix.

FossilOrigin-Name: 1bb17c863a269ab8b28df94b9fdaac3ee70777ccd0a30300131bf67df6722052
2019-01-31 02:42:47 +00:00
drh 9b747068ba Improvements to "PRAGMA parser_trace=ON": Make it a flag pragma, and then
use the flag to show the complete SQL text at the beginning of the parse.

FossilOrigin-Name: 507c43537f00d089efb3c3020fb6e826e8f89f3efa2caaa12c5309d35dd0c22e
2019-01-31 01:39:01 +00:00
drh 8bf4126c84 Change the error message slightly for when two or more indexes have the
same rootpage.

FossilOrigin-Name: 916c52dad414b224695d455a42af36f85dff216504c2aa67d1d2c5818cdca8d6
2019-01-30 19:50:07 +00:00
dan da7a4c0f7a When parsing the schema, check for duplicate index root page numbers before adding the index to the schema hash table.
FossilOrigin-Name: 6b360bc0b9ad18ccda9d58d43a8388d19999432bfdf294abcf5beb44ef990cb4
2019-01-30 19:12:13 +00:00
dan 56b99ebc32 Add test case for the previous commit.
FossilOrigin-Name: 197edb235b785c68fda7be788efbc61137d9452886599415a927b959ade93c65
2019-01-30 18:47:35 +00:00
drh 8d40673c84 Detect if two indexes of the same table share a common rootpage while
parsing the schema, and throw an error immediately.

FossilOrigin-Name: f21c6f1343edc4ba68f9f8e68caac34da0d1c651526ecaf61c0e2d66593a555e
2019-01-30 18:33:33 +00:00
drh ba7bd02002 Fix an off-by-one error when parsing the names of indexes that do not have
arguments in the index_usage utility.

FossilOrigin-Name: dc794d8f518ed46536928a77a560d46e4f9365c30a00cd108f000d8556a66c00
2019-01-30 16:58:04 +00:00
drh a8614259c1 Add the --progress, --using, and -q options to the index_usage utility program.
FossilOrigin-Name: a5e6be7cbc5d931308ddcc073c9cd6275c9711cae055d72a7c4aa71c1d15914c
2019-01-30 15:47:38 +00:00
drh 5a9c6bcc15 Enhancements to the index_usage utility program.
FossilOrigin-Name: 19c739b4a8a43d894e37a99fa34838f3e3fa1fe0d019aefbc33f1d38d76af1a4
2019-01-30 14:01:43 +00:00
dan dd579233e8 Fix another buffer overread in fts5 that may occur when accessing a corrupt database.
FossilOrigin-Name: 760d14374d40bcd9ce3a89771c18dc236c9728553c4747c9b7452ee7b24f4140
2019-01-30 12:15:27 +00:00
drh 3f4f6823ac Fix harmless compiler warnings.
FossilOrigin-Name: 9a93c68a7673bda2e6c308d3b2798d0fb12fde399996cae24b1f0d5864adf355
2019-01-29 16:54:31 +00:00
drh 4551005332 Load all the latest dbsqlfuzz finds into test/fuzzdata8.db.
FossilOrigin-Name: e744d2dd93a78235e6c1d938b08232183b5ce7e355d1b7daf2199e585b03c106
2019-01-29 16:47:46 +00:00
drh a046643820 More robust handling of corrupt database file in the rebalance operation of
the btree logic.

FossilOrigin-Name: 97704cb7d29fa7cc4ea9a6761a7844c1946d637ea2b22d287fc787ae0f63c407
2019-01-29 16:41:13 +00:00
dan e25646d64c Avoid an integer overflow in the fts5 snippet() function triggered by a corrupt database record.
FossilOrigin-Name: 7c862c4655841e1263cf548d01f5b4331685ab7d396494891cad0a5f50c63e16
2019-01-29 16:34:45 +00:00
dan eb2ed10ec0 Avoid a crash when the fts5 snippet() function (or similar) is used with a special query pattern, like '*id' or '*reads'.
FossilOrigin-Name: 9d58a15737f7379fed724749cfd5b4de5b44231870e99fc664683ad483c3e6ba
2019-01-29 15:30:03 +00:00
dan 3993397e6c Fix a buffer overrun triggered by a merge operation on a corrupt fts5 database.
FossilOrigin-Name: 7ee3cd5b2cdf8db35f70400b3df58f7c421c78ae77c50f22b0ee22d5a3039429
2019-01-29 11:42:43 +00:00
drh 4a7e9a25b6 Set a low limit on the length of strings and blobs in the OSSFuzz module,
in an effort to avoid timeouts when the fuzzer does things like
"randomblob(1e12)".

FossilOrigin-Name: 119d1609fa415894fdd0aa19440ca1c658bd01910838a4cfadbe0e304b033bfd
2019-01-29 02:37:22 +00:00
drh 3967d946c7 Fix the query planner so that it is able to use an index on a CAST expression.
FossilOrigin-Name: 2c886f3d49c9569e9f6ee28b89b57e2d4004c8972d11da0c23f7b2d2e0c9900a
2019-01-28 19:06:17 +00:00
drh e86974c619 Fix a performance regression caused by the previous commit.
FossilOrigin-Name: c4db0ad12d4f3d2800d36404f391b325cdc4aa7f8dcea93b2d63a489d9095ad4
2019-01-28 18:58:54 +00:00
dan 95d5a88058 Make indexes on CAST(...) expressions work.
FossilOrigin-Name: 3ef711d98fb239cf24472f124e7b36b0dde33355de5a2c9a3a978bbdd042a735
2019-01-28 18:08:59 +00:00
dan c7def600bd Fix a buffer overread in fts3 that could occur when accessing a corrupt database.
FossilOrigin-Name: a9faf9033910927c74553e66c474d84ed3386f263cef3eec299e25d8306f410d
2019-01-28 16:50:42 +00:00
dan 6c43dbad98 Do not assume that text parameters passed to fts4aux queries do not contain embedded nul characters.
FossilOrigin-Name: df04859a995571cd6faf1abe088725708f35e81195760274df9e2ec9bd47f69f
2019-01-28 13:27:25 +00:00
drh 9e35a61e59 Add a new test case to fuzzdata8.db.
FossilOrigin-Name: ce8e279a7d37594e865c2d9197a5efe5d647e11f074dbaf4a4ee31c74c71dbc9
2019-01-28 11:54:13 +00:00
drh 0c873bf28a Change the definition of the BtCursor.skipNext field so that it is undefined
for states CURSOR_VALID and CURSOR_INVALID.

FossilOrigin-Name: 6089d5dba73437d787259033e94a38cf1b0c87cac4a89c27e69d8239c22f496e
2019-01-28 00:42:06 +00:00
drh c07eee7a50 Improvements to the ".eqp trace" command in the CLI so that it ensures that
the schema has been read prior to activing the tracing feature, to avoid
cluttering the output with a trace of the schema parse.

FossilOrigin-Name: 42687d45aa1a2b2a32ddfc5711b4ae9cf76b8cfbeb20b57d6705ecaf5824fcb6
2019-01-27 19:50:56 +00:00
drh 05d49d1442 New test cases form dbsqlfuzz
FossilOrigin-Name: 9cf8ebd141aa2eb661d457624c76433bd9e4abfdef04aa52e28bc169172c2c8f
2019-01-27 02:45:32 +00:00
drh 211a0857b9 Window functions that can abort should indicate this, so that if they are
used in DML statement, a statement journal will be used.

FossilOrigin-Name: 0ea05a0eb96acb860d8af2e788e29a5ae3b161e7892ab62f1ff2f3e722c0dcb6
2019-01-27 02:41:34 +00:00
drh e5da9356e0 Update fuzzcheck so that with the --load-dbsql options it screens its
inputs to ensure that they are valid dbsqlfuzz cases.  Add new dbsqlfuzz
finds to the test/fuzzdata8.db database.

FossilOrigin-Name: 004f7d9bbeee049c22a7e1c82c6cc0ea79a237967de3ff57686acea3060d5f45
2019-01-27 01:11:40 +00:00
drh e6a9efb976 Ensure that the btree cursor is correctly set up prior to backing it up
as part of a delete operation on a divider cell in an index.

FossilOrigin-Name: a3ea1a822d3a110f4f186f2fc8550f435c8c98635d058096b7be9d4df7066b8b
2019-01-26 23:34:50 +00:00
dan 32bb700a95 Fix a broken assert() in fts3. Also some test script issues causing failures with builds that do not support fts3.
FossilOrigin-Name: d59567dda231e7ffec437d5e055676cf42d791196406cdc696cafa2583eb483b
2019-01-26 21:05:54 +00:00
drh b4e5039316 Add the ".eqp trace" command to the CLI when using SQLITE_DEBUG, as a
convenient shorthand for "PRAGMA vdbe_debug=ON" but with automatic indentation
feature for program listings provided by the CLI.

FossilOrigin-Name: 626502faa17b5b7a0fa36cabfd12e463eb09aec048d01c587a18d3977cf04662
2019-01-26 15:40:04 +00:00
drh 0814acd981 Do not accidently truncate zeroblob values when doing an arithmetic
operation.  Fix for ticket [bb4bdb9f7f654b0bb9f34cfba].

FossilOrigin-Name: 13f6942eb0da2d92a0830f18640ce64208bd0cd6ff6d0c97e4a4c57ac3d65ba6
2019-01-25 20:09:04 +00:00
drh b2e61bc66b Reinitialize debugging information on registers of a trigger prior to each
invocation of the trigger.  This prevents false-positives from the
sqlite3VdbeMemAboutToChange() test logic.

FossilOrigin-Name: 98b3b97573ccb3d986d1552f97f96e15088a598945923adcac77010c1e8b7fe4
2019-01-25 19:29:01 +00:00
drh f69af053dc Fix harmless compiler warnings.
FossilOrigin-Name: 3ff220ad378d547538b4501e6b2201e835a2c66891e5e40856db377c101a50e5
2019-01-25 18:17:37 +00:00
drh 0578084507 Fix the assert_fts3_nc() macro so that it works for test builds that omit
SQLITE_DEBUG.

FossilOrigin-Name: b10df2b569e356551cf51ca179f307e4f8827413ee9feb886db1f1e0650e6c5f
2019-01-25 18:17:03 +00:00
drh ed457037c4 Fix harmless compiler warnings in fuzzcheck
FossilOrigin-Name: a82539665718c8183d9d0bb7bcb3adcb1a23294b8c30f364829a982dab89a332
2019-01-25 17:51:06 +00:00
dan c2ea77e5b2 Fix a segfault that could follow an OOM when querying a table that has one or more columns with default values "true" or "false".
FossilOrigin-Name: 202f9919c222ee933924c63c15ad36ec4481457b1e4d9179af14c9f284117c0c
2019-01-25 17:26:59 +00:00
dan e88609f23e Fix asan warnings in fts5 triggered by corrupt databases - passing NULL to memcmp, out-of-range left-shift values and signed integer overflow.
FossilOrigin-Name: 93f8ec146d63af13f04e337ada4fa75e9254f72b1394df09701ae12e185f27e2
2019-01-25 16:54:06 +00:00
dan c1f6618217 Add an assert_fts3_nc() macro to fts3 - for assert() conditions that are only true when it is guaranteed that the fts3 database is not corrupt.
FossilOrigin-Name: 3498908cd7f3d0e35b70796537124e3da0bd99d48750ba51bcb9eba87e28ed4d
2019-01-25 14:48:18 +00:00
drh 31ab7d8e5c Extend fuzzcheck so that it can process dbsqlfuzz cases. Add a collection
of interesting dbsqlfuzz cases to the standard test suite.

FossilOrigin-Name: e2991a7ecf5dd241c4bab7c7cadc4901043fb0c3ea1fac70b684f6d8332677f1
2019-01-25 14:23:36 +00:00
drh 94f0a83421 Fix the xFetch method of the "memdb" VFS (used by deserialize) so that it
is robust against corrupt database file.

FossilOrigin-Name: 2c1ef40e787a6bc355b50168527a47eb09acd30d0d88cff8336a434ad554115d
2019-01-25 14:16:01 +00:00
dan ba14c69b4f Fix a couple of assert() statments in btree.c that could fail with corrupt databases.
FossilOrigin-Name: 5eb5e8289fa71e5e29e081d33d4a59c64b463bf6b06d7070c05c46d77d808ad4
2019-01-25 13:42:12 +00:00
drh 725a9c7f6c In fuzzcheck, activate vdbe_debug for dbsqlfuzz cases when using the -vvvvv
verbosity level or above.

FossilOrigin-Name: 2e6f7c2aced49824a38b3494b796a8ec73aa7a90b51159f670596df15ed1c5ab
2019-01-25 13:03:38 +00:00
drh df21659a40 Improved automatic detection of dbsqlfuzz cases in fuzzcheck.
FossilOrigin-Name: 1ef24e89c9630fd383ba32f5aefcf9c27907f27f5072f3537a1cfd75a093a8d7
2019-01-25 04:43:26 +00:00
drh a47e709e89 Add the ability to process dbsqlfuzz cases in fuzzcheck and add an initial
set of interesting dbsqlfuzz cases.

FossilOrigin-Name: fb9074ff450a67feaa62ca61d19154de26d5c8a8d147409ee6d1fbd667b2914f
2019-01-25 04:00:14 +00:00
dan 813ed78054 Fix a buffer overread in fts3 that could occur in a prefix query on a corrupted database.
FossilOrigin-Name: d0d5689371577b2861d4a9464443d055f3256f3f51d89e0388233a4cbe2601ee
2019-01-24 17:41:12 +00:00
dan f467744d5f Fix a problem with running ALTER TABLE on a schema that contains expressions of the type "col IN ()" (empty set on RHS of IN operator).
FossilOrigin-Name: 2d9cd06715092c312c8c0ec392696a0e90ed090b074e2082e0b830f1399aa941
2019-01-24 16:27:10 +00:00
drh 3cc9af2140 Omit deprecated PRAGMAs when compiling with the -DSQLITE_OMIT_DEPRECATED option.
FossilOrigin-Name: 008112bcef561a8a3ebfb007cbef36cbc0071f547e6ebdba3d3bbb39e2c48c7a
2019-01-24 16:07:18 +00:00
drh 491b6d897d Make sure the column name flags are restored correctly after an error
inside of sqlite3ResultSetOfSelect().

FossilOrigin-Name: b1601db7adba2dccd4f90fbbe5099c801a2b0d97af087fbe82ed98d05496b38c
2019-01-24 15:51:03 +00:00
dan b0c4c94996 Fix a potential problem with "INSERT INTO ... SELECT * FROM" (or VACUUM) statements on a corrupted database.
FossilOrigin-Name: db4b4c2c1e9f1adacfb1b2fedb717a4d8bb0a299c3b11835404a99fcd67bf24b
2019-01-24 15:16:17 +00:00
drh 936ade4dba Change a integer variable in sqlite3VdbeRecordUnpack() to unsigned in order
to avoid any possibility of an integer overflow.

FossilOrigin-Name: 1b536f6fd8d58800042f130842f0586aaa357841ee0d1b690a9815c865d50826
2019-01-24 14:16:20 +00:00
drh 55469bbafb Use memmove() instead of memcpy() in a place where buffers might overlap
if the database file is badly corrupted, to prevent warnings
from ASAN and valgrind.

FossilOrigin-Name: 65ad6c55f1ba9bc2f75afffa3adaf19f145fad7ac9a00ccce6372e9a2cc4341b
2019-01-24 13:36:47 +00:00
drh 6a02f237e3 Remove an unreachable branch.
FossilOrigin-Name: 4c976f171342ba2d39779279c28f3bc088572c440922e3e4421a3bf541263360
2019-01-24 04:44:54 +00:00
dan b4738ddb20 Fix an assert() in vdbemem.c that could fire if the database was corrupt.
FossilOrigin-Name: a70958cd7d5cf750c293537856918e5789013b70f6a827f724d83559b38629c8
2019-01-23 20:31:56 +00:00
dan a5f9f42a0e Fix a problem with renaming a table within a schema that contains a composite query that uses a column alias as an ORDER BY term.
FossilOrigin-Name: 2ca6b8f84ec07e313aa4e1c0894827401b418dcc4221e9c54c384f1c3893952a
2019-01-23 19:50:46 +00:00
drh e3dadac591 Stricter enforcement of cell sizes when doing balancing operations on the
btree, in order to catch file corruption sooner.

FossilOrigin-Name: 12713f320b2c1def273dd8b7833dddaaad5331aba779d4b1ec9aa949814f38fe
2019-01-23 19:25:59 +00:00
dan f8f47dd8c5 Fix another fts5 crash that can occur if the database is corrupted.
FossilOrigin-Name: 44ce8baa47192be03c8f11777904c3c07fa5cc5c97b6d8e81572d380995ac688
2019-01-23 19:17:05 +00:00
dan d99950310f Fix problems with sub-selects in WINDOW definitions. Also rename-column operations when the column being renamed appears in a WINDOW definition that is part of a VIEW or TRIGGER.
FossilOrigin-Name: 0387cb3add992b2028efe4f2100188d8f9fdfdcb233329857aa4b46a293cfc97
2019-01-23 16:59:24 +00:00
dan 4c7bdd1597 Fix a buffer overwrite triggered by a prefix query on a corrupt fts5 table.
FossilOrigin-Name: 1d8172a94bce2d067027685e5aa1dc8f5d5d55b5da0832ad2836f6939de68c8f
2019-01-23 12:19:22 +00:00
dan ccfa550922 Fix a buffer overrun that could occur in fts5 if a prefix query is made on a corrupt database.
FossilOrigin-Name: 1abc4415648e69362061e9f9a4f2c1d419ba33801999b377650d8b9a4d2d3a7c
2019-01-22 21:17:40 +00:00
dan 8e4fe01dda Do not run shmlock.test as part of the journaltest permutation.
FossilOrigin-Name: 5b7d0c784e6467154d9549af0163d788b69d5e5a6478a735834cdea945e7dbb7
2019-01-22 20:18:29 +00:00
drh c5ea2d474d Use _strdup() instead of strdup() on Windows builds of the CLI, to avoid
a compiler warning reported on the mailing list.

FossilOrigin-Name: a7126a4f4fb4e3e25be95d673323f835252bb2b427469616046a90b2acf64071
2019-01-22 16:44:59 +00:00
drh f186f0b058 Fix the SQLITE_DESERIALIZE_READONLY feature so that it does not cause
an assertion fault in the pager.

FossilOrigin-Name: b9eccef7825c61980678599358b62bc394283124653061ce163ead0c653f481d
2019-01-22 16:43:47 +00:00
drh 178edcd774 Update dbfuzz2 to set a maximum database size of 100MiB by default, but
with the new --max-db-size N option to change that limit.

FossilOrigin-Name: 21d6bb78ef2979d011b917d2d6519d7cd0009fcad83ed23ab2e9a5e02d8e51ab
2019-01-22 16:11:31 +00:00
drh 6ca644818b Enhancements to deserialize: (1) Add the SQLITE_FCNTL_SIZE_LIMIT file control
to set a maximum size for an in-memory database, defaulting to 
SQLITE_MEMDB_DEFAULT_MAXSIZE or 1GiB.  (2) Honor the SQLITE_DESERIALIZE_READONLY
flag. (3) Enhance the TCL interface to support -maxsize N and -readonly BOOLEAN.
(4) Add the --maxsize option to the ".open" command and on the command-line for
the CLI.

FossilOrigin-Name: 30f08d58882819a69e353bcc1b6b349664bbfbe00aa1c115ba44a9fd899fcc5b
2019-01-22 16:06:20 +00:00
drh 247c1b4a0b Make sure cursors are opened on all indexes for an UPDATE OR REPLACE
regardless of whether or not the indexes are partial or contain columns
that might need to be updated.

FossilOrigin-Name: e148cdad35520e6684cfeba23b003f60b55f83a6bf621aff16be8aa5612cdcee
2019-01-22 13:45:48 +00:00
dan 2c7a73eaea Fix another segfault caused by a corrupt fts3 database.
FossilOrigin-Name: ba3b8412726548a0716c1a2d67260c3b7e31956474f4cd4ce607cf2cebc667dd
2019-01-22 12:21:28 +00:00
drh 9b13365bba Ensure that a key comparison does not read a collating sequence past the
end of the KeyInfo, even if the key field of an index is corrupted by having
a string in the last column instead of the ROWID.

FossilOrigin-Name: 058a8006dceda78a894ea9446f057aa60b6d38e96506d4d91bda0ee2f9314ba3
2019-01-22 02:34:35 +00:00
drh 87c3ad4537 Enhance the btree search routine so that it does early detection of
impossibly large keys and thereby avoids a large malloc() call.

FossilOrigin-Name: 3ecaaee69f49e43d38047b7d53b82689eba7f7d33541fcac3c32b6dc8a568458
2019-01-21 23:18:22 +00:00
dan 129371553c Avoid deferencing a freed pointer following an OOM or SQLITE_CORRUPT error in
the fts3 xDestroy method.

FossilOrigin-Name: 505ed9a47825240979338a24044559613fbbd2a7850bdff70c7164da054ec63d
2019-01-21 17:57:31 +00:00
dan ac30553f76 Remove a faulty assert() from fts3.
FossilOrigin-Name: 6c33a303ebbb0f5193ead535280ba63118e14fb4f9977ce80dc716a0b082ec99
2019-01-21 16:12:20 +00:00
drh e6c628e98c Make sure the extra bytes allocated for the saved cursor position by
check-in [160b1e31c0f27257] are initialized to zero.

FossilOrigin-Name: 2737564929e86ead84a3ff6512369268198d38b46e3e02866f8ce34babc76cb9
2019-01-21 16:01:17 +00:00
drh 50b910a8b5 Add the --memtrace option to the CLI.
FossilOrigin-Name: a1e12fa2a8eb5648a96cc2d8d39899d6f87c5e2269cec7de486964c8b915e724
2019-01-21 14:55:03 +00:00
drh 7c04c69204 Minor fix the fallocate.test module change from [7cd56cad5efead5]
FossilOrigin-Name: 94fb7a47003c3c1a52e833e98d27399cfec5382afde2b3990e8223c8bff7cfa0
2019-01-21 14:49:14 +00:00
drh 5976552a72 Add the --max-data and --max-as options to dbfuzz2. Also cause dbfuzz2 to
show its maximum RSS size upon exit in standalone mode with the -v option.

FossilOrigin-Name: 7ce93e824a954d1e0cf8d7343e59a2660175f42bd4dac02aed8ad77644e7eb2f
2019-01-21 13:47:55 +00:00
drh 8ed07d1274 Add the --max-stack option to dbfuzz2.
FossilOrigin-Name: c11ae4fed89484f0a0061002861b5d599bbda8e40a1f0c33fdbe8cb072134d5c
2019-01-20 00:03:59 +00:00
dan 27a037354c Avoid a division-by-zero error in fts5 caused by a corrupt database.
FossilOrigin-Name: 928e622178bd004be52b2271ac554176aebe9d6e115ecac4e7072eccbb4262b5
2019-01-19 15:55:27 +00:00
dan b8852ae083 Remove a broken assert() triggered by a "PRAGMA max_page_count = N"
invocation, where N is larger than the number of pages in the database image,
but smaller than the number of pages in the database file.

FossilOrigin-Name: 7cd56cad5efead5097e9918c87313bb46e583fe62bae0df1be60e10117e2c3cb
2019-01-19 15:27:09 +00:00
dan 93b6c1666d Fix a problem with using ALTER TABLE to rename a table or column when the
database schema contains a trigger or view that itself contains an expression
 "<column> AND 0".

FossilOrigin-Name: 908ff7fffa302255a74e2334ca3a1779ed43acb0268fce5a83a56fd16794dc88
2019-01-19 14:07:37 +00:00
dan 225b05795f Fix a memory leak introduced by [55c5d72a].
FossilOrigin-Name: fbd681dce2905d8b8ad7948ba684b0b62d6c04be0f7a2992ee7d6836a99010de
2019-01-18 21:17:08 +00:00
dan 6e0a75a2b8 Fix a crash in the fts5vocab module caused by including a "term < NULL" term
in a WHERE clause.

FossilOrigin-Name: 9e717c4377c0116a5d36815fbc30f8b8803f14770d30be361feb27cc5b5b537b
2019-01-18 21:12:32 +00:00
dan a86b20820d Fix an infinite loop caused by a corrupt database in fts3. Also an undefined
left-shift in fts5.

FossilOrigin-Name: 55c5d72af9510e2f27c33544d804a58d4282b0efb384ead38484129ce91b574f
2019-01-18 21:03:15 +00:00
dan 4c1c79035f Avoid passing a NULL pointer to memcpy in fts5, even if the database is corrupt.
FossilOrigin-Name: acccc9808f52009b2c7794770c8b7efe2ce861fa184d32e287e7114c74e2b522
2019-01-18 20:15:02 +00:00
drh d00ad9a656 Typecasts added to the GeoPoly extension to avoid harmless UBSAN warnings.
FossilOrigin-Name: a1f6a093ac4a2de8c5b02c30fe57e09770460fd5bdddfe9c7a9a24fb83a6b491
2019-01-18 19:33:56 +00:00
dan 451297752c Fix problems causing undefined left-shift operations in the fts3 snippet()
function.

FossilOrigin-Name: b90dbaed3092236e97f9796fa63989a3648060e16189e1267c430f4a7e799fac
2019-01-18 19:26:48 +00:00
drh ed968fa4cb Avoid integer overflow when computing the array of a bounding box with
the rtree_i32 virtual table.

FossilOrigin-Name: b352f1590d20a574b0681e011ececcf4f41fa5b157503d330e03939404aca0e9
2019-01-18 18:52:17 +00:00
drh e3b89d2c5f Handle oversize floating point values carefully when converting to integers
for the '%' binary operator.

FossilOrigin-Name: 048add13fc10e69ae504a49c4663612381d928b2cf1f9cdab4ff34bd40f601a3
2019-01-18 17:53:50 +00:00
dan 0e14e98706 Fix a fairly obscure problem allowing an "ALTER TABLE RENAME col TO ..." statement to modify the schema in such a way as to break a reference within a trigger program.
FossilOrigin-Name: 64bec9e6214c6932fab5a3fb8c569ae14cd2d603bd0f8b26104815c3bb9d396a
2019-01-18 16:06:18 +00:00
drh 3cb79202f8 Use the full 64-bit integer value in the argument to randomblob().
FossilOrigin-Name: 05df5f7aeaf2132810452e8871132d1e66650a841991cb2a9ce32f2d03e20bf4
2019-01-18 14:53:15 +00:00
drh 21908b2166 Disable the xfer-optimization if the two tables have the same root page
due to schema corruption.

FossilOrigin-Name: f31b3bd2a6a8aa35a6454f37f3a4b4595e2ad74256cd180439019ab4c6c2059e
2019-01-17 20:19:35 +00:00
dan 934d4f7bac Fix another corruption related crash in fts5.
FossilOrigin-Name: 4538d9afe4e6360e20c7b474e77314e5ad293453e1edbe356bf6ea84c05857ee
2019-01-17 20:06:56 +00:00
drh aa0f2d0efa Add the SQLITE_ENABLE_EARLY_CURSOR_CLOSE compile-time option which causes
read cursors to be closed after their usefulness ends during a two-pass
UPDATE.

FossilOrigin-Name: 7def6c8edd85f19ee09038e01541f75b1f71ca39b9fb782b8f0fcac89207c353
2019-01-17 19:33:16 +00:00
dan f66da6ce8e Fix a buffer overwrite that could occur when running an fts5 prefix query
against a corrupt database.

FossilOrigin-Name: 3910b5639d5c96d1840d4feeea64d3a55073531b7365a4e75d9cda6f119f3cfc
2019-01-17 19:11:10 +00:00
dan 25fb50674f Fix problems with joining two or more fts5_vocab tables that access the same
underlying fts5 table.

FossilOrigin-Name: 49956395e14b61f6bf839e59ae7dd95eb32ebf32f3d16388844de6621b9c2d98
2019-01-17 17:39:15 +00:00
drh 29c992cb04 Revamp the SrcList allocator routines to be methods of Parse instead of
being methods of the "sqlite3" object, so that they can leave better error
messages when the SrcList object grows too large.

FossilOrigin-Name: df08d472b090b212fb77ce2aae0e1ffe79ae5db4b1accf55e6fdb18e8b0a7098
2019-01-17 15:40:41 +00:00
drh 0ad7aa8182 Limit the size of SrcList objects to 200 entries (compile-time configurable
using -DSQLITE_MAX_SRCLIST=n).  The maximum number of tables in a join has
always been 64, so this is not a real constraint on capability.  Limiting the
size of a SrcList prevents DOS attacks (discovered by OSSFuzz) using crazy
nexted CTE joins.

FossilOrigin-Name: 7cac614d5df55eb092b863163483b6782b942b21bd15fd787576fef5619fa849
2019-01-17 14:34:46 +00:00
drh 04fcef00ee Fix a corner-case for the logic that cause an insert of a NULL into an
INTEGER PRIMARY KEY column to be converted into a valid integer key,
when the NULL results from a CASE expression that lacks an ELSE clause.

FossilOrigin-Name: 9a425051e7ba59e797636f5cf32b5f6efafdb21c8d5300e099b8008b829c1439
2019-01-17 04:40:04 +00:00
drh 30fdb45da0 Ensure that the variable-length integer decoder in FTS3 never tries to
left-shift a negative number.

FossilOrigin-Name: 10ffc1fe006a1766ff2f1ffc6129786afb86b6b1f8d3a17334e8ecb838d37b9c
2019-01-17 03:43:38 +00:00
drh f20bbc5f69 Fix a failure in sqlite3ExprCompare()
FossilOrigin-Name: 835e2cc55feea2f2426c99816c27f9c35d2fd4cdd9bf1c7f46f889ecfd222778
2019-01-17 01:06:00 +00:00
dan 8b20e4a3eb Fix a problem with fix [b4b57413].
FossilOrigin-Name: ca7b7aaed010ec67bec5355a9ac1d7f229d6d5f2ba2d796b76f5e908b1267688
2019-01-16 20:48:13 +00:00
dan e011ee2830 Fix a problem in the fts3 matchinfo() function with corrupt database handling.
FossilOrigin-Name: 24ed5fb6aea30b098d2faf3cf9d638933e518657217e903239ffaa1e25d34f66
2019-01-16 19:44:09 +00:00
drh 375afb8bda Fix a problem in the code generator for sorting results with SRT_EphemTab
and a LIMIT clause.

FossilOrigin-Name: 49fcde2f1f981ac0c75728bed3444e7c1d3167311db282d3375c96ce090b2210
2019-01-16 19:26:31 +00:00
dan 5e970a8f40 Fix a problem with renaming a column that is used as part of an ORDER BY on a
compound SELECT within a database view or trigger.

FossilOrigin-Name: b4b5741366578b25ec6e4c415ab8239215e53b1c900be613575f40a826cfccc9
2019-01-16 14:58:37 +00:00
dan fb8ac325d7 Avoid a dangling pointer comparison when renaming a table that has a trigger
that itself contains a window function with an (illegal) column reference in a
FOLLOWING expression.

FossilOrigin-Name: d45bee36f2c1091a2d32c16ca8921bf4e7c9e40c46d0a36fbcb179ecfafcfbf0
2019-01-16 12:05:22 +00:00
dan 4ccb41fc99 Fix a memory leak that could occur in fts3 when handling a corrupt database.
FossilOrigin-Name: 65cebb06a0afcbcb4157c3d518a62ed188b1e90d9e9b69d88fece484bcb6e380
2019-01-16 11:38:06 +00:00
dan dfb5c963a0 Fix a problem with ALTER TABLE and vector assignments in UPDATE statements
within triggers.

FossilOrigin-Name: cc6cd7531fee39b4c2a9f522f1089c1d79254a9e25acae59468322031f94c25a
2019-01-15 20:51:35 +00:00
dan 1a39d2bb5c Handle SQL NULL values without crashing in the fts5 snippet() and highlight()
functions.

FossilOrigin-Name: a5e9cc794f17566160c4b2b5791601a744a21ace987b19ff8a5816fd78dce56a
2019-01-15 18:14:27 +00:00
dan a783931794 Fix a buffer overread in fts3 caused by a corrupt record.
FossilOrigin-Name: e54efd60c20bbfc5d70ddb9e1dd6ffb68cbbcfa57b4f07cb104767ef08c1a559
2019-01-15 16:14:31 +00:00
dan 2d4e720579 Have fts5 reject attempts to insert a non-integer, non-null value into a rowid
column with SQLITE_MISMATCH.

FossilOrigin-Name: 4a9483f81e9ca1aa41d6ca33cb3171370418ccc71fdee9741bbf6f694bf4fbaa
2019-01-15 15:18:58 +00:00
drh e2dcc42e1f Fix a harmless memory leak in the Lemon parser generator utility program.
FossilOrigin-Name: 1caff0fb0b2051e205e7a8cfd5dadf92680c52a88a441ded95b1ea6542db5f83
2019-01-15 14:44:23 +00:00
dan 58ed374370 Fix a problem triggered by DELETE statements with WHERE clauses that use the
OR-optimization on some virtual tables.

FossilOrigin-Name: ecf5caa7e9825a8b03d15ee525ec68be78c55926ddfaca27a040a7614caf0e85
2019-01-15 14:31:01 +00:00
dan 9c039d9f2e Add scalar function "prefix_length()" to ext/misc/prefixes.c.
FossilOrigin-Name: 0bf1550507d9d3c8a41f8a50db3a59bf808f0a4e24637dc0905d35579305eca7
2019-01-14 20:44:00 +00:00
dan 9274ad898f Fix a problem causing some Tcl test cases to fail with errors like "expected: [<multiline-whitespace>], got: []".
FossilOrigin-Name: 11b8a4cba747ca214fe3506caa3b711c87be4d55412754e673cc0603afefb086
2019-01-14 19:13:30 +00:00
drh 4ead96348e Add the "prefixes" table-valued function in the ext/misc folder.
FossilOrigin-Name: f0fd2163fc23a555ef03af43294a14fcabae6921f52e64c979286c745b4f6218
2019-01-14 16:16:30 +00:00
dan f8a488bb6b Fix a problem causing a crash if an fts5vocab table was created to query an
fts3/4 FTS index.

FossilOrigin-Name: 9cd64ce453e4435d80117b8610c22a0a4b53cd6e84b39815e70e684f6b0295c8
2019-01-14 15:35:15 +00:00
dan 94ec92a1f7 Fix a problem with querying a corrupt fts3 database.
FossilOrigin-Name: 65e50706a017751d72d0f9c7f575955194977decd0acf13aaca90c3cb925f20e
2019-01-14 15:09:00 +00:00
drh 4067ce7d54 When parsing a corrupt record using sqlite3VdbeRecordUnpack(), make sure
that the resulting UnpackedRecord object is completely initialized, to avoid
(harmless) MSAN warnings.

FossilOrigin-Name: ddc3697efd61830fad55c6bf7f9115f4a7f53e08838eba5a82e1406c7a721665
2019-01-14 13:32:15 +00:00
dan 68c1f9ce9a Have fts3 ignore empty sets of parenthesis if built with
SQLITE_ENABLE_FTS3_PARENTHESIS.

FossilOrigin-Name: c93c6b45a317c40eb5c0abb6620d21f5821a601632c791e11e5ce62e039eccda
2019-01-14 11:56:13 +00:00
drh d12db3dabb Avoid reading off the front of a page buffer when balancing a corrupt
btree page.

FossilOrigin-Name: cb50509020d952fa9efed8df7fa08b07b71ae9bdbdefea216b6e660863291039
2019-01-14 05:48:10 +00:00
drh b10a50e7f8 In dbfuzz2, avoid using a malloc in the LLVMFuzzerInitialize() initializer
routine, so that no memory leaks are reported.  Also, show the version of
SQLite being used when the -v option is on.

FossilOrigin-Name: 824f93246988ffa213bbd41a7de08886999b1a8ae00fdf6b9767acb6e3ec6a1f
2019-01-13 20:23:34 +00:00
drh f202c6cdcf Relax the minimum size database file constraint on the dbtotxt utility program.
FossilOrigin-Name: 97e723d746eeb2159f5bf1701532271ac6a4620879c82d496f4499c178b64479
2019-01-13 20:17:52 +00:00
drh 0f1bf4c1ac Improved detection of database corruption while balancing pages from an
auto_vacuum database with overflow pages.  Test cases in TH3.

FossilOrigin-Name: 35f04235c477501390acea126d07a730d81d03cdf7abcd82d861e397b3f75b0f
2019-01-13 20:17:21 +00:00
drh a1bd5c6aae Move a local variable declaration into the outermost scope in which it
is used. This fixes an ASAN warning.

FossilOrigin-Name: ac3b6021d9437ab1c027850d321f0a3e575b008763d8d515e2347f7d4e7c294b
2019-01-13 00:58:57 +00:00
drh a79bcf358b Prevent unsigned 32-bit integer overflow from leading to a buffer overread
inside of an assert().  The problem fixed here is no reachable in production
code.

FossilOrigin-Name: 0f850a25d67a752fe1e9059c0c3f78e00c222113e556a7605fd3c50817b573cb
2019-01-12 21:30:26 +00:00
dan 951d165125 Fix another problem with handling corrupt records in fts5_decode().
FossilOrigin-Name: 726e398b9ddc15ea1b67c40e2a12ddf5d04428a866699588c5fa1af75af846e1
2019-01-12 20:55:36 +00:00
drh 6214d93993 Fix an off-by-one error on a Goto in the code generator, that only
causes problems for a REPLACE on an INTEGER PRIMARY KEY in non-debug
builds.  Test case in TH3.

FossilOrigin-Name: e35eb8776ed539afe1d5db099470ab1124d8dd2db73ee5db7c811f8df9a9576e
2019-01-12 16:19:23 +00:00
dan b4439eef10 Fix a problem with corrupt database handling in the fts3 matchinfo() function.
FossilOrigin-Name: 703646b1b5c84d550fe0d74e399c0eeb729da1d263e4693320f69e6509678985
2019-01-12 14:58:35 +00:00
drh 5d4589014a Improved detection of shadow table corruption in the fts5_decode() SQL function.
FossilOrigin-Name: b74e5f3f3057ee7a98ebcb14ca0751048eacbec8fca3e11e241883029a57ecdf
2019-01-12 00:45:20 +00:00
drh 3e534eac19 Improved shadow table corruption detection in the matchinfo() function of FTS3.
FossilOrigin-Name: 567be3bb1e8b6477f3bf1c7b4cd6ec066fba69d0dcf8785632e244ce25db639f
2019-01-12 00:12:33 +00:00
drh a2dc7494ef Indicate that the database may be corrupt in the fts3corrupt4.test test script.
FossilOrigin-Name: 473626d5579dd19023abccaf7c1822ac0c883a0b98904837ea096fa16e4f41c4
2019-01-12 00:07:48 +00:00
drh 73bce66701 Use 64-bit APIs in the fileio.c extension.
FossilOrigin-Name: b49d56a0faf012978c50fb8662125ea21bdf5054fddf5975644cbc941c153e70
2019-01-11 23:08:56 +00:00
dan 90294961da Fix a segfault in fts3 prompted by a corrupted database.
FossilOrigin-Name: 2d7b1d1d41ff69d5465fcb861420816ecb066c25a9015eefdab5fae15a2e1c9f
2019-01-11 21:34:25 +00:00
dan 0ad63e5e0c Fix another problem with corrupt databases in fts5.
FossilOrigin-Name: 9bf811ea89a133d481a86407683a7518e909eccb7aa3aa02f7932bdb33387572
2019-01-11 19:27:55 +00:00
dan e6370e9c29 Fix a problem handling a negative value in the "number-of-pages" database
header field. Also a problem with running "REINDEX tbl" against a virtual
table for which the SQL passed to sqlite3_declare_vtab() contains PRIMARY KEY
or UNIQUE constraints.

FossilOrigin-Name: 556dd8922f65af93084ee725c638b8dc696b611dd508c212a3b507d6ca474031
2019-01-11 17:41:23 +00:00
drh 1735f91df4 Improved detection and reporting of errors in the readfile() extension SQL
function.

FossilOrigin-Name: d2f0b5a483869d39f5c5814c9d6df3d3b8a46d582b4dcf0cf11e23b707c4213e
2019-01-11 17:20:25 +00:00
drh 2bd207ff6d Omit errors about missing SAVEPOINTs when aborting the .archive command
in the CLI.

FossilOrigin-Name: 2a47387ba6aa3c294607b7641aa1c4cf70a7b27a861e1098c2f79a38e5b7036a
2019-01-11 17:19:59 +00:00
drh 2a58dbde30 Improved detection of cell corruption in sqlite3VdbeRecordCompareWithSkip().
FossilOrigin-Name: fa47f4c6589c431cf678560ac33dea6b695052012bea2096b2c92869ed51c688
2019-01-11 16:44:16 +00:00
drh f10ce63651 Fix PRAGMA integrity_check so that it does not cancel the PRAGMA vdbe_debug
setting.

FossilOrigin-Name: aaa3a19f8cf5ba7003634e4610abc7832354af91d7c7f65469218678f66bcd46
2019-01-11 14:46:44 +00:00
drh 1972c8cf07 Add the --vdbe-debug command-line option to dbfuzz2.
FossilOrigin-Name: 599b4df43c64ce295517c804b6bb4c3ab77d77e0ba585dc0657274f55489a3b1
2019-01-11 14:38:47 +00:00
drh 26391eeefe Add the "dbfuzz2" target to main.mk. Remove an unused local variable
from dbfuzz2.c.

FossilOrigin-Name: 05c7609cfd02f49114876267d7090f4e0ea2467f3aa7c65019c5986ec8f60a87
2019-01-11 14:22:33 +00:00
drh 51d35b0fa9 The keywords TRUE and FALSE should only act as boolean literal values if
unquoted.

FossilOrigin-Name: 5547f39de993c708f72301ef25df190a2f007e0c4253799bdd9e86bb1ae41777
2019-01-11 13:32:23 +00:00
drh e65b9c6a5e Separate makefile targets for "dbfuzz2", "dbfuzz2-asan", and "dbfuzz2-msan".
FossilOrigin-Name: ea119641a7edcd0e1ec14371d93e35f860971888bd98cb0019253358a2ef123b
2019-01-11 13:03:06 +00:00
dan 6ca98ad6b1 Fix a memory leak in fts5 that could occur if scalar function fts5_decode()
was passed a corrupt record.

FossilOrigin-Name: 240f1c0c92cad8a1c19438b38489aedb831f62a4603c53f22367e876d8f644ff
2019-01-10 19:26:52 +00:00
dan f7d687c9d3 Fix a memory leak in fts5.
FossilOrigin-Name: ff3b011f17f4f02e486f3c8de607f62eddf3b86562e2df82dba57ea166994b65
2019-01-10 18:35:09 +00:00
dan 25e3073741 Avoid use-after-free and double-free errors that could occur if an fts5 table
is modified in certain ways while there are active cursors.

FossilOrigin-Name: 3291b2a6fe6f38ae91b933e5cd2bf7d97432374b4fb1fccd92b4bd759b02ee06
2019-01-10 17:08:20 +00:00
dan c80864d77a Fix further problems with fts5 handling corrupt databases.
FossilOrigin-Name: 83c467d7af63bd2e7800aff4fe9b09dbd75557460b75a9e07205dfae7e28312c
2019-01-10 15:17:32 +00:00
drh 69ab18d213 More aggressive early detection of orphaned and malformed autoindexes when
parsing the schema.

FossilOrigin-Name: 10f9e39d6ed2413fa9abc6c82da3ed48f32a42b6190b6219fca7faf850d05113
2019-01-10 14:33:15 +00:00
drh 5f913ecb62 Use the new SQLITE_IDXTYPE_IPK values (3) on Index.idxType to indicate the
fake INTEGER PRIMARY KEY index used during query planning.

FossilOrigin-Name: e22d2f905fe840bea51b536ebedc9b637190ea0a37f16559668d99a61e971411
2019-01-10 13:56:08 +00:00
drh c49d43a787 Fix the fts3DecodeIntArray() function so that it will not read off the end
of the buffer it is handed.  Any unread integers are set to zero.

FossilOrigin-Name: 666cf8f6b39ae1f72e82b45e9cacba23caf61370ca0c695b3b14452accbb1a0d
2019-01-10 01:12:43 +00:00
dan a47e45f734 Fix an out-of-bounds read in SQL function fts5_decode() that could occur if it
was passed a corrupt record.

FossilOrigin-Name: 931278b257b12ac14fc8fbc82c6dc88ce4ac4b8e0d668543e68f0289d825daa1
2019-01-09 21:12:23 +00:00
drh 1757fed87f Adjustments to the page cache to try to avoid harmless TSAN warnings.
FossilOrigin-Name: 383437be276719ac1c72688ae81017c63907ac561f2ffb8e42c43b012248f294
2019-01-09 14:49:58 +00:00
drh 8eaf565feb Improved database corruption detection in the dbstat virtual table.
FossilOrigin-Name: fc5ecc88f8a0855ba90039177ee284721b2035e4de56a1024e323216f011f0af
2019-01-09 11:19:41 +00:00
drh 3e08ba4521 Small simplification to the dbstat virtual table.
FossilOrigin-Name: 9d4c156fa26f80bb8f88b6ad8f24520a15af296de9c110604f6bd42c257455a0
2019-01-09 11:06:03 +00:00
drh 885eeb676b Enhance the ALTER TABLE RENAME COLUMN feature so that it works on tables
that have redundant UNIQUE and/or PRIMARY KEY constraints.
Fix for ticket [bc8d94f0fbd633fd9a051e3]

FossilOrigin-Name: f09aa3248e2b4a32ff5b5d37084cb2a27445322cb06a3354cef723f4f0b2cd34
2019-01-09 02:02:24 +00:00
drh 2d77d80a65 Use 64-bit math to compute the sizes of memory allocations in extensions.
FossilOrigin-Name: ca67f2ec0e294384c397db438605df1b47aae5f348a8de94f97286997625d169
2019-01-08 20:02:48 +00:00
drh c930b405f0 Performance improvement on the instr() function, especially for large
haystacks.

FossilOrigin-Name: ce51f1a2b6a1789a5876e01cf829e45d84f3851d135a2fa5c44a56f948673a60
2019-01-08 15:18:24 +00:00
drh c0f162020e Fix a possible memory leak when trying to UPDATE a corrupt RTREE index.
FossilOrigin-Name: 63eb803dbc27077007dbee8def659d1523724eb73f1def1cdb68027e5c20843a
2019-01-08 14:28:02 +00:00
dan 174c21ff06 Fix further problems with fts5 and corrupt databases causing integer overflow.
FossilOrigin-Name: 673a7dd698eca05bb2909fa01f962a0667361732a6d0e61cf7780ead4a07c967
2019-01-08 08:02:12 +00:00
dan d9d7d253fc Fix another potential buffer overread in fts5.
FossilOrigin-Name: d0e943d9574c7cab1af4a0fe753a0b5f91ea0e884b91a85b13239144b71f067c
2019-01-07 16:52:00 +00:00
dan 418454c63f For SQLITE_ENABLE_PREUPDATE_HOOK builds, disable the optimization for a
REPLACE command on a WITHOUT ROWID table with no indexes, triggers or foreign
key constraints that causes SQLite to clobber any existing row without
separately checking for it. This optimization causes SQLite to omit the
expected pre-update-hook callbacks.

FossilOrigin-Name: 6281ef974c0ac7a7133c9e1e04c09fdbd627c019c6ff3227293548caf8283864
2019-01-07 15:57:35 +00:00
drh dcc2700d7e The page size becomes fixed as soon as page1 from a non-empty database file
is read.

FossilOrigin-Name: 6064584d578f0ac7aba3f67912a5d9eb1a3c6001469f6b9becbe68871131f887
2019-01-06 02:06:31 +00:00
drh a8e057618a Add the exprNodeCopy() routine that will safely memcpy() an Expr node that
might be a size-reduced node.

FossilOrigin-Name: a874c649960ba2e2b2fd380d08c02a45884a1060d3922be8847729008ca6766e
2019-01-05 21:56:12 +00:00
drh 6b86e51eea If the OP_ParseSchema opcode with a non-NULL P4 operand does not parse any
rows out of the sqlite_master table, that indicates that the sqlite_master
table is corrupt, so raise an SQLITE_CORRUPT error.

FossilOrigin-Name: 598d7358e7329f0de6e3defc217665909e46874258ac29592ee2fd53e6411cda
2019-01-05 21:09:37 +00:00
dan c210c08891 Fix two more problems with corrupt database handling in fts5.
FossilOrigin-Name: 444c7c99beb9f8b82963e9784aa2be54124c7011f4771122b4f608c02aa26408
2019-01-05 07:17:56 +00:00
drh b042d92128 Give a meaningful error on an attempt to use UPSERT on a virtual table,
rather than simply not working.

FossilOrigin-Name: fa98748f956cff95fcfda3a513cea4df27aa573ae795a6855c40bfeca661d0b2
2019-01-04 23:39:37 +00:00
drh f25cc4f3c5 If the ".open" command fails in the CLI, reopen to :memory: so that at least
some database is available for subsequent commands.

FossilOrigin-Name: d7f55c62c3fa053b9b930a044b60076a8278cbf679d8e5116b95f2ff19247f6b
2019-01-04 14:29:21 +00:00
drh 48cd0f28c5 Remove debugging pragmas accidently left in by a prior change.
FossilOrigin-Name: 26275fc7e89eb2542a65d01fd271cef016a4a1815bc3845c599cf2f4fbf7513d
2019-01-04 12:46:01 +00:00
drh dfe3b58315 Fix a typo in a comment used to generate documentation. No functional changes.
FossilOrigin-Name: ccc4f7424bc8f37c168333091dd9e3d6f80ccff9e2b06f182df65be59a7e3349
2019-01-04 12:35:50 +00:00
dan 2f36262dbf Fix another fts5 assert() that may fail if the database is corrupt.
FossilOrigin-Name: 0888fc2e881d56ccd5222383d1a08cdf16fbd15c40da7ebfc14346be69ffb26a
2019-01-04 11:20:14 +00:00
dan e9ad07c0a3 Fix some problems with sqlite3_interrupt() handling in fts5.
FossilOrigin-Name: c0eb839a3c23612b93002d2e1fbc41bf5db140775267989f85db52146144750b
2019-01-03 19:12:21 +00:00
drh 1baae57a72 Fix the csv01.test module so that it works on systems with \r\n line endings.
FossilOrigin-Name: 36eaf5a5e51b20699328aae67c2bfd325f81bea342e2b167fddd859a50a26e28
2019-01-03 16:03:48 +00:00
drh 94e02d9c2c Fix the shmlock.test script so that it works with the Windows restriction
that UnlockFile must exactly correspond to a prior LockFile.

FossilOrigin-Name: df939c89fa90b7f9ccf961027ca4eca4f987c49eabf530b5719a83e5ab0d346d
2019-01-03 16:00:23 +00:00
drh 20c0082371 Fix a harmless compiler warning in the CSV extension.
FossilOrigin-Name: fbcd72565f4425016cebbbf5dfd6aa510234cfb31c785cf364f04fff444aacae
2019-01-03 15:22:33 +00:00
dan 0d756cc83a Fix a problem with the second and subsequent sqlite3rbu_savestate() calls made
on an RBU vacuum handle.

FossilOrigin-Name: bef216dfa1456a787e3d9c74936ee1c6600827d4e252bd13e7a93046ce07469f
2019-01-03 15:17:01 +00:00
drh 232f278084 Fix the geopoly_svg() function so that it returns NULL when given zero
arguments.

FossilOrigin-Name: 120cb1768338eb86412fb69d4c7677247775bb37875ab3a98766cffd535f04cf
2019-01-03 00:44:03 +00:00
drh 8fc4a11c94 Fix harmless compiler warnings in the unicode2 logic of FTS3 and FTS5.
FossilOrigin-Name: 703029ac6d24860230a8c30fcbf5e7e1da619e84f1cc9b9e65ebc74879a184d2
2019-01-02 23:49:47 +00:00
dan ca076bf26e Add another test case to vacuum-into.test.
FossilOrigin-Name: 0465d2fc0d3f8beaa1b6b0bd7bd51d69a524f30d889c9402e7d02cc06164a310
2019-01-02 16:01:59 +00:00
dan 992e927281 Add test cases for commit [6c6fb1c6].
FossilOrigin-Name: 3961995cb56b43f1753c53fc869edf336f1c17ec994d67dc74e44e8e02493894
2019-01-02 15:27:27 +00:00
drh ee751fab4c Raise an error if the argument to VACUUM INTO is an identifier.
FossilOrigin-Name: 6c6fb1c6ea452c70b56fd4ac796affebee21512adba0455ae81c291b715f544f
2019-01-02 14:34:46 +00:00
dan 9b0da8319c Fix another fts5 problem caused by a corrupt database.
FossilOrigin-Name: 911342f7512145a8a189bb0ec59e70e4c9ddc9f20f3e84816ab25139ead5dc45
2019-01-01 19:17:42 +00:00
dan 97c8cb3ed8 Ensure that when a new cursor is opened by OP_OpenDup, any existing cursor
with the same id opened by a previous OP_OpenDup is closed first.

FossilOrigin-Name: 5c188361a91407805c0feb4bf6d3214522ce3e55013efcf63a4613ecd416bcbc
2019-01-01 18:00:17 +00:00
dan fff1dc8e05 Fix another case in fts5 where a corrupt database could cause a buffer
overread.

FossilOrigin-Name: f7e6cdc5625664f449d0edbe39af2d45910c4137bfd856ae1f770dd826c138ff
2019-01-01 13:59:34 +00:00
drh f9231c34eb Fix harmless compiler warnings.
FossilOrigin-Name: b57c545a384ab5d62becf3164945b32b1e108b2fb4c8dbd939a1706c2079e18b
2018-12-31 21:43:55 +00:00
drh f01dae1f32 Additional steps to help ensure that scalar subqueries are only evaluated
once even if they are used in multiple places within the query.  This fixes
a performance regression reported on the mailing list and caused by
check-in [531eca6104e41e43] which was a fix for ticket
[787fa716be3a7f650c]. Think of this check-in as an improved fix for
that ticket.

FossilOrigin-Name: e130319317e761193890ef75787a3c114b61166f518df019697be8e2c820ec54
2018-12-31 20:39:37 +00:00
drh d471bcb396 Remove an optimization that can no longer occur, being superceded by the
subquery-reuse optimization.  Put an assert in place of the optimization
to detect if the need for this optimization ever returns.

FossilOrigin-Name: 4fcdc7a2939457e51aab37cab168677cd7f464a9a0aff4f8981e864a30828b3b
2018-12-31 20:13:12 +00:00
drh 0de6efe59e Merge enhancements and bug fixes from trunk.
FossilOrigin-Name: 9fb646f29c05bca5f677a2c7c4f45c36bfe0a0c6a88cb7968b4a0459bdd63bb2
2018-12-31 18:30:41 +00:00
drh d0fb7960ce Small changes to the OP_OpenEphemeral opcode to improve testability.
FossilOrigin-Name: f856676c8438dbf52d299e78f6dd6148d929755dc05cdcabafd17d9a86439435
2018-12-31 17:58:05 +00:00
drh 4afdfa195b Fix the OP_OpenEphemeral opcode in the bytecode engine so that if it is called
a second or subsequent time, it merely clears the existing table rather than
creating a new one.  Proposed fix for ticket [d0866b26f83e9c55e30de0821f5d].

FossilOrigin-Name: 4678cb1044f0b4dc813e48f3bd0f85240a66e2ecf8763280d66726cc031c93a7
2018-12-31 16:36:42 +00:00
drh d1d158bf5a Additional small performance increase and size reduction to the
sqlite3VdbeMakeLabel() mechanism.

FossilOrigin-Name: 1bdee199a71e0a6c247b85e72de9e3a3099b7179c33288735721facef3b96459
2018-12-29 14:23:22 +00:00
drh ec4ccdbcb1 A new implementation of sqlite3VdbeMakeLabel() is faster and makes fewer
memory allocations by deferring memory allocation until 
sqlite3VdbeResolveLabel() is called, at which point the code generator has
a better idea of how big the relocation table needs to be.
The sqlite3VdbeMakeLabel() routine now takes a Parse* parameter instead of
Vdbe*.

FossilOrigin-Name: 4a0929ac76d8aa5dd65eac3b83d6bbf41e505e01d175ca0fb2b19ba02d439415
2018-12-29 02:26:59 +00:00
drh 01e92df41e Merge performance enhancements from trunk.
FossilOrigin-Name: 0f1b9ff9e1e6f13e03045fcb7d0907227085054f9eb0b0b8471fb26b0094b13a
2018-12-28 21:32:35 +00:00
drh 81f9159b5e Faster allocation of new sqlite3_stmt objects.
FossilOrigin-Name: 891f1f72187f0f9ec0d24fda98cc08be3ae3c3ff8b27c4e409ee7135c3106398
2018-12-28 20:48:07 +00:00
drh b6991796b4 Move the nOpAlloc field from Parse into Vdbe to avoid an extra pointer
deference on the fast path in sqlite3VdbeAddOp3().

FossilOrigin-Name: 8f10efc29dea7b816b1ba401726c268950d6671d890f686911269082a241d8d9
2018-12-28 20:14:03 +00:00
drh 64919e9b00 Merge patches and enhancements from trunk.
FossilOrigin-Name: da53f3d3ff26cc32d3a5ac788b6785baa3d1688e50d9354025a3130dc7e71a38
2018-12-28 19:23:20 +00:00
dan 4177c8a2b7 Fix another problem with loading the structure record from a corrupt fts5
database.

FossilOrigin-Name: c4d44542d259bbec11aea60ae94fcb4acd53e97e125723cae078cf0f8873f8ef
2018-12-28 18:09:45 +00:00
dan 1d4b16405b Fix a problem causing the sqlite_master entry corresponding to a virtual table
to be removed by a DROP TABLE even if the call to the vtabs xDestroy() method
failed.

FossilOrigin-Name: 0140f6dbfbea93eadcd7f727d84064a0c0d1f0806dbe3e5ef1017da603157e3b
2018-12-28 17:45:08 +00:00
dan eefc72d12f Avoid an undefined left-shift operation in fts5 caused by malformed utf-8
text.

FossilOrigin-Name: c3a3a11194586bef80a9d7ca54caae8af30d4e7b464b8bb3d257ba2d2ec4791f
2018-12-28 14:33:55 +00:00
dan 666636b6de Fix a buffer overwrite in fts5 triggered by a corrupt database.
FossilOrigin-Name: a385298df264dbfa6765f63ad8708f74bc8e8a1404239c1049890b39a1bda888
2018-12-28 13:57:30 +00:00
dan b163b57212 Fix problems in fts5 found by ASAN.
FossilOrigin-Name: c564bf870106faef297594a51995619c80311d06bd5f8a0c7644f666f22ba576
2018-12-28 07:37:22 +00:00
dan 593c716781 Fix another problem with corrupt database handling in fts5.
FossilOrigin-Name: fb0d7fba07865ff557bfcdacfda7b625d099ac8b4dcbe0c08cd2d4b84a068bb9
2018-12-27 20:12:02 +00:00
drh aa243aa7cd Modify the btree02.test module so that it does not depend on whether TCL
interprets a value as a string or as an integer.

FossilOrigin-Name: d9e4f9574659c6285deba3dca68eca9989e615971cea3a901ffcda12fb4ee36f
2018-12-27 16:55:01 +00:00
dan e80834f6ff Fix another problem in fts5 caused by a corrupt schema record.
FossilOrigin-Name: ff45f9dd69fe1e1c7875e5bb73ac3dde2a31746475d3765cda9233f8e06e26ca
2018-12-27 15:36:16 +00:00
drh 57e141bc28 Fix the filename normalization in the dbtotxt utility program.
FossilOrigin-Name: 29a00a05dd40ff59be340969e1aca4fee41e092f2faa1cea85a3448265a83c2c
2018-12-27 13:52:45 +00:00
dan cd80dc3667 Fix a null-pointer dereference that could occur in fts5 with a corrupt
database.

FossilOrigin-Name: b0a49d5e6df116bb5eacb60a0bb0f482760aec38bd417d4250d9e57d43bdbb13
2018-12-27 07:46:37 +00:00
drh bdefaf08ee Fix a problem in which nested CTEs with the same table name trick the
code generator into thinking they are the same CTE, which then tries to
use the manifest them both into the same transient table.

FossilOrigin-Name: 202dd033019dd27428e3cc5f6e164c95b37efe39e2753515112b201ddefca67b
2018-12-27 02:16:01 +00:00
drh 7eb2c9176a In the treeview debugging output,
provide additional details for the Table object
associated with each FROM clause term.

FossilOrigin-Name: 11d4682d2eec133ccca99ca9cf2620cd249b4afe55918f3ebf93b454431f9c55
2018-12-27 00:30:42 +00:00
dan f6febee0e2 Update the coverage-wal permutation to cover branches enabled by
SQLITE_ENABLE_SNAPSHOT.

FossilOrigin-Name: 6821c61f1d71be2be7f867e59fd94582a1eaf45a4d1fb88be995807a77cc22ea
2018-12-26 18:34:56 +00:00
dan 89dec01e48 Add a few more test cases to walvfs.test.
FossilOrigin-Name: 14a64df36efe0dc36795311d58385f9c65dc465b214059e07c2ee6b95ea99c87
2018-12-26 17:49:57 +00:00
dan 0f55a571fc Avoid an "unitialized value read" problem in fts5 that can occur with a
corrupt database.

FossilOrigin-Name: 6cae81cd1ffb0180e0260d5ba921502c7dee2f54637bff3558a4d1cb5dfd3f32
2018-12-26 16:57:47 +00:00
dan c2909bf8ac Fix a problem with handling corrupt databases in the fts5 integrity-check
function.

FossilOrigin-Name: 9bad745d373f4686a2726c3f77a2ccad60e7181645d7ed483a2e43075a4ef30c
2018-12-26 16:04:54 +00:00
dan d8f3b4c320 Fix a problem with corrupt fts3 database detection introduced by [95a9a39f].
FossilOrigin-Name: c80bb15b44e9b6a3c0c5a49d5e93e66376c3520ecefc1db7425c8a7e09d3eade
2018-12-26 14:15:09 +00:00
drh 8625221444 Fix a problem with the CSV extension when it uses the "header" option on
a real file.

FossilOrigin-Name: 7acaed08f946633fca3ab8434dd6349ea6f1bac4fd9ec21f476db013ee06de30
2018-12-26 12:50:47 +00:00
drh e4c26c41b4 Fix a typo in a comment that is used to generate session documentation.
FossilOrigin-Name: a1f50d57ce76f6c08a0ddbdd3c3fe2732d0e57dda14cb9aa3da00a14ceb4bc44
2018-12-25 11:17:50 +00:00
drh 47df8a2c40 Increase the number of parameters to sqlite3WhereCodeOneLoopStart() to
encourage the compiler to inline that routine within sqlite3WhereBegin().
This gives a performance improvement.

FossilOrigin-Name: 3c2ad0e915e835b1cb2962879beff50b2745d0cefe1cfc89ef90b7879c139ce6
2018-12-25 00:15:37 +00:00
drh bd462bcc10 Improvements to EXPLAIN QUERY PLAN formatting. The MULTI-INDEX OR now shows
a separate "INDEX" subtree for each index.  SCALAR SUBQUERY entries provide
a subquery number that is related back to the .selecttrace output.

FossilOrigin-Name: 7153552bac51295c56a1c42ca79d57195851e232509f9e9610375692f48c7e86
2018-12-24 20:21:06 +00:00
dan 92107a38dc Add a few more test cases to walfault2.test and walvfs.test.
FossilOrigin-Name: 3873941c4fb9aa2d0de1129722c5fcdf2be1ea261677d4841ed99f896c778459
2018-12-24 20:00:27 +00:00
dan 1ab76166e3 Change another fts5 assert() that may fail with a corrupt database to an
assert_nc().

FossilOrigin-Name: d9653380c455b4bf6c371540d677cbde6d17664c58662b5cc9a12929f46192dd
2018-12-24 19:59:37 +00:00
dan 76e4990b25 Add test cases to test file walvfs.test.
FossilOrigin-Name: d697f6f3ca47350dad30feb529914fc5254fa662ece783408eea963d912918c1
2018-12-24 18:51:13 +00:00
drh c310c53e01 Always include OP_Explain opcodes in the bytecode when SQLITE_DEBUG is enabled.
FossilOrigin-Name: d8c1235c02b745138ac2b12e8bbb00dda4cac321176be92a2fa9547be029b3d0
2018-12-24 18:10:39 +00:00
dan 94e95ea46e Copy some extra test infrastructure from the mutexfree-shmlock branch to trunk.
FossilOrigin-Name: 883337ffdb434b6856ceaada121c0be67e2fdec7b447675f45e85568ef28d7d9
2018-12-24 15:22:47 +00:00
drh a599e150ca Restore a line of code that was previously commented out for debugging.
FossilOrigin-Name: e53781f5bdf5c7b7d91ffe76565ea2fe5d1b3a9b162b3a88a7017bbe785d4c72
2018-12-24 14:30:11 +00:00
dan 29e9af8848 Change the way a comparison used to detect corrupt databases in fts3 is done
to avoid potential pointer overflow in 32-bit builds.

FossilOrigin-Name: 95a9a39ff784b960b62dd6298e722a620ba3f9c8b76839a49bbef35d7bc84a8e
2018-12-24 13:34:36 +00:00
drh 5198ff5767 Do not generate subroutines for non-static SELECT and EXISTS expressions.
Fix up some test cases to account for the minor changes in EXPLAIN QUERY PLAN
output.

FossilOrigin-Name: 06de44ec9e173992ca9afb89dd2b4e40d2a7e35512c7959603cdceb606f5dfbd
2018-12-24 12:09:47 +00:00
drh efb699fc7c Prevent the use of subroutines to implement the RHS of IN operators within
CHECK constraints.

FossilOrigin-Name: 6b24d3fb94e787d25e49501714780dfb0c0c99077102056aa68445f4808cdd57
2018-12-24 11:55:44 +00:00
drh 2c04131ca7 Experimental code that tries to put the computation of subqueries inside a
subroutine, and reuse that subroutine if the same subquery is evaluated more
than once.  Current code does not work for CHECK constraints.

FossilOrigin-Name: 6c44838adbe5dc482bc010e91a6dd7a0f777c989f443dd600740d2c783208e0d
2018-12-24 02:34:49 +00:00
drh 85bcdce270 Split the code generation for the RHS of IN operators and for SELECT and
EXISTS expressions into two separate subroutines, because there is now little
commonality between those to functions. This is intended to help make the
code easier to read and maintain.

FossilOrigin-Name: 2b6494b1509f0d0189f98aa34c990eee99c775ff57826e79b2c5b0a12b4c97ad
2018-12-23 21:27:29 +00:00
dan 8d69a58119 Improve the coverage of wal.c provided by the "coverage-wal" test permutation.
FossilOrigin-Name: 6231485114eb07b258cd0e6e163ca05f7e9cf5664e071808fcb1329b33e4c4f5
2018-12-22 20:32:28 +00:00
dan 6a509d56bc Catch another case of a corrupted structure record in fts5.
FossilOrigin-Name: fb17fea4b9779fbd3adb6ff9500da83a6ca4fa7cba379aa70074e4328814a7f2
2018-12-22 19:54:17 +00:00
dan 862faf28bb Change a faulty assert() in fts5 that could fail on a corrupt db to an if() statement.
FossilOrigin-Name: 1daaba9fb46706af8ed0669a661c304df999a69cf639d29d93208f422c515d8c
2018-12-22 19:09:46 +00:00
drh 11d07ed643 Fix one more instance of excess whitespace in test result strings.
FossilOrigin-Name: c064964deb0b7220ba784f07ca9c603680f3c8bb936d56ab4eca1962beac1359
2018-12-22 16:14:45 +00:00
drh 3a07548b0d Remove unnecessary whitespace from testcase result strings.
FossilOrigin-Name: ad70f03ceda74163903d247a975666b35fae722a27c48dd3efd31c1164b5627e
2018-12-22 15:46:23 +00:00
dan b63d6070ee Fix an assert() in fts5 that could fail with a corrupt database.
FossilOrigin-Name: 83935b950619855fb3bf05486091804ac2a61fb993c6ec826c89f943264fabc3
2018-12-22 15:21:31 +00:00
dan 634ac14488 Fix a "jump or move depends on uninitialized value" valgrind error that could
occur in fts5 when dealing with a corrupt database.

FossilOrigin-Name: 3518c09b944c92974939b1de244401afd34de5d9aa75050e5ad55581a94e1e71
2018-12-22 13:34:52 +00:00
dan fb11bf8c91 Avoid a left-shift of a negative value (undefined behaviour) when dealing with a corrupt database in
fts3.

FossilOrigin-Name: b851d12474035328df8354c7da8d81bc78833c8c704153f9f573c19b47a8487e
2018-12-22 09:39:06 +00:00
dan 583521fbb0 Fix cut-and-paste error in test file fts4umlaut.test.
FossilOrigin-Name: cad5da1bf5f65ad87d97b72e9a84081fde455ba4085e79943fdf6c0144b1ef83
2018-12-22 07:16:42 +00:00
drh 9bfb079409 Do not all REPLACE to sneak a NULL value into a NOT NULL column. Detect that
situation and ABORT instead.  Fix for ticket [e6f1f2e34dceeb1ed61531c7e98].

FossilOrigin-Name: db8d1d12f5c1673404b2afb5426d5ea3afe3b69d01f8f2bc47ffdf70684fdf24
2018-12-22 01:13:25 +00:00
drh a42325e731 The OP_Eq and OP_Ne operators have a special P5 value SQLITE_NOTNULL that
asserts that the values are not null.  Except that is not always true for
a corrupt database.  Adjust the assert() and add a testcase() to make this
point clear.

FossilOrigin-Name: a3fdb2c78d23b94d68dc08126b22d03152ac6068496a42402cdfb336cd4a7e33
2018-12-22 00:34:30 +00:00
drh a86c8ce940 Update the dbtotxt utility program so that it does not output characters that
are special to TCL, thus making the output of dbtotxt easier to insert into
test scripts.

FossilOrigin-Name: 48438bb35b48955a1df83ef90f0ef6c9cfed0b16d2e938f36d74ad9d53b4b5b4
2018-12-21 22:11:37 +00:00
drh cde4bf8ba7 Improved detection of shadow table corruption in RTREE.
FossilOrigin-Name: b39bf4356e6bcf1d8442721d6cbbfe06caba01325104fb469da8fe69e1f623a2
2018-12-21 22:08:59 +00:00
dan 6ba81ef1bf Add new sqlite3_prepare_v3() flag SQLITE_PREPARE_NO_VTAB, for
preparing statements that are not allowed to use any virtual tables.
Use this to prevent circular references in triggers on virtual table
shadow tables from causing resource leaks.

FossilOrigin-Name: da587d18575ac06a6b65fec1d106f0cc65bc10f493ca6c6b99117a2162d15a52
2018-12-21 20:18:06 +00:00
dan deb201b866 Use SQLITE_PREPARE_NO_VTAB in rtree as well.
FossilOrigin-Name: 82a2ae7132964eab0dfad9a8314a399ffd3b72366b35e1767df6452125dd1d80
2018-12-21 19:55:20 +00:00
dan 38e3853240 Add tests for the use of SQLITE_PREPARE_NO_VTAB in fts5.
FossilOrigin-Name: 1999612010e310fc2430d1f00076f69fade0c66d202771dbb0f3d5597ac0a03c
2018-12-21 19:30:18 +00:00
dan 1ea0443c2d Add new sqlite3_prepare_v3() flag SQLITE_PREPARE_NO_VTAB, for preparing
statements that are not allowed to use any virtual tables. Use this to prevent
circular references in triggers on virtual table shadow tables from causing
resource leaks.

FossilOrigin-Name: 25666e3d03950caf753295cdb55df162e07dbcf6840b05875c6e0b127c469ecb
2018-12-21 19:29:11 +00:00
drh afdc9e23fc In FTS3, avoid calling memcpy() with a NULL source pointer, even if the
transfer amount is zero bytes.

FossilOrigin-Name: 1abb83d29a06308c96bea379311b390240347c5f81824749348d18ad75840c96
2018-12-21 18:51:27 +00:00
drh 8bcc686614 The fts4umlaut.test module requires FTS5, so do not try to run it without that
module.

FossilOrigin-Name: dee3ae900129d39d69aff3ec6187376be100803ee6170bbf39529f37b4253260
2018-12-21 18:50:43 +00:00
drh 687e20079c Fix the node hash function in RTREE to ensure that it always returns a
non-negative value.

FossilOrigin-Name: 0bf4c70a6849da74797e8616a4f3730492ad02882ae67a0fe0f3b3cc3f1043b4
2018-12-21 18:17:35 +00:00
drh 273e01b4c6 Fix a potential NULL-pointer deference in RTREE due to corrupt shadow tables.
FossilOrigin-Name: 1fdd3604eef880414682e9e6f74d714520fe1c63f267ec4da752d2dc1da6bf72
2018-12-21 17:51:30 +00:00
drh fb077f3c50 Prevent an infinite loop in rtree that can result from a corrupt shadow table.
FossilOrigin-Name: 085667180b230587abb82abfdd14da8859e23620994d5cf152236b64c756dd04
2018-12-21 16:53:58 +00:00
drh 1429eca9d4 Fix the RTree extension so that it correctly ignores constraints that it
does not understand, even if they are against a dimension column.

FossilOrigin-Name: ed8531e57596f0d5911a05a26d5ae61e1eccfaadee49219d7f6e212cac288238
2018-12-21 15:13:49 +00:00
drh 558ef11ad9 In RTREE, turn an assert() into an if() because the condition can
sometimes be false when dealing with a corrupt database.

FossilOrigin-Name: 99bce4358beb5dbaba47048ee2eec5c376dcd86e5b1462238a37ea4c5f3d77db
2018-12-21 13:30:34 +00:00
dan e1e28ec35c Remove an assert() that could fail on a corrupt db from fts3_write.c.
FossilOrigin-Name: 4cdcda408a4edcd2845584ddef64f0efdd2b4cc030afbc05fc2b8b555c69d3f6
2018-12-21 11:53:43 +00:00
drh 94f4f873b2 Do not set the Cursor.seekOp test variable in the OP_NotExists opcode.
This is a change to test logic only and does not affect deliverable builds.

FossilOrigin-Name: 98f343077887c4d3fc2ca3bbc7f20c80ec37b0e521d70af9c986ab80bb2c7903
2018-12-20 22:08:32 +00:00
dan e46201e264 Fix a bug in the code that detects self-referencing rows as part of foreign
key processing. Fix for [50d2a6c2].

FossilOrigin-Name: 16fff05347f42fe9fa0f3150290b98b59a9bb921e49dc07ca397aa1de7a7e17d
2018-12-20 17:32:33 +00:00
dan 16dd3985f0 Fix a segfault caused by using the RAISE function incorrectly (library now
returns an error instead of crashing).

FossilOrigin-Name: ddf06db702761d663119d508afe21d7dfebe963d576bb42fc2f2024205ab86f8
2018-12-20 15:04:38 +00:00
dan 397a78d4a1 In defensive mode, do not allow shadow tables to be renamed using ALTER TABLE.
FossilOrigin-Name: 23e200da5cfbde0798e67cd9e016e4a1cd73b67981e1af841493fcd123d8f547
2018-12-18 20:31:14 +00:00
mistachkin 99490934ae Move variable declaration to address compilation issue (C89).
FossilOrigin-Name: d64f248da3ce7762fe2c17fbc83f7bea9ffca73723bb3ad0982a85320839da90
2018-12-17 22:19:57 +00:00
dan bef06d2637 Fix errors in comments in fts5.h.
FossilOrigin-Name: 4002790d9418289f3e090c694f651a89d8f523119c8ce2f396999b0387148241
2018-12-15 07:12:34 +00:00
drh 3c2db5def6 Fix harmless compiler warnings.
FossilOrigin-Name: 27221c69901d2b4546167639c4a3c8f54b2e18820f1346870fa26b7c919027db
2018-12-14 18:11:02 +00:00
drh ae10474125 Fix possible integer overflow while running PRAGMA integrity_check on a
database file with a badly corrupted freelist.

FossilOrigin-Name: 395599116d801324f0763e59bc5e2fc8622aa5b7572e0c1c9a982efbb3cc8280
2018-12-14 17:57:01 +00:00
drh d7a5e49840 Back out the expansion of the temporary buffer size from
[32754ca6f86da816] and replace it with an explicit test for buffer
overreads.

FossilOrigin-Name: 8ba3d9f38090c4bbbcffba1930e5c26f69ff61f49b72a4a5a59253d37341380f
2018-12-14 16:20:54 +00:00
drh e7acce66b2 Avoid a buffer overread in ptrmapPutOvflPtr() that can occurs in a
corrupt database file that has large entries and uses autovacuum.

FossilOrigin-Name: f8b781cf41800e9f61a1c5376404a97e76a2bbbcaa17396d42be62f731363947
2018-12-14 16:00:38 +00:00
drh fa94d492c8 Fix a harmless compiler warning in Sessions.
FossilOrigin-Name: fc9791ea987352e3e1322fbb7f833c23b402432af8249f9d397c6f7456788637
2018-12-14 13:47:17 +00:00
drh d6401e869b Expand the size of the temporary page used during btree rebalancing by a
few bytes, to avoid problems with small buffer overreads that can occur
on corrupted database files.

FossilOrigin-Name: 32754ca6f86da8165e274f98f35fc3df3aebd273e9da08387e2d0c3c89abda0f
2018-12-14 13:35:48 +00:00
dan fffaf23013 When saving the position of a cursor at the b-tree layer, allocate a few extra
bytes at the end of the buffer used to save the key. Otherwise, if the key is
corrupt, the code that restores the cursor position may overread the buffer by a
little.

FossilOrigin-Name: 160b1e31c0f27257c06c2987af9ec3a64abfacb2150325b72e8ccd3d217b5baa
2018-12-14 13:18:35 +00:00
drh 5a1ce4369f Fix a problem with bytecode generation when a query involves two or more
indexes on expressions connected by OR.
Ticket [d96eba87698a428c1ddd0790ea04]

FossilOrigin-Name: 7e4ed8b5c2047b69bbb037497111e56e465a4d9f8afca3b337f9ac744471dc4a
2018-12-14 11:16:52 +00:00
dan 7525b87b6c Posible fix for [d96eba87].
FossilOrigin-Name: 89a25abfcd069aebdf817890e5c27f46de3000fb858ae01029e4528f9d677567
2018-12-14 08:40:11 +00:00
drh d8cc8b30b4 Fix a bug in fuzzcheck that cause it to overlook a pointer-map bug that was
trigger by the fuzzcheck test data, and also fix the pointer-map bug.

FossilOrigin-Name: cc42dd15100db28a9796254f69a4e367ea5eae29f546be055017cf3e12aa66ba
2018-12-14 03:16:17 +00:00
drh 203b1ea0f5 Detect when an attempt is made to write to a pointer map page that is also
being used as a btree page and report corruption.

FossilOrigin-Name: 3036fd71ac7063359b04a0ed54a6c63a380eb7ff75cd29ed27486d4259066aee
2018-12-14 03:14:18 +00:00
drh e45985b595 Fix a bug in the custom in-memory VFS used by fuzzcheck. This bug masks
other bugs that should have caused some existing fuzzdata7.db entries to
fail, and so this fix is initially on a branch until those other bugs can
be repaired.

FossilOrigin-Name: e0994e99955cf11f23dba029b5ed7f150f467887558848d5f03510e2fb5855f9
2018-12-14 02:29:56 +00:00
drh f354e77f3d Fix the dbtotxt decoder in the CLI so that it ignores excess bytes.
FossilOrigin-Name: 18740bd448887d618fafee0b5a7c004aa2f2632244f7d29e2428772baa36b828
2018-12-13 22:58:52 +00:00
drh 6301c43f23 dbfuzz2 found a NEVER() that is sometimes true.
FossilOrigin-Name: 1201615cbbd3070158ea5fab3d2c8c95f41b25d6da096a44cb9257a7b7405efc
2018-12-13 21:52:18 +00:00
drh 8061ad8abd Add extra tests for database corruption inside the defragmentPage() routine,
as dbfuzz2 has found ways for corruption to leak into that point.  Add test
cases in fuzzdata7.db.

FossilOrigin-Name: 997b65117f8c12dba5fb85434fde9765cdb0d2a49cc3e31979abba3e21350086
2018-12-13 21:11:22 +00:00
drh 1641f11f4c Fix a problem in sqlite3BtreeDelete() in which deleting an entry from a
corrupt database can leave a btree page with zero cells.

FossilOrigin-Name: 682053d1e603c21b8085c39db618a39b23ec8d2c4d822fd19634db0e03038ea2
2018-12-13 21:05:45 +00:00
drh f7e74904cc Add the "decode_hexdb" TCL command to testfixture. Add the dbfuzz001.test
module to demonstration how to use decode_hexdb to deserialize a dbtotxt
database description for use in a corruption test.

FossilOrigin-Name: 1f583c53f3b7318c69f6e235934d97ef9493278feeab0837217076d7d071c35b
2018-12-13 20:49:43 +00:00
drh 2c8ee026ba Fix the CLI to keep proper track of input line numbers for use in error
messages, even after processing in-line hex database inputs using
".open --hexdb".

FossilOrigin-Name: 7ffa9858162774cba03a565a7b65135d9e8bfea726af1a29de6898f66c4b1261
2018-12-13 18:59:30 +00:00
drh 60379d4243 Fix the CLI so that the ".open --hexdb" command works even if it is contained
in a subscript that is read using ".read".

FossilOrigin-Name: 67a87399b8ad8f1ce3052ee3159906f5c6df3d7b5691b3acac856bd2f1c82088
2018-12-13 18:30:01 +00:00
drh 51caa04836 Merge the dbtotxt enhancement from trunk.
FossilOrigin-Name: b386fce9a23e628dce7362dcca2904b8d0af6da58a6fe6eb7f12f058a8363e49
2018-12-13 15:52:31 +00:00
drh 3374648545 Add the "dbtotxt" utility program and the ability to read "dbtotxt" output
as a deserialized input database in the CLI, using the --hexdb option to
the ".open" command.

FossilOrigin-Name: e3bf1d3ea5f748c5142c2403813fdace5aedc1fc68f0dcd5eae40a2fe763fedb
2018-12-13 15:06:26 +00:00
drh 69a66a7be1 Include OPTS in the build of dbfuzz2.
FossilOrigin-Name: eac9c0c49650b008951318a2225b932709a0a8dffbb01ed57684c40357b2e25c
2018-12-13 12:37:13 +00:00
drh bc1be957c1 Fix the Makefile so that it honors CFLAGS when building sessionfuzz.
FossilOrigin-Name: 54231ac4ca506e6c34c31bc02bb8d3db22f14e1b01679bc70529b165d7dabb83
2018-12-13 12:28:01 +00:00
drh 5881dfea2c New database corruption test cases discovered by dbfuzz2. The new cases
have been added to test/fuzzdata7.db, but have not yet all been fixed,
so tests will not currently pass.

FossilOrigin-Name: b4210d320c6426d2838d4cc08709fdfd015c1c95fcad9a5f9e8fd390c23b9fad
2018-12-13 03:36:13 +00:00
drh cb0e04f929 Fix another problem found by Matthew Denton's new fuzzer.
FossilOrigin-Name: 2b690dbdffe144bd69ca0aa291c230faf3d9d73f7a2985d50f016fe54003f9a9
2018-12-12 21:34:17 +00:00
drh 89b6de0357 Remove an ALWAYS() from a branch that is not always taken. The test case
found by OSSFuzz has been added to TH3.

FossilOrigin-Name: 5c7dab85535ac42c021977dbd4a39cef5a72e3d9dccff1c5ca5570a1780516cd
2018-12-12 20:11:23 +00:00
drh 03c5c21328 OSSFuzz found a case where an assert() inside sqlite3ExprCompare() can be
true.  Test case added to TH3.

FossilOrigin-Name: 23b62fb160d86dc9d9073bcc714601f5b7695f96abd893eafecf4b2e565b87f2
2018-12-12 11:23:40 +00:00
drh cfc078318c Small performance improvement in sqlite3_step().
FossilOrigin-Name: d1db8d5894450b24bb0335983503d9bbf6cc48a0ae4b83291283fb2d32b6b25b
2018-12-11 12:51:46 +00:00
drh 368bfe8b00 Small performance improvement in the sqlite3_bind() family of interfaces.
FossilOrigin-Name: 1dc0c3df32572f09265fc73eeaa0748159e0e9523b9b2d6768b834a29c909968
2018-12-11 12:20:41 +00:00
drh 1a6c2b1d38 Further refinements to the sqlite3_normalized_sql() interface. TH3 now
gives 100% MC/DC on that interface.

FossilOrigin-Name: c96bf6cca220e363b099455ce35195ce7e89d374a52dc787f56e7b11e587bced
2018-12-10 20:01:40 +00:00
drh 21b9225ff5 Refactor the sqlite3_normalized_sql() implementation.
FossilOrigin-Name: 06e955e5d2b857b9ce94a73fb174b620c101bdb160842f9a0e958bdb48e8c987
2018-12-10 18:15:44 +00:00
drh 9042ff214b Fix issues with the new normalizer.
FossilOrigin-Name: 057d7d40c56b7416a59a79cb627b2b3e5837eca2d6dbcb50127baaadf1941f51
2018-12-10 16:49:33 +00:00
drh 643d855da9 Refactor the sqlite3_normalized_sql() implementation. This is a
work-in-progress. There are still issues.

FossilOrigin-Name: a4c890b0af9786295e6df05022009d8946550adb873535c610be805c2b7a4083
2018-12-10 16:00:57 +00:00
dan dc6214ee39 Fix a problem with using "<db>-vacuum" (the default) as the state database
when resuming an RBU vacuum.

FossilOrigin-Name: c878d741733a897d47a1a0b57b454bc9095ce302b48cc01089336d5d20e2a24c
2018-12-10 08:41:32 +00:00
drh fb34559eb1 Add support for the VACUUM INTO command.
FossilOrigin-Name: 77f150b8b46761f4f62f9d8926c10a95a70589a4525393fc16b321bd98c083a7
2018-12-10 01:48:29 +00:00
drh 4d342827d6 Fix the shell1.test test for the new format of the .backup command.
FossilOrigin-Name: 9748d7995bc1dd632d66d2d326048d50e29c6f5e6993d5a6294d14421d2cb72f
2018-12-10 00:41:28 +00:00
drh 2134eb5721 Merge fixes from trunk.
FossilOrigin-Name: ab1e58fac9e3f9d7d90cefb39f8f145d211d38ec0cb393208c4531cc646056c1
2018-12-10 00:40:43 +00:00
drh ce706c2cf3 New test case for ticket [1d958d90596593a77420e59].
FossilOrigin-Name: b7bf3c9832bde26b359f4d58ebcf7788c500586d311387d022192ed65a126252
2018-12-09 18:55:05 +00:00
drh d4a4a36171 Do not use a partial index as a table scan in an IN operator.
Fix for ticket [1d958d90596593a77420e59].

FossilOrigin-Name: 15bc915dd7ae25bfdfbe357c3792db3639799e4d121c6b5b24297af2d6d7129e
2018-12-08 20:30:31 +00:00
drh a50bffb85e Add the --async option to the ".backup" command in the CLI.
FossilOrigin-Name: 7b6a605b1883dfcbe237b0a58f6f0c233a109e88b521c3b3d97198526c8a0317
2018-12-08 01:09:14 +00:00
drh 2f6239ed4e Allow the INTO clause of VACUUM to be a text-valued expression.
FossilOrigin-Name: af172b53b46759f491f522356e14c5e2374d3f25ec70fbc1e100cadded8f9b22
2018-12-08 00:43:08 +00:00
drh 7464f578ed Do not allow VACUUM INTO into a file that already exists.
FossilOrigin-Name: 92f70e0fa3c9de7fde046f11cc0a7c2800511bb5ace8e68c845133931607616e
2018-12-07 23:48:41 +00:00
drh 52993b31e1 Merge the VACUUM simplification from trunk.
FossilOrigin-Name: 93d92a0a5d21a1856316c0205ecaa253691b6e5349b552d43027005676d14820
2018-12-07 20:40:12 +00:00
drh 83da91b7bd Remove a line of code from VACUUM that is no longer needed, due to the
change that allows ATTACH to run within a transaction.

FossilOrigin-Name: a92c398fc5df142ff1459c1be4a6832f2219bc7fabe5789535be3bbd41a4269b
2018-12-07 20:26:29 +00:00
drh b0b7db91b8 Prototype implementation for the VACUUM INTO command.
FossilOrigin-Name: 036e3320a4af36c1311b25b2e504b0079c8b33df8ad7b7e5fddad07150e6f87d
2018-12-07 17:28:28 +00:00
drh 893bd3751b Fix the sqlite3_normalized_sql() interface so that it renders
double-quoted string literals as "?".

FossilOrigin-Name: 0d8e150434bbd179696f1ffe71d1e06cb3d43e6468496c7e481fca8486387bad
2018-12-07 16:32:11 +00:00
drh 62a88294e8 Fix dbfuzz2.c so that it works with -DSQLITE_OMIT_INIT
FossilOrigin-Name: 9ad796a8822f1b7e1e99b73c2cc5be59dbfd85e9c27f3e795c29a2c002c611d1
2018-12-07 03:01:07 +00:00
drh b9a0e668f3 Fix the sqlite3ExprDup() function so that it correctly duplicates the
Window object list on a Select that contains window functions.  Fix
for ticket [f09fcd17810f65f717].

FossilOrigin-Name: db5ed2268eda2e6c1df15cd8df4176463d89103b8fda33ba9a0604f0d92bd4da
2018-12-07 01:56:26 +00:00
drh a37b6a5e31 Performance improvement: Avoid using sqlite3WalkerSelectExpr()
and sqlite3WalkerSelectFrom() twice, so that the compiler will in-line their
implementation.

FossilOrigin-Name: 2b9258b8b0342330ebe8c22b59ec276fd042a05547d15b24fdf29e16280868de
2018-12-06 22:12:18 +00:00
drh a838997544 Fix the sqlite3ExprDup() routine so that it makes complete duplications of
subqueries containing window functions.

FossilOrigin-Name: 940174543e87184a0278fcd02e8a096a11510174d9c1d65d21878819790ddaff
2018-12-06 22:04:19 +00:00
drh bb383df7c6 New test case that still hits an assertion fault, just to prove that the
previous checkin merely made the problem more obscure and did not completely
fix it.

FossilOrigin-Name: a9a3b532643b5f106509bb29c3e6bc9d41ec5b2da5a0cd4067898f376eb626a2
2018-12-06 19:56:20 +00:00
drh 11df7d2839 Simplify the query flattener so that it does not duplicate the WHERE clause
of subquery that is being incorporated into the outer query - copies it
directly.  This is more efficient.  And it also fixes the specific test case
show for ticket [f09fcd17810f65f71789525] but it does not resolve the more
general problem that sqlite3ExprDup() does not correctly duplicate expressions
that contain subqueries with window functions.

FossilOrigin-Name: f1b18d44ff855573542c1947a42d4025dff54cacc13dac14d044521762ea9736
2018-12-06 19:15:36 +00:00
drh d5b44d60c7 When masking bits off of sqlite3.flags, make sure the mask is 64 bits
in size so as not to accidentally mask of high-order bits.

FossilOrigin-Name: 53d3b169d8e1892163526caff2c843302c92e280fdeff6831e23a9bb15b82be3
2018-12-06 17:06:02 +00:00
drh 70d5dfba68 When saving off the value of sqlite3.flags, take care to preserve all 64
bits.

FossilOrigin-Name: 9c6dbcfab5952cf4e54de30cf9cee48f988b91a35dc3f04d64d6d994dd84a076
2018-12-06 16:50:55 +00:00
drh ec8fc62c42 Issue a warning whenever a double-quoted string literal is used.
FossilOrigin-Name: ac9ad5043026b30394812457e1535df2759aea0d4510029561e92e386672796f
2018-12-06 16:11:14 +00:00
drh 3e2d47d49f Invoking the sqlite3_trace() or sqlite3_trace_v2() interfaces cancels
any sqlite3_profile() that is running.

FossilOrigin-Name: ec63d3506bd429560077f82a4c5ed9d189780789fe1c134fff4f3b8733be1a3f
2018-12-06 03:59:25 +00:00
drh fc08a1aef8 Remove the unused pColHash field from the Table object.
FossilOrigin-Name: 3a2c047989facc3461c63a2f9eed412014c951035a80da47c52a70139fb552de
2018-12-06 02:01:17 +00:00
drh 974b24896a Fix a potential NULL pointer dereference that can occur in ALTER TABLE
following an OOM.  Test case in TH3.

FossilOrigin-Name: ea50815bf80ab0d36891518f209acbcd3d6d8d84529741bffd4e841874c78aff
2018-12-06 01:53:12 +00:00
drh 1f169fefca Fix a missing mutex in the sqlite3_normalized_sql() interface when it is
called on a prepared statement that did not previously have a computed
normalization of the input SQL.

FossilOrigin-Name: 1a1a59c6c570879c8f318bbc132103c0285088ba233dd8c32e049b86419347b0
2018-12-06 01:08:58 +00:00
drh 7b278f0c3d Get rid of the hash table used to track IN operators in the
sqlite3_normalized_sql() implementation.  Use simple integer variables
instead.

FossilOrigin-Name: 272dc74fd0304d6a28aaa8798d13e2f950c1a24d92d17519e3c32aef86714586
2018-12-05 23:56:02 +00:00
drh 253a6af532 The sqlite3_normalized_sql() interface should not be transforming quoted
identifier names into wildcards.  Fix this, and at the same time simplify
the code substantially.

FossilOrigin-Name: e8540377ec66fa5f9ae3c93bedb5c094057698199c37fc211f7ea95429e815e4
2018-12-05 23:45:46 +00:00
drh d4a4dd6ebc Fix an imbalanced lock problem in sqlite3Normalize() introduced by the
simplification in [94ea6379178e3ff6a].

FossilOrigin-Name: f69624373e33c4d370a9264a317ffdb0adbce967a950f243de2b41161a8c7ded
2018-12-05 21:55:39 +00:00
drh 8a65380de9 Increase the version number to 3.27.0 for the next development cycle.
FossilOrigin-Name: 8f8d682825d065bcaebda4cba63f8b67789b923d8b62eb7c576a5bc01536f577
2018-12-05 19:42:59 +00:00
drh 19efd0db41 Simplifications to the sqlite3_normalized_sql() implementation.
FossilOrigin-Name: 94ea6379178e3ff6a0d1d5819ca4ac558bdadb1ca8a3637c797079db7dc0cd61
2018-12-05 17:48:57 +00:00
dan ea41251eb0 Ensure that ALTER TABLE modifies table and column names embedded in WITH
clauses that are part of views and triggers.

FossilOrigin-Name: f44bc7a8b3fac82aa5598e9bdaf65ea4dd3c331cf90c1d5ba26ff1698e92c230
2018-12-05 13:49:04 +00:00
drh 707821ff72 Enhance the sqlite3_normalize_sql() interface so that it works even if the
prepared statement was not initially compiled using
SQLITE_PREPARE_NORMALIZED.  Enhance the ".trace" command in the CLI so that
it is able to access the full scope of functionality provided by 
sqlite3_trace_v2() and in particular so that it is able to show normalized
SQL output using the newly enhanced sqlite3_normalize_sql() interface.

FossilOrigin-Name: 7da617e97eb905cb009c47403786682b911e32a630f266e1c53ea72836fc88b5
2018-12-05 13:39:06 +00:00
drh 731dd6ebda Add the "index_usage" utility program.
FossilOrigin-Name: df95455213c9d1db7229e94217e78edc05cbf9e40f39528105494ea6ac52be94
2018-12-04 16:51:42 +00:00
drh 04c6747a80 Performance improvement in sqlite3_step() by creating a new mTrace flag
for the legacy xProfile pointer that is set by sqlite3_profile().

FossilOrigin-Name: e28584e8bc7b7405380064b60523fa6191f827f74075f6d117eb7732d752ba5e
2018-12-04 14:33:02 +00:00
drh b7de827137 Small performance increase in sqlite3_step() for the common case where
it returns SQLITE_ROW.

FossilOrigin-Name: 893448265299f4c70c32c8e92ea66f8d33c1c213b21701f73fa3815514cd5ef6
2018-12-04 13:51:26 +00:00
drh cfc45b1021 Reduce the size of the parser tables generated by Lemon by splitting the
yyRuleInfo structure into separate yyRuleInfoLhs and yyRuleInfoNRhs arrays.

FossilOrigin-Name: 70fe8ec2ae3099b8773834c7ac2e56768addbecd57956ac523e71a7dc264049c
2018-12-03 23:57:27 +00:00
drh f8c2fea195 Remove the unused sqlite3Fts5UnicodeNCat() function.
FossilOrigin-Name: 7149dacf1d440a19f62808b4591c3fa8da202b2ec742d5490a63f2ec005ff9e7
2018-12-03 17:40:46 +00:00
dan e89feee5c3 Add the "remove_diacritics=2" option to the unicode61 tokenizer in both FTS5
and FTS3/4.

FossilOrigin-Name: 06177f3f114b5d804b84c27ac843740282e2176fdf0f7a999feda0e1b624adec
2018-12-03 16:14:49 +00:00
mistachkin 8c53b4e7f6 Update the autoconf makefile for MSVC.
FossilOrigin-Name: 675aba1f8b989cfd99370704ecb09031026dc3321cccad122ea91d816e02fdba
2018-12-03 14:58:07 +00:00
drh de72d2a81a Remove two lines of unnecessary code, for a very small performance increase
and size decrease.

FossilOrigin-Name: 15824ccda0f110794a479b58fbf36082d8c383f34bae9dc0921d96547fb37869
2018-12-03 01:58:02 +00:00
drh 4a5cff73a7 Fix a parser bug in the use of parentheses around table-valued functions.
FossilOrigin-Name: 58a51123d1a6381cc67d3c64ba3468ec5a92c299ad6fd86de0b843d0ffafb846
2018-12-03 01:47:41 +00:00
drh fdc75c9f53 Omit a line of code that has no affect on the outcome.
FossilOrigin-Name: 5d933aa659eb7a13f9ab44fe7762be292a1c3c75b957a3b7e0bc6188257b62f4
2018-12-02 01:15:16 +00:00
drh 04ab586bf3 Very slightly smaller and faster.
FossilOrigin-Name: 27798f17f567ad065f8a99effcb287bc241df7b450330ef890d192c70528e62b
2018-12-01 21:13:41 +00:00
drh 4f939e86df Version 3.26.0
FossilOrigin-Name: bf8c1b2b7a5960c282e543b9c293686dccff272512d08865f4600fb58238b4f9
2018-12-01 12:34:55 +00:00
drh 1ba88c7f1d Fix a typo in a comment. No changes to code.
FossilOrigin-Name: 23684cb841ac2cb0d69e5470253bd96feb733762a7553b952a08470834fe85fa
2018-11-30 20:59:00 +00:00
drh f7c44f9bd2 Fix the name of the trig function approximation in geopoly. No functional
changes to the code.

FossilOrigin-Name: 33576b12b450a37b467ba012e77b297eb80d7147b12a5b23302009bb32455720
2018-11-29 12:00:02 +00:00
drh 4d2f81eb73 Fix a typo in a comment used to generate documentation. No changes to code.
FossilOrigin-Name: 62360ceae9d2321003c49cfac3e9f915969a0da12d02c3e633cfa898c0a68566
2018-11-28 19:23:28 +00:00
dan 3a85a298c9 Update incrvacuum.test so that it works with builds that do not support mmap().
FossilOrigin-Name: 8eb62fd5fa9adb88de51aa812270dbdb32ee5cacd636d200e658c507a14a035b
2018-11-29 01:20:51 +00:00
dan 909f78cbd8 Update some test cases to account for SQLITE_OMIT_VIRTUAL_TABLE builds.
FossilOrigin-Name: b53a9a3dc6b0422a102b245451769b0cd8c0d67090fefabf7cb3a65137a73771
2018-11-28 11:49:46 +00:00
drh 26505e5f51 Follow-up to [0bf0fd242b93c3bd30]: only reset the pager when adding a
new codec, not when overwriting an existing codec.  Also, improve a
comment in the pcache1 subsystem.

FossilOrigin-Name: 5c040fdb013d178e5dffa300621eab91b92beb085ffb9ef2ba08f6bf1dd4013e
2018-11-28 11:09:09 +00:00
dan 49f6a0d82a Changes to Makefile.in to allow testfixture to be built with
SQLITE_USER_AUTHENTICATION.

FossilOrigin-Name: 7b510f59fd2cf68331c35ef6b4c2bcf092adf1120ea22be74d1bab1f42a171f5
2018-11-28 08:24:41 +00:00
dan 1af016b7f4 Remove -DSQLITE_USER_AUTHENTICATION from the "Unlock-Notify" configuration.
Create a dedicated "User-Auth" configuration for testing this feature.

FossilOrigin-Name: 8c41024fbba8c70b671c63a5719c6757f0e6dc731ce52caa755edbb8e21d6944
2018-11-28 08:09:08 +00:00
dan f6e015fab9 Fixes for SQLITE_OMIT_VIRTUAL_TABLE builds.
FossilOrigin-Name: 9bcdec85e21a5228c700f7373b92ae7ea14b585bcda34235b605be4f7ec15a15
2018-11-28 08:02:28 +00:00
drh f6fa95b81d Always enable SQLITE_ENABLE_DESERIALIZE for the MSVC makefile as this is necessary
to get releasetest.tcl to work.

FossilOrigin-Name: d362dedba3637013d654f2a890fc7b61476f2adeb6bf3bffb4e715c1d1d0b7c2
2018-11-28 01:45:05 +00:00
dan 63e50b9ed6 Fix a failing assert() in sqlite3ResetAllSchemasOfConnection().
FossilOrigin-Name: 0ea049f342d11c676e148239e45d252164081362e921a4beb735d6899eb77344
2018-11-27 19:47:55 +00:00
drh fcee090746 Improvements to two cases in pragma4.test.
FossilOrigin-Name: 3c893d9bcc34c391505b08cc35808dd3abddf3c5d952798334c296547bcae6a6
2018-11-27 17:02:38 +00:00
drh 746a1515b2 Remove the sqlite3PagerUseWal() routine which was made obsolete by
the [81629ba91475938b6ad] change.

FossilOrigin-Name: 4331b4990cbc1221d94fadd376dfc6efe83f67836aef00912126da4c924bf659
2018-11-27 14:41:07 +00:00
drh 60ce5d3135 Add a simple test case for Lemon. Always include assert.h in the
Lemon-generated parser.

FossilOrigin-Name: 9c9c46dcbe92aeabe3d5675bb69681b6dfd53798bc67e6a2ceba67ed3c4fb0af
2018-11-27 14:34:33 +00:00
drh b8a762827c Fix to the error handling logic in the Lemon parser template. This does
not affect SQLite since SQLite does not use that part of the Lemon parser
template.

FossilOrigin-Name: c6dfc59eb12a02d35b708b5d94239377c79f688fa572f72bad51a157b1bf599c
2018-11-27 14:03:11 +00:00
dan bcdef69482 Add an "#ifndef SQLITE_DISABLE_FTS4_DEFERRED" block around function
fts3EvalDeferredPhrase() in fts3 in order to silence a compiler warning.

FossilOrigin-Name: 6f4b0d0494446d46ac22b17650a25b025995cc545cac8fbc4776cf9dd388bcd8
2018-11-27 09:57:10 +00:00
drh eea8eb6d04 Do not allow direct access to internal-use SQL functions such as
sqlite_rename_column() and sqlite3_rename_table() except when the
new SQLITE_TESTCTRL_INTERNAL_FUNCTIONS flag is set.

FossilOrigin-Name: 6e1330545e7b74fe5f1f20751a3425e2788441485fc07fcb7626e448c72027ce
2018-11-26 18:09:15 +00:00
drh 49b269e095 Minor comment enhancement in alter.c. No changes to code.
FossilOrigin-Name: 12920bcb99b25e147e1877ee001bc551a743e3530c954fe2b45a18a4eef9eeff
2018-11-26 15:00:25 +00:00
drh 52f0c6205c Fix a bug in the geopoly_ccw() function. Test cases in TH3.
FossilOrigin-Name: 773c5c1d9c0ec40c51949c38c9dc17e778086f3f92791cca9b85288de0076dab
2018-11-24 20:44:46 +00:00
drh eafb9a0ae5 Make the winTruncate() method of the windows VFS be a no-op if there are
outstanding references to the memory-mapped pages.  Otherwise, memory might
be deleted out from under those references when the file is remapped during
the truncate operation.

FossilOrigin-Name: ffce4aac18dacbf2a3112ae2ab56c7db20cb164f179683d90a66ef38f4a98f2b
2018-11-24 17:46:07 +00:00
drh 48ea97e5dd Remove the unused mmapSizeActual field from the Windows sqlite3_file
implementation.

FossilOrigin-Name: 0e7aa62227d1d9c3540b54d7caf44a1ce7ccfa706672fc41dbb2be477ab3a667
2018-11-24 16:07:21 +00:00
dan 09236755ee Fix a problem reading from temp databases in SQLITE_DIRECT_OVERFLOW_READ
builds.

FossilOrigin-Name: 81629ba91475938b6ad528e7b1dbef4ad22239782bb2e9c1bb59413aba11da87
2018-11-22 19:10:14 +00:00
drh 8055a3ead4 Improvements to the ossfuzz.c fuzz-testing module so that it works with
-DSQLITE_OMIT_PROGRESS_CALLBACK and with -DSQLITE_OMIT_INIT.

FossilOrigin-Name: d343f7d6b05865c282eb73a0e39dc396f2927982af45b3d045de03ef73715693
2018-11-21 14:27:34 +00:00
dan 3c425484a7 Fix problems in pragma.c causing some PRAGMA statements to test the wrong
schema-cookie before proceeding, or to try to open cursors on the wrong
database ("PRAGMA foreign_key_check" only).

FossilOrigin-Name: 6982f52f579d20b8a2965373731d41622bda7f09fbf82cc005bb378321829f4c
2018-11-20 18:09:59 +00:00
drh 2d588b8c08 Fix the regexp used to recognize libdl errors on OS-X.
FossilOrigin-Name: 1740025307531a52e4f0641e2e74dc14715130858f2e9236be13b66924f00220
2018-11-17 14:59:35 +00:00
drh 92cd307c1c Fix harmless compiler warnings that appear with SQLITE_OMIT_EXPLAIN.
FossilOrigin-Name: 5fff00b0d5eb634d40e767671d5a0e8bd263d15d88abe531f6072f01bc789568
2018-11-17 14:26:45 +00:00
drh 0c5a95e43a Remove a C++-style comment.
FossilOrigin-Name: 645232f2b9ce3ee345b1d22c0db1265e39bb674bef9ab6fb10d5bee8ab696787
2018-11-17 14:19:34 +00:00
dan 8e2d4ad30c Fix a problem in test script e_fkey.test.
FossilOrigin-Name: acfd0a05a8957728c1f0eb936f4121ce26f291f20dd583bd57ce2bb271617d3f
2018-11-17 13:08:07 +00:00
drh d905113e97 Fix a test case so that it works on windows.
FossilOrigin-Name: 2d92d25fae5d9757866a0d0b30427b50d635e9b05e12df9464f095419fd7ef3e
2018-11-16 20:50:53 +00:00
drh 20b3fc4db1 Add SQLITE_CONSTRAINT support to the xBestIndex methods on dbstat,
sqlite_dbpage, and zipfile.

FossilOrigin-Name: 5cd24e552b4fed71cfb2e37929371175682f23f1430df2900a87e6a5823d138e
2018-11-16 20:18:07 +00:00
drh d16f26a708 Update the explain virtual table to make use of SQLITE_CONSTRAINT.
FossilOrigin-Name: b2d41ff7027b44ccb5dffc303c47d42f1f6fd66ce22e90450d3a666c73fe8b8e
2018-11-16 19:19:58 +00:00
drh 43579191e8 Fix the JSON table-valued functions to make use of SQLITE_CONSTRAINT.
FossilOrigin-Name: 3f34f4f561c77f8ec88906818f2984dcf8f17d1645bac175e9027595517560bc
2018-11-16 16:04:50 +00:00
drh a69262c0f2 Add an assert() to the generate_series virtual table to verify
assumptions about the design.

FossilOrigin-Name: cd13b499a20a7d476edb8500537edef4c5151410ba0300469ebf0f7ba16964b8
2018-11-16 15:41:27 +00:00
drh e4f90b7075 Update the generate_series() table-valued function to make use of the new
SQLITE_CONSTRAINT return from xBestIndex.

FossilOrigin-Name: 4372ad644dda5a1fa46b6b6070092320c835439b41f598cbc041e9deef786988
2018-11-16 15:08:31 +00:00
dan c86b23bfbc In order to avoid exporting a symbol, use a macro instead of a function to
replace sqlite3_complete() in the shell code when SQLITE_OMIT_COMPLETE is
defined.

FossilOrigin-Name: d584a0cb512815945ef06ee3b5ebadbf2a543b008487f6d098e1e8ab79f61d2d
2018-11-16 14:36:42 +00:00
drh 32dcc847b5 Enhance the xBestIndex interface of virtual table so that if the xBestIndex
method returns SQLITE_CONSTRAINT then that particular combination of
constraints is considered unusable and does not participate further in
query planning.

FossilOrigin-Name: 684013cef6bfcfd920a4aec645df9f5d41ace8b34e75fca61759c1b4f82cc89e
2018-11-16 13:56:15 +00:00
drh eabbf37fae Fix comments and make magic numbers into #defines in the fsdir
implementation.

FossilOrigin-Name: c537c9c3630ca979bdccab977275bfc11cce33ea54adb71a4bd4f46c85f65c6f
2018-11-16 13:06:30 +00:00
dan cbfaa076d7 Fix a problem with virtual table "fsdir" and some join queries.
FossilOrigin-Name: 7fffcee0fc3fe8d036f0d93ec17673992c3edcf2bb454dc90d80142435b37946
2018-11-16 08:36:15 +00:00
drh 6f147c54ef Improvements to the CSV virtual table.
FossilOrigin-Name: 0406ecbbe75513e342040b71fdd342462222dbb3820486b5f745d7865805c00b
2018-11-16 01:42:26 +00:00
mistachkin 23bfa80c19 Fix typos in the previous check-in.
FossilOrigin-Name: 9b37bbf5f338dea962331e4fd73dfa0baae98ba63344a2fa737b845b90ecb0c5
2018-11-15 19:12:22 +00:00
drh 36d248812b Include geopoly in the compiler-warning script.
FossilOrigin-Name: 3d947e1ec0f0800fcad3a04e4876d5247fd1b23e51ed7f49d428fff6683e8a16
2018-11-15 16:56:33 +00:00
drh b1b4a3dbca New fuzztest cases.
FossilOrigin-Name: e8316ba47f566c8d2cb48d9d54308e8869743ef39d35b662a8764b0479aed9e0
2018-11-15 13:51:48 +00:00
drh f9dc5f7726 Fix a potential buffer overread in the dbstat virtual table when processing
a corrupt database file.

FossilOrigin-Name: a62e6b593b59eae44d299842a4d02b9346a0c72a3e1206882f304ab40f2cd5c5
2018-11-13 20:21:52 +00:00
drh 91a21f4d08 Turn on ASAN for the dbfuzz2 utility. Fix a buffer overread associated
with sqlite3_deserialize().

FossilOrigin-Name: 4e38f27b55030e908bd36f32101e26b30f10dbde67e12c8197d0363ee12aa06d
2018-11-13 19:51:41 +00:00
drh 2296b67598 New hyperlinks in comments used to generate documentation. No changes to code.
FossilOrigin-Name: f9755f81b1c0fd29f242dce78a2fba570fa2714d76e93b8563f426a040352513
2018-11-12 15:20:44 +00:00
dan 2639ddc474 Fix a use-after-free problem in the fts5vocab virtual table.
FossilOrigin-Name: ac69d169c61c973448b1d3eef5b8ff0de2d932d7bb74068344cb1b79bd330578
2018-11-12 13:20:00 +00:00
drh 38fa8c9bb0 Add support for read-only shadow tables on virtual tables. Added the
SQLITE_DEFAULT_DEFENSIVE compile-time option that can put SQLite in 
defensive mode by default.

FossilOrigin-Name: 9c685171c4d7ae8615d1489c9621aba79fe4ef1f0e56b75823b88c3e70d127df
2018-11-10 18:23:32 +00:00
dan d01372f1b8 Add the "changesetfuzz" program. For fuzzing changeset blobs.
FossilOrigin-Name: 2bae0e7c1c1393aeb0bb7234865e410c9ca0e3c31cdc8566e9503f70ca7ac64c
2018-11-10 17:37:39 +00:00
dan ad5bafa699 Merge latest trunk changes.
FossilOrigin-Name: b6d549c988e765789c4a81d586170451db9f5da1973dde8aa0329445f915fbb2
2018-11-10 17:36:55 +00:00
drh ab0659fdab Remove a NEVER() that is reachable after all. Reverts checkin [9292d3351c40339].
FossilOrigin-Name: c5dc7fb873b15bd4e4f31b944c9feee78ab7ec2cb74f5fc55b615fd0e2784a88
2018-11-10 04:14:51 +00:00
drh 1ca9a8b9df Merge fixes from trunk.
FossilOrigin-Name: bf88efcec40036e0805940ff6371643dbc518442457d2bc18c711753607ae36c
2018-11-10 03:47:40 +00:00
drh ac4b8dea9b Fix invalid use of unprotected sqlite3_value objects in the sqldiff utility,
when using the --changeset option.

FossilOrigin-Name: a8d65214a567eb1afd703ee4d09d398247e060a610b46097a726364db2861001
2018-11-09 23:41:57 +00:00
dan b430701823 When a table is renamed using "ALTER TABLE RENAME TO", update any REFERENCES
clauses that refer to the table, unless "PRAGMA legacy_alter_table" is true
and "PRAGMA foreign_keys" is set to false (i.e. so that when "PRAGMA
legacy_alter_table" is set behaviour is still compatible with versions 3.24
and earlier).

FossilOrigin-Name: ae9638e9c0ad0c366f93c88a850f6b4cc86881e9f3f9f1e39574d9d83ddd8a6a
2018-11-09 20:04:05 +00:00
drh 0b57d312b7 Fix for ticket [787fa716be3a7f650cac]
FossilOrigin-Name: 531eca6104e41e4301fa2cf58bb8fec811da31e151a0f766c93aece5521d235b
2018-11-09 14:17:51 +00:00
drh 145d0a35d9 In the treeview.c module, break out the display of SrcList into a separate
subroutine, so that it can be invoked while debugging.

FossilOrigin-Name: 8c74065f0031274d9bc711d5d53c39aefcfb2b2679811105974a2c7c7a9e1dcb
2018-11-08 22:53:06 +00:00
drh 635b4ce5f7 Improved documentation for SQLITE_DBCONFIG_DEFENSIVE. Add a NEVER() macro
on an unreachable branch.

FossilOrigin-Name: 9292d3351c40339de7ad6bc26c02e7592e6cdee2592e0c790fae63ccf21ea88c
2018-11-08 17:32:50 +00:00
dan dbc1e9e6a8 Add tests and a fix for program "changesetfuzz".
FossilOrigin-Name: 09b90db56c2d5e3aceae59c6bf1eb07f9db9ef38da29d2162046b88d39e47b86
2018-11-08 14:59:51 +00:00
dan be075d1188 Merge latest trunk changes into this branch.
FossilOrigin-Name: 53cd91d00594f1bd7c0a565a35ec9cac3095a583022d6211158a369e942257b0
2018-11-07 20:13:45 +00:00
dan 5704f455b9 Fix minor issues in the changesetfuzz program.
FossilOrigin-Name: 5c7f024073bc93089f038b5cf122a7a9d5b933f7c1b357f6d20ae925739ffc38
2018-11-07 20:07:28 +00:00
dan 7844d21536 Update the "changesetfuzz" program to work with patchsets as well as
changesets.

FossilOrigin-Name: 75b00fbe884d4bd8ba099d7c0a2e8af2f40fedfdef2d9b624dd51cb66952611c
2018-11-07 17:52:29 +00:00
drh e1857cc015 Performance improvement in subroutine that decides whether or not a table
is read-only.

FossilOrigin-Name: 6e4968b00507c4fdbe7e3c91f3f9cd61c6f1848092ddcf306f9fcb101a47fce7
2018-11-07 16:46:43 +00:00
drh b39dd52adb Merge the onefile permutation fix from trunk.
FossilOrigin-Name: e543bff87d1efc31a5b863085c056ce06c365cc7d9d3fef0ced7521bde536783
2018-11-07 16:12:34 +00:00
drh b7c2cf0aaf More test-case adjustments for defensive mode.
FossilOrigin-Name: 911e8a17a3810cd7042e91a32aba80dc3d6be88320c208e48f7bcee8b22a0ff2
2018-11-07 14:41:08 +00:00
dan 9db4828662 Fix a problem with the handling of SQLITE_FCNTL_PRAGMA in the test_onefile.c
demo.

FossilOrigin-Name: 13e21b7da8fe754e230b09ca0b9f1f69cd9aa20d4407ddd8b95ca3fb18c9abeb
2018-11-07 14:39:22 +00:00
drh 6b758e1d96 Merge the permutations fix from trunk.
FossilOrigin-Name: b753d849fe0524e14ae9367a47e29be76332fafb77bfe13e266aeef1ef6742ce
2018-11-07 13:41:27 +00:00
dan 7d0fa14c03 Partially revert [3e1a2f661], as some test scripts require separate $presql
and $dbconfig variables.

FossilOrigin-Name: cbf85284beb60d068b446c52f000d694a810d4de9096ad2951523a4c88e7334c
2018-11-07 11:56:23 +00:00
drh 6ab91a7a7a Add the SQLITE_DEFAULT_DEFENSIVE compile-time option. Fix up test cases
so that they work with DEFENSIVE enabled.

FossilOrigin-Name: 3212733cb6d1a59516d67a86df7c7b1d2456a1b2e5d7080c26b0e87b2609c65d
2018-11-07 02:17:01 +00:00
dan 005d4c61c1 Update the changesetfuzz program to fuzz changeset schemas as well as data.
FossilOrigin-Name: 141a93c843d501d8bb640228645ead0a83870c1c11e9d4b07ed24b296c69a0b8
2018-11-06 20:08:03 +00:00
drh 0f0d3ddf71 Enable DEFENSIVE mode by default for tests. This requires lots of case of
turning DEFENSIVE off in order to dodgy things to the database for testing
purposes.  No all of those cases are yet handled, so "make test" does not run
to completion.

FossilOrigin-Name: a1d6c6712c3304fd736077432c8c180692cf7d79be7f3a073510b6dab0eb951f
2018-11-06 19:26:04 +00:00
drh aef15e74c8 Turn on defensive mode for running test scripts. Does not yet work.
FossilOrigin-Name: 1c1d24edbb732f2a2002a741c7a7afdd010b67e1b5e6d90ff36c6428897e7612
2018-11-06 15:57:59 +00:00
drh fc25721c9e Only allow shadow table to be written from within a recursive SQL call.
Omit the SQLITE_PREPARE_SHADOW flag.  Some tests are failing because the
tests depend on being able to write to shadow tables.

FossilOrigin-Name: d890c6582524677666e6f5b5817331dec332ade16b2f744cbb8a3c7dd9b63e21
2018-11-06 14:03:07 +00:00
drh 5a65470300 Add enforcement of read-only on shadow tables. This does not currently work
since some virtual tables are attempting to update shadow tables using
sqlite3_exec().

FossilOrigin-Name: f79b47c9859de597d5924870752dd7cab89c8f0608e5cceb2281f6ffb2e91930
2018-11-06 13:37:20 +00:00
drh 84c501bac1 Initial code to make shadow tables read-only to ordinary SQL. The now
xShadowName method is added to the sqlite3_module object and is used
to identify potential shadow tables.  The SQLITE_PREPARE_SHADOW argument
to sqlite3_prepare_v3() is defined.  It is designed to permit writing to
shadow tables, but is currently an unused placeholder.

FossilOrigin-Name: 31942b3dd3f66eb0d9977bf1cadc2f2d7be7967cce2b55784be0b939dfef1985
2018-11-05 23:01:45 +00:00
dan f095a1affb Add preliminary version of "changesetfuzz" program. For fuzzing changeset data
without creating corrupt changesets.

FossilOrigin-Name: 81ac8745faac0bda8d68ac113f1938f0e25208642e8ceb2af452680086454cb5
2018-11-05 20:37:33 +00:00
drh 2d13f6016b Add the SQLITE_DBCONFIG_DEFENSIVE flag.
FossilOrigin-Name: 11d98414eac467affb0b3cf0c7e5cc3d43184fc2b6e7e898bb5277b51ea9e1fa
2018-11-05 19:37:30 +00:00
drh 9196c81406 Eponymous virtual tables appear to exist in all schemas. This is an alternative
and improved fix to the eponymous virtual table in trigger problem that
was previously addressed by checkin [1fa74930ab56171e].

FossilOrigin-Name: b8d35c4a7c99ce3753761e5b81269d52c3c910c603fa70b72549883ba68bc485
2018-11-05 16:38:10 +00:00
drh 383bb4fa62 Disable the IS NOT NULL optimization when the IS NOT NULL operator is part
of the ON clause of a LEFT JOIN. Fix for ticket [65eb38f6e46de8c75e188a17ec].

FossilOrigin-Name: af39661e60f562b9eb10343fd83e8fe21be4d7276111e7853c1179a24cab09ce
2018-11-05 07:53:17 +00:00
drh 0f1c2eb5f2 Correct the internal logic for SQLITE_DBCONFIG_DEFENSIVE.
FossilOrigin-Name: 76094345821246c887a31a234b339d03a78eddbb9fab33b06c3c20797c038349
2018-11-03 17:31:48 +00:00
dan 29d77dc450 Add extra defenses against strategically corrupt databases to fts3/4.
FossilOrigin-Name: d44318f59044162e229a444582692e9788f17b5c404b4eb702f4c2114b22fefe
2018-11-03 16:51:30 +00:00
drh a296cda016 Add the SQLITE_DBCONFIG_DEFENSIVE flag.
FossilOrigin-Name: af3f29d49359af2291b1d9e06e0db76fd000fbd24b4ac84d2668a0d1322efd83
2018-11-03 16:09:59 +00:00
drh c6e519f335 Fix a assert() in the query planner that can arise when doing row-value
operations on a PRIMARY KEY that contains duplicate columns.
Ticket [1a84668dcfdebaf12415d].

FossilOrigin-Name: dcb8c73594ea6b12bad98dc883a585d3e6b925c2ead267dc40332b3d266db5e8
2018-11-03 13:11:24 +00:00
drh 147ad061f6 Enhance triggers so that they can use table-valued-functions that exist in
schemas outside of the schema in which the trigger is defined.

FossilOrigin-Name: 1fa74930ab56171e2e840d4a5b259abafb0ad1e0320fc3030066570a6dd10002
2018-11-02 17:38:39 +00:00
drh 7301e77402 Deploy the sqlite3Strlen30NN() function (argument guaranteed to be non-NULL) for
a small performance improvement.

FossilOrigin-Name: 4a6ad5190b62020d97a7de02c801544f20b7b98145ceff14af1f2834d3057f9c
2018-10-31 20:52:00 +00:00
drh a60c63013e Add support for the SQLITE_PREPARE_NORMALIZED flag and the
sqlite3_normalized_sql() when compiling with SQLITE_ENABLE_NORMALIZE.
Also remove unnecessary whitespace from Makefiles.

FossilOrigin-Name: 790ea39a6585ea9f4dad9e132e1fb0447ac1558f728196580d2c3edee84823f7
2018-10-31 19:01:13 +00:00
drh f8181eaa20 Tweaks to the test_intarray documentation and tests.
FossilOrigin-Name: 7107f0dacf4467430d1ca157cb848dde984e48e529e7d67a88b7594b0f8159c9
2018-10-31 18:24:29 +00:00
drh 05209e9021 Merge fuzz test cases computed by dbfuzz2.
FossilOrigin-Name: e0d30c1862884049098e1fa9b7c228ff8318a40c09e2516ef2dc8db22e2048e2
2018-10-31 01:12:06 +00:00
drh 49272bc728 Improved corrupt database detection in the relocatePage() routine of
the b-tree module.

FossilOrigin-Name: d57873337a2a7a0d717dc7726cd2682b5bea594d2d1ff8f16c2485161fcd6b16
2018-10-31 01:04:18 +00:00
drh c985c2822c Add new fuzzer cases generated by dbfuzz2.
FossilOrigin-Name: 79fdad8b42869100845eed36224602452486d0166c18cec7d343040fdac7379e
2018-10-30 23:45:18 +00:00
dan b74cf4b6ea Update comments in sqlite3session.c to describe the format of "rebase blobs",
as well as changesets and patchsets.

FossilOrigin-Name: bf93f7b56b1d15682988daf3f1c293caf755433defdecd52ba8782fc40e92bd7
2018-10-30 19:14:16 +00:00
drh fd748c6460 Split the SQLITE_WriteSchema flag in two flags, WriteSchema and
SQLITE_NoSchemaError.  Set only WriteSchema on a VACUUM to avoid problems
when trying to vacuum a corrupt database.  With this change, the size
of the flags field on sqlite3 must grow from 32 to 64 bytes.

FossilOrigin-Name: 4f9878107a54356b7105fa1db7655ee239685d570436f6ad4d4221c9bd829b3d
2018-10-30 16:25:35 +00:00
drh a751f39c3f Modify the CLI so that the --deserialize option is only available if it is
compiled with SQLITE_ENABLE_DESERIALIZE.  DESERIALIZE is now off by default
for the main.mk makefile, but on for Makefile.in and Makefile.msc.

FossilOrigin-Name: 90b2a684f775e1468d63bf950119cf0aaa62b5a449f518e7cc513c314191dd14
2018-10-30 15:31:22 +00:00
drh ad9bfa5e07 Improvements to the -fsanitize=fuzzer based database file fuzzer.
(Cherrypick from the rubust-against-damaged-db branch.)

FossilOrigin-Name: 3cc01a0eaf54e3d5adf206825cfcab15edf73bd5aea10dfc497efd78071a17d0
2018-10-30 15:20:35 +00:00
drh 2b3c4af553 In the CLI, when opening a file that begins with the normal SQLite prefix,
open the file as a normal database even if it has a ZIP for AppendVFS record
at the end.

FossilOrigin-Name: 7989bbda70a24611c3b8af96a53114bb53d87a2e1145ec7ad4f1b4cbf8d6040c
2018-10-30 14:36:21 +00:00
drh 60f34ae091 Enable sqlite3_deserialize() in the CLI. The --deserialize option associated
with opening a new database cause the database file to be read into memory
and accessed using the sqlite3_deserialize() API.  This simplifies running 
tests on a database without risk of modifying the file on disk.

FossilOrigin-Name: 5e0129ee9afa7c2d707f8ac9e29ef3583c49bb1d0965085c067d58f828ac8cdf
2018-10-30 13:19:49 +00:00
drh f4452cfbed Fix a potential assertion fault that can occur while trying to DROP a table
from a corrupted database file.

FossilOrigin-Name: 147a9429a558cf34c316ab8f87832e97caff55d92df696ab6fd045466c8c663d
2018-10-29 21:01:28 +00:00
drh 5aa20378f7 Fix minor memory leak in the dbstat extension that can occur following an
attempt to analyze a corrupt database file.

FossilOrigin-Name: cb874fd87384be397008e953242d5773ef5d64e07c3e1ae352a42a25d70597b4
2018-10-29 18:33:42 +00:00
378 changed files with 26365 additions and 3640 deletions
+56 -9
View File
@@ -32,6 +32,7 @@ CC = @CC@
CFLAGS = @CPPFLAGS@ @CFLAGS@
TCC = ${CC} ${CFLAGS} -I. -I${TOP}/src -I${TOP}/ext/rtree -I${TOP}/ext/icu
TCC += -I${TOP}/ext/fts3 -I${TOP}/ext/async -I${TOP}/ext/session
TCC += -I${TOP}/ext/userauth
# Define this for the autoconf-based build, so that the code knows it can
# include the generated config.h
@@ -187,7 +188,7 @@ LIBOBJS0 = alter.lo analyze.lo attach.lo auth.lo \
random.lo resolve.lo rowset.lo rtree.lo \
sqlite3session.lo select.lo sqlite3rbu.lo status.lo stmt.lo \
table.lo threads.lo tokenize.lo treeview.lo trigger.lo \
update.lo upsert.lo util.lo vacuum.lo \
update.lo userauth.lo upsert.lo util.lo vacuum.lo \
vdbe.lo vdbeapi.lo vdbeaux.lo vdbeblob.lo vdbemem.lo vdbesort.lo \
vdbetrace.lo wal.lo walker.lo where.lo wherecode.lo whereexpr.lo \
window.lo utf.lo vtab.lo
@@ -355,6 +356,9 @@ SRC += \
SRC += \
$(TOP)/ext/session/sqlite3session.c \
$(TOP)/ext/session/sqlite3session.h
SRC += \
$(TOP)/ext/userauth/userauth.c \
$(TOP)/ext/userauth/sqlite3userauth.h
SRC += \
$(TOP)/ext/rbu/sqlite3rbu.h \
$(TOP)/ext/rbu/sqlite3rbu.c
@@ -448,6 +452,7 @@ TESTSRC += \
$(TOP)/ext/misc/nextchar.c \
$(TOP)/ext/misc/normalize.c \
$(TOP)/ext/misc/percentile.c \
$(TOP)/ext/misc/prefixes.c \
$(TOP)/ext/misc/regexp.c \
$(TOP)/ext/misc/remember.c \
$(TOP)/ext/misc/series.c \
@@ -455,7 +460,8 @@ TESTSRC += \
$(TOP)/ext/misc/totype.c \
$(TOP)/ext/misc/unionvtab.c \
$(TOP)/ext/misc/wholenumber.c \
$(TOP)/ext/misc/zipfile.c
$(TOP)/ext/misc/zipfile.c \
$(TOP)/ext/userauth/userauth.c
# Source code to the library files needed by the test fixture
#
@@ -471,6 +477,7 @@ TESTSRC2 = \
$(TOP)/src/dbstat.c \
$(TOP)/src/expr.c \
$(TOP)/src/func.c \
$(TOP)/src/global.c \
$(TOP)/src/insert.c \
$(TOP)/src/wal.c \
$(TOP)/src/main.c \
@@ -560,6 +567,8 @@ EXTHDR += \
$(TOP)/ext/icu/sqliteicu.h
EXTHDR += \
$(TOP)/ext/rtree/sqlite3rtree.h
EXTHDR += \
$(TOP)/ext/userauth/sqlite3userauth.h
# executables needed for testing
#
@@ -579,7 +588,9 @@ FUZZDATA = \
$(TOP)/test/fuzzdata3.db \
$(TOP)/test/fuzzdata4.db \
$(TOP)/test/fuzzdata5.db \
$(TOP)/test/fuzzdata6.db
$(TOP)/test/fuzzdata6.db \
$(TOP)/test/fuzzdata7.db \
$(TOP)/test/fuzzdata8.db
# Standard options to testfixture
#
@@ -596,11 +607,18 @@ SHELL_OPT += -DSQLITE_ENABLE_STMTVTAB
SHELL_OPT += -DSQLITE_ENABLE_DBPAGE_VTAB
SHELL_OPT += -DSQLITE_ENABLE_DBSTAT_VTAB
SHELL_OPT += -DSQLITE_ENABLE_OFFSET_SQL_FUNC
SHELL_OPT += -DSQLITE_ENABLE_DESERIALIZE
SHELL_OPT += -DSQLITE_INTROSPECTION_PRAGMAS
FUZZERSHELL_OPT = -DSQLITE_ENABLE_JSON1
FUZZCHECK_OPT = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_MEMSYS5 -DSQLITE_OSS_FUZZ
FUZZCHECK_OPT += -DSQLITE_MAX_MEMORY=50000000
FUZZCHECK_OPT += -DSQLITE_PRINTF_PRECISION_LIMIT=1000
FUZZCHECK_OPT += -DSQLITE_ENABLE_DESERIALIZE
FUZZCHECK_OPT += -DSQLITE_ENABLE_FTS4
#FUZZCHECK_OPT += -DSQLITE_ENABLE_FTS5
FUZZCHECK_OPT += -DSQLITE_ENABLE_RTREE
FUZZCHECK_OPT += -DSQLITE_ENABLE_GEOPOLY
FUZZCHECK_OPT += -DSQLITE_ENABLE_DBSTAT_VTAB
FUZZCHECK_SRC = $(TOP)/test/fuzzcheck.c $(TOP)/test/ossfuzz.c
DBFUZZ_OPT =
@@ -659,7 +677,7 @@ ossshell$(TEXE): $(TOP)/test/ossfuzz.c $(TOP)/test/ossshell.c sqlite3.c sqlite3.
$(TOP)/test/ossfuzz.c sqlite3.c $(TLIBS)
sessionfuzz$(TEXE): $(TOP)/test/sessionfuzz.c sqlite3.c sqlite3.h
$(CC) $(CFLAGS) -I. -o $@ $(TOP)/test/sessionfuzz.c $(TLIBS)
$(LTLINK) -o $@ $(TOP)/test/sessionfuzz.c $(TLIBS)
dbfuzz$(TEXE): $(TOP)/test/dbfuzz.c sqlite3.c sqlite3.h
$(LTLINK) -o $@ $(DBFUZZ_OPT) $(TOP)/test/dbfuzz.c sqlite3.c $(TLIBS)
@@ -672,11 +690,26 @@ DBFUZZ2_OPTS = \
-DSQLITE_ENABLE_DBSTAT_VTAB \
-DSQLITE_ENABLE_RTREE \
-DSQLITE_ENABLE_FTS4 \
-DSQLITE_EANBLE_FTS5
-DSQLITE_ENABLE_FTS5
dbfuzz2: $(TOP)/test/dbfuzz2.c sqlite3.c sqlite3.h
clang-6.0 -I. -g -O0 -fsanitize=fuzzer,undefined -o dbfuzz2 \
$(DBFUZZ2_OPTS) $(TOP)/test/dbfuzz2.c sqlite3.c
dbfuzz2$(TEXE): $(TOP)/test/dbfuzz2.c sqlite3.c sqlite3.h
$(CC) $(OPT_FEATURE_FLAGS) $(OPTS) -I. -g -O0 \
-DSTANDALONE -o dbfuzz2 \
$(DBFUZZ2_OPTS) $(TOP)/test/dbfuzz2.c sqlite3.c $(TLIBS)
mkdir -p dbfuzz2-dir
cp $(TOP)/test/dbfuzz2-seed* dbfuzz2-dir
dbfuzz2-asan: $(TOP)/test/dbfuzz2.c sqlite3.c sqlite3.h
clang-6.0 $(OPT_FEATURE_FLAGS) $(OPTS) -I. -g -O0 \
-fsanitize=fuzzer,undefined,address -o dbfuzz2-asan \
$(DBFUZZ2_OPTS) $(TOP)/test/dbfuzz2.c sqlite3.c $(TLIBS)
mkdir -p dbfuzz2-dir
cp $(TOP)/test/dbfuzz2-seed* dbfuzz2-dir
dbfuzz2-msan: $(TOP)/test/dbfuzz2.c sqlite3.c sqlite3.h
clang-6.0 $(OPT_FEATURE_FLAGS) $(OPTS) -I. -g -O0 \
-fsanitize=fuzzer,undefined,memory -o dbfuzz2-msan \
$(DBFUZZ2_OPTS) $(TOP)/test/dbfuzz2.c sqlite3.c $(TLIBS)
mkdir -p dbfuzz2-dir
cp $(TOP)/test/dbfuzz2-seed* dbfuzz2-dir
@@ -1042,6 +1075,7 @@ SHELL_SRC = \
$(TOP)/ext/expert/sqlite3expert.c \
$(TOP)/ext/expert/sqlite3expert.h \
$(TOP)/ext/misc/zipfile.c \
$(TOP)/ext/misc/memtrace.c \
$(TOP)/src/test_windirent.c
shell.c: $(SHELL_SRC) $(TOP)/tool/mkshellc.tcl
@@ -1115,7 +1149,10 @@ fts3_write.lo: $(TOP)/ext/fts3/fts3_write.c $(HDR) $(EXTHDR)
rtree.lo: $(TOP)/ext/rtree/rtree.c $(HDR) $(EXTHDR)
$(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/rtree/rtree.c
sqlite3session.lo: $(TOP)/ext/session/sqlite3session.c $(HDR) $(EXTHDR)
sqlite3session.lo: $(TOP)/ext/userauth/userauth.c $(HDR) $(EXTHDR)
$(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/userauth/userauth.c
userauth.lo: $(TOP)/ext/session/sqlite3session.c $(HDR) $(EXTHDR)
$(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/session/sqlite3session.c
json1.lo: $(TOP)/ext/misc/json1.c
@@ -1176,6 +1213,7 @@ TESTFIXTURE_FLAGS += -DSQLITE_SERIES_CONSTRAINT_VERIFY=1
TESTFIXTURE_FLAGS += -DSQLITE_DEFAULT_PAGE_SIZE=1024
TESTFIXTURE_FLAGS += -DSQLITE_ENABLE_STMTVTAB
TESTFIXTURE_FLAGS += -DSQLITE_ENABLE_DBPAGE_VTAB
TESTFIXTURE_FLAGS += -DSQLITE_ENABLE_DESERIALIZE
TESTFIXTURE_SRC0 = $(TESTSRC2) libsqlite3.la
TESTFIXTURE_SRC1 = sqlite3.c
@@ -1278,6 +1316,9 @@ dbdump$(TEXE): $(TOP)/ext/misc/dbdump.c sqlite3.lo
$(LTLINK) -DDBDUMP_STANDALONE -o $@ \
$(TOP)/ext/misc/dbdump.c sqlite3.lo $(TLIBS)
dbtotxt$(TEXE): $(TOP)/tool/dbtotxt.c
$(LTLINK)-o $@ $(TOP)/tool/dbtotxt.c
showdb$(TEXE): $(TOP)/tool/showdb.c sqlite3.lo
$(LTLINK) -o $@ $(TOP)/tool/showdb.c sqlite3.lo $(TLIBS)
@@ -1293,9 +1334,15 @@ showwal$(TEXE): $(TOP)/tool/showwal.c sqlite3.lo
showshm$(TEXE): $(TOP)/tool/showshm.c
$(LTLINK) -o $@ $(TOP)/tool/showshm.c
index_usage$(TEXE): $(TOP)/tool/index_usage.c sqlite3.lo
$(LTLINK) $(SHELL_OPT) -o $@ $(TOP)/tool/index_usage.c sqlite3.lo $(TLIBS)
changeset$(TEXE): $(TOP)/ext/session/changeset.c sqlite3.lo
$(LTLINK) -o $@ $(TOP)/ext/session/changeset.c sqlite3.lo $(TLIBS)
changesetfuzz$(TEXE): $(TOP)/ext/session/changesetfuzz.c sqlite3.lo
$(LTLINK) -o $@ $(TOP)/ext/session/changesetfuzz.c sqlite3.lo $(TLIBS)
rollback-test$(TEXE): $(TOP)/tool/rollback-test.c sqlite3.lo
$(LTLINK) -o $@ $(TOP)/tool/rollback-test.c sqlite3.lo $(TLIBS)
+29 -4
View File
@@ -345,6 +345,7 @@ OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_STMTVTAB=1
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_DBPAGE_VTAB=1
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_DBSTAT_VTAB=1
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_INTROSPECTION_PRAGMAS=1
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_DESERIALIZE=1
!ENDIF
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_COLUMN_METADATA=1
!ENDIF
@@ -1526,6 +1527,7 @@ TESTEXT = \
$(TOP)\ext\misc\nextchar.c \
$(TOP)\ext\misc\normalize.c \
$(TOP)\ext\misc\percentile.c \
$(TOP)\ext\misc\prefixes.c \
$(TOP)\ext\misc\regexp.c \
$(TOP)\ext\misc\remember.c \
$(TOP)\ext\misc\series.c \
@@ -1623,7 +1625,9 @@ FUZZDATA = \
$(TOP)\test\fuzzdata3.db \
$(TOP)\test\fuzzdata4.db \
$(TOP)\test\fuzzdata5.db \
$(TOP)\test\fuzzdata6.db
$(TOP)\test\fuzzdata6.db \
$(TOP)\test\fuzzdata7.db \
$(TOP)\test\fuzzdata8.db
# <</mark>>
# Additional compiler options for the shell. These are only effective
@@ -1633,6 +1637,7 @@ FUZZDATA = \
SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_FTS4=1
SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_EXPLAIN_COMMENTS=1
SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_OFFSET_SQL_FUNC=1
SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_DESERIALIZE=1
!ENDIF
# <<mark>>
@@ -1640,7 +1645,13 @@ SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_OFFSET_SQL_FUNC=1
#
MPTESTER_COMPILE_OPTS = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_FTS5
FUZZERSHELL_COMPILE_OPTS = -DSQLITE_ENABLE_JSON1
FUZZCHECK_COMPILE_OPTS = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_MEMSYS5 -DSQLITE_OSS_FUZZ -DSQLITE_MAX_MEMORY=50000000 -DSQLITE_PRINTF_PRECISION_LIMIT=1000
FUZZCHECK_OPTS = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_MEMSYS5 -DSQLITE_OSS_FUZZ -DSQLITE_MAX_MEMORY=50000000 -DSQLITE_PRINTF_PRECISION_LIMIT=1000
FUZZCHECK_OPTS = $(FUZZCHECK_OPTS) -DSQLITE_ENABLE_DESERIALIZE
FUZZCHECK_OPTS = $(FUZZCHECK_OPTS) -DSQLITE_ENABLE_FTS4
FUZZCHECK_OPTS = $(FUZZCHECK_OPTS) -DSQLITE_ENABLE_RTREE
FUZZCHECK_OPTS = $(FUZZCHECK_OPTS) -DSQLITE_ENABLE_GEOPOLY
FUZZCHECK_OPTS = $(FUZZCHECK_OPTS) -DSQLITE_ENABLE_DBSTAT_VTAB
FUZZCHECK_SRC = $(TOP)\test\fuzzcheck.c $(TOP)\test\ossfuzz.c
OSSSHELL_SRC = $(TOP)\test\ossshell.c $(TOP)\test\ossfuzz.c
DBFUZZ_COMPILE_OPTS = -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION
@@ -1727,10 +1738,10 @@ dbfuzz.exe: $(TOP)\test\dbfuzz.c $(SQLITE3C) $(SQLITE3H)
$(LTLINK) $(NO_WARN) $(DBFUZZ_COMPILE_OPTS) $(TOP)\test\dbfuzz.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
fuzzcheck.exe: $(FUZZCHECK_SRC) $(SQLITE3C) $(SQLITE3H)
$(LTLINK) $(NO_WARN) $(FUZZCHECK_COMPILE_OPTS) $(FUZZCHECK_SRC) $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
$(LTLINK) $(NO_WARN) $(FUZZCHECK_OPTS) $(FUZZCHECK_SRC) $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
ossshell.exe: $(OSSSHELL_SRC) $(SQLITE3C) $(SQLITE3H)
$(LTLINK) $(NO_WARN) $(FUZZCHECK_COMPILE_OPTS) $(OSSSHELL_SRC) $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
$(LTLINK) $(NO_WARN) $(FUZZCHECK_OPTS) $(OSSSHELL_SRC) $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
sessionfuzz.exe: zlib $(TOP)\test\sessionfuzz.c $(SQLITE3C) $(SQLITE3H)
$(LTLINK) $(NO_WARN) -I$(ZLIBINCDIR) $(TOP)\test\sessionfuzz.c /link $(LDFLAGS) $(LTLINKOPTS) /LIBPATH:$(ZLIBLIBDIR) $(ZLIBLIB)
@@ -2127,6 +2138,7 @@ SHELL_SRC = \
$(TOP)\ext\misc\completion.c \
$(TOP)\ext\expert\sqlite3expert.c \
$(TOP)\ext\expert\sqlite3expert.h \
$(TOP)\ext\misc\memtrace.c \
$(TOP)\src\test_windirent.c
# If use of zlib is enabled, add the "zipfile.c" source file.
@@ -2295,6 +2307,7 @@ TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_DEFAULT_PAGE_SIZE=1024
TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_ENABLE_STMTVTAB=1
TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_ENABLE_DBPAGE_VTAB=1
TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_ENABLE_JSON1=1
TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_ENABLE_DESERIALIZE=1
TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) $(TEST_CCONV_OPTS)
TESTFIXTURE_SRC0 = $(TESTEXT) $(TESTSRC2)
@@ -2422,6 +2435,9 @@ testloadext.lo: $(TOP)\src\test_loadext.c $(SQLITE3H)
testloadext.dll: testloadext.lo
$(LD) $(LDFLAGS) $(LTLINKOPTS) $(LTLIBPATHS) /DLL /OUT:$@ testloadext.lo
dbtotxt.exe: $(TOP)\tool\dbtotxt.c
$(LTLINK) $(NO_WARN) $(TOP)\tool\dbtotxt.c /link $(LDFLAGS) $(LTLINKOPTS)
showdb.exe: $(TOP)\tool\showdb.c $(SQLITE3C) $(SQLITE3H)
$(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION \
$(TOP)\tool\showdb.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
@@ -2441,11 +2457,20 @@ showwal.exe: $(TOP)\tool\showwal.c $(SQLITE3C) $(SQLITE3H)
showshm.exe: $(TOP)\tool\showshm.c
$(LTLINK) $(NO_WARN) $(TOP)\tool\showshm.c /link $(LDFLAGS) $(LTLINKOPTS)
index_usage.exe: $(TOP)\tool\index_usage.c $(SQLITE3C) $(SQLITE3H)
$(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION \
$(TOP)\tool\index_usage.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
changeset.exe: $(TOP)\ext\session\changeset.c $(SQLITE3C) $(SQLITE3H)
$(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION \
-DSQLITE_ENABLE_SESSION=1 -DSQLITE_ENABLE_PREUPDATE_HOOK=1 \
$(TOP)\ext\session\changeset.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
changesetfuzz.exe: $(TOP)\ext\session\changesetfuzz.c $(SQLITE3C) $(SQLITE3H)
$(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION \
-DSQLITE_ENABLE_SESSION=1 -DSQLITE_ENABLE_PREUPDATE_HOOK=1 \
$(TOP)\ext\session\changesetfuzz.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
fts3view.exe: $(TOP)\ext\fts3\tool\fts3view.c $(SQLITE3C) $(SQLITE3H)
$(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION \
$(TOP)\ext\fts3\tool\fts3view.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
+1 -1
View File
@@ -1 +1 @@
3.26.0
3.28.0
+2
View File
@@ -283,6 +283,7 @@ OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_STMTVTAB=1
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_DBPAGE_VTAB=1
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_DBSTAT_VTAB=1
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_INTROSPECTION_PRAGMAS=1
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_DESERIALIZE=1
!ENDIF
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_COLUMN_METADATA=1
!ENDIF
@@ -937,6 +938,7 @@ LIBRESOBJS =
SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_FTS4=1
SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_EXPLAIN_COMMENTS=1
SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_OFFSET_SQL_FUNC=1
SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_DESERIALIZE=1
!ENDIF
Vendored
+9 -9
View File
@@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.69 for sqlite 3.26.0.
# Generated by GNU Autoconf 2.69 for sqlite 3.28.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.26.0'
PACKAGE_STRING='sqlite 3.26.0'
PACKAGE_VERSION='3.28.0'
PACKAGE_STRING='sqlite 3.28.0'
PACKAGE_BUGREPORT=''
PACKAGE_URL=''
@@ -1466,7 +1466,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.26.0 to adapt to many kinds of systems.
\`configure' configures sqlite 3.28.0 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1531,7 +1531,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
short | recursive ) echo "Configuration of sqlite 3.26.0:";;
short | recursive ) echo "Configuration of sqlite 3.28.0:";;
esac
cat <<\_ACEOF
@@ -1657,7 +1657,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
sqlite configure 3.26.0
sqlite configure 3.28.0
generated by GNU Autoconf 2.69
Copyright (C) 2012 Free Software Foundation, Inc.
@@ -2076,7 +2076,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.26.0, which was
It was created by sqlite $as_me 3.28.0, which was
generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@
@@ -12232,7 +12232,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.26.0, which was
This file was extended by sqlite $as_me 3.28.0, which was
generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -12298,7 +12298,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.26.0
sqlite config.status 3.28.0
configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\"
+3
View File
@@ -777,6 +777,9 @@ For example:</p>
<p>This might be needed, for example, if some of the C actions in the
grammar call functions that are prototyped in unistd.h.</p>
<p>Use the <tt><a href="#pcode">%code</a></tt> directive to add code to
the end of the generated parser.</p>
<a name='pleft'></a>
<h4>The <tt>%left</tt> directive</h4>
+4 -2
View File
@@ -243,8 +243,10 @@ do_setup_rec_test $tn.12.1 {
CREATE INDEX t7_idx_00000062 ON t7(b);
CREATE INDEX t7_idx_00000061 ON t7(a);
MULTI-INDEX OR
SEARCH TABLE t7 USING INDEX t7_idx_00000061 (a=?)
SEARCH TABLE t7 USING INDEX t7_idx_00000062 (b=?)
INDEX 1
SEARCH TABLE t7 USING INDEX t7_idx_00000061 (a=?)
INDEX 2
SEARCH TABLE t7 USING INDEX t7_idx_00000062 (b=?)
}
# rowid terms.
+1
View File
@@ -644,6 +644,7 @@ static int idxRegisterVtab(sqlite3expert *p){
0, /* xSavepoint */
0, /* xRelease */
0, /* xRollbackTo */
0, /* xShadowName */
};
return sqlite3_create_module(p->dbv, "expert", &expertModule, (void*)p);
+102 -56
View File
@@ -320,6 +320,14 @@ int sqlite3Fts3Never(int b) { assert( !b ); return b; }
# endif
#endif
/*
** This variable is set to false when running tests for which the on disk
** structures should not be corrupt. Otherwise, true. If it is false, extra
** assert() conditions in the fts3 code are activated - conditions that are
** only true if it is guaranteed that the fts3 database is not corrupt.
*/
int sqlite3_fts3_may_be_corrupt = 1;
/*
** Write a 64-bit variable-length integer to memory starting at p[0].
** The length of data written will be between 1 and FTS3_VARINT_MAX bytes.
@@ -338,7 +346,7 @@ int sqlite3Fts3PutVarint(char *p, sqlite_int64 v){
}
#define GETVARINT_STEP(v, ptr, shift, mask1, mask2, var, ret) \
v = (v & mask1) | ( (*ptr++) << shift ); \
v = (v & mask1) | ( (*(const unsigned char*)(ptr++)) << shift ); \
if( (v & mask2)==0 ){ var = v; return ret; }
#define GETVARINT_INIT(v, ptr, shift, mask1, mask2, var, ret) \
v = (*ptr++); \
@@ -376,20 +384,21 @@ int sqlite3Fts3GetVarint(const char *pBuf, sqlite_int64 *v){
** a non-negative 32-bit integer before it is returned.
*/
int sqlite3Fts3GetVarint32(const char *p, int *pi){
const unsigned char *ptr = (const unsigned char*)p;
u32 a;
#ifndef fts3GetVarint32
GETVARINT_INIT(a, p, 0, 0x00, 0x80, *pi, 1);
GETVARINT_INIT(a, ptr, 0, 0x00, 0x80, *pi, 1);
#else
a = (*p++);
a = (*ptr++);
assert( a & 0x80 );
#endif
GETVARINT_STEP(a, p, 7, 0x7F, 0x4000, *pi, 2);
GETVARINT_STEP(a, p, 14, 0x3FFF, 0x200000, *pi, 3);
GETVARINT_STEP(a, p, 21, 0x1FFFFF, 0x10000000, *pi, 4);
GETVARINT_STEP(a, ptr, 7, 0x7F, 0x4000, *pi, 2);
GETVARINT_STEP(a, ptr, 14, 0x3FFF, 0x200000, *pi, 3);
GETVARINT_STEP(a, ptr, 21, 0x1FFFFF, 0x10000000, *pi, 4);
a = (a & 0x0FFFFFFF );
*pi = (int)(a | ((u32)(*p & 0x07) << 28));
*pi = (int)(a | ((u32)(*ptr & 0x07) << 28));
assert( 0==(a & 0x80000000) );
assert( *pi>=0 );
return 5;
@@ -560,13 +569,18 @@ static int fts3DestroyMethod(sqlite3_vtab *pVtab){
sqlite3 *db = p->db; /* Database handle */
/* Drop the shadow tables */
if( p->zContentTbl==0 ){
fts3DbExec(&rc, db, "DROP TABLE IF EXISTS %Q.'%q_content'", zDb, p->zName);
}
fts3DbExec(&rc, db, "DROP TABLE IF EXISTS %Q.'%q_segments'", zDb,p->zName);
fts3DbExec(&rc, db, "DROP TABLE IF EXISTS %Q.'%q_segdir'", zDb, p->zName);
fts3DbExec(&rc, db, "DROP TABLE IF EXISTS %Q.'%q_docsize'", zDb, p->zName);
fts3DbExec(&rc, db, "DROP TABLE IF EXISTS %Q.'%q_stat'", zDb, p->zName);
fts3DbExec(&rc, db,
"DROP TABLE IF EXISTS %Q.'%q_segments';"
"DROP TABLE IF EXISTS %Q.'%q_segdir';"
"DROP TABLE IF EXISTS %Q.'%q_docsize';"
"DROP TABLE IF EXISTS %Q.'%q_stat';"
"%s DROP TABLE IF EXISTS %Q.'%q_content';",
zDb, p->zName,
zDb, p->zName,
zDb, p->zName,
zDb, p->zName,
(p->zContentTbl ? "--" : ""), zDb,p->zName
);
/* If everything has worked, invoke fts3DisconnectMethod() to free the
** memory associated with the Fts3Table structure and return SQLITE_OK.
@@ -798,10 +812,10 @@ static void fts3Appendf(
** memory.
*/
static char *fts3QuoteId(char const *zInput){
int nRet;
sqlite3_int64 nRet;
char *zRet;
nRet = 2 + (int)strlen(zInput)*2 + 1;
zRet = sqlite3_malloc(nRet);
zRet = sqlite3_malloc64(nRet);
if( zRet ){
int i;
char *z = zRet;
@@ -982,7 +996,7 @@ static int fts3PrefixParameter(
}
}
aIndex = sqlite3_malloc(sizeof(struct Fts3Index) * nIndex);
aIndex = sqlite3_malloc64(sizeof(struct Fts3Index) * nIndex);
*apIndex = aIndex;
if( !aIndex ){
return SQLITE_NOMEM;
@@ -1061,7 +1075,7 @@ static int fts3ContentColumns(
if( rc==SQLITE_OK ){
const char **azCol; /* Output array */
int nStr = 0; /* Size of all column names (incl. 0x00) */
sqlite3_int64 nStr = 0; /* Size of all column names (incl. 0x00) */
int nCol; /* Number of table columns */
int i; /* Used to iterate through columns */
@@ -1071,11 +1085,11 @@ static int fts3ContentColumns(
nCol = sqlite3_column_count(pStmt);
for(i=0; i<nCol; i++){
const char *zCol = sqlite3_column_name(pStmt, i);
nStr += (int)strlen(zCol) + 1;
nStr += strlen(zCol) + 1;
}
/* Allocate and populate the array to return. */
azCol = (const char **)sqlite3_malloc(sizeof(char *) * nCol + nStr);
azCol = (const char **)sqlite3_malloc64(sizeof(char *) * nCol + nStr);
if( azCol==0 ){
rc = SQLITE_NOMEM;
}else{
@@ -1123,7 +1137,7 @@ static int fts3InitVtab(
Fts3Table *p = 0; /* Pointer to allocated vtab */
int rc = SQLITE_OK; /* Return code */
int i; /* Iterator variable */
int nByte; /* Size of allocation used for *p */
sqlite3_int64 nByte; /* Size of allocation used for *p */
int iCol; /* Column index */
int nString = 0; /* Bytes required to hold all column names */
int nCol = 0; /* Number of columns in the FTS table */
@@ -1157,10 +1171,10 @@ static int fts3InitVtab(
nName = (int)strlen(argv[2]) + 1;
nByte = sizeof(const char *) * (argc-2);
aCol = (const char **)sqlite3_malloc(nByte);
aCol = (const char **)sqlite3_malloc64(nByte);
if( aCol ){
memset((void*)aCol, 0, nByte);
azNotindexed = (char **)sqlite3_malloc(nByte);
azNotindexed = (char **)sqlite3_malloc64(nByte);
}
if( azNotindexed ){
memset(azNotindexed, 0, nByte);
@@ -1355,7 +1369,7 @@ static int fts3InitVtab(
nName + /* zName */
nDb + /* zDb */
nString; /* Space for azColumn strings */
p = (Fts3Table*)sqlite3_malloc(nByte);
p = (Fts3Table*)sqlite3_malloc64(nByte);
if( p==0 ){
rc = SQLITE_NOMEM;
goto fts3_init_out;
@@ -1821,7 +1835,7 @@ static int fts3ScanInteriorNode(
const char *zCsr = zNode; /* Cursor to iterate through node */
const char *zEnd = &zCsr[nNode];/* End of interior node buffer */
char *zBuffer = 0; /* Buffer to load terms into */
int nAlloc = 0; /* Size of allocated buffer */
i64 nAlloc = 0; /* Size of allocated buffer */
int isFirstTerm = 1; /* True when processing first term on page */
sqlite3_int64 iChild; /* Block id of child node to descend to */
@@ -1859,14 +1873,14 @@ static int fts3ScanInteriorNode(
zCsr += fts3GetVarint32(zCsr, &nSuffix);
assert( nPrefix>=0 && nSuffix>=0 );
if( &zCsr[nSuffix]>zEnd ){
if( nPrefix>zCsr-zNode || nSuffix>zEnd-zCsr ){
rc = FTS_CORRUPT_VTAB;
goto finish_scan;
}
if( nPrefix+nSuffix>nAlloc ){
if( (i64)nPrefix+nSuffix>nAlloc ){
char *zNew;
nAlloc = (nPrefix+nSuffix) * 2;
zNew = (char *)sqlite3_realloc(zBuffer, nAlloc);
nAlloc = ((i64)nPrefix+nSuffix) * 2;
zNew = (char *)sqlite3_realloc64(zBuffer, nAlloc);
if( !zNew ){
rc = SQLITE_NOMEM;
goto finish_scan;
@@ -2134,7 +2148,7 @@ static int fts3PutColNumber(char **pp, int iCol){
** updated appropriately. The caller is responsible for insuring
** that there is enough space in *pp to hold the complete output.
*/
static void fts3PoslistMerge(
static int fts3PoslistMerge(
char **pp, /* Output buffer */
char **pp1, /* Left input list */
char **pp2 /* Right input list */
@@ -2147,11 +2161,17 @@ static void fts3PoslistMerge(
int iCol1; /* The current column index in pp1 */
int iCol2; /* The current column index in pp2 */
if( *p1==POS_COLUMN ) fts3GetVarint32(&p1[1], &iCol1);
if( *p1==POS_COLUMN ){
fts3GetVarint32(&p1[1], &iCol1);
if( iCol1==0 ) return FTS_CORRUPT_VTAB;
}
else if( *p1==POS_END ) iCol1 = POSITION_LIST_END;
else iCol1 = 0;
if( *p2==POS_COLUMN ) fts3GetVarint32(&p2[1], &iCol2);
if( *p2==POS_COLUMN ){
fts3GetVarint32(&p2[1], &iCol2);
if( iCol2==0 ) return FTS_CORRUPT_VTAB;
}
else if( *p2==POS_END ) iCol2 = POSITION_LIST_END;
else iCol2 = 0;
@@ -2199,6 +2219,7 @@ static void fts3PoslistMerge(
*pp = p;
*pp1 = p1 + 1;
*pp2 = p2 + 1;
return SQLITE_OK;
}
/*
@@ -2263,10 +2284,9 @@ static int fts3PoslistPhraseMerge(
p += sqlite3Fts3PutVarint(p, iCol1);
}
assert( *p1!=POS_END && *p1!=POS_COLUMN );
assert( *p2!=POS_END && *p2!=POS_COLUMN );
fts3GetDeltaVarint(&p1, &iPos1); iPos1 -= 2;
fts3GetDeltaVarint(&p2, &iPos2); iPos2 -= 2;
if( iPos1<0 || iPos2<0 ) break;
while( 1 ){
if( iPos2==iPos1+nToken
@@ -2492,6 +2512,7 @@ static int fts3DoclistOrMerge(
char *a2, int n2, /* Second doclist */
char **paOut, int *pnOut /* OUT: Malloc'd doclist */
){
int rc = SQLITE_OK;
sqlite3_int64 i1 = 0;
sqlite3_int64 i2 = 0;
sqlite3_int64 iPrev = 0;
@@ -2535,7 +2556,7 @@ static int fts3DoclistOrMerge(
** A symetric argument may be made if the doclists are in descending
** order.
*/
aOut = sqlite3_malloc(n1+n2+FTS3_VARINT_MAX-1);
aOut = sqlite3_malloc64((i64)n1+n2+FTS3_VARINT_MAX-1+FTS3_BUFFER_PADDING);
if( !aOut ) return SQLITE_NOMEM;
p = aOut;
@@ -2546,7 +2567,8 @@ static int fts3DoclistOrMerge(
if( p2 && p1 && iDiff==0 ){
fts3PutDeltaVarint3(&p, bDescDoclist, &iPrev, &bFirstOut, i1);
fts3PoslistMerge(&p, &p1, &p2);
rc = fts3PoslistMerge(&p, &p1, &p2);
if( rc ) break;
fts3GetDeltaVarint3(&p1, pEnd1, bDescDoclist, &i1);
fts3GetDeltaVarint3(&p2, pEnd2, bDescDoclist, &i2);
}else if( !p2 || (p1 && iDiff<0) ){
@@ -2560,10 +2582,16 @@ static int fts3DoclistOrMerge(
}
}
if( rc!=SQLITE_OK ){
sqlite3_free(aOut);
p = aOut = 0;
}else{
assert( (p-aOut)<=n1+n2+FTS3_VARINT_MAX-1 );
memset(&aOut[(p-aOut)], 0, FTS3_BUFFER_PADDING);
}
*paOut = aOut;
*pnOut = (int)(p-aOut);
assert( *pnOut<=n1+n2+FTS3_VARINT_MAX-1 );
return SQLITE_OK;
return rc;
}
/*
@@ -2598,7 +2626,7 @@ static int fts3DoclistPhraseMerge(
assert( nDist>0 );
if( bDescDoclist ){
aOut = sqlite3_malloc(*pnRight + FTS3_VARINT_MAX);
aOut = sqlite3_malloc64((sqlite3_int64)*pnRight + FTS3_VARINT_MAX);
if( aOut==0 ) return SQLITE_NOMEM;
}else{
aOut = aRight;
@@ -2782,6 +2810,7 @@ static int fts3TermSelectMerge(
pTS->anOutput[0] = nDoclist;
if( pTS->aaOutput[0] ){
memcpy(pTS->aaOutput[0], aDoclist, nDoclist);
memset(&pTS->aaOutput[0][nDoclist], 0, FTS3_VARINT_MAX);
}else{
return SQLITE_NOMEM;
}
@@ -2833,8 +2862,8 @@ static int fts3SegReaderCursorAppend(
){
if( (pCsr->nSegment%16)==0 ){
Fts3SegReader **apNew;
int nByte = (pCsr->nSegment + 16)*sizeof(Fts3SegReader*);
apNew = (Fts3SegReader **)sqlite3_realloc(pCsr->apSegment, nByte);
sqlite3_int64 nByte = (pCsr->nSegment + 16)*sizeof(Fts3SegReader*);
apNew = (Fts3SegReader **)sqlite3_realloc64(pCsr->apSegment, nByte);
if( !apNew ){
sqlite3Fts3SegReaderFree(pNew);
return SQLITE_NOMEM;
@@ -2898,7 +2927,7 @@ static int fts3SegReaderCursor(
/* If zTerm is not NULL, and this segment is not stored entirely on its
** root node, the range of leaves scanned can be reduced. Do this. */
if( iStartBlock && zTerm ){
if( iStartBlock && zTerm && zRoot ){
sqlite3_int64 *pi = (isPrefix ? &iLeavesEndBlock : 0);
rc = fts3SelectLeaf(p, zTerm, nTerm, zRoot, nRoot, &iStartBlock, pi);
if( rc!=SQLITE_OK ) goto finished;
@@ -3840,14 +3869,28 @@ static int fts3RollbackToMethod(sqlite3_vtab *pVtab, int iSavepoint){
Fts3Table *p = (Fts3Table*)pVtab;
UNUSED_PARAMETER(iSavepoint);
assert( p->inTransaction );
assert( p->mxSavepoint >= iSavepoint );
TESTONLY( p->mxSavepoint = iSavepoint );
sqlite3Fts3PendingTermsClear(p);
return SQLITE_OK;
}
/*
** Return true if zName is the extension on one of the shadow tables used
** by this module.
*/
static int fts3ShadowName(const char *zName){
static const char *azName[] = {
"content", "docsize", "segdir", "segments", "stat",
};
unsigned int i;
for(i=0; i<sizeof(azName)/sizeof(azName[0]); i++){
if( sqlite3_stricmp(zName, azName[i])==0 ) return 1;
}
return 0;
}
static const sqlite3_module fts3Module = {
/* iVersion */ 2,
/* iVersion */ 3,
/* xCreate */ fts3CreateMethod,
/* xConnect */ fts3ConnectMethod,
/* xBestIndex */ fts3BestIndexMethod,
@@ -3870,6 +3913,7 @@ static const sqlite3_module fts3Module = {
/* xSavepoint */ fts3SavepointMethod,
/* xRelease */ fts3ReleaseMethod,
/* xRollbackTo */ fts3RollbackToMethod,
/* xShadowName */ fts3ShadowName,
};
/*
@@ -4150,6 +4194,7 @@ static int fts3EvalPhraseLoad(
return rc;
}
#ifndef SQLITE_DISABLE_FTS4_DEFERRED
/*
** This function is called on each phrase after the position lists for
** any deferred tokens have been loaded into memory. It updates the phrases
@@ -4253,6 +4298,7 @@ static int fts3EvalDeferredPhrase(Fts3Cursor *pCsr, Fts3Phrase *pPhrase){
return SQLITE_OK;
}
#endif /* SQLITE_DISABLE_FTS4_DEFERRED */
/*
** Maximum number of tokens a phrase may have to be considered for the
@@ -4597,9 +4643,10 @@ static int fts3EvalIncrPhraseNext(
if( bEof==0 ){
int nList = 0;
int nByte = a[p->nToken-1].nList;
char *aDoclist = sqlite3_malloc(nByte+1);
char *aDoclist = sqlite3_malloc(nByte+FTS3_BUFFER_PADDING);
if( !aDoclist ) return SQLITE_NOMEM;
memcpy(aDoclist, a[p->nToken-1].pList, nByte+1);
memset(&aDoclist[nByte], 0, FTS3_BUFFER_PADDING);
for(i=0; i<(p->nToken-1); i++){
if( a[i].bIgnore==0 ){
@@ -4990,7 +5037,7 @@ static int fts3EvalStart(Fts3Cursor *pCsr){
if( rc==SQLITE_OK && nToken>1 && pTab->bFts4 ){
Fts3TokenAndCost *aTC;
Fts3Expr **apOr;
aTC = (Fts3TokenAndCost *)sqlite3_malloc(
aTC = (Fts3TokenAndCost *)sqlite3_malloc64(
sizeof(Fts3TokenAndCost) * nToken
+ sizeof(Fts3Expr *) * nOr * 2
);
@@ -5301,7 +5348,7 @@ static int fts3EvalNearTest(Fts3Expr *pExpr, int *pRc){
&& (pExpr->pParent==0 || pExpr->pParent->eType!=FTSQUERY_NEAR)
){
Fts3Expr *p;
int nTmp = 0; /* Bytes of temp space */
sqlite3_int64 nTmp = 0; /* Bytes of temp space */
char *aTmp; /* Temp space for PoslistNearMerge() */
/* Allocate temporary working space. */
@@ -5310,7 +5357,7 @@ static int fts3EvalNearTest(Fts3Expr *pExpr, int *pRc){
nTmp += p->pRight->pPhrase->doclist.nList;
}
nTmp += p->pPhrase->doclist.nList;
aTmp = sqlite3_malloc(nTmp*2);
aTmp = sqlite3_malloc64(nTmp*2);
if( !aTmp ){
*pRc = SQLITE_NOMEM;
res = 0;
@@ -5580,15 +5627,14 @@ static void fts3EvalRestart(
** found in Fts3Expr.pPhrase->doclist.pList for each of the phrase
** expression nodes.
*/
static void fts3EvalUpdateCounts(Fts3Expr *pExpr){
static void fts3EvalUpdateCounts(Fts3Expr *pExpr, int nCol){
if( pExpr ){
Fts3Phrase *pPhrase = pExpr->pPhrase;
if( pPhrase && pPhrase->doclist.pList ){
int iCol = 0;
char *p = pPhrase->doclist.pList;
assert( *p );
while( 1 ){
do{
u8 c = 0;
int iCnt = 0;
while( 0xFE & (*p | c) ){
@@ -5604,11 +5650,11 @@ static void fts3EvalUpdateCounts(Fts3Expr *pExpr){
if( *p==0x00 ) break;
p++;
p += fts3GetVarint32(p, &iCol);
}
}while( iCol<nCol );
}
fts3EvalUpdateCounts(pExpr->pLeft);
fts3EvalUpdateCounts(pExpr->pRight);
fts3EvalUpdateCounts(pExpr->pLeft, nCol);
fts3EvalUpdateCounts(pExpr->pRight, nCol);
}
}
@@ -5652,7 +5698,7 @@ static int fts3EvalGatherStats(
for(p=pRoot; p; p=p->pLeft){
Fts3Expr *pE = (p->eType==FTSQUERY_PHRASE?p:p->pRight);
assert( pE->aMI==0 );
pE->aMI = (u32 *)sqlite3_malloc(pTab->nColumn * 3 * sizeof(u32));
pE->aMI = (u32 *)sqlite3_malloc64(pTab->nColumn * 3 * sizeof(u32));
if( !pE->aMI ) return SQLITE_NOMEM;
memset(pE->aMI, 0, pTab->nColumn * 3 * sizeof(u32));
}
@@ -5678,7 +5724,7 @@ static int fts3EvalGatherStats(
);
if( rc==SQLITE_OK && pCsr->isEof==0 ){
fts3EvalUpdateCounts(pRoot);
fts3EvalUpdateCounts(pRoot, pTab->nColumn);
}
}
+14
View File
@@ -95,6 +95,8 @@ SQLITE_EXTENSION_INIT3
*/
#define FTS3_VARINT_MAX 10
#define FTS3_BUFFER_PADDING 8
/*
** FTS4 virtual tables may maintain multiple indexes - one index of all terms
** in the document set and zero or more prefix indexes. All indexes are stored
@@ -127,6 +129,18 @@ SQLITE_EXTENSION_INIT3
#define POS_COLUMN (1) /* Column-list terminator */
#define POS_END (0) /* Position-list terminator */
/*
** The assert_fts3_nc() macro is similar to the assert() macro, except that it
** is used for assert() conditions that are true only if it can be
** guranteed that the database is not corrupt.
*/
#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
extern int sqlite3_fts3_may_be_corrupt;
# define assert_fts3_nc(x) assert(sqlite3_fts3_may_be_corrupt || (x))
#else
# define assert_fts3_nc(x) assert(x)
#endif
/*
** This section provides definitions to allow the
** FTS3 extension to be compiled outside of the
+7 -6
View File
@@ -66,7 +66,7 @@ static int fts3auxConnectMethod(
char const *zFts3; /* Name of fts3 table */
int nDb; /* Result of strlen(zDb) */
int nFts3; /* Result of strlen(zFts3) */
int nByte; /* Bytes of space to allocate here */
sqlite3_int64 nByte; /* Bytes of space to allocate here */
int rc; /* value returned by declare_vtab() */
Fts3auxTable *p; /* Virtual table object to return */
@@ -98,7 +98,7 @@ static int fts3auxConnectMethod(
if( rc!=SQLITE_OK ) return rc;
nByte = sizeof(Fts3auxTable) + sizeof(Fts3Table) + nDb + nFts3 + 2;
p = (Fts3auxTable *)sqlite3_malloc(nByte);
p = (Fts3auxTable *)sqlite3_malloc64(nByte);
if( !p ) return SQLITE_NOMEM;
memset(p, 0, nByte);
@@ -248,7 +248,7 @@ static int fts3auxCloseMethod(sqlite3_vtab_cursor *pCursor){
static int fts3auxGrowStatArray(Fts3auxCursor *pCsr, int nSize){
if( nSize>pCsr->nStat ){
struct Fts3auxColstats *aNew;
aNew = (struct Fts3auxColstats *)sqlite3_realloc(pCsr->aStat,
aNew = (struct Fts3auxColstats *)sqlite3_realloc64(pCsr->aStat,
sizeof(struct Fts3auxColstats) * nSize
);
if( aNew==0 ) return SQLITE_NOMEM;
@@ -416,15 +416,15 @@ static int fts3auxFilterMethod(
assert( (iEq==0 && iGe==-1) || (iEq==-1 && iGe==0) );
if( zStr ){
pCsr->filter.zTerm = sqlite3_mprintf("%s", zStr);
pCsr->filter.nTerm = sqlite3_value_bytes(apVal[0]);
if( pCsr->filter.zTerm==0 ) return SQLITE_NOMEM;
pCsr->filter.nTerm = (int)strlen(pCsr->filter.zTerm);
}
}
if( iLe>=0 ){
pCsr->zStop = sqlite3_mprintf("%s", sqlite3_value_text(apVal[iLe]));
pCsr->nStop = sqlite3_value_bytes(apVal[iLe]);
if( pCsr->zStop==0 ) return SQLITE_NOMEM;
pCsr->nStop = (int)strlen(pCsr->zStop);
}
if( iLangid>=0 ){
@@ -539,7 +539,8 @@ int sqlite3Fts3InitAux(sqlite3 *db){
0, /* xRename */
0, /* xSavepoint */
0, /* xRelease */
0 /* xRollbackTo */
0, /* xRollbackTo */
0 /* xShadowName */
};
int rc; /* Return code */
+7 -8
View File
@@ -122,8 +122,8 @@ static int fts3isspace(char c){
** zero the memory before returning a pointer to it. If unsuccessful,
** return NULL.
*/
static void *fts3MallocZero(int nByte){
void *pRet = sqlite3_malloc(nByte);
static void *fts3MallocZero(sqlite3_int64 nByte){
void *pRet = sqlite3_malloc64(nByte);
if( pRet ) memset(pRet, 0, nByte);
return pRet;
}
@@ -198,7 +198,7 @@ static int getNextToken(
if( rc==SQLITE_OK ){
const char *zToken;
int nToken = 0, iStart = 0, iEnd = 0, iPosition = 0;
int nByte; /* total space to allocate */
sqlite3_int64 nByte; /* total space to allocate */
rc = pModule->xNext(pCursor, &zToken, &nToken, &iStart, &iEnd, &iPosition);
if( rc==SQLITE_OK ){
@@ -252,8 +252,8 @@ static int getNextToken(
** Enlarge a memory allocation. If an out-of-memory allocation occurs,
** then free the old allocation.
*/
static void *fts3ReallocOrFree(void *pOrig, int nNew){
void *pRet = sqlite3_realloc(pOrig, nNew);
static void *fts3ReallocOrFree(void *pOrig, sqlite3_int64 nNew){
void *pRet = sqlite3_realloc64(pOrig, nNew);
if( !pRet ){
sqlite3_free(pOrig);
}
@@ -497,7 +497,6 @@ static int getNextNode(
int nConsumed = 0;
pParse->nNest++;
rc = fts3ExprParse(pParse, zInput+1, nInput-1, ppExpr, &nConsumed);
if( rc==SQLITE_OK && !*ppExpr ){ rc = SQLITE_DONE; }
*pnConsumed = (int)(zInput - z) + 1 + nConsumed;
return rc;
}else if( *zInput==')' ){
@@ -796,7 +795,7 @@ static int fts3ExprBalance(Fts3Expr **pp, int nMaxDepth){
if( rc==SQLITE_OK ){
if( (eType==FTSQUERY_AND || eType==FTSQUERY_OR) ){
Fts3Expr **apLeaf;
apLeaf = (Fts3Expr **)sqlite3_malloc(sizeof(Fts3Expr *) * nMaxDepth);
apLeaf = (Fts3Expr **)sqlite3_malloc64(sizeof(Fts3Expr *) * nMaxDepth);
if( 0==apLeaf ){
rc = SQLITE_NOMEM;
}else{
@@ -1216,7 +1215,7 @@ static void fts3ExprTestCommon(
zExpr = (const char *)sqlite3_value_text(argv[1]);
nExpr = sqlite3_value_bytes(argv[1]);
nCol = argc-2;
azCol = (char **)sqlite3_malloc(nCol*sizeof(char *));
azCol = (char **)sqlite3_malloc64(nCol*sizeof(char *));
if( !azCol ){
sqlite3_result_error_nomem(context);
goto exprtest_out;
+2 -2
View File
@@ -35,8 +35,8 @@
/*
** Malloc and Free functions
*/
static void *fts3HashMalloc(int n){
void *p = sqlite3_malloc(n);
static void *fts3HashMalloc(sqlite3_int64 n){
void *p = sqlite3_malloc64(n);
if( p ){
memset(p, 0, n);
}
+2 -2
View File
@@ -60,7 +60,7 @@ static int icuCreate(
if( argc>0 ){
n = strlen(argv[0])+1;
}
p = (IcuTokenizer *)sqlite3_malloc(sizeof(IcuTokenizer)+n);
p = (IcuTokenizer *)sqlite3_malloc64(sizeof(IcuTokenizer)+n);
if( !p ){
return SQLITE_NOMEM;
}
@@ -117,7 +117,7 @@ static int icuOpen(
nInput = strlen(zInput);
}
nChar = nInput+1;
pCsr = (IcuCursor *)sqlite3_malloc(
pCsr = (IcuCursor *)sqlite3_malloc64(
sizeof(IcuCursor) + /* IcuCursor */
((nChar+3)&~3) * sizeof(UChar) + /* IcuCursor.aChar[] */
(nChar+1) * sizeof(int) /* IcuCursor.aOffset[] */
+41 -23
View File
@@ -178,7 +178,7 @@ static void (*fts3MIBufferAlloc(MatchinfoBuffer *p, u32 **paOut))(void*){
aOut = &p->aMatchinfo[p->nElem+2];
xRet = fts3MIBufferFree;
}else{
aOut = (u32*)sqlite3_malloc(p->nElem * sizeof(u32));
aOut = (u32*)sqlite3_malloc64(p->nElem * sizeof(u32));
if( aOut ){
xRet = sqlite3_free;
if( p->bGlobal ) memcpy(aOut, &p->aMatchinfo[1], p->nElem*sizeof(u32));
@@ -433,7 +433,8 @@ static void fts3SnippetDetails(
int j;
u64 mPhrase = (u64)1 << i;
u64 mPos = (u64)1 << (iCsr - iStart);
assert( iCsr>=iStart );
assert( iCsr>=iStart && (iCsr - iStart)<=64 );
assert( i>=0 && i<=64 );
if( (mCover|mCovered)&mPhrase ){
iScore++;
}else{
@@ -475,11 +476,14 @@ static int fts3SnippetFindPositions(Fts3Expr *pExpr, int iPhrase, void *ctx){
int iFirst = 0;
pPhrase->pList = pCsr;
fts3GetDeltaPosition(&pCsr, &iFirst);
assert( iFirst>=0 );
pPhrase->pHead = pCsr;
pPhrase->pTail = pCsr;
pPhrase->iHead = iFirst;
pPhrase->iTail = iFirst;
if( iFirst<0 ){
rc = FTS_CORRUPT_VTAB;
}else{
pPhrase->pHead = pCsr;
pPhrase->pTail = pCsr;
pPhrase->iHead = iFirst;
pPhrase->iTail = iFirst;
}
}else{
assert( rc!=SQLITE_OK || (
pPhrase->pList==0 && pPhrase->pHead==0 && pPhrase->pTail==0
@@ -516,7 +520,7 @@ static int fts3BestSnippet(
int rc; /* Return Code */
int nList; /* Number of phrases in expression */
SnippetIter sIter; /* Iterates through snippet candidates */
int nByte; /* Number of bytes of space to allocate */
sqlite3_int64 nByte; /* Number of bytes of space to allocate */
int iBestScore = -1; /* Best snippet score found so far */
int i; /* Loop counter */
@@ -534,7 +538,7 @@ static int fts3BestSnippet(
** the required space using malloc().
*/
nByte = sizeof(SnippetPhrase) * nList;
sIter.aPhrase = (SnippetPhrase *)sqlite3_malloc(nByte);
sIter.aPhrase = (SnippetPhrase *)sqlite3_malloc64(nByte);
if( !sIter.aPhrase ){
return SQLITE_NOMEM;
}
@@ -604,8 +608,8 @@ static int fts3StringAppend(
** appended data.
*/
if( pStr->n+nAppend+1>=pStr->nAlloc ){
int nAlloc = pStr->nAlloc+nAppend+100;
char *zNew = sqlite3_realloc(pStr->z, nAlloc);
sqlite3_int64 nAlloc = pStr->nAlloc+(sqlite3_int64)nAppend+100;
char *zNew = sqlite3_realloc64(pStr->z, nAlloc);
if( !zNew ){
return SQLITE_NOMEM;
}
@@ -660,6 +664,7 @@ static int fts3SnippetShift(
for(nLeft=0; !(hlmask & ((u64)1 << nLeft)); nLeft++);
for(nRight=0; !(hlmask & ((u64)1 << (nSnippet-1-nRight))); nRight++);
assert( (nSnippet-1-nRight)<=63 && (nSnippet-1-nRight)>=0 );
nDesired = (nLeft-nRight)/2;
/* Ideally, the start of the snippet should be pushed forward in the
@@ -852,7 +857,7 @@ static int fts3ColumnlistCount(char **ppCollist){
/*
** This function gathers 'y' or 'b' data for a single phrase.
*/
static void fts3ExprLHits(
static int fts3ExprLHits(
Fts3Expr *pExpr, /* Phrase expression node */
MatchInfo *p /* Matchinfo context */
){
@@ -882,25 +887,29 @@ static void fts3ExprLHits(
if( *pIter!=0x01 ) break;
pIter++;
pIter += fts3GetVarint32(pIter, &iCol);
if( iCol>=p->nCol ) return FTS_CORRUPT_VTAB;
}
return SQLITE_OK;
}
/*
** Gather the results for matchinfo directives 'y' and 'b'.
*/
static void fts3ExprLHitGather(
static int fts3ExprLHitGather(
Fts3Expr *pExpr,
MatchInfo *p
){
int rc = SQLITE_OK;
assert( (pExpr->pLeft==0)==(pExpr->pRight==0) );
if( pExpr->bEof==0 && pExpr->iDocid==p->pCursor->iPrevId ){
if( pExpr->pLeft ){
fts3ExprLHitGather(pExpr->pLeft, p);
fts3ExprLHitGather(pExpr->pRight, p);
rc = fts3ExprLHitGather(pExpr->pLeft, p);
if( rc==SQLITE_OK ) rc = fts3ExprLHitGather(pExpr->pRight, p);
}else{
fts3ExprLHits(pExpr, p);
rc = fts3ExprLHits(pExpr, p);
}
}
return rc;
}
/*
@@ -1117,11 +1126,12 @@ static int fts3MatchinfoLcs(Fts3Cursor *pCsr, MatchInfo *pInfo){
int i;
int iCol;
int nToken = 0;
int rc = SQLITE_OK;
/* Allocate and populate the array of LcsIterator objects. The array
** contains one element for each matchable phrase in the query.
**/
aIter = sqlite3_malloc(sizeof(LcsIterator) * pCsr->nPhrase);
aIter = sqlite3_malloc64(sizeof(LcsIterator) * pCsr->nPhrase);
if( !aIter ) return SQLITE_NOMEM;
memset(aIter, 0, sizeof(LcsIterator) * pCsr->nPhrase);
(void)fts3ExprIterate(pCsr->pExpr, fts3MatchinfoLcsCb, (void*)aIter);
@@ -1137,13 +1147,16 @@ static int fts3MatchinfoLcs(Fts3Cursor *pCsr, MatchInfo *pInfo){
int nLive = 0; /* Number of iterators in aIter not at EOF */
for(i=0; i<pInfo->nPhrase; i++){
int rc;
LcsIterator *pIt = &aIter[i];
rc = sqlite3Fts3EvalPhrasePoslist(pCsr, pIt->pExpr, iCol, &pIt->pRead);
if( rc!=SQLITE_OK ) return rc;
if( rc!=SQLITE_OK ) goto matchinfo_lcs_out;
if( pIt->pRead ){
pIt->iPos = pIt->iPosOffset;
fts3LcsIteratorAdvance(&aIter[i]);
fts3LcsIteratorAdvance(pIt);
if( pIt->pRead==0 ){
rc = FTS_CORRUPT_VTAB;
goto matchinfo_lcs_out;
}
nLive++;
}
}
@@ -1175,8 +1188,9 @@ static int fts3MatchinfoLcs(Fts3Cursor *pCsr, MatchInfo *pInfo){
pInfo->aMatchinfo[iCol] = nLcs;
}
matchinfo_lcs_out:
sqlite3_free(aIter);
return SQLITE_OK;
return rc;
}
/*
@@ -1272,7 +1286,7 @@ static int fts3MatchinfoValues(
case FTS3_MATCHINFO_LHITS: {
int nZero = fts3MatchinfoSize(pInfo, zArg[i]) * sizeof(u32);
memset(pInfo->aMatchinfo, 0, nZero);
fts3ExprLHitGather(pCsr->pExpr, pInfo);
rc = fts3ExprLHitGather(pCsr->pExpr, pInfo);
break;
}
@@ -1424,6 +1438,10 @@ void sqlite3Fts3Snippet(
return;
}
/* Limit the snippet length to 64 tokens. */
if( nToken<-64 ) nToken = -64;
if( nToken>+64 ) nToken = +64;
for(nSnippet=1; 1; nSnippet++){
int iSnip; /* Loop counter 0..nSnippet-1 */
@@ -1566,7 +1584,7 @@ void sqlite3Fts3Offsets(
if( rc!=SQLITE_OK ) goto offsets_out;
/* Allocate the array of TermOffset iterators. */
sCtx.aTerm = (TermOffset *)sqlite3_malloc(sizeof(TermOffset)*nToken);
sCtx.aTerm = (TermOffset *)sqlite3_malloc64(sizeof(TermOffset)*nToken);
if( 0==sCtx.aTerm ){
rc = SQLITE_NOMEM;
goto offsets_out;
+5 -4
View File
@@ -68,9 +68,9 @@ static int fts3termConnectMethod(
char const *zFts3; /* Name of fts3 table */
int nDb; /* Result of strlen(zDb) */
int nFts3; /* Result of strlen(zFts3) */
int nByte; /* Bytes of space to allocate here */
sqlite3_int64 nByte; /* Bytes of space to allocate here */
int rc; /* value returned by declare_vtab() */
Fts3termTable *p; /* Virtual table object to return */
Fts3termTable *p; /* Virtual table object to return */
int iIndex = 0;
UNUSED_PARAMETER(pCtx);
@@ -96,7 +96,7 @@ static int fts3termConnectMethod(
if( rc!=SQLITE_OK ) return rc;
nByte = sizeof(Fts3termTable) + sizeof(Fts3Table) + nDb + nFts3 + 2;
p = (Fts3termTable *)sqlite3_malloc(nByte);
p = (Fts3termTable *)sqlite3_malloc64(nByte);
if( !p ) return SQLITE_NOMEM;
memset(p, 0, nByte);
@@ -361,7 +361,8 @@ int sqlite3Fts3InitTerm(sqlite3 *db){
0, /* xRename */
0, /* xSavepoint */
0, /* xRelease */
0 /* xRollbackTo */
0, /* xRollbackTo */
0 /* xShadowName */
};
int rc; /* Return code */
+30 -1
View File
@@ -574,6 +574,33 @@ static int SQLITE_TCLAPI fts3_test_varint_cmd(
** End of tokenizer code.
**************************************************************************/
/*
** sqlite3_fts3_may_be_corrupt BOOLEAN
**
** Set or clear the global "may-be-corrupt" flag. Return the old value.
*/
static int SQLITE_TCLAPI fts3_may_be_corrupt(
void * clientData,
Tcl_Interp *interp,
int objc,
Tcl_Obj *CONST objv[]
){
int bOld = sqlite3_fts3_may_be_corrupt;
if( objc!=2 && objc!=1 ){
Tcl_WrongNumArgs(interp, 1, objv, "?BOOLEAN?");
return TCL_ERROR;
}
if( objc==2 ){
int bNew;
if( Tcl_GetBooleanFromObj(interp, objv[1], &bNew) ) return TCL_ERROR;
sqlite3_fts3_may_be_corrupt = bNew;
}
Tcl_SetObjResult(interp, Tcl_NewIntObj(bOld));
return TCL_OK;
}
int Sqlitetestfts3_Init(Tcl_Interp *interp){
Tcl_CreateObjCommand(interp, "fts3_near_match", fts3_near_match_cmd, 0, 0);
Tcl_CreateObjCommand(interp,
@@ -582,10 +609,12 @@ int Sqlitetestfts3_Init(Tcl_Interp *interp){
Tcl_CreateObjCommand(
interp, "fts3_test_tokenizer", fts3_test_tokenizer_cmd, 0, 0
);
Tcl_CreateObjCommand(
interp, "fts3_test_varint", fts3_test_varint_cmd, 0, 0
);
Tcl_CreateObjCommand(
interp, "sqlite3_fts3_may_be_corrupt", fts3_may_be_corrupt, 0, 0
);
return TCL_OK;
}
#endif /* SQLITE_ENABLE_FTS3 || SQLITE_ENABLE_FTS4 */
+3 -2
View File
@@ -122,7 +122,7 @@ static int fts3tokDequoteArray(
nByte += (int)(strlen(argv[i]) + 1);
}
*pazDequote = azDequote = sqlite3_malloc(sizeof(char *)*argc + nByte);
*pazDequote = azDequote = sqlite3_malloc64(sizeof(char *)*argc + nByte);
if( azDequote==0 ){
rc = SQLITE_NOMEM;
}else{
@@ -443,7 +443,8 @@ int sqlite3Fts3InitTok(sqlite3 *db, Fts3Hash *pHash){
0, /* xRename */
0, /* xSavepoint */
0, /* xRelease */
0 /* xRollbackTo */
0, /* xRollbackTo */
0 /* xShadowName */
};
int rc; /* Return code */
+10 -7
View File
@@ -82,7 +82,7 @@ typedef struct unicode_cursor unicode_cursor;
struct unicode_tokenizer {
sqlite3_tokenizer base;
int bRemoveDiacritic;
int eRemoveDiacritic;
int nException;
int *aiException;
};
@@ -155,7 +155,7 @@ static int unicodeAddExceptions(
int *aNew; /* New aiException[] array */
int nNew; /* Number of valid entries in array aNew[] */
aNew = sqlite3_realloc(p->aiException, (p->nException+nEntry)*sizeof(int));
aNew = sqlite3_realloc64(p->aiException,(p->nException+nEntry)*sizeof(int));
if( aNew==0 ) return SQLITE_NOMEM;
nNew = p->nException;
@@ -227,17 +227,20 @@ static int unicodeCreate(
pNew = (unicode_tokenizer *) sqlite3_malloc(sizeof(unicode_tokenizer));
if( pNew==NULL ) return SQLITE_NOMEM;
memset(pNew, 0, sizeof(unicode_tokenizer));
pNew->bRemoveDiacritic = 1;
pNew->eRemoveDiacritic = 1;
for(i=0; rc==SQLITE_OK && i<nArg; i++){
const char *z = azArg[i];
int n = (int)strlen(z);
if( n==19 && memcmp("remove_diacritics=1", z, 19)==0 ){
pNew->bRemoveDiacritic = 1;
pNew->eRemoveDiacritic = 1;
}
else if( n==19 && memcmp("remove_diacritics=0", z, 19)==0 ){
pNew->bRemoveDiacritic = 0;
pNew->eRemoveDiacritic = 0;
}
else if( n==19 && memcmp("remove_diacritics=2", z, 19)==0 ){
pNew->eRemoveDiacritic = 2;
}
else if( n>=11 && memcmp("tokenchars=", z, 11)==0 ){
rc = unicodeAddExceptions(pNew, 1, &z[11], n-11);
@@ -341,7 +344,7 @@ static int unicodeNext(
/* Grow the output buffer if required. */
if( (zOut-pCsr->zToken)>=(pCsr->nAlloc-4) ){
char *zNew = sqlite3_realloc(pCsr->zToken, pCsr->nAlloc+64);
char *zNew = sqlite3_realloc64(pCsr->zToken, pCsr->nAlloc+64);
if( !zNew ) return SQLITE_NOMEM;
zOut = &zNew[zOut - pCsr->zToken];
pCsr->zToken = zNew;
@@ -350,7 +353,7 @@ static int unicodeNext(
/* Write the folded case of the last character read to the output */
zEnd = z;
iOut = sqlite3FtsUnicodeFold((int)iCode, p->bRemoveDiacritic);
iOut = sqlite3FtsUnicodeFold((int)iCode, p->eRemoveDiacritic);
if( iOut ){
WRITE_UTF8(zOut, iOut);
}
+45 -26
View File
@@ -1,5 +1,5 @@
/*
** 2012 May 25
** 2012-05-25
**
** The author disclaims copyright to this source code. In place of
** a legal notice, here is a blessing:
@@ -159,32 +159,48 @@ int sqlite3FtsUnicodeIsalnum(int c){
** E"). The resuls of passing a codepoint that corresponds to an
** uppercase letter are undefined.
*/
static int remove_diacritic(int c){
static int remove_diacritic(int c, int bComplex){
unsigned short aDia[] = {
0, 1797, 1848, 1859, 1891, 1928, 1940, 1995,
2024, 2040, 2060, 2110, 2168, 2206, 2264, 2286,
2344, 2383, 2472, 2488, 2516, 2596, 2668, 2732,
2782, 2842, 2894, 2954, 2984, 3000, 3028, 3336,
3456, 3696, 3712, 3728, 3744, 3896, 3912, 3928,
3968, 4008, 4040, 4106, 4138, 4170, 4202, 4234,
4266, 4296, 4312, 4344, 4408, 4424, 4472, 4504,
6148, 6198, 6264, 6280, 6360, 6429, 6505, 6529,
61448, 61468, 61534, 61592, 61642, 61688, 61704, 61726,
61784, 61800, 61836, 61880, 61914, 61948, 61998, 62122,
62154, 62200, 62218, 62302, 62364, 62442, 62478, 62536,
62554, 62584, 62604, 62640, 62648, 62656, 62664, 62730,
62924, 63050, 63082, 63274, 63390,
3456, 3696, 3712, 3728, 3744, 3766, 3832, 3896,
3912, 3928, 3944, 3968, 4008, 4040, 4056, 4106,
4138, 4170, 4202, 4234, 4266, 4296, 4312, 4344,
4408, 4424, 4442, 4472, 4488, 4504, 6148, 6198,
6264, 6280, 6360, 6429, 6505, 6529, 61448, 61468,
61512, 61534, 61592, 61610, 61642, 61672, 61688, 61704,
61726, 61784, 61800, 61816, 61836, 61880, 61896, 61914,
61948, 61998, 62062, 62122, 62154, 62184, 62200, 62218,
62252, 62302, 62364, 62410, 62442, 62478, 62536, 62554,
62584, 62604, 62640, 62648, 62656, 62664, 62730, 62766,
62830, 62890, 62924, 62974, 63032, 63050, 63082, 63118,
63182, 63242, 63274, 63310, 63368, 63390,
};
char aChar[] = {
'\0', 'a', 'c', 'e', 'i', 'n', 'o', 'u', 'y', 'y', 'a', 'c',
'd', 'e', 'e', 'g', 'h', 'i', 'j', 'k', 'l', 'n', 'o', 'r',
's', 't', 'u', 'u', 'w', 'y', 'z', 'o', 'u', 'a', 'i', 'o',
'u', 'g', 'k', 'o', 'j', 'g', 'n', 'a', 'e', 'i', 'o', 'r',
'u', 's', 't', 'h', 'a', 'e', 'o', 'y', '\0', '\0', '\0', '\0',
'\0', '\0', '\0', '\0', 'a', 'b', 'd', 'd', 'e', 'f', 'g', 'h',
'h', 'i', 'k', 'l', 'l', 'm', 'n', 'p', 'r', 'r', 's', 't',
'u', 'v', 'w', 'w', 'x', 'y', 'z', 'h', 't', 'w', 'y', 'a',
'e', 'i', 'o', 'u', 'y',
#define HIBIT ((unsigned char)0x80)
unsigned char aChar[] = {
'\0', 'a', 'c', 'e', 'i', 'n',
'o', 'u', 'y', 'y', 'a', 'c',
'd', 'e', 'e', 'g', 'h', 'i',
'j', 'k', 'l', 'n', 'o', 'r',
's', 't', 'u', 'u', 'w', 'y',
'z', 'o', 'u', 'a', 'i', 'o',
'u', 'u'|HIBIT, 'a'|HIBIT, 'g', 'k', 'o',
'o'|HIBIT, 'j', 'g', 'n', 'a'|HIBIT, 'a',
'e', 'i', 'o', 'r', 'u', 's',
't', 'h', 'a', 'e', 'o'|HIBIT, 'o',
'o'|HIBIT, 'y', '\0', '\0', '\0', '\0',
'\0', '\0', '\0', '\0', 'a', 'b',
'c'|HIBIT, 'd', 'd', 'e'|HIBIT, 'e', 'e'|HIBIT,
'f', 'g', 'h', 'h', 'i', 'i'|HIBIT,
'k', 'l', 'l'|HIBIT, 'l', 'm', 'n',
'o'|HIBIT, 'p', 'r', 'r'|HIBIT, 'r', 's',
's'|HIBIT, 't', 'u', 'u'|HIBIT, 'v', 'w',
'w', 'x', 'y', 'z', 'h', 't',
'w', 'y', 'a', 'a'|HIBIT, 'a'|HIBIT, 'a'|HIBIT,
'e', 'e'|HIBIT, 'e'|HIBIT, 'i', 'o', 'o'|HIBIT,
'o'|HIBIT, 'o'|HIBIT, 'u', 'u'|HIBIT, 'u'|HIBIT, 'y',
};
unsigned int key = (((unsigned int)c)<<3) | 0x00000007;
@@ -201,7 +217,8 @@ static int remove_diacritic(int c){
}
}
assert( key>=aDia[iRes] );
return ((c > (aDia[iRes]>>3) + (aDia[iRes]&0x07)) ? c : (int)aChar[iRes]);
if( bComplex==0 && (aChar[iRes] & 0x80) ) return c;
return (c > (aDia[iRes]>>3) + (aDia[iRes]&0x07)) ? c : ((int)aChar[iRes] & 0x7F);
}
@@ -214,8 +231,8 @@ int sqlite3FtsUnicodeIsdiacritic(int c){
unsigned int mask1 = 0x000361F8;
if( c<768 || c>817 ) return 0;
return (c < 768+32) ?
(mask0 & (1 << (c-768))) :
(mask1 & (1 << (c-768-32)));
(mask0 & ((unsigned int)1 << (c-768))) :
(mask1 & ((unsigned int)1 << (c-768-32)));
}
@@ -228,7 +245,7 @@ int sqlite3FtsUnicodeIsdiacritic(int c){
** The results are undefined if the value passed to this function
** is less than zero.
*/
int sqlite3FtsUnicodeFold(int c, int bRemoveDiacritic){
int sqlite3FtsUnicodeFold(int c, int eRemoveDiacritic){
/* Each entry in the following array defines a rule for folding a range
** of codepoints to lower case. The rule applies to a range of nRange
** codepoints starting at codepoint iCode.
@@ -351,7 +368,9 @@ int sqlite3FtsUnicodeFold(int c, int bRemoveDiacritic){
assert( ret>0 );
}
if( bRemoveDiacritic ) ret = remove_diacritic(ret);
if( eRemoveDiacritic ){
ret = remove_diacritic(ret, eRemoveDiacritic==2);
}
}
else if( c>=66560 && c<66600 ){
+51 -23
View File
@@ -396,10 +396,12 @@ static int fts3SqlStmt(
pStmt = p->aStmt[eStmt];
if( !pStmt ){
int f = SQLITE_PREPARE_PERSISTENT|SQLITE_PREPARE_NO_VTAB;
char *zSql;
if( eStmt==SQL_CONTENT_INSERT ){
zSql = sqlite3_mprintf(azSql[eStmt], p->zDb, p->zName, p->zWriteExprlist);
}else if( eStmt==SQL_SELECT_CONTENT_BY_ROWID ){
f &= ~SQLITE_PREPARE_NO_VTAB;
zSql = sqlite3_mprintf(azSql[eStmt], p->zReadExprlist);
}else{
zSql = sqlite3_mprintf(azSql[eStmt], p->zDb, p->zName);
@@ -407,8 +409,7 @@ static int fts3SqlStmt(
if( !zSql ){
rc = SQLITE_NOMEM;
}else{
rc = sqlite3_prepare_v3(p->db, zSql, -1, SQLITE_PREPARE_PERSISTENT,
&pStmt, NULL);
rc = sqlite3_prepare_v3(p->db, zSql, -1, f, &pStmt, NULL);
sqlite3_free(zSql);
assert( rc==SQLITE_OK || pStmt==0 );
p->aStmt[eStmt] = pStmt;
@@ -566,7 +567,7 @@ static sqlite3_int64 getAbsoluteLevel(
int iLevel /* Level of segments */
){
sqlite3_int64 iBase; /* First absolute level for iLangid/iIndex */
assert( iLangid>=0 );
assert_fts3_nc( iLangid>=0 );
assert( p->nIndex>0 );
assert( iIndex>=0 && iIndex<p->nIndex );
@@ -1347,7 +1348,9 @@ static int fts3SegReaderNext(
/* If iCurrentBlock>=iLeafEndBlock, this is an EOF condition. All leaf
** blocks have already been traversed. */
assert( pReader->iCurrentBlock<=pReader->iLeafEndBlock );
#ifdef CORRUPT_DB
assert( pReader->iCurrentBlock<=pReader->iLeafEndBlock || CORRUPT_DB );
#endif
if( pReader->iCurrentBlock>=pReader->iLeafEndBlock ){
return SQLITE_OK;
}
@@ -1374,15 +1377,19 @@ static int fts3SegReaderNext(
** safe (no risk of overread) even if the node data is corrupted. */
pNext += fts3GetVarint32(pNext, &nPrefix);
pNext += fts3GetVarint32(pNext, &nSuffix);
if( nPrefix<0 || nSuffix<=0
|| &pNext[nSuffix]>&pReader->aNode[pReader->nNode]
if( nSuffix<=0
|| (&pReader->aNode[pReader->nNode] - pNext)<nSuffix
|| nPrefix>pReader->nTermAlloc
){
return FTS_CORRUPT_VTAB;
}
if( nPrefix+nSuffix>pReader->nTermAlloc ){
int nNew = (nPrefix+nSuffix)*2;
char *zNew = sqlite3_realloc(pReader->zTerm, nNew);
/* Both nPrefix and nSuffix were read by fts3GetVarint32() and so are
** between 0 and 0x7FFFFFFF. But the sum of the two may cause integer
** overflow - hence the (i64) casts. */
if( (i64)nPrefix+nSuffix>(i64)pReader->nTermAlloc ){
i64 nNew = ((i64)nPrefix+nSuffix)*2;
char *zNew = sqlite3_realloc64(pReader->zTerm, nNew);
if( !zNew ){
return SQLITE_NOMEM;
}
@@ -1404,7 +1411,7 @@ static int fts3SegReaderNext(
** b-tree node. And that the final byte of the doclist is 0x00. If either
** of these statements is untrue, then the data structure is corrupt.
*/
if( &pReader->aDoclist[pReader->nDoclist]>&pReader->aNode[pReader->nNode]
if( pReader->nDoclist > pReader->nNode-(pReader->aDoclist-pReader->aNode)
|| (pReader->nPopulate==0 && pReader->aDoclist[pReader->nDoclist-1])
){
return FTS_CORRUPT_VTAB;
@@ -1604,8 +1611,13 @@ int sqlite3Fts3SegReaderNew(
Fts3SegReader *pReader; /* Newly allocated SegReader object */
int nExtra = 0; /* Bytes to allocate segment root node */
assert( iStartLeaf<=iEndLeaf );
assert( zRoot!=0 || nRoot==0 );
#ifdef CORRUPT_DB
assert( zRoot!=0 || CORRUPT_DB );
#endif
if( iStartLeaf==0 ){
if( iEndLeaf!=0 ) return FTS_CORRUPT_VTAB;
nExtra = nRoot + FTS3_NODE_PADDING;
}
@@ -1625,7 +1637,7 @@ int sqlite3Fts3SegReaderNew(
pReader->aNode = (char *)&pReader[1];
pReader->rootOnly = 1;
pReader->nNode = nRoot;
memcpy(pReader->aNode, zRoot, nRoot);
if( nRoot ) memcpy(pReader->aNode, zRoot, nRoot);
memset(&pReader->aNode[nRoot], 0, FTS3_NODE_PADDING);
}else{
pReader->iCurrentBlock = iStartLeaf-1;
@@ -2245,6 +2257,11 @@ static int fts3SegWriterAdd(
nPrefix = fts3PrefixCompress(pWriter->zTerm, pWriter->nTerm, zTerm, nTerm);
nSuffix = nTerm-nPrefix;
/* If nSuffix is zero or less, then zTerm/nTerm must be a prefix of
** pWriter->zTerm/pWriter->nTerm. i.e. must be equal to or less than when
** compared with BINARY collation. This indicates corruption. */
if( nSuffix<=0 ) return FTS_CORRUPT_VTAB;
/* Figure out how many bytes are required by this new entry */
nReq = sqlite3Fts3VarintLen(nPrefix) + /* varint containing prefix size */
sqlite3Fts3VarintLen(nSuffix) + /* varint containing suffix size */
@@ -2952,7 +2969,9 @@ int sqlite3Fts3SegReaderStep(
}else{
iDelta = iDocid - iPrev;
}
assert( iDelta>0 || (nDoclist==0 && iDelta==iDocid) );
if( iDelta<=0 && (nDoclist>0 || iDelta!=iDocid) ){
return FTS_CORRUPT_VTAB;
}
assert( nDoclist>0 || iDelta==iDocid );
nByte = sqlite3Fts3VarintLen(iDelta) + (isRequirePos?nList+1:0);
@@ -3218,8 +3237,10 @@ static int fts3SegmentMerge(
if( rc!=SQLITE_OK ) goto finished;
assert( csr.nSegment>0 );
assert( iNewLevel>=getAbsoluteLevel(p, iLangid, iIndex, 0) );
assert( iNewLevel<getAbsoluteLevel(p, iLangid, iIndex,FTS3_SEGDIR_MAXLEVEL) );
assert_fts3_nc( iNewLevel>=getAbsoluteLevel(p, iLangid, iIndex, 0) );
assert_fts3_nc(
iNewLevel<getAbsoluteLevel(p, iLangid, iIndex,FTS3_SEGDIR_MAXLEVEL)
);
memset(&filter, 0, sizeof(Fts3SegFilter));
filter.flags = FTS3_SEGMENT_REQUIRE_POS;
@@ -3318,14 +3339,16 @@ static void fts3DecodeIntArray(
const char *zBuf, /* The BLOB containing the varints */
int nBuf /* size of the BLOB */
){
int i, j;
UNUSED_PARAMETER(nBuf);
for(i=j=0; i<N; i++){
sqlite3_int64 x;
j += sqlite3Fts3GetVarint(&zBuf[j], &x);
assert(j<=nBuf);
a[i] = (u32)(x & 0xffffffff);
int i = 0;
if( nBuf && (zBuf[nBuf-1]&0x80)==0 ){
int j;
for(i=j=0; i<N && j<nBuf; i++){
sqlite3_int64 x;
j += sqlite3Fts3GetVarint(&zBuf[j], &x);
a[i] = (u32)(x & 0xffffffff);
}
}
while( i<N ) a[i++] = 0;
}
/*
@@ -3730,6 +3753,9 @@ static int nodeReaderNext(NodeReader *p){
}
p->iOff += fts3GetVarint32(&p->aNode[p->iOff], &nSuffix);
if( nPrefix>p->iOff || nSuffix>p->nNode-p->iOff ){
return FTS_CORRUPT_VTAB;
}
blobGrowBuffer(&p->term, nPrefix+nSuffix, &rc);
if( rc==SQLITE_OK ){
memcpy(&p->term.a[nPrefix], &p->aNode[p->iOff], nSuffix);
@@ -3737,6 +3763,9 @@ static int nodeReaderNext(NodeReader *p){
p->iOff += nSuffix;
if( p->iChild==0 ){
p->iOff += fts3GetVarint32(&p->aNode[p->iOff], &p->nDoclist);
if( (p->nNode-p->iOff)<p->nDoclist ){
return FTS_CORRUPT_VTAB;
}
p->aDoclist = &p->aNode[p->iOff];
p->iOff += p->nDoclist;
}
@@ -3744,7 +3773,6 @@ static int nodeReaderNext(NodeReader *p){
}
assert( p->iOff<=p->nNode );
return rc;
}
+31 -22
View File
@@ -9,11 +9,12 @@ proc print_rd {map} {
set nRange 1
set iFirst [lindex $map 0 0]
set cPrev [lindex $map 0 1]
set fPrev [lindex $map 0 2]
foreach m [lrange $map 1 end] {
foreach {i c} $m {}
foreach {i c f} $m {}
if {$cPrev == $c} {
if {$cPrev == $c && $fPrev==$f} {
for {set j [expr $iFirst+$nRange]} {$j<$i} {incr j} {
if {[info exists tl_lookup_table($j)]==0} break
}
@@ -29,13 +30,16 @@ proc print_rd {map} {
lappend lRange [list $iFirst $nRange]
lappend aChar $cPrev
lappend aFlag $fPrev
set iFirst $i
set cPrev $c
set fPrev $f
set nRange 1
}
lappend lRange [list $iFirst $nRange]
lappend aChar $cPrev
lappend aFlag $fPrev
puts "/*"
puts "** If the argument is a codepoint corresponding to a lowercase letter"
@@ -45,7 +49,7 @@ proc print_rd {map} {
puts "** E\"). The resuls of passing a codepoint that corresponds to an"
puts "** uppercase letter are undefined."
puts "*/"
puts "static int ${::remove_diacritic}(int c)\{"
puts "static int ${::remove_diacritic}(int c, int bComplex)\{"
puts " unsigned short aDia\[\] = \{"
puts -nonewline " 0, "
set i 1
@@ -59,14 +63,19 @@ proc print_rd {map} {
}
puts ""
puts " \};"
puts " char aChar\[\] = \{"
puts -nonewline " '\\0', "
puts "#define HIBIT ((unsigned char)0x80)"
puts " unsigned char aChar\[\] = \{"
puts -nonewline " '\\0', "
set i 1
foreach c $aChar {
set str "'$c', "
if {$c == ""} { set str "'\\0', " }
foreach c $aChar f $aFlag {
if { $f } {
set str "'$c'|HIBIT, "
} else {
set str "'$c', "
}
if {$c == ""} { set str "'\\0', " }
if {($i % 12)==0} {puts "" ; puts -nonewline " " }
if {($i % 6)==0} {puts "" ; puts -nonewline " " }
incr i
puts -nonewline "$str"
}
@@ -87,7 +96,8 @@ proc print_rd {map} {
}
}
assert( key>=aDia[iRes] );
return ((c > (aDia[iRes]>>3) + (aDia[iRes]&0x07)) ? c : (int)aChar[iRes]);}
if( bComplex==0 && (aChar[iRes] & 0x80) ) return c;
return (c > (aDia[iRes]>>3) + (aDia[iRes]&0x07)) ? c : ((int)aChar[iRes] & 0x7F);}
puts "\}"
}
@@ -95,7 +105,8 @@ proc print_isdiacritic {zFunc map} {
set lCode [list]
foreach m $map {
foreach {code char} $m {}
foreach {code char flag} $m {}
if {$flag} continue
if {$code && $char == ""} { lappend lCode $code }
}
set lCode [lsort -integer $lCode]
@@ -124,8 +135,8 @@ proc print_isdiacritic {zFunc map} {
puts " if( c<$iFirst || c>$iLast ) return 0;"
puts " return (c < $iFirst+32) ?"
puts " (mask0 & (1 << (c-$iFirst))) :"
puts " (mask1 & (1 << (c-$iFirst-32)));"
puts " (mask0 & ((unsigned int)1 << (c-$iFirst))) :"
puts " (mask1 & ((unsigned int)1 << (c-$iFirst-32)));"
puts "\}"
}
@@ -472,7 +483,7 @@ proc print_fold {zFunc} {
puts "** The results are undefined if the value passed to this function"
puts "** is less than zero."
puts "*/"
puts "int ${zFunc}\(int c, int bRemoveDiacritic)\{"
puts "int ${zFunc}\(int c, int eRemoveDiacritic)\{"
set liOff [tl_generate_ioff_table $lRecord]
tl_print_table_header
@@ -516,7 +527,9 @@ proc print_fold {zFunc} {
assert( ret>0 );
}
if( bRemoveDiacritic ) ret = ${::remove_diacritic}(ret);
if( eRemoveDiacritic ){
ret = ${::remove_diacritic}(ret, eRemoveDiacritic==2);
}
}
}]
@@ -605,10 +618,6 @@ proc print_categories {lMap} {
set nCat [expr [llength [array names C]] + 1]
puts [code {
int sqlite3Fts5UnicodeNCat(void) {
return $nCat;
}
int sqlite3Fts5UnicodeCatParse(const char *zCat, u8 *aArray){
aArray[0] = 1;
switch( zCat[0] ){
@@ -691,7 +700,7 @@ proc print_categories {lMap} {
static u16 aFts5UnicodeMap[] = {$aMapArray};
static u16 aFts5UnicodeData[] = {$aDataArray};
int sqlite3Fts5UnicodeCategory(int iCode) {
int sqlite3Fts5UnicodeCategory(u32 iCode) {
int iRes = -1;
int iHi;
int iLo;
@@ -774,7 +783,7 @@ proc print_test_categories {lMap} {
aArray[0] = 1;
}
c = sqlite3Fts5UnicodeCategory(i);
c = sqlite3Fts5UnicodeCategory((u32)i);
if( aArray[c]==0 ){
*piCode = i;
return 1;
@@ -829,7 +838,7 @@ proc print_fold_test {zFunc mappings} {
proc print_fileheader {} {
puts [string trim {
/*
** 2012 May 25
** 2012-05-25
**
** The author disclaims copyright to this source code. In place of
** a legal notice, here is a blessing:
+27 -4
View File
@@ -7,12 +7,24 @@
# character that it should be replaced with, or an empty string if the
# codepoint should simply be removed from the input. Examples:
#
# { 224 a } (replace codepoint 224 to "a")
# { 769 "" } (remove codepoint 769 from input)
# { 224 a 0 } (replace codepoint 224 to "a")
# { 769 "" 0 } (remove codepoint 769 from input)
#
# Mappings are only returned for non-upper case codepoints. It is assumed
# that the input has already been folded to lower case.
#
# The third value in the list is always either 0 or 1. 0 if the
# UnicodeData.txt file maps the codepoint to a single ASCII character and
# a diacritic, or 1 if the mapping is indirect. For example, consider the
# two entries:
#
# 1ECD;LATIN SMALL LETTER O WITH DOT BELOW;Ll;0;L;006F 0323;;;;N;;;1ECC;;1ECC
# 1ED9;LATIN SMALL LETTER O WITH CIRCUMFLEX AND DOT BELOW;Ll;0;L;1ECD 0302;;;;N;;;1ED8;;1ED8
#
# The first codepoint is a direct mapping (as 006F is ASCII and 0323 is a
# diacritic). The second is an indirect mapping, as it maps to the
# first codepoint plus 0302 (a diacritic).
#
proc rd_load_unicodedata_text {zName} {
global tl_lookup_table
@@ -53,18 +65,29 @@ proc rd_load_unicodedata_text {zName} {
set iAscii [expr "0x[lindex $character_decomposition_mapping 0]"]
set iDia [expr "0x[lindex $character_decomposition_mapping 1]"]
# Filter out upper-case characters, as they will be mapped to their
# lower-case equivalents before this data is used.
if {[info exists tl_lookup_table($iCode)]} continue
# Check if this is an indirect mapping. If so, set bIndirect to true
# and change $iAscii to the indirectly mappped ASCII character.
set bIndirect 0
if {[info exists dia($iDia)] && [info exists mapping($iAscii)]} {
set iAscii $mapping($iAscii)
set bIndirect 1
}
if { ($iAscii >= 97 && $iAscii <= 122)
|| ($iAscii >= 65 && $iAscii <= 90)
} {
lappend lRet [list $iCode [string tolower [format %c $iAscii]]]
lappend lRet [list $iCode [string tolower [format %c $iAscii]] $bIndirect]
set mapping($iCode) $iAscii
set dia($iDia) 1
}
}
foreach d [array names dia] {
lappend lRet [list $d ""]
lappend lRet [list $d "" 0]
}
set lRet [lsort -integer -index 0 $lRet]
+10 -14
View File
@@ -120,12 +120,8 @@ struct Fts5PhraseIter {
**
** 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.
** first token of the phrase. 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.
@@ -166,7 +162,7 @@ struct Fts5PhraseIter {
** Save the pointer passed as the second argument as the extension functions
** "auxiliary data". The pointer may then be retrieved by the current or any
** future invocation of the same fts5 extension function made as part of
** of the same MATCH query using the xGetAuxdata() API.
** the same MATCH query using the xGetAuxdata() API.
**
** Each extension function is allocated a single auxiliary data slot for
** each FTS query (MATCH expression). If the extension function is invoked
@@ -181,7 +177,7 @@ struct Fts5PhraseIter {
** The xDelete callback, if one is specified, is also invoked on the
** auxiliary data pointer after the FTS5 query has finished.
**
** If an error (e.g. an OOM condition) occurs within this function, an
** If an error (e.g. an OOM condition) occurs within this function,
** the auxiliary data is set to NULL and an error code returned. If the
** xDelete parameter was not NULL, it is invoked on the auxiliary data
** pointer before returning.
@@ -414,11 +410,11 @@ struct Fts5ExtensionApi {
** the tokenizer substitutes "first" for "1st" and the query works
** as expected.
**
** <li> By adding multiple synonyms for a single term to the FTS index.
** In this case, when tokenizing query text, the tokenizer may
** provide multiple synonyms for a single term within the document.
** FTS5 then queries the index for each synonym individually. For
** example, faced with the query:
** <li> By querying the index for all synonyms of each query term
** separately. In this case, when tokenizing query text, the
** tokenizer may provide multiple synonyms for a single term
** within the document. FTS5 then queries the index for each
** synonym individually. For example, faced with the query:
**
** <codeblock>
** ... MATCH 'first place'</codeblock>
@@ -442,7 +438,7 @@ struct Fts5ExtensionApi {
** "place".
**
** This way, even if the tokenizer does not provide synonyms
** when tokenizing query text (it should not - to do would be
** when tokenizing query text (it should not - to do so would be
** inefficient), it doesn't matter if the user queries for
** 'first + place' or '1st + place', as there are entries in the
** FTS index corresponding to both forms of the first token.
+23 -5
View File
@@ -87,6 +87,12 @@ extern int sqlite3_fts5_may_be_corrupt;
# define assert_nc(x) assert(x)
#endif
/*
** A version of memcmp() that does not cause asan errors if one of the pointer
** parameters is NULL and the number of bytes to compare is zero.
*/
#define fts5Memcmp(s1, s2, n) ((n)==0 ? 0 : memcmp((s1), (s2), (n)))
/* Mark a function parameter as unused, to suppress nuisance compiler
** warnings. */
#ifndef UNUSED_PARAM
@@ -274,7 +280,7 @@ void sqlite3Fts5Put32(u8*, int);
int sqlite3Fts5Get32(const u8*);
#define FTS5_POS2COLUMN(iPos) (int)(iPos >> 32)
#define FTS5_POS2OFFSET(iPos) (int)(iPos & 0xFFFFFFFF)
#define FTS5_POS2OFFSET(iPos) (int)(iPos & 0x7FFFFFFF)
typedef struct Fts5PoslistReader Fts5PoslistReader;
struct Fts5PoslistReader {
@@ -309,7 +315,7 @@ int sqlite3Fts5PoslistNext64(
);
/* Malloc utility */
void *sqlite3Fts5MallocZero(int *pRc, int nByte);
void *sqlite3Fts5MallocZero(int *pRc, sqlite3_int64 nByte);
char *sqlite3Fts5Strndup(int *pRc, const char *pIn, int nIn);
/* Character set tests (like isspace(), isalpha() etc.) */
@@ -520,9 +526,19 @@ int sqlite3Fts5PutVarint(unsigned char *p, u64 v);
/**************************************************************************
** Interface to code in fts5.c.
** Interface to code in fts5_main.c.
*/
/*
** Virtual-table object.
*/
typedef struct Fts5Table Fts5Table;
struct Fts5Table {
sqlite3_vtab base; /* Base class used by SQLite core */
Fts5Config *pConfig; /* Virtual table configuration */
Fts5Index *pIndex; /* Full-text index */
};
int sqlite3Fts5GetTokenizer(
Fts5Global*,
const char **azArg,
@@ -532,7 +548,9 @@ int sqlite3Fts5GetTokenizer(
char **pzErr
);
Fts5Index *sqlite3Fts5IndexFromCsrid(Fts5Global*, i64, Fts5Config **);
Fts5Table *sqlite3Fts5TableFromCsrid(Fts5Global*, i64);
int sqlite3Fts5FlushToDisk(Fts5Table*);
/*
** End of interface to code in fts5.c.
@@ -788,7 +806,7 @@ int sqlite3Fts5UnicodeIsdiacritic(int c);
int sqlite3Fts5UnicodeFold(int c, int bRemoveDiacritic);
int sqlite3Fts5UnicodeCatParse(const char*, u8*);
int sqlite3Fts5UnicodeCategory(int iCode);
int sqlite3Fts5UnicodeCategory(u32 iCode);
void sqlite3Fts5UnicodeAscii(u8*, u8*);
/*
** End of interface to code in fts5_unicode2.c.
+11 -9
View File
@@ -136,7 +136,7 @@ static void fts5HighlightAppend(
HighlightContext *p,
const char *z, int n
){
if( *pRc==SQLITE_OK ){
if( *pRc==SQLITE_OK && 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;
@@ -268,7 +268,7 @@ static int fts5SentenceFinderAdd(Fts5SFinder *p, int iAdd){
int nNew = p->nFirstAlloc ? p->nFirstAlloc*2 : 64;
int *aNew;
aNew = (int*)sqlite3_realloc(p->aFirst, nNew*sizeof(int));
aNew = (int*)sqlite3_realloc64(p->aFirst, nNew*sizeof(int));
if( aNew==0 ) return SQLITE_NOMEM;
p->aFirst = aNew;
p->nFirstAlloc = nNew;
@@ -335,11 +335,12 @@ static int fts5SnippetScore(
int nInst;
int nScore = 0;
int iLast = 0;
sqlite3_int64 iEnd = (sqlite3_int64)iPos + nToken;
rc = pApi->xInstCount(pFts, &nInst);
for(i=0; i<nInst && rc==SQLITE_OK; i++){
rc = pApi->xInst(pFts, i, &ip, &ic, &iOff);
if( rc==SQLITE_OK && ic==iCol && iOff>=iPos && iOff<(iPos+nToken) ){
if( rc==SQLITE_OK && ic==iCol && iOff>=iPos && iOff<iEnd ){
nScore += (aSeen[ip] ? 1 : 1000);
aSeen[ip] = 1;
if( iFirst<0 ) iFirst = iOff;
@@ -349,7 +350,7 @@ static int fts5SnippetScore(
*pnScore = nScore;
if( piPos ){
int iAdj = iFirst - (nToken - (iLast-iFirst)) / 2;
sqlite3_int64 iAdj = iFirst - (nToken - (iLast-iFirst)) / 2;
if( (iAdj+nToken)>nDocsize ) iAdj = nDocsize - nToken;
if( iAdj<0 ) iAdj = 0;
*piPos = iAdj;
@@ -442,7 +443,9 @@ static void fts5SnippetFunction(
int jj;
rc = pApi->xInst(pFts, ii, &ip, &ic, &io);
if( ic!=i || rc!=SQLITE_OK ) continue;
if( ic!=i ) continue;
if( io>nDocsize ) rc = FTS5_CORRUPT;
if( rc!=SQLITE_OK ) continue;
memset(aSeen, 0, nPhrase);
rc = fts5SnippetScore(pApi, pFts, nDocsize, aSeen, i,
io, nToken, &nScore, &iAdj
@@ -568,13 +571,13 @@ static int fts5Bm25GetData(
int nPhrase; /* Number of phrases in query */
sqlite3_int64 nRow = 0; /* Number of rows in table */
sqlite3_int64 nToken = 0; /* Number of tokens in table */
int nByte; /* Bytes of space to allocate */
sqlite3_int64 nByte; /* Bytes of space to allocate */
int i;
/* Allocate the Fts5Bm25Data object */
nPhrase = pApi->xPhraseCount(pFts);
nByte = sizeof(Fts5Bm25Data) + nPhrase*2*sizeof(double);
p = (Fts5Bm25Data*)sqlite3_malloc(nByte);
p = (Fts5Bm25Data*)sqlite3_malloc64(nByte);
if( p==0 ){
rc = SQLITE_NOMEM;
}else{
@@ -586,6 +589,7 @@ static int fts5Bm25GetData(
/* Calculate the average document length for this FTS5 table */
if( rc==SQLITE_OK ) rc = pApi->xRowCount(pFts, &nRow);
assert( rc!=SQLITE_OK || nRow>0 );
if( rc==SQLITE_OK ) rc = pApi->xColumnTotalSize(pFts, -1, &nToken);
if( rc==SQLITE_OK ) p->avgdl = (double)nToken / (double)nRow;
@@ -710,5 +714,3 @@ int sqlite3Fts5AuxInit(fts5_api *pApi){
return rc;
}
+6 -6
View File
@@ -17,12 +17,12 @@
int sqlite3Fts5BufferSize(int *pRc, Fts5Buffer *pBuf, u32 nByte){
if( (u32)pBuf->nSpace<nByte ){
u32 nNew = pBuf->nSpace ? pBuf->nSpace : 64;
u64 nNew = pBuf->nSpace ? pBuf->nSpace : 64;
u8 *pNew;
while( nNew<nByte ){
nNew = nNew * 2;
}
pNew = sqlite3_realloc(pBuf->p, nNew);
pNew = sqlite3_realloc64(pBuf->p, nNew);
if( pNew==0 ){
*pRc = SQLITE_NOMEM;
return 1;
@@ -52,7 +52,7 @@ void sqlite3Fts5Put32(u8 *aBuf, int iVal){
}
int sqlite3Fts5Get32(const u8 *aBuf){
return (aBuf[0] << 24) + (aBuf[1] << 16) + (aBuf[2] << 8) + aBuf[3];
return (int)((((u32)aBuf[0])<<24) + (aBuf[1]<<16) + (aBuf[2]<<8) + aBuf[3]);
}
/*
@@ -183,7 +183,7 @@ int sqlite3Fts5PoslistNext64(
iOff = ((i64)iVal) << 32;
fts5FastGetVarint32(a, i, iVal);
}
*piOff = iOff + (iVal-2);
*piOff = iOff + ((iVal-2) & 0x7FFFFFFF);
*pi = i;
return 0;
}
@@ -244,10 +244,10 @@ int sqlite3Fts5PoslistWriterAppend(
return SQLITE_OK;
}
void *sqlite3Fts5MallocZero(int *pRc, int nByte){
void *sqlite3Fts5MallocZero(int *pRc, sqlite3_int64 nByte){
void *pRet = 0;
if( *pRc==SQLITE_OK ){
pRet = sqlite3_malloc(nByte);
pRet = sqlite3_malloc64(nByte);
if( pRet==0 ){
if( nByte>0 ) *pRc = SQLITE_NOMEM;
}else{
+4 -4
View File
@@ -295,7 +295,7 @@ static int fts5ConfigParseSpecial(
if( sqlite3_strnicmp("tokenize", zCmd, nCmd)==0 ){
const char *p = (const char*)zArg;
int nArg = (int)strlen(zArg) + 1;
sqlite3_int64 nArg = strlen(zArg) + 1;
char **azArg = sqlite3Fts5MallocZero(&rc, sizeof(char*) * nArg);
char *pDel = sqlite3Fts5MallocZero(&rc, nArg * 2);
char *pSpace = pDel;
@@ -425,8 +425,8 @@ static const char *fts5ConfigGobbleWord(
){
const char *zRet = 0;
int nIn = (int)strlen(zIn);
char *zOut = sqlite3_malloc(nIn+1);
sqlite3_int64 nIn = strlen(zIn);
char *zOut = sqlite3_malloc64(nIn+1);
assert( *pRc==SQLITE_OK );
*pbQuoted = 0;
@@ -529,7 +529,7 @@ int sqlite3Fts5ConfigParse(
int rc = SQLITE_OK; /* Return code */
Fts5Config *pRet; /* New object to return */
int i;
int nByte;
sqlite3_int64 nByte;
*ppOut = pRet = (Fts5Config*)sqlite3_malloc(sizeof(Fts5Config));
if( pRet==0 ) return SQLITE_NOMEM;
+29 -26
View File
@@ -211,7 +211,7 @@ static int fts5ExprGetToken(
return tok;
}
static void *fts5ParseAlloc(u64 t){ return sqlite3_malloc((int)t); }
static void *fts5ParseAlloc(u64 t){ return sqlite3_malloc64((sqlite3_int64)t);}
static void fts5ParseFree(void *p){ sqlite3_free(p); }
int sqlite3Fts5ExprNew(
@@ -356,8 +356,8 @@ static int fts5ExprSynonymList(
if( sqlite3Fts5IterEof(pIter)==0 && pIter->iRowid==iRowid ){
if( pIter->nData==0 ) continue;
if( nIter==nAlloc ){
int nByte = sizeof(Fts5PoslistReader) * nAlloc * 2;
Fts5PoslistReader *aNew = (Fts5PoslistReader*)sqlite3_malloc(nByte);
sqlite3_int64 nByte = sizeof(Fts5PoslistReader) * nAlloc * 2;
Fts5PoslistReader *aNew = (Fts5PoslistReader*)sqlite3_malloc64(nByte);
if( aNew==0 ){
rc = SQLITE_NOMEM;
goto synonym_poslist_out;
@@ -437,8 +437,8 @@ static int fts5ExprPhraseIsMatch(
/* If the aStatic[] array is not large enough, allocate a large array
** using sqlite3_malloc(). This approach could be improved upon. */
if( pPhrase->nTerm>ArraySize(aStatic) ){
int nByte = sizeof(Fts5PoslistReader) * pPhrase->nTerm;
aIter = (Fts5PoslistReader*)sqlite3_malloc(nByte);
sqlite3_int64 nByte = sizeof(Fts5PoslistReader) * pPhrase->nTerm;
aIter = (Fts5PoslistReader*)sqlite3_malloc64(nByte);
if( !aIter ) return SQLITE_NOMEM;
}
memset(aIter, 0, sizeof(Fts5PoslistReader) * pPhrase->nTerm);
@@ -572,7 +572,7 @@ static int fts5ExprNearIsMatch(int *pRc, Fts5ExprNearset *pNear){
/* If the aStatic[] array is not large enough, allocate a large array
** using sqlite3_malloc(). This approach could be improved upon. */
if( pNear->nPhrase>ArraySize(aStatic) ){
int nByte = sizeof(Fts5NearTrimmer) * pNear->nPhrase;
sqlite3_int64 nByte = sizeof(Fts5NearTrimmer) * pNear->nPhrase;
a = (Fts5NearTrimmer*)sqlite3Fts5MallocZero(&rc, nByte);
}else{
memset(aStatic, 0, sizeof(aStatic));
@@ -1481,8 +1481,9 @@ Fts5ExprNearset *sqlite3Fts5ParseNearset(
return pNear;
}
if( pNear==0 ){
int nByte = sizeof(Fts5ExprNearset) + SZALLOC * sizeof(Fts5ExprPhrase*);
pRet = sqlite3_malloc(nByte);
sqlite3_int64 nByte;
nByte = sizeof(Fts5ExprNearset) + SZALLOC * sizeof(Fts5ExprPhrase*);
pRet = sqlite3_malloc64(nByte);
if( pRet==0 ){
pParse->rc = SQLITE_NOMEM;
}else{
@@ -1490,9 +1491,10 @@ Fts5ExprNearset *sqlite3Fts5ParseNearset(
}
}else if( (pNear->nPhrase % SZALLOC)==0 ){
int nNew = pNear->nPhrase + SZALLOC;
int nByte = sizeof(Fts5ExprNearset) + nNew * sizeof(Fts5ExprPhrase*);
sqlite3_int64 nByte;
pRet = (Fts5ExprNearset*)sqlite3_realloc(pNear, nByte);
nByte = sizeof(Fts5ExprNearset) + nNew * sizeof(Fts5ExprPhrase*);
pRet = (Fts5ExprNearset*)sqlite3_realloc64(pNear, nByte);
if( pRet==0 ){
pParse->rc = SQLITE_NOMEM;
}
@@ -1556,8 +1558,8 @@ static int fts5ParseTokenize(
if( pPhrase && pPhrase->nTerm>0 && (tflags & FTS5_TOKEN_COLOCATED) ){
Fts5ExprTerm *pSyn;
int nByte = sizeof(Fts5ExprTerm) + sizeof(Fts5Buffer) + nToken+1;
pSyn = (Fts5ExprTerm*)sqlite3_malloc(nByte);
sqlite3_int64 nByte = sizeof(Fts5ExprTerm) + sizeof(Fts5Buffer) + nToken+1;
pSyn = (Fts5ExprTerm*)sqlite3_malloc64(nByte);
if( pSyn==0 ){
rc = SQLITE_NOMEM;
}else{
@@ -1573,7 +1575,7 @@ static int fts5ParseTokenize(
Fts5ExprPhrase *pNew;
int nNew = SZALLOC + (pPhrase ? pPhrase->nTerm : 0);
pNew = (Fts5ExprPhrase*)sqlite3_realloc(pPhrase,
pNew = (Fts5ExprPhrase*)sqlite3_realloc64(pPhrase,
sizeof(Fts5ExprPhrase) + sizeof(Fts5ExprTerm) * nNew
);
if( pNew==0 ){
@@ -1659,9 +1661,9 @@ Fts5ExprPhrase *sqlite3Fts5ParseTerm(
if( pAppend==0 ){
if( (pParse->nPhrase % 8)==0 ){
int nByte = sizeof(Fts5ExprPhrase*) * (pParse->nPhrase + 8);
sqlite3_int64 nByte = sizeof(Fts5ExprPhrase*) * (pParse->nPhrase + 8);
Fts5ExprPhrase **apNew;
apNew = (Fts5ExprPhrase**)sqlite3_realloc(pParse->apPhrase, nByte);
apNew = (Fts5ExprPhrase**)sqlite3_realloc64(pParse->apPhrase, nByte);
if( apNew==0 ){
pParse->rc = SQLITE_NOMEM;
fts5ExprPhraseFree(sCtx.pPhrase);
@@ -1716,8 +1718,10 @@ int sqlite3Fts5ExprClonePhrase(
if( rc==SQLITE_OK ){
Fts5Colset *pColsetOrig = pOrig->pNode->pNear->pColset;
if( pColsetOrig ){
int nByte = sizeof(Fts5Colset) + (pColsetOrig->nCol-1) * sizeof(int);
Fts5Colset *pColset = (Fts5Colset*)sqlite3Fts5MallocZero(&rc, nByte);
sqlite3_int64 nByte;
Fts5Colset *pColset;
nByte = sizeof(Fts5Colset) + (pColsetOrig->nCol-1) * sizeof(int);
pColset = (Fts5Colset*)sqlite3Fts5MallocZero(&rc, nByte);
if( pColset ){
memcpy(pColset, pColsetOrig, nByte);
}
@@ -1837,7 +1841,7 @@ static Fts5Colset *fts5ParseColset(
assert( pParse->rc==SQLITE_OK );
assert( iCol>=0 && iCol<pParse->pConfig->nCol );
pNew = sqlite3_realloc(p, sizeof(Fts5Colset) + sizeof(int)*nCol);
pNew = sqlite3_realloc64(p, sizeof(Fts5Colset) + sizeof(int)*nCol);
if( pNew==0 ){
pParse->rc = SQLITE_NOMEM;
}else{
@@ -1933,7 +1937,7 @@ Fts5Colset *sqlite3Fts5ParseColset(
static Fts5Colset *fts5CloneColset(int *pRc, Fts5Colset *pOrig){
Fts5Colset *pRet;
if( pOrig ){
int nByte = sizeof(Fts5Colset) + (pOrig->nCol-1) * sizeof(int);
sqlite3_int64 nByte = sizeof(Fts5Colset) + (pOrig->nCol-1) * sizeof(int);
pRet = (Fts5Colset*)sqlite3Fts5MallocZero(pRc, nByte);
if( pRet ){
memcpy(pRet, pOrig, nByte);
@@ -2087,7 +2091,7 @@ Fts5ExprNode *sqlite3Fts5ParseNode(
if( pParse->rc==SQLITE_OK ){
int nChild = 0; /* Number of children of returned node */
int nByte; /* Bytes of space to allocate for this node */
sqlite3_int64 nByte; /* Bytes of space to allocate for this node */
assert( (eType!=FTS5_STRING && !pNear)
|| (eType==FTS5_STRING && !pLeft && !pRight)
@@ -2219,7 +2223,7 @@ Fts5ExprNode *sqlite3Fts5ParseImplicitAnd(
}
static char *fts5ExprTermPrint(Fts5ExprTerm *pTerm){
int nByte = 0;
sqlite3_int64 nByte = 0;
Fts5ExprTerm *p;
char *zQuoted;
@@ -2227,7 +2231,7 @@ static char *fts5ExprTermPrint(Fts5ExprTerm *pTerm){
for(p=pTerm; p; p=p->pSynonym){
nByte += (int)strlen(pTerm->zTerm) * 2 + 3 + 2;
}
zQuoted = sqlite3_malloc(nByte);
zQuoted = sqlite3_malloc64(nByte);
if( zQuoted ){
int i = 0;
@@ -2467,7 +2471,7 @@ static void fts5ExprFunction(
}
nConfig = 3 + (nArg-iArg);
azConfig = (const char**)sqlite3_malloc(sizeof(char*) * nConfig);
azConfig = (const char**)sqlite3_malloc64(sizeof(char*) * nConfig);
if( azConfig==0 ){
sqlite3_result_error_nomem(pCtx);
return;
@@ -2553,7 +2557,7 @@ static void fts5ExprIsAlnum(
sqlite3Fts5UnicodeCatParse("N*", aArr);
sqlite3Fts5UnicodeCatParse("Co", aArr);
iCode = sqlite3_value_int(apVal[0]);
sqlite3_result_int(pCtx, aArr[sqlite3Fts5UnicodeCategory(iCode)]);
sqlite3_result_int(pCtx, aArr[sqlite3Fts5UnicodeCategory((u32)iCode)]);
}
static void fts5ExprFold(
@@ -2648,7 +2652,7 @@ struct Fts5PoslistPopulator {
Fts5PoslistPopulator *sqlite3Fts5ExprClearPoslists(Fts5Expr *pExpr, int bLive){
Fts5PoslistPopulator *pRet;
pRet = sqlite3_malloc(sizeof(Fts5PoslistPopulator)*pExpr->nPhrase);
pRet = sqlite3_malloc64(sizeof(Fts5PoslistPopulator)*pExpr->nPhrase);
if( pRet ){
int i;
memset(pRet, 0, sizeof(Fts5PoslistPopulator)*pExpr->nPhrase);
@@ -2847,4 +2851,3 @@ int sqlite3Fts5ExprPhraseCollist(
return rc;
}
+11 -11
View File
@@ -90,14 +90,14 @@ int sqlite3Fts5HashNew(Fts5Config *pConfig, Fts5Hash **ppNew, int *pnByte){
if( pNew==0 ){
rc = SQLITE_NOMEM;
}else{
int nByte;
sqlite3_int64 nByte;
memset(pNew, 0, sizeof(Fts5Hash));
pNew->pnByte = pnByte;
pNew->eDetail = pConfig->eDetail;
pNew->nSlot = 1024;
nByte = sizeof(Fts5HashEntry*) * pNew->nSlot;
pNew->aSlot = (Fts5HashEntry**)sqlite3_malloc(nByte);
pNew->aSlot = (Fts5HashEntry**)sqlite3_malloc64(nByte);
if( pNew->aSlot==0 ){
sqlite3_free(pNew);
*ppNew = 0;
@@ -165,7 +165,7 @@ static int fts5HashResize(Fts5Hash *pHash){
Fts5HashEntry **apNew;
Fts5HashEntry **apOld = pHash->aSlot;
apNew = (Fts5HashEntry**)sqlite3_malloc(nNew*sizeof(Fts5HashEntry*));
apNew = (Fts5HashEntry**)sqlite3_malloc64(nNew*sizeof(Fts5HashEntry*));
if( !apNew ) return SQLITE_NOMEM;
memset(apNew, 0, nNew*sizeof(Fts5HashEntry*));
@@ -259,7 +259,7 @@ int sqlite3Fts5HashWrite(
if( p==0 ){
/* Figure out how much space to allocate */
char *zKey;
int nByte = sizeof(Fts5HashEntry) + (nToken+1) + 1 + 64;
sqlite3_int64 nByte = sizeof(Fts5HashEntry) + (nToken+1) + 1 + 64;
if( nByte<128 ) nByte = 128;
/* Grow the Fts5Hash.aSlot[] array if necessary. */
@@ -270,7 +270,7 @@ int sqlite3Fts5HashWrite(
}
/* Allocate new Fts5HashEntry and add it to the hash table. */
p = (Fts5HashEntry*)sqlite3_malloc(nByte);
p = (Fts5HashEntry*)sqlite3_malloc64(nByte);
if( !p ) return SQLITE_NOMEM;
memset(p, 0, sizeof(Fts5HashEntry));
p->nAlloc = nByte;
@@ -309,12 +309,12 @@ int sqlite3Fts5HashWrite(
** + 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;
sqlite3_int64 nNew = p->nAlloc * 2;
Fts5HashEntry *pNew;
Fts5HashEntry **pp;
pNew = (Fts5HashEntry*)sqlite3_realloc(p, nNew);
pNew = (Fts5HashEntry*)sqlite3_realloc64(p, nNew);
if( pNew==0 ) return SQLITE_NOMEM;
pNew->nAlloc = nNew;
pNew->nAlloc = (int)nNew;
for(pp=&pHash->aSlot[iHash]; *pp!=p; pp=&(*pp)->pHashNext);
*pp = pNew;
p = pNew;
@@ -438,7 +438,7 @@ static int fts5HashEntrySort(
int i;
*ppSorted = 0;
ap = sqlite3_malloc(sizeof(Fts5HashEntry*) * nMergeSlot);
ap = sqlite3_malloc64(sizeof(Fts5HashEntry*) * nMergeSlot);
if( !ap ) return SQLITE_NOMEM;
memset(ap, 0, sizeof(Fts5HashEntry*) * nMergeSlot);
@@ -483,7 +483,8 @@ int sqlite3Fts5HashQuery(
for(p=pHash->aSlot[iHash]; p; p=p->pHashNext){
zKey = fts5EntryKey(p);
if( memcmp(zKey, pTerm, nTerm)==0 && zKey[nTerm]==0 ) break;
assert( p->nKey+1==(int)strlen(zKey) );
if( nTerm==p->nKey+1 && memcmp(zKey, pTerm, nTerm)==0 ) break;
}
if( p ){
@@ -534,4 +535,3 @@ void sqlite3Fts5HashScanEntry(
*pnDoclist = 0;
}
}
+156 -100
View File
@@ -512,7 +512,6 @@ struct Fts5Iter {
Fts5IndexIter base; /* Base class containing output vars */
Fts5Index *pIndex; /* Index that owns this iterator */
Fts5Structure *pStruct; /* Database structure for this iterator */
Fts5Buffer poslist; /* Buffer containing current poslist */
Fts5Colset *pColset; /* Restrict matches to these columns */
@@ -573,7 +572,7 @@ static u16 fts5GetU16(const u8 *aIn){
** If an OOM error is encountered, return NULL and set the error code in
** the Fts5Index handle passed as the first argument.
*/
static void *fts5IdxMalloc(Fts5Index *p, int nByte){
static void *fts5IdxMalloc(Fts5Index *p, sqlite3_int64 nByte){
return sqlite3Fts5MallocZero(&p->rc, nByte);
}
@@ -607,7 +606,7 @@ static int fts5BufferCompareBlob(
*/
static int fts5BufferCompare(Fts5Buffer *pLeft, Fts5Buffer *pRight){
int nCmp = MIN(pLeft->n, pRight->n);
int res = memcmp(pLeft->p, pRight->p, nCmp);
int res = fts5Memcmp(pLeft->p, pRight->p, nCmp);
return (res==0 ? (pLeft->n - pRight->n) : res);
}
@@ -673,8 +672,8 @@ static Fts5Data *fts5DataRead(Fts5Index *p, i64 iRowid){
if( rc==SQLITE_OK ){
u8 *aOut = 0; /* Read blob data into this buffer */
int nByte = sqlite3_blob_bytes(p->pReader);
int nAlloc = sizeof(Fts5Data) + nByte + FTS5_DATA_PADDING;
pRet = (Fts5Data*)sqlite3_malloc(nAlloc);
sqlite3_int64 nAlloc = sizeof(Fts5Data) + nByte + FTS5_DATA_PADDING;
pRet = (Fts5Data*)sqlite3_malloc64(nAlloc);
if( pRet ){
pRet->nn = nByte;
aOut = pRet->p = (u8*)&pRet[1];
@@ -690,6 +689,7 @@ static Fts5Data *fts5DataRead(Fts5Index *p, i64 iRowid){
pRet = 0;
}else{
/* TODO1: Fix this */
pRet->p[nByte] = 0x00;
pRet->szLeaf = fts5GetU16(&pRet->p[2]);
}
}
@@ -729,7 +729,8 @@ static int fts5IndexPrepareStmt(
if( p->rc==SQLITE_OK ){
if( zSql ){
p->rc = sqlite3_prepare_v3(p->pConfig->db, zSql, -1,
SQLITE_PREPARE_PERSISTENT, ppStmt, 0);
SQLITE_PREPARE_PERSISTENT|SQLITE_PREPARE_NO_VTAB,
ppStmt, 0);
}else{
p->rc = SQLITE_NOMEM;
}
@@ -770,23 +771,12 @@ static void fts5DataDelete(Fts5Index *p, i64 iFirst, i64 iLast){
if( p->rc!=SQLITE_OK ) return;
if( p->pDeleter==0 ){
int rc;
Fts5Config *pConfig = p->pConfig;
char *zSql = sqlite3_mprintf(
"DELETE FROM '%q'.'%q_data' WHERE id>=? AND id<=?",
pConfig->zDb, pConfig->zName
);
if( zSql==0 ){
rc = SQLITE_NOMEM;
}else{
rc = sqlite3_prepare_v3(pConfig->db, zSql, -1,
SQLITE_PREPARE_PERSISTENT, &p->pDeleter, 0);
sqlite3_free(zSql);
}
if( rc!=SQLITE_OK ){
p->rc = rc;
return;
}
if( fts5IndexPrepareStmt(p, &p->pDeleter, zSql) ) return;
}
sqlite3_bind_int64(p->pDeleter, 1, iFirst);
@@ -858,7 +848,7 @@ static int fts5StructureDecode(
int iLvl;
int nLevel = 0;
int nSegment = 0;
int nByte; /* Bytes of space to allocate at pRet */
sqlite3_int64 nByte; /* Bytes of space to allocate at pRet */
Fts5Structure *pRet = 0; /* Structure object to return */
/* Grab the cookie value */
@@ -869,6 +859,11 @@ static int fts5StructureDecode(
** structure record. */
i += fts5GetVarint32(&pData[i], nLevel);
i += fts5GetVarint32(&pData[i], nSegment);
if( nLevel>FTS5_MAX_SEGMENT || nLevel<0
|| nSegment>FTS5_MAX_SEGMENT || nSegment<0
){
return FTS5_CORRUPT;
}
nByte = (
sizeof(Fts5Structure) + /* Main structure */
sizeof(Fts5StructureLevel) * (nLevel-1) /* aLevel[] array */
@@ -891,25 +886,35 @@ static int fts5StructureDecode(
}else{
i += fts5GetVarint32(&pData[i], pLvl->nMerge);
i += fts5GetVarint32(&pData[i], nTotal);
assert( nTotal>=pLvl->nMerge );
if( nTotal<pLvl->nMerge ) rc = FTS5_CORRUPT;
pLvl->aSeg = (Fts5StructureSegment*)sqlite3Fts5MallocZero(&rc,
nTotal * sizeof(Fts5StructureSegment)
);
nSegment -= nTotal;
}
if( rc==SQLITE_OK ){
pLvl->nSeg = nTotal;
for(iSeg=0; iSeg<nTotal; iSeg++){
Fts5StructureSegment *pSeg = &pLvl->aSeg[iSeg];
if( i>=nData ){
rc = FTS5_CORRUPT;
break;
}
i += fts5GetVarint32(&pData[i], pLvl->aSeg[iSeg].iSegid);
i += fts5GetVarint32(&pData[i], pLvl->aSeg[iSeg].pgnoFirst);
i += fts5GetVarint32(&pData[i], pLvl->aSeg[iSeg].pgnoLast);
i += fts5GetVarint32(&pData[i], pSeg->iSegid);
i += fts5GetVarint32(&pData[i], pSeg->pgnoFirst);
i += fts5GetVarint32(&pData[i], pSeg->pgnoLast);
if( pSeg->pgnoLast<pSeg->pgnoFirst ){
rc = FTS5_CORRUPT;
break;
}
}
if( iLvl>0 && pLvl[-1].nMerge && nTotal==0 ) rc = FTS5_CORRUPT;
if( iLvl==nLevel-1 && pLvl->nMerge ) rc = FTS5_CORRUPT;
}
}
if( nSegment!=0 && rc==SQLITE_OK ) rc = FTS5_CORRUPT;
if( rc!=SQLITE_OK ){
fts5StructureRelease(pRet);
pRet = 0;
@@ -927,12 +932,12 @@ static void fts5StructureAddLevel(int *pRc, Fts5Structure **ppStruct){
if( *pRc==SQLITE_OK ){
Fts5Structure *pStruct = *ppStruct;
int nLevel = pStruct->nLevel;
int nByte = (
sqlite3_int64 nByte = (
sizeof(Fts5Structure) + /* Main structure */
sizeof(Fts5StructureLevel) * (nLevel+1) /* aLevel[] array */
);
pStruct = sqlite3_realloc(pStruct, nByte);
pStruct = sqlite3_realloc64(pStruct, nByte);
if( pStruct ){
memset(&pStruct->aLevel[nLevel], 0, sizeof(Fts5StructureLevel));
pStruct->nLevel++;
@@ -957,10 +962,10 @@ static void fts5StructureExtendLevel(
if( *pRc==SQLITE_OK ){
Fts5StructureLevel *pLvl = &pStruct->aLevel[iLvl];
Fts5StructureSegment *aNew;
int nByte;
sqlite3_int64 nByte;
nByte = (pLvl->nSeg + nExtra) * sizeof(Fts5StructureSegment);
aNew = sqlite3_realloc(pLvl->aSeg, nByte);
aNew = sqlite3_realloc64(pLvl->aSeg, nByte);
if( aNew ){
if( bInsert==0 ){
memset(&aNew[pLvl->nSeg], 0, sizeof(Fts5StructureSegment) * nExtra);
@@ -1474,10 +1479,10 @@ static Fts5DlidxIter *fts5DlidxIterInit(
int bDone = 0;
for(i=0; p->rc==SQLITE_OK && bDone==0; i++){
int nByte = sizeof(Fts5DlidxIter) + i * sizeof(Fts5DlidxLvl);
sqlite3_int64 nByte = sizeof(Fts5DlidxIter) + i * sizeof(Fts5DlidxLvl);
Fts5DlidxIter *pNew;
pNew = (Fts5DlidxIter*)sqlite3_realloc(pIter, nByte);
pNew = (Fts5DlidxIter*)sqlite3_realloc64(pIter, nByte);
if( pNew==0 ){
p->rc = SQLITE_NOMEM;
}else{
@@ -1647,12 +1652,13 @@ static void fts5SegIterLoadTerm(Fts5Index *p, Fts5SegIter *pIter, int nKeep){
int nNew; /* Bytes of new data */
iOff += fts5GetVarint32(&a[iOff], nNew);
if( iOff+nNew>pIter->pLeaf->nn ){
if( iOff+nNew>pIter->pLeaf->szLeaf || nKeep>pIter->term.n || nNew==0 ){
p->rc = FTS5_CORRUPT;
return;
}
pIter->term.n = nKeep;
fts5BufferAppendBlob(&p->rc, &pIter->term, nNew, &a[iOff]);
assert( pIter->term.n<=pIter->term.nSpace );
iOff += nNew;
pIter->iTermLeafOffset = iOff;
pIter->iTermLeafPgno = pIter->iLeafPgno;
@@ -1717,7 +1723,7 @@ static void fts5SegIterInit(
if( p->rc==SQLITE_OK ){
pIter->iLeafOffset = 4;
assert_nc( pIter->pLeaf->nn>4 );
assert( fts5LeafFirstTermOff(pIter->pLeaf)==4 );
assert_nc( fts5LeafFirstTermOff(pIter->pLeaf)==4 );
pIter->iPgidxOff = pIter->pLeaf->szLeaf+1;
fts5SegIterLoadTerm(p, pIter, 0);
fts5SegIterLoadNPos(p, pIter);
@@ -1773,7 +1779,7 @@ static void fts5SegIterReverseInitPage(Fts5Index *p, Fts5SegIter *pIter){
/* If necessary, grow the pIter->aRowidOffset[] array. */
if( iRowidOffset>=pIter->nRowidOffset ){
int nNew = pIter->nRowidOffset + 8;
int *aNew = (int*)sqlite3_realloc(pIter->aRowidOffset, nNew*sizeof(int));
int *aNew = (int*)sqlite3_realloc64(pIter->aRowidOffset,nNew*sizeof(int));
if( aNew==0 ){
p->rc = SQLITE_NOMEM;
break;
@@ -2227,10 +2233,10 @@ static void fts5LeafSeek(
int szLeaf = pIter->pLeaf->szLeaf;
int n = pIter->pLeaf->nn;
int nMatch = 0;
int nKeep = 0;
int nNew = 0;
int iTermOff;
u32 nMatch = 0;
u32 nKeep = 0;
u32 nNew = 0;
u32 iTermOff;
int iPgidx; /* Current offset in pgidx */
int bEndOfPage = 0;
@@ -2254,15 +2260,15 @@ static void fts5LeafSeek(
assert( nKeep>=nMatch );
if( nKeep==nMatch ){
int nCmp;
int i;
nCmp = MIN(nNew, nTerm-nMatch);
u32 nCmp;
u32 i;
nCmp = (u32)MIN(nNew, nTerm-nMatch);
for(i=0; i<nCmp; i++){
if( a[iOff+i]!=pTerm[nMatch+i] ) break;
}
nMatch += i;
if( nTerm==nMatch ){
if( (u32)nTerm==nMatch ){
if( i==nNew ){
goto search_success;
}else{
@@ -2306,6 +2312,7 @@ static void fts5LeafSeek(
iPgidx += fts5GetVarint32(&pIter->pLeaf->p[iPgidx], iOff);
if( iOff<4 || iOff>=pIter->pLeaf->szLeaf ){
p->rc = FTS5_CORRUPT;
return;
}else{
nKeep = 0;
iTermOff = iOff;
@@ -2318,8 +2325,11 @@ static void fts5LeafSeek(
}
search_success:
pIter->iLeafOffset = iOff + nNew;
if( pIter->iLeafOffset>n || nNew<1 ){
p->rc = FTS5_CORRUPT;
return;
}
pIter->iTermLeafOffset = pIter->iLeafOffset;
pIter->iTermLeafPgno = pIter->iLeafPgno;
@@ -2426,7 +2436,7 @@ static void fts5SegIterSeekInit(
** 4) the FTS5INDEX_QUERY_SCAN flag was set and the iterator points
** to an entry with a term greater than or equal to (pTerm/nTerm).
*/
assert( p->rc!=SQLITE_OK /* 1 */
assert_nc( p->rc!=SQLITE_OK /* 1 */
|| pIter->pLeaf==0 /* 2 */
|| fts5BufferCompareBlob(&pIter->term, pTerm, nTerm)==0 /* 3 */
|| (bGe && fts5BufferCompareBlob(&pIter->term, pTerm, nTerm)>0) /* 4 */
@@ -2524,7 +2534,7 @@ static void fts5AssertComparisonResult(
assert( pRes->iFirst==i1 );
}else{
int nMin = MIN(p1->term.n, p2->term.n);
int res = memcmp(p1->term.p, p2->term.p, nMin);
int res = fts5Memcmp(p1->term.p, p2->term.p, nMin);
if( res==0 ) res = p1->term.n - p2->term.n;
if( res==0 ){
@@ -2747,7 +2757,6 @@ static void fts5MultiIterFree(Fts5Iter *pIter){
for(i=0; i<pIter->nSeg; i++){
fts5SegIterClear(&pIter->aSeg[i]);
}
fts5StructureRelease(pIter->pStruct);
fts5BufferFree(&pIter->poslist);
sqlite3_free(pIter);
}
@@ -3095,7 +3104,8 @@ static void fts5SegiterPoslist(
Fts5Colset *pColset,
Fts5Buffer *pBuf
){
if( 0==fts5BufferGrow(&p->rc, pBuf, pSeg->nPos) ){
if( 0==fts5BufferGrow(&p->rc, pBuf, pSeg->nPos+FTS5_DATA_ZERO_PADDING) ){
memset(&pBuf->p[pBuf->n+pSeg->nPos], 0, FTS5_DATA_ZERO_PADDING);
if( pColset==0 ){
fts5ChunkIterate(p, pSeg, (void*)pBuf, fts5PoslistCallback);
}else{
@@ -3393,9 +3403,7 @@ static void fts5MultiIterNew(
if( pNew==0 ) return;
pNew->bRev = (0!=(flags & FTS5INDEX_QUERY_DESC));
pNew->bSkipEmpty = (0!=(flags & FTS5INDEX_QUERY_SKIPEMPTY));
pNew->pStruct = pStruct;
pNew->pColset = pColset;
fts5StructureRef(pStruct);
if( (flags & FTS5INDEX_QUERY_NOOUTPUT)==0 ){
fts5IterSetOutputCb(&p->rc, pNew);
}
@@ -3573,24 +3581,24 @@ static int fts5AllocateSegid(Fts5Index *p, Fts5Structure *pStruct){
for(iLvl=0; iLvl<pStruct->nLevel; iLvl++){
for(iSeg=0; iSeg<pStruct->aLevel[iLvl].nSeg; iSeg++){
int iId = pStruct->aLevel[iLvl].aSeg[iSeg].iSegid;
if( iId<=FTS5_MAX_SEGMENT ){
aUsed[(iId-1) / 32] |= 1 << ((iId-1) % 32);
if( iId<=FTS5_MAX_SEGMENT && iId>0 ){
aUsed[(iId-1) / 32] |= (u32)1 << ((iId-1) % 32);
}
}
}
for(i=0; aUsed[i]==0xFFFFFFFF; i++);
mask = aUsed[i];
for(iSegid=0; mask & (1 << iSegid); iSegid++);
for(iSegid=0; mask & ((u32)1 << iSegid); iSegid++);
iSegid += 1 + i*32;
#ifdef SQLITE_DEBUG
for(iLvl=0; iLvl<pStruct->nLevel; iLvl++){
for(iSeg=0; iSeg<pStruct->aLevel[iLvl].nSeg; iSeg++){
assert( iSegid!=pStruct->aLevel[iLvl].aSeg[iSeg].iSegid );
assert_nc( iSegid!=pStruct->aLevel[iLvl].aSeg[iSeg].iSegid );
}
}
assert( iSegid>0 && iSegid<=FTS5_MAX_SEGMENT );
assert_nc( iSegid>0 && iSegid<=FTS5_MAX_SEGMENT );
{
sqlite3_stmt *pIdxSelect = fts5IdxSelectStmt(p);
@@ -3598,7 +3606,7 @@ static int fts5AllocateSegid(Fts5Index *p, Fts5Structure *pStruct){
u8 aBlob[2] = {0xff, 0xff};
sqlite3_bind_int(pIdxSelect, 1, iSegid);
sqlite3_bind_blob(pIdxSelect, 2, aBlob, 2, SQLITE_STATIC);
assert( sqlite3_step(pIdxSelect)!=SQLITE_ROW );
assert_nc( sqlite3_step(pIdxSelect)!=SQLITE_ROW );
p->rc = sqlite3_reset(pIdxSelect);
sqlite3_bind_null(pIdxSelect, 2);
}
@@ -3668,7 +3676,7 @@ static int fts5WriteDlidxGrow(
int nLvl
){
if( p->rc==SQLITE_OK && nLvl>=pWriter->nDlidx ){
Fts5DlidxWriter *aDlidx = (Fts5DlidxWriter*)sqlite3_realloc(
Fts5DlidxWriter *aDlidx = (Fts5DlidxWriter*)sqlite3_realloc64(
pWriter->aDlidx, sizeof(Fts5DlidxWriter) * nLvl
);
if( aDlidx==0 ){
@@ -3747,8 +3755,10 @@ static void fts5WriteBtreeTerm(
int nTerm, const u8 *pTerm /* First term on new page */
){
fts5WriteFlushBtree(p, pWriter);
fts5BufferSet(&p->rc, &pWriter->btterm, nTerm, pTerm);
pWriter->iBtPage = pWriter->writer.pgno;
if( p->rc==SQLITE_OK ){
fts5BufferSet(&p->rc, &pWriter->btterm, nTerm, pTerm);
pWriter->iBtPage = pWriter->writer.pgno;
}
}
/*
@@ -3899,6 +3909,7 @@ static void fts5WriteAppendTerm(
int nPrefix; /* Bytes of prefix compression for term */
Fts5PageWriter *pPage = &pWriter->writer;
Fts5Buffer *pPgidx = &pWriter->writer.pgidx;
int nMin = MIN(pPage->term.n, nTerm);
assert( p->rc==SQLITE_OK );
assert( pPage->buf.n>=4 );
@@ -3908,6 +3919,7 @@ static void fts5WriteAppendTerm(
if( (pPage->buf.n + pPgidx->n + nTerm + 2)>=p->pConfig->pgsz ){
if( pPage->buf.n>4 ){
fts5WriteFlushLeaf(p, pWriter);
if( p->rc!=SQLITE_OK ) return;
}
fts5BufferGrow(&p->rc, &pPage->buf, nTerm+FTS5_DATA_PADDING);
}
@@ -3940,13 +3952,14 @@ static void fts5WriteAppendTerm(
** inefficient, but still correct. */
int n = nTerm;
if( pPage->term.n ){
n = 1 + fts5PrefixCompress(pPage->term.n, pPage->term.p, pTerm);
n = 1 + fts5PrefixCompress(nMin, pPage->term.p, pTerm);
}
fts5WriteBtreeTerm(p, pWriter, n, pTerm);
if( p->rc!=SQLITE_OK ) return;
pPage = &pWriter->writer;
}
}else{
nPrefix = fts5PrefixCompress(pPage->term.n, pPage->term.p, pTerm);
nPrefix = fts5PrefixCompress(nMin, pPage->term.p, pTerm);
fts5BufferAppendVarint(&p->rc, &pPage->buf, nPrefix);
}
@@ -3993,7 +4006,7 @@ static void fts5WriteAppendRowid(
if( pWriter->bFirstRowidInDoclist || pWriter->bFirstRowidInPage ){
fts5BufferAppendVarint(&p->rc, &pPage->buf, iRowid);
}else{
assert( p->rc || iRowid>pWriter->iPrevRowid );
assert_nc( p->rc || iRowid>pWriter->iPrevRowid );
fts5BufferAppendVarint(&p->rc, &pPage->buf, iRowid - pWriter->iPrevRowid);
}
pWriter->iPrevRowid = iRowid;
@@ -4115,7 +4128,7 @@ static void fts5TrimSegments(Fts5Index *p, Fts5Iter *pIter){
int i;
Fts5Buffer buf;
memset(&buf, 0, sizeof(Fts5Buffer));
for(i=0; i<pIter->nSeg; i++){
for(i=0; i<pIter->nSeg && p->rc==SQLITE_OK; i++){
Fts5SegIter *pSeg = &pIter->aSeg[i];
if( pSeg->pSeg==0 ){
/* no-op */
@@ -4133,35 +4146,44 @@ static void fts5TrimSegments(Fts5Index *p, Fts5Iter *pIter){
u8 aHdr[4] = {0x00, 0x00, 0x00, 0x00};
iLeafRowid = FTS5_SEGMENT_ROWID(iId, pSeg->iTermLeafPgno);
pData = fts5DataRead(p, iLeafRowid);
pData = fts5LeafRead(p, iLeafRowid);
if( pData ){
fts5BufferZero(&buf);
fts5BufferGrow(&p->rc, &buf, pData->nn);
fts5BufferAppendBlob(&p->rc, &buf, sizeof(aHdr), aHdr);
fts5BufferAppendVarint(&p->rc, &buf, pSeg->term.n);
fts5BufferAppendBlob(&p->rc, &buf, pSeg->term.n, pSeg->term.p);
fts5BufferAppendBlob(&p->rc, &buf, pData->szLeaf-iOff, &pData->p[iOff]);
if( p->rc==SQLITE_OK ){
/* Set the szLeaf field */
fts5PutU16(&buf.p[2], (u16)buf.n);
}
if( iOff>pData->szLeaf ){
/* This can occur if the pages that the segments occupy overlap - if
** a single page has been assigned to more than one segment. In
** this case a prior iteration of this loop may have corrupted the
** segment currently being trimmed. */
p->rc = FTS5_CORRUPT;
}else{
fts5BufferZero(&buf);
fts5BufferGrow(&p->rc, &buf, pData->nn);
fts5BufferAppendBlob(&p->rc, &buf, sizeof(aHdr), aHdr);
fts5BufferAppendVarint(&p->rc, &buf, pSeg->term.n);
fts5BufferAppendBlob(&p->rc, &buf, pSeg->term.n, pSeg->term.p);
fts5BufferAppendBlob(&p->rc, &buf, pData->szLeaf-iOff,&pData->p[iOff]);
if( p->rc==SQLITE_OK ){
/* Set the szLeaf field */
fts5PutU16(&buf.p[2], (u16)buf.n);
}
/* Set up the new page-index array */
fts5BufferAppendVarint(&p->rc, &buf, 4);
if( pSeg->iLeafPgno==pSeg->iTermLeafPgno
&& pSeg->iEndofDoclist<pData->szLeaf
){
int nDiff = pData->szLeaf - pSeg->iEndofDoclist;
fts5BufferAppendVarint(&p->rc, &buf, buf.n - 1 - nDiff - 4);
fts5BufferAppendBlob(&p->rc, &buf,
pData->nn - pSeg->iPgidxOff, &pData->p[pSeg->iPgidxOff]
);
}
/* Set up the new page-index array */
fts5BufferAppendVarint(&p->rc, &buf, 4);
if( pSeg->iLeafPgno==pSeg->iTermLeafPgno
&& pSeg->iEndofDoclist<pData->szLeaf
&& pSeg->iPgidxOff<=pData->nn
){
int nDiff = pData->szLeaf - pSeg->iEndofDoclist;
fts5BufferAppendVarint(&p->rc, &buf, buf.n - 1 - nDiff - 4);
fts5BufferAppendBlob(&p->rc, &buf,
pData->nn - pSeg->iPgidxOff, &pData->p[pSeg->iPgidxOff]
);
}
pSeg->pSeg->pgnoFirst = pSeg->iTermLeafPgno;
fts5DataDelete(p, FTS5_SEGMENT_ROWID(iId, 1), iLeafRowid);
fts5DataWrite(p, iLeafRowid, buf.p, buf.n);
}
fts5DataRelease(pData);
pSeg->pSeg->pgnoFirst = pSeg->iTermLeafPgno;
fts5DataDelete(p, FTS5_SEGMENT_ROWID(iId, 1), iLeafRowid);
fts5DataWrite(p, iLeafRowid, buf.p, buf.n);
}
}
}
@@ -4253,7 +4275,7 @@ static void fts5IndexMergeLevel(
const u8 *pTerm;
pTerm = fts5MultiIterTerm(pIter, &nTerm);
if( nTerm!=term.n || memcmp(pTerm, term.p, nTerm) ){
if( nTerm!=term.n || fts5Memcmp(pTerm, term.p, nTerm) ){
if( pnRem && writer.nLeafWritten>nRem ){
break;
}
@@ -4508,6 +4530,7 @@ static void fts5FlushOneHash(Fts5Index *p){
/* Write the term for this entry to disk. */
sqlite3Fts5HashScanEntry(pHash, &zTerm, &pDoclist, &nDoclist);
fts5WriteAppendTerm(p, &writer, (int)strlen(zTerm), (const u8*)zTerm);
if( p->rc!=SQLITE_OK ) break;
assert( writer.bFirstRowidInPage==0 );
if( pgsz>=(pBuf->n + pPgidx->n + nDoclist + 1) ){
@@ -4530,6 +4553,7 @@ static void fts5FlushOneHash(Fts5Index *p){
pBuf->n += sqlite3Fts5PutVarint(&pBuf->p[pBuf->n], iRowid);
writer.bFirstRowidInPage = 0;
fts5WriteDlidxAppend(p, &writer, iRowid);
if( p->rc!=SQLITE_OK ) break;
}else{
pBuf->n += sqlite3Fts5PutVarint(&pBuf->p[pBuf->n], iDelta);
}
@@ -4587,7 +4611,7 @@ static void fts5FlushOneHash(Fts5Index *p){
/* TODO2: Doclist terminator written here. */
/* pBuf->p[pBuf->n++] = '\0'; */
assert( pBuf->n<=pBuf->nSpace );
sqlite3Fts5HashScanNext(pHash);
if( p->rc==SQLITE_OK ) sqlite3Fts5HashScanNext(pHash);
}
sqlite3Fts5HashClear(pHash);
fts5WriteFinish(p, &writer, &pgnoLast);
@@ -4631,7 +4655,7 @@ static Fts5Structure *fts5IndexOptimizeStruct(
Fts5Structure *pStruct
){
Fts5Structure *pNew = 0;
int nByte = sizeof(Fts5Structure);
sqlite3_int64 nByte = sizeof(Fts5Structure);
int nSeg = pStruct->nSegment;
int i;
@@ -4761,11 +4785,13 @@ static void fts5AppendPoslist(
Fts5Buffer *pBuf
){
int nData = pMulti->base.nData;
int nByte = nData + 9 + 9 + FTS5_DATA_ZERO_PADDING;
assert( nData>0 );
if( p->rc==SQLITE_OK && 0==fts5BufferGrow(&p->rc, pBuf, nData+9+9) ){
if( p->rc==SQLITE_OK && 0==fts5BufferGrow(&p->rc, pBuf, nByte) ){
fts5BufferSafeAppendVarint(pBuf, iDelta);
fts5BufferSafeAppendVarint(pBuf, nData*2);
fts5BufferSafeAppendBlob(pBuf, pMulti->base.pData, nData);
memset(&pBuf->p[pBuf->n], 0, FTS5_DATA_ZERO_PADDING);
}
}
@@ -4946,6 +4972,8 @@ static void fts5MergePrefixLists(
int iOff2 = 0;
u8 *a1 = &i1.aPoslist[i1.nSize];
u8 *a2 = &i2.aPoslist[i2.nSize];
int nCopy;
u8 *aCopy;
i64 iPrev = 0;
Fts5PoslistWriter writer;
@@ -4977,7 +5005,7 @@ static void fts5MergePrefixLists(
sqlite3Fts5PoslistNext64(a1, i1.nPoslist, &iOff1, &iPos1);
if( iPos1<0 ) break;
}else{
assert( iPos2!=iPrev );
assert_nc( iPos2!=iPrev );
sqlite3Fts5PoslistSafeAppend(&tmp, &iPrev, iPos2);
sqlite3Fts5PoslistNext64(a2, i2.nPoslist, &iOff2, &iPos2);
if( iPos2<0 ) break;
@@ -4989,11 +5017,16 @@ static void fts5MergePrefixLists(
if( iPos1!=iPrev ){
sqlite3Fts5PoslistSafeAppend(&tmp, &iPrev, iPos1);
}
fts5BufferSafeAppendBlob(&tmp, &a1[iOff1], i1.nPoslist-iOff1);
aCopy = &a1[iOff1];
nCopy = i1.nPoslist - iOff1;
}else{
assert( iPos2>=0 && iPos2!=iPrev );
sqlite3Fts5PoslistSafeAppend(&tmp, &iPrev, iPos2);
fts5BufferSafeAppendBlob(&tmp, &a2[iOff2], i2.nPoslist-iOff2);
aCopy = &a2[iOff2];
nCopy = i2.nPoslist - iOff2;
}
if( nCopy>0 ){
fts5BufferSafeAppendBlob(&tmp, aCopy, nCopy);
}
/* WRITEPOSLISTSIZE */
@@ -5001,6 +5034,7 @@ static void fts5MergePrefixLists(
fts5BufferSafeAppendBlob(&out, tmp.p, tmp.n);
fts5DoclistIterNext(&i1);
fts5DoclistIterNext(&i2);
assert( out.n<=(p1->n+p2->n+9) );
if( i1.aPoslist==0 || i2.aPoslist==0 ) break;
}
}
@@ -5102,7 +5136,7 @@ static void fts5SetupPrefixIter(
}
fts5MultiIterFree(p1);
pData = fts5IdxMalloc(p, sizeof(Fts5Data) + doclist.n);
pData = fts5IdxMalloc(p, sizeof(Fts5Data)+doclist.n+FTS5_DATA_ZERO_PADDING);
if( pData ){
pData->p = (u8*)&pData[1];
pData->nn = pData->szLeaf = doclist.n;
@@ -5402,7 +5436,7 @@ int sqlite3Fts5IndexQuery(
fts5CloseReader(p);
}
*ppIter = &pRet->base;
*ppIter = (Fts5IndexIter*)pRet;
sqlite3Fts5BufferFree(&buf);
}
return fts5IndexReturn(p);
@@ -5864,11 +5898,11 @@ static void fts5IndexIntegrityCheckSegment(
iOff = fts5LeafFirstTermOff(pLeaf);
iRowidOff = fts5LeafFirstRowidOff(pLeaf);
if( iRowidOff>=iOff ){
if( iRowidOff>=iOff || iOff>=pLeaf->szLeaf ){
p->rc = FTS5_CORRUPT;
}else{
iOff += fts5GetVarint32(&pLeaf->p[iOff], nTerm);
res = memcmp(&pLeaf->p[iOff], zIdxTerm, MIN(nTerm, nIdxTerm));
res = fts5Memcmp(&pLeaf->p[iOff], zIdxTerm, MIN(nTerm, nIdxTerm));
if( res==0 ) res = nTerm - nIdxTerm;
if( res<0 ) p->rc = FTS5_CORRUPT;
}
@@ -6263,7 +6297,7 @@ static void fts5DecodeFunction(
u8 *a = 0;
Fts5Buffer s; /* Build up text to return here */
int rc = SQLITE_OK; /* Return code */
int nSpace = 0;
sqlite3_int64 nSpace = 0;
int eDetailNone = (sqlite3_user_data(pCtx)!=0);
assert( nArg==2 );
@@ -6279,8 +6313,7 @@ static void fts5DecodeFunction(
nSpace = n + FTS5_DATA_ZERO_PADDING;
a = (u8*)sqlite3Fts5MallocZero(&rc, nSpace);
if( a==0 ) goto decode_out;
memcpy(a, aBlob, n);
if( n>0 ) memcpy(a, aBlob, n);
fts5DecodeRowid(iRowid, &iSegid, &bDlidx, &iHeight, &iPgno);
@@ -6375,6 +6408,9 @@ static void fts5DecodeFunction(
iPgidxOff = szLeaf = fts5GetU16(&a[2]);
if( iPgidxOff<n ){
fts5GetVarint32(&a[iPgidxOff], iTermOff);
}else if( iPgidxOff>n ){
rc = FTS5_CORRUPT;
goto decode_out;
}
}
@@ -6386,14 +6422,22 @@ static void fts5DecodeFunction(
}else{
iOff = szLeaf;
}
if( iOff>n ){
rc = FTS5_CORRUPT;
goto decode_out;
}
fts5DecodePoslist(&rc, &s, &a[4], iOff-4);
/* Decode any more doclist data that appears on the page before the
** first term. */
nDoclist = (iTermOff ? iTermOff : szLeaf) - iOff;
if( nDoclist+iOff>n ){
rc = FTS5_CORRUPT;
goto decode_out;
}
fts5DecodeDoclist(&rc, &s, &a[iOff], nDoclist);
while( iPgidxOff<n ){
while( iPgidxOff<n && rc==SQLITE_OK ){
int bFirst = (iPgidxOff==szLeaf); /* True for first term on page */
int nByte; /* Bytes of data */
int iEnd;
@@ -6408,12 +6452,24 @@ static void fts5DecodeFunction(
}else{
iEnd = szLeaf;
}
if( iEnd>szLeaf ){
rc = FTS5_CORRUPT;
break;
}
if( bFirst==0 ){
iOff += fts5GetVarint32(&a[iOff], nByte);
if( nByte>term.n ){
rc = FTS5_CORRUPT;
break;
}
term.n = nByte;
}
iOff += fts5GetVarint32(&a[iOff], nByte);
if( iOff+nByte>n ){
rc = FTS5_CORRUPT;
break;
}
fts5BufferAppendBlob(&rc, &term, nByte, &a[iOff]);
iOff += nByte;
+173 -151
View File
@@ -28,8 +28,8 @@ int sqlite3_fts5_may_be_corrupt = 1;
typedef struct Fts5Auxdata Fts5Auxdata;
typedef struct Fts5Auxiliary Fts5Auxiliary;
typedef struct Fts5Cursor Fts5Cursor;
typedef struct Fts5FullTable Fts5FullTable;
typedef struct Fts5Sorter Fts5Sorter;
typedef struct Fts5Table Fts5Table;
typedef struct Fts5TokenizerModule Fts5TokenizerModule;
/*
@@ -110,13 +110,8 @@ struct Fts5TokenizerModule {
Fts5TokenizerModule *pNext; /* Next registered tokenizer module */
};
/*
** Virtual-table object.
*/
struct Fts5Table {
sqlite3_vtab base; /* Base class used by SQLite core */
Fts5Config *pConfig; /* Virtual table configuration */
Fts5Index *pIndex; /* Full-text index */
struct Fts5FullTable {
Fts5Table p; /* Public class members from fts5Int.h */
Fts5Storage *pStorage; /* Document store */
Fts5Global *pGlobal; /* Global (connection wide) data */
Fts5Cursor *pSortCsr; /* Sort data from this cursor */
@@ -254,7 +249,7 @@ struct Fts5Auxdata {
#define FTS5_SAVEPOINT 5
#define FTS5_RELEASE 6
#define FTS5_ROLLBACKTO 7
static void fts5CheckTransactionState(Fts5Table *p, int op, int iSavepoint){
static void fts5CheckTransactionState(Fts5FullTable *p, int op, int iSavepoint){
switch( op ){
case FTS5_BEGIN:
assert( p->ts.eState==0 );
@@ -293,7 +288,7 @@ static void fts5CheckTransactionState(Fts5Table *p, int op, int iSavepoint){
case FTS5_ROLLBACKTO:
assert( p->ts.eState==1 );
assert( iSavepoint>=0 );
assert( iSavepoint>=-1 );
assert( iSavepoint<=p->ts.iSavepoint );
p->ts.iSavepoint = iSavepoint;
break;
@@ -306,18 +301,18 @@ static void fts5CheckTransactionState(Fts5Table *p, int op, int iSavepoint){
/*
** Return true if pTab is a contentless table.
*/
static int fts5IsContentless(Fts5Table *pTab){
return pTab->pConfig->eContent==FTS5_CONTENT_NONE;
static int fts5IsContentless(Fts5FullTable *pTab){
return pTab->p.pConfig->eContent==FTS5_CONTENT_NONE;
}
/*
** Delete a virtual table handle allocated by fts5InitVtab().
*/
static void fts5FreeVtab(Fts5Table *pTab){
static void fts5FreeVtab(Fts5FullTable *pTab){
if( pTab ){
sqlite3Fts5IndexClose(pTab->pIndex);
sqlite3Fts5IndexClose(pTab->p.pIndex);
sqlite3Fts5StorageClose(pTab->pStorage);
sqlite3Fts5ConfigFree(pTab->pConfig);
sqlite3Fts5ConfigFree(pTab->p.pConfig);
sqlite3_free(pTab);
}
}
@@ -326,7 +321,7 @@ static void fts5FreeVtab(Fts5Table *pTab){
** The xDisconnect() virtual table method.
*/
static int fts5DisconnectMethod(sqlite3_vtab *pVtab){
fts5FreeVtab((Fts5Table*)pVtab);
fts5FreeVtab((Fts5FullTable*)pVtab);
return SQLITE_OK;
}
@@ -337,7 +332,7 @@ static int fts5DestroyMethod(sqlite3_vtab *pVtab){
Fts5Table *pTab = (Fts5Table*)pVtab;
int rc = sqlite3Fts5DropAll(pTab->pConfig);
if( rc==SQLITE_OK ){
fts5FreeVtab((Fts5Table*)pVtab);
fts5FreeVtab((Fts5FullTable*)pVtab);
}
return rc;
}
@@ -366,28 +361,28 @@ static int fts5InitVtab(
const char **azConfig = (const char**)argv;
int rc = SQLITE_OK; /* Return code */
Fts5Config *pConfig = 0; /* Results of parsing argc/argv */
Fts5Table *pTab = 0; /* New virtual table object */
Fts5FullTable *pTab = 0; /* New virtual table object */
/* Allocate the new vtab object and parse the configuration */
pTab = (Fts5Table*)sqlite3Fts5MallocZero(&rc, sizeof(Fts5Table));
pTab = (Fts5FullTable*)sqlite3Fts5MallocZero(&rc, sizeof(Fts5FullTable));
if( rc==SQLITE_OK ){
rc = sqlite3Fts5ConfigParse(pGlobal, db, argc, azConfig, &pConfig, pzErr);
assert( (rc==SQLITE_OK && *pzErr==0) || pConfig==0 );
}
if( rc==SQLITE_OK ){
pTab->pConfig = pConfig;
pTab->p.pConfig = pConfig;
pTab->pGlobal = pGlobal;
}
/* Open the index sub-system */
if( rc==SQLITE_OK ){
rc = sqlite3Fts5IndexOpen(pConfig, bCreate, &pTab->pIndex, pzErr);
rc = sqlite3Fts5IndexOpen(pConfig, bCreate, &pTab->p.pIndex, pzErr);
}
/* Open the storage sub-system */
if( rc==SQLITE_OK ){
rc = sqlite3Fts5StorageOpen(
pConfig, pTab->pIndex, bCreate, &pTab->pStorage, pzErr
pConfig, pTab->p.pIndex, bCreate, &pTab->pStorage, pzErr
);
}
@@ -400,8 +395,8 @@ static int fts5InitVtab(
if( rc==SQLITE_OK ){
assert( pConfig->pzErrmsg==0 );
pConfig->pzErrmsg = pzErr;
rc = sqlite3Fts5IndexLoadConfig(pTab->pIndex);
sqlite3Fts5IndexRollback(pTab->pIndex);
rc = sqlite3Fts5IndexLoadConfig(pTab->p.pIndex);
sqlite3Fts5IndexRollback(pTab->p.pIndex);
pConfig->pzErrmsg = 0;
}
@@ -614,7 +609,7 @@ static int fts5BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){
return SQLITE_OK;
}
static int fts5NewTransaction(Fts5Table *pTab){
static int fts5NewTransaction(Fts5FullTable *pTab){
Fts5Cursor *pCsr;
for(pCsr=pTab->pGlobal->pCsr; pCsr; pCsr=pCsr->pNext){
if( pCsr->base.pVtab==(sqlite3_vtab*)pTab ) return SQLITE_OK;
@@ -626,16 +621,16 @@ static int fts5NewTransaction(Fts5Table *pTab){
** Implementation of xOpen method.
*/
static int fts5OpenMethod(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCsr){
Fts5Table *pTab = (Fts5Table*)pVTab;
Fts5Config *pConfig = pTab->pConfig;
Fts5FullTable *pTab = (Fts5FullTable*)pVTab;
Fts5Config *pConfig = pTab->p.pConfig;
Fts5Cursor *pCsr = 0; /* New cursor object */
int nByte; /* Bytes of space to allocate */
sqlite3_int64 nByte; /* Bytes of space to allocate */
int rc; /* Return code */
rc = fts5NewTransaction(pTab);
if( rc==SQLITE_OK ){
nByte = sizeof(Fts5Cursor) + pConfig->nCol * sizeof(int);
pCsr = (Fts5Cursor*)sqlite3_malloc(nByte);
pCsr = (Fts5Cursor*)sqlite3_malloc64(nByte);
if( pCsr ){
Fts5Global *pGlobal = pTab->pGlobal;
memset(pCsr, 0, nByte);
@@ -673,7 +668,7 @@ static void fts5CsrNewrow(Fts5Cursor *pCsr){
}
static void fts5FreeCursorComponents(Fts5Cursor *pCsr){
Fts5Table *pTab = (Fts5Table*)(pCsr->base.pVtab);
Fts5FullTable *pTab = (Fts5FullTable*)(pCsr->base.pVtab);
Fts5Auxdata *pData;
Fts5Auxdata *pNext;
@@ -717,7 +712,7 @@ static void fts5FreeCursorComponents(Fts5Cursor *pCsr){
*/
static int fts5CloseMethod(sqlite3_vtab_cursor *pCursor){
if( pCursor ){
Fts5Table *pTab = (Fts5Table*)(pCursor->pVtab);
Fts5FullTable *pTab = (Fts5FullTable*)(pCursor->pVtab);
Fts5Cursor *pCsr = (Fts5Cursor*)pCursor;
Fts5Cursor **pp;
@@ -774,7 +769,7 @@ static int fts5SorterNext(Fts5Cursor *pCsr){
** Set the FTS5CSR_REQUIRE_RESEEK flag on all FTS5_PLAN_MATCH cursors
** open on table pTab.
*/
static void fts5TripCursors(Fts5Table *pTab){
static void fts5TripCursors(Fts5FullTable *pTab){
Fts5Cursor *pCsr;
for(pCsr=pTab->pGlobal->pCsr; pCsr; pCsr=pCsr->pNext){
if( pCsr->ePlan==FTS5_PLAN_MATCH
@@ -801,11 +796,11 @@ static int fts5CursorReseek(Fts5Cursor *pCsr, int *pbSkip){
int rc = SQLITE_OK;
assert( *pbSkip==0 );
if( CsrFlagTest(pCsr, FTS5CSR_REQUIRE_RESEEK) ){
Fts5Table *pTab = (Fts5Table*)(pCsr->base.pVtab);
Fts5FullTable *pTab = (Fts5FullTable*)(pCsr->base.pVtab);
int bDesc = pCsr->bDesc;
i64 iRowid = sqlite3Fts5ExprRowid(pCsr->pExpr);
rc = sqlite3Fts5ExprFirst(pCsr->pExpr, pTab->pIndex, iRowid, bDesc);
rc = sqlite3Fts5ExprFirst(pCsr->pExpr, pTab->p.pIndex, iRowid, bDesc);
if( rc==SQLITE_OK && iRowid!=sqlite3Fts5ExprRowid(pCsr->pExpr) ){
*pbSkip = 1;
}
@@ -902,18 +897,22 @@ static int fts5PrepareStatement(
return rc;
}
static int fts5CursorFirstSorted(Fts5Table *pTab, Fts5Cursor *pCsr, int bDesc){
Fts5Config *pConfig = pTab->pConfig;
static int fts5CursorFirstSorted(
Fts5FullTable *pTab,
Fts5Cursor *pCsr,
int bDesc
){
Fts5Config *pConfig = pTab->p.pConfig;
Fts5Sorter *pSorter;
int nPhrase;
int nByte;
sqlite3_int64 nByte;
int rc;
const char *zRank = pCsr->zRank;
const char *zRankArgs = pCsr->zRankArgs;
nPhrase = sqlite3Fts5ExprPhraseCount(pCsr->pExpr);
nByte = sizeof(Fts5Sorter) + sizeof(int) * (nPhrase-1);
pSorter = (Fts5Sorter*)sqlite3_malloc(nByte);
pSorter = (Fts5Sorter*)sqlite3_malloc64(nByte);
if( pSorter==0 ) return SQLITE_NOMEM;
memset(pSorter, 0, nByte);
pSorter->nIdx = nPhrase;
@@ -950,10 +949,10 @@ static int fts5CursorFirstSorted(Fts5Table *pTab, Fts5Cursor *pCsr, int bDesc){
return rc;
}
static int fts5CursorFirst(Fts5Table *pTab, Fts5Cursor *pCsr, int bDesc){
static int fts5CursorFirst(Fts5FullTable *pTab, Fts5Cursor *pCsr, int bDesc){
int rc;
Fts5Expr *pExpr = pCsr->pExpr;
rc = sqlite3Fts5ExprFirst(pExpr, pTab->pIndex, pCsr->iFirstRowid, bDesc);
rc = sqlite3Fts5ExprFirst(pExpr, pTab->p.pIndex, pCsr->iFirstRowid, bDesc);
if( sqlite3Fts5ExprEof(pExpr) ){
CsrFlagSet(pCsr, FTS5CSR_EOF);
}
@@ -968,7 +967,7 @@ static int fts5CursorFirst(Fts5Table *pTab, Fts5Cursor *pCsr, int bDesc){
** parameters.
*/
static int fts5SpecialMatch(
Fts5Table *pTab,
Fts5FullTable *pTab,
Fts5Cursor *pCsr,
const char *zQuery
){
@@ -979,18 +978,18 @@ static int fts5SpecialMatch(
while( z[0]==' ' ) z++;
for(n=0; z[n] && z[n]!=' '; n++);
assert( pTab->base.zErrMsg==0 );
assert( pTab->p.base.zErrMsg==0 );
pCsr->ePlan = FTS5_PLAN_SPECIAL;
if( 0==sqlite3_strnicmp("reads", z, n) ){
pCsr->iSpecial = sqlite3Fts5IndexReads(pTab->pIndex);
pCsr->iSpecial = sqlite3Fts5IndexReads(pTab->p.pIndex);
}
else if( 0==sqlite3_strnicmp("id", z, n) ){
pCsr->iSpecial = pCsr->iCsrId;
}
else{
/* An unrecognized directive. Return an error message. */
pTab->base.zErrMsg = sqlite3_mprintf("unknown special query: %.*s", n, z);
pTab->p.base.zErrMsg = sqlite3_mprintf("unknown special query: %.*s", n, z);
rc = SQLITE_ERROR;
}
@@ -1002,7 +1001,7 @@ static int fts5SpecialMatch(
** pTab. If one is found, return a pointer to the corresponding Fts5Auxiliary
** structure. Otherwise, if no such function exists, return NULL.
*/
static Fts5Auxiliary *fts5FindAuxiliary(Fts5Table *pTab, const char *zName){
static Fts5Auxiliary *fts5FindAuxiliary(Fts5FullTable *pTab, const char *zName){
Fts5Auxiliary *pAux;
for(pAux=pTab->pGlobal->pAux; pAux; pAux=pAux->pNext){
@@ -1015,8 +1014,8 @@ static Fts5Auxiliary *fts5FindAuxiliary(Fts5Table *pTab, const char *zName){
static int fts5FindRankFunction(Fts5Cursor *pCsr){
Fts5Table *pTab = (Fts5Table*)(pCsr->base.pVtab);
Fts5Config *pConfig = pTab->pConfig;
Fts5FullTable *pTab = (Fts5FullTable*)(pCsr->base.pVtab);
Fts5Config *pConfig = pTab->p.pConfig;
int rc = SQLITE_OK;
Fts5Auxiliary *pAux = 0;
const char *zRank = pCsr->zRank;
@@ -1032,7 +1031,7 @@ static int fts5FindRankFunction(Fts5Cursor *pCsr){
assert( rc==SQLITE_OK || pCsr->pRankArgStmt==0 );
if( rc==SQLITE_OK ){
if( SQLITE_ROW==sqlite3_step(pStmt) ){
int nByte;
sqlite3_int64 nByte;
pCsr->nRankArg = sqlite3_column_count(pStmt);
nByte = sizeof(sqlite3_value*)*pCsr->nRankArg;
pCsr->apRankArg = (sqlite3_value**)sqlite3Fts5MallocZero(&rc, nByte);
@@ -1054,8 +1053,8 @@ static int fts5FindRankFunction(Fts5Cursor *pCsr){
if( rc==SQLITE_OK ){
pAux = fts5FindAuxiliary(pTab, zRank);
if( pAux==0 ){
assert( pTab->base.zErrMsg==0 );
pTab->base.zErrMsg = sqlite3_mprintf("no such function: %s", zRank);
assert( pTab->p.base.zErrMsg==0 );
pTab->p.base.zErrMsg = sqlite3_mprintf("no such function: %s", zRank);
rc = SQLITE_ERROR;
}
}
@@ -1130,8 +1129,8 @@ static int fts5FilterMethod(
int nVal, /* Number of elements in apVal */
sqlite3_value **apVal /* Arguments for the indexing scheme */
){
Fts5Table *pTab = (Fts5Table*)(pCursor->pVtab);
Fts5Config *pConfig = pTab->pConfig;
Fts5FullTable *pTab = (Fts5FullTable*)(pCursor->pVtab);
Fts5Config *pConfig = pTab->p.pConfig;
Fts5Cursor *pCsr = (Fts5Cursor*)pCursor;
int rc = SQLITE_OK; /* Error code */
int iVal = 0; /* Counter for apVal[] */
@@ -1160,8 +1159,8 @@ static int fts5FilterMethod(
assert( pCsr->zRank==0 );
assert( pCsr->zRankArgs==0 );
assert( pzErrmsg==0 || pzErrmsg==&pTab->base.zErrMsg );
pConfig->pzErrmsg = &pTab->base.zErrMsg;
assert( pzErrmsg==0 || pzErrmsg==&pTab->p.base.zErrMsg );
pConfig->pzErrmsg = &pTab->p.base.zErrMsg;
/* Decode the arguments passed through to this function.
**
@@ -1227,7 +1226,7 @@ static int fts5FilterMethod(
** but a request for an internal parameter. */
rc = fts5SpecialMatch(pTab, pCsr, &zExpr[1]);
}else{
char **pzErr = &pTab->base.zErrMsg;
char **pzErr = &pTab->p.base.zErrMsg;
rc = sqlite3Fts5ExprNew(pConfig, iCol, zExpr, &pCsr->pExpr, pzErr);
if( rc==SQLITE_OK ){
if( bOrderByRank ){
@@ -1250,7 +1249,7 @@ static int fts5FilterMethod(
** by rowid (ePlan==FTS5_PLAN_ROWID). */
pCsr->ePlan = (pRowidEq ? FTS5_PLAN_ROWID : FTS5_PLAN_SCAN);
rc = sqlite3Fts5StorageStmt(
pTab->pStorage, fts5StmtType(pCsr), &pCsr->pStmt, &pTab->base.zErrMsg
pTab->pStorage, fts5StmtType(pCsr), &pCsr->pStmt, &pTab->p.base.zErrMsg
);
if( rc==SQLITE_OK ){
if( pCsr->ePlan==FTS5_PLAN_ROWID ){
@@ -1333,12 +1332,12 @@ static int fts5SeekCursor(Fts5Cursor *pCsr, int bErrormsg){
/* If the cursor does not yet have a statement handle, obtain one now. */
if( pCsr->pStmt==0 ){
Fts5Table *pTab = (Fts5Table*)(pCsr->base.pVtab);
Fts5FullTable *pTab = (Fts5FullTable*)(pCsr->base.pVtab);
int eStmt = fts5StmtType(pCsr);
rc = sqlite3Fts5StorageStmt(
pTab->pStorage, eStmt, &pCsr->pStmt, (bErrormsg?&pTab->base.zErrMsg:0)
pTab->pStorage, eStmt, &pCsr->pStmt, (bErrormsg?&pTab->p.base.zErrMsg:0)
);
assert( rc!=SQLITE_OK || pTab->base.zErrMsg==0 );
assert( rc!=SQLITE_OK || pTab->p.base.zErrMsg==0 );
assert( CsrFlagTest(pCsr, FTS5CSR_REQUIRE_CONTENT) );
}
@@ -1360,11 +1359,11 @@ static int fts5SeekCursor(Fts5Cursor *pCsr, int bErrormsg){
return rc;
}
static void fts5SetVtabError(Fts5Table *p, const char *zFormat, ...){
static void fts5SetVtabError(Fts5FullTable *p, const char *zFormat, ...){
va_list ap; /* ... printf arguments */
va_start(ap, zFormat);
assert( p->base.zErrMsg==0 );
p->base.zErrMsg = sqlite3_vmprintf(zFormat, ap);
assert( p->p.base.zErrMsg==0 );
p->p.base.zErrMsg = sqlite3_vmprintf(zFormat, ap);
va_end(ap);
}
@@ -1384,11 +1383,11 @@ static void fts5SetVtabError(Fts5Table *p, const char *zFormat, ...){
** more commands are added to this function.
*/
static int fts5SpecialInsert(
Fts5Table *pTab, /* Fts5 table object */
Fts5FullTable *pTab, /* Fts5 table object */
const char *zCmd, /* Text inserted into table-name column */
sqlite3_value *pVal /* Value inserted into rank column */
){
Fts5Config *pConfig = pTab->pConfig;
Fts5Config *pConfig = pTab->p.pConfig;
int rc = SQLITE_OK;
int bError = 0;
@@ -1423,9 +1422,9 @@ static int fts5SpecialInsert(
pConfig->bPrefixIndex = sqlite3_value_int(pVal);
#endif
}else{
rc = sqlite3Fts5IndexLoadConfig(pTab->pIndex);
rc = sqlite3Fts5IndexLoadConfig(pTab->p.pIndex);
if( rc==SQLITE_OK ){
rc = sqlite3Fts5ConfigSetValue(pTab->pConfig, zCmd, pVal, &bError);
rc = sqlite3Fts5ConfigSetValue(pTab->p.pConfig, zCmd, pVal, &bError);
}
if( rc==SQLITE_OK ){
if( bError ){
@@ -1439,7 +1438,7 @@ static int fts5SpecialInsert(
}
static int fts5SpecialDelete(
Fts5Table *pTab,
Fts5FullTable *pTab,
sqlite3_value **apVal
){
int rc = SQLITE_OK;
@@ -1453,7 +1452,7 @@ static int fts5SpecialDelete(
static void fts5StorageInsert(
int *pRc,
Fts5Table *pTab,
Fts5FullTable *pTab,
sqlite3_value **apVal,
i64 *piRowid
){
@@ -1487,8 +1486,8 @@ static int fts5UpdateMethod(
sqlite3_value **apVal, /* Array of arguments */
sqlite_int64 *pRowid /* OUT: The affected (or effected) rowid */
){
Fts5Table *pTab = (Fts5Table*)pVtab;
Fts5Config *pConfig = pTab->pConfig;
Fts5FullTable *pTab = (Fts5FullTable*)pVtab;
Fts5Config *pConfig = pTab->p.pConfig;
int eType0; /* value_type() of apVal[0] */
int rc = SQLITE_OK; /* Return code */
@@ -1497,12 +1496,11 @@ static int fts5UpdateMethod(
assert( pVtab->zErrMsg==0 );
assert( nArg==1 || nArg==(2+pConfig->nCol+2) );
assert( nArg==1
|| sqlite3_value_type(apVal[1])==SQLITE_INTEGER
|| sqlite3_value_type(apVal[1])==SQLITE_NULL
assert( sqlite3_value_type(apVal[0])==SQLITE_INTEGER
|| sqlite3_value_type(apVal[0])==SQLITE_NULL
);
assert( pTab->pConfig->pzErrmsg==0 );
pTab->pConfig->pzErrmsg = &pTab->base.zErrMsg;
assert( pTab->p.pConfig->pzErrmsg==0 );
pTab->p.pConfig->pzErrmsg = &pTab->p.base.zErrMsg;
/* Put any active cursors into REQUIRE_SEEK state. */
fts5TripCursors(pTab);
@@ -1543,7 +1541,7 @@ static int fts5UpdateMethod(
/* Filter out attempts to run UPDATE or DELETE on contentless tables.
** This is not suported. */
if( eType0==SQLITE_INTEGER && fts5IsContentless(pTab) ){
pTab->base.zErrMsg = sqlite3_mprintf(
pTab->p.base.zErrMsg = sqlite3_mprintf(
"cannot %s contentless fts5 table: %s",
(nArg>1 ? "UPDATE" : "DELETE from"), pConfig->zName
);
@@ -1556,46 +1554,52 @@ static int fts5UpdateMethod(
rc = sqlite3Fts5StorageDelete(pTab->pStorage, iDel, 0);
}
/* INSERT */
else if( eType0!=SQLITE_INTEGER ){
/* If this is a REPLACE, first remove the current entry (if any) */
if( eConflict==SQLITE_REPLACE
&& sqlite3_value_type(apVal[1])==SQLITE_INTEGER
){
i64 iNew = sqlite3_value_int64(apVal[1]); /* Rowid to delete */
rc = sqlite3Fts5StorageDelete(pTab->pStorage, iNew, 0);
}
fts5StorageInsert(&rc, pTab, apVal, pRowid);
}
/* UPDATE */
/* INSERT or UPDATE */
else{
i64 iOld = sqlite3_value_int64(apVal[0]); /* Old rowid */
i64 iNew = sqlite3_value_int64(apVal[1]); /* New rowid */
if( iOld!=iNew ){
if( eConflict==SQLITE_REPLACE ){
rc = sqlite3Fts5StorageDelete(pTab->pStorage, iOld, 0);
if( rc==SQLITE_OK ){
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, 0);
}
if( rc==SQLITE_OK ){
rc = sqlite3Fts5StorageIndexInsert(pTab->pStorage, apVal, *pRowid);
}
int eType1 = sqlite3_value_numeric_type(apVal[1]);
if( eType1!=SQLITE_INTEGER && eType1!=SQLITE_NULL ){
rc = SQLITE_MISMATCH;
}
else if( eType0!=SQLITE_INTEGER ){
/* If this is a REPLACE, first remove the current entry (if any) */
if( eConflict==SQLITE_REPLACE && eType1==SQLITE_INTEGER ){
i64 iNew = sqlite3_value_int64(apVal[1]); /* Rowid to delete */
rc = sqlite3Fts5StorageDelete(pTab->pStorage, iNew, 0);
}
}else{
rc = sqlite3Fts5StorageDelete(pTab->pStorage, iOld, 0);
fts5StorageInsert(&rc, pTab, apVal, pRowid);
}
/* UPDATE */
else{
i64 iOld = sqlite3_value_int64(apVal[0]); /* Old rowid */
i64 iNew = sqlite3_value_int64(apVal[1]); /* New rowid */
if( eType1==SQLITE_INTEGER && iOld!=iNew ){
if( eConflict==SQLITE_REPLACE ){
rc = sqlite3Fts5StorageDelete(pTab->pStorage, iOld, 0);
if( rc==SQLITE_OK ){
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, 0);
}
if( rc==SQLITE_OK ){
rc = sqlite3Fts5StorageIndexInsert(pTab->pStorage, apVal,*pRowid);
}
}
}else{
rc = sqlite3Fts5StorageDelete(pTab->pStorage, iOld, 0);
fts5StorageInsert(&rc, pTab, apVal, pRowid);
}
}
}
}
pTab->pConfig->pzErrmsg = 0;
pTab->p.pConfig->pzErrmsg = 0;
return rc;
}
@@ -1604,12 +1608,12 @@ static int fts5UpdateMethod(
*/
static int fts5SyncMethod(sqlite3_vtab *pVtab){
int rc;
Fts5Table *pTab = (Fts5Table*)pVtab;
Fts5FullTable *pTab = (Fts5FullTable*)pVtab;
fts5CheckTransactionState(pTab, FTS5_SYNC, 0);
pTab->pConfig->pzErrmsg = &pTab->base.zErrMsg;
pTab->p.pConfig->pzErrmsg = &pTab->p.base.zErrMsg;
fts5TripCursors(pTab);
rc = sqlite3Fts5StorageSync(pTab->pStorage);
pTab->pConfig->pzErrmsg = 0;
pTab->p.pConfig->pzErrmsg = 0;
return rc;
}
@@ -1617,8 +1621,8 @@ static int fts5SyncMethod(sqlite3_vtab *pVtab){
** Implementation of xBegin() method.
*/
static int fts5BeginMethod(sqlite3_vtab *pVtab){
fts5CheckTransactionState((Fts5Table*)pVtab, FTS5_BEGIN, 0);
fts5NewTransaction((Fts5Table*)pVtab);
fts5CheckTransactionState((Fts5FullTable*)pVtab, FTS5_BEGIN, 0);
fts5NewTransaction((Fts5FullTable*)pVtab);
return SQLITE_OK;
}
@@ -1629,7 +1633,7 @@ static int fts5BeginMethod(sqlite3_vtab *pVtab){
*/
static int fts5CommitMethod(sqlite3_vtab *pVtab){
UNUSED_PARAM(pVtab); /* Call below is a no-op for NDEBUG builds */
fts5CheckTransactionState((Fts5Table*)pVtab, FTS5_COMMIT, 0);
fts5CheckTransactionState((Fts5FullTable*)pVtab, FTS5_COMMIT, 0);
return SQLITE_OK;
}
@@ -1639,7 +1643,7 @@ static int fts5CommitMethod(sqlite3_vtab *pVtab){
*/
static int fts5RollbackMethod(sqlite3_vtab *pVtab){
int rc;
Fts5Table *pTab = (Fts5Table*)pVtab;
Fts5FullTable *pTab = (Fts5FullTable*)pVtab;
fts5CheckTransactionState(pTab, FTS5_ROLLBACK, 0);
rc = sqlite3Fts5StorageRollback(pTab->pStorage);
return rc;
@@ -1663,13 +1667,13 @@ static int fts5ApiColumnTotalSize(
sqlite3_int64 *pnToken
){
Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
Fts5Table *pTab = (Fts5Table*)(pCsr->base.pVtab);
Fts5FullTable *pTab = (Fts5FullTable*)(pCsr->base.pVtab);
return sqlite3Fts5StorageSize(pTab->pStorage, iCol, pnToken);
}
static int fts5ApiRowCount(Fts5Context *pCtx, i64 *pnRow){
Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
Fts5Table *pTab = (Fts5Table*)(pCsr->base.pVtab);
Fts5FullTable *pTab = (Fts5FullTable*)(pCsr->base.pVtab);
return sqlite3Fts5StorageRowCount(pTab->pStorage, pnRow);
}
@@ -1704,7 +1708,9 @@ static int fts5ApiColumnText(
){
int rc = SQLITE_OK;
Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
if( fts5IsContentless((Fts5Table*)(pCsr->base.pVtab)) ){
if( fts5IsContentless((Fts5FullTable*)(pCsr->base.pVtab))
|| pCsr->ePlan==FTS5_PLAN_SPECIAL
){
*pz = 0;
*pn = 0;
}else{
@@ -1773,10 +1779,11 @@ static int fts5CacheInstArray(Fts5Cursor *pCsr){
int rc = SQLITE_OK;
Fts5PoslistReader *aIter; /* One iterator for each phrase */
int nIter; /* Number of iterators/phrases */
int nCol = ((Fts5Table*)pCsr->base.pVtab)->pConfig->nCol;
nIter = sqlite3Fts5ExprPhraseCount(pCsr->pExpr);
if( pCsr->aInstIter==0 ){
int nByte = sizeof(Fts5PoslistReader) * nIter;
sqlite3_int64 nByte = sizeof(Fts5PoslistReader) * nIter;
pCsr->aInstIter = (Fts5PoslistReader*)sqlite3Fts5MallocZero(&rc, nByte);
}
aIter = pCsr->aInstIter;
@@ -1811,7 +1818,7 @@ static int fts5CacheInstArray(Fts5Cursor *pCsr){
nInst++;
if( nInst>=pCsr->nInstAlloc ){
pCsr->nInstAlloc = pCsr->nInstAlloc ? pCsr->nInstAlloc*2 : 32;
aInst = (int*)sqlite3_realloc(
aInst = (int*)sqlite3_realloc64(
pCsr->aInst, pCsr->nInstAlloc*sizeof(int)*3
);
if( aInst ){
@@ -1826,6 +1833,10 @@ static int fts5CacheInstArray(Fts5Cursor *pCsr){
aInst[0] = iBest;
aInst[1] = FTS5_POS2COLUMN(aIter[iBest].iPos);
aInst[2] = FTS5_POS2OFFSET(aIter[iBest].iPos);
if( aInst[1]<0 || aInst[1]>=nCol ){
rc = FTS5_CORRUPT;
break;
}
sqlite3Fts5PoslistReaderNext(&aIter[iBest]);
}
}
@@ -1898,8 +1909,8 @@ static int fts5ColumnSizeCb(
static int fts5ApiColumnSize(Fts5Context *pCtx, int iCol, int *pnToken){
Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
Fts5Table *pTab = (Fts5Table*)(pCsr->base.pVtab);
Fts5Config *pConfig = pTab->pConfig;
Fts5FullTable *pTab = (Fts5FullTable*)(pCsr->base.pVtab);
Fts5Config *pConfig = pTab->p.pConfig;
int rc = SQLITE_OK;
if( CsrFlagTest(pCsr, FTS5CSR_REQUIRE_DOCSIZE) ){
@@ -2155,7 +2166,7 @@ static int fts5ApiQueryPhrase(
int(*xCallback)(const Fts5ExtensionApi*, Fts5Context*, void*)
){
Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
Fts5Table *pTab = (Fts5Table*)(pCsr->base.pVtab);
Fts5FullTable *pTab = (Fts5FullTable*)(pCsr->base.pVtab);
int rc;
Fts5Cursor *pNew = 0;
@@ -2232,25 +2243,19 @@ static void fts5ApiCallback(
/*
** Given cursor id iId, return a pointer to the corresponding Fts5Index
** Given cursor id iId, return a pointer to the corresponding Fts5Table
** object. Or NULL If the cursor id does not exist.
**
** If successful, set *ppConfig to point to the associated config object
** before returning.
*/
Fts5Index *sqlite3Fts5IndexFromCsrid(
Fts5Table *sqlite3Fts5TableFromCsrid(
Fts5Global *pGlobal, /* FTS5 global context for db handle */
i64 iCsrId, /* Id of cursor to find */
Fts5Config **ppConfig /* OUT: Configuration object */
i64 iCsrId /* Id of cursor to find */
){
Fts5Cursor *pCsr;
Fts5Table *pTab;
pCsr = fts5CursorFromCsrid(pGlobal, iCsrId);
pTab = (Fts5Table*)pCsr->base.pVtab;
*ppConfig = pTab->pConfig;
return pTab->pIndex;
if( pCsr ){
return (Fts5Table*)pCsr->base.pVtab;
}
return 0;
}
/*
@@ -2330,8 +2335,8 @@ static int fts5ColumnMethod(
sqlite3_context *pCtx, /* Context for sqlite3_result_xxx() calls */
int iCol /* Index of column to read value from */
){
Fts5Table *pTab = (Fts5Table*)(pCursor->pVtab);
Fts5Config *pConfig = pTab->pConfig;
Fts5FullTable *pTab = (Fts5FullTable*)(pCursor->pVtab);
Fts5Config *pConfig = pTab->p.pConfig;
Fts5Cursor *pCsr = (Fts5Cursor*)pCursor;
int rc = SQLITE_OK;
@@ -2383,7 +2388,7 @@ static int fts5FindFunctionMethod(
void (**pxFunc)(sqlite3_context*,int,sqlite3_value**), /* OUT: Result */
void **ppArg /* OUT: User data for *pxFunc */
){
Fts5Table *pTab = (Fts5Table*)pVtab;
Fts5FullTable *pTab = (Fts5FullTable*)pVtab;
Fts5Auxiliary *pAux;
UNUSED_PARAM(nUnused);
@@ -2405,21 +2410,24 @@ static int fts5RenameMethod(
sqlite3_vtab *pVtab, /* Virtual table handle */
const char *zName /* New name of table */
){
Fts5Table *pTab = (Fts5Table*)pVtab;
Fts5FullTable *pTab = (Fts5FullTable*)pVtab;
return sqlite3Fts5StorageRename(pTab->pStorage, zName);
}
int sqlite3Fts5FlushToDisk(Fts5Table *pTab){
fts5TripCursors((Fts5FullTable*)pTab);
return sqlite3Fts5StorageSync(((Fts5FullTable*)pTab)->pStorage);
}
/*
** The xSavepoint() method.
**
** Flush the contents of the pending-terms table to disk.
*/
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);
fts5CheckTransactionState((Fts5FullTable*)pVtab, FTS5_SAVEPOINT, iSavepoint);
return sqlite3Fts5FlushToDisk((Fts5Table*)pVtab);
}
/*
@@ -2428,11 +2436,9 @@ static int fts5SavepointMethod(sqlite3_vtab *pVtab, int iSavepoint){
** This is a no-op.
*/
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);
fts5CheckTransactionState((Fts5FullTable*)pVtab, FTS5_RELEASE, iSavepoint);
return sqlite3Fts5FlushToDisk((Fts5Table*)pVtab);
}
/*
@@ -2441,7 +2447,7 @@ static int fts5ReleaseMethod(sqlite3_vtab *pVtab, int iSavepoint){
** Discard the contents of the pending terms table.
*/
static int fts5RollbackToMethod(sqlite3_vtab *pVtab, int iSavepoint){
Fts5Table *pTab = (Fts5Table*)pVtab;
Fts5FullTable *pTab = (Fts5FullTable*)pVtab;
UNUSED_PARAM(iSavepoint); /* Call below is a no-op for NDEBUG builds */
fts5CheckTransactionState(pTab, FTS5_ROLLBACKTO, iSavepoint);
fts5TripCursors(pTab);
@@ -2645,9 +2651,24 @@ static void fts5SourceIdFunc(
sqlite3_result_text(pCtx, "--FTS5-SOURCE-ID--", -1, SQLITE_TRANSIENT);
}
/*
** Return true if zName is the extension on one of the shadow tables used
** by this module.
*/
static int fts5ShadowName(const char *zName){
static const char *azName[] = {
"config", "content", "data", "docsize", "idx"
};
unsigned int i;
for(i=0; i<sizeof(azName)/sizeof(azName[0]); i++){
if( sqlite3_stricmp(zName, azName[i])==0 ) return 1;
}
return 0;
}
static int fts5Init(sqlite3 *db){
static const sqlite3_module fts5Mod = {
/* iVersion */ 2,
/* iVersion */ 3,
/* xCreate */ fts5CreateMethod,
/* xConnect */ fts5ConnectMethod,
/* xBestIndex */ fts5BestIndexMethod,
@@ -2670,6 +2691,7 @@ static int fts5Init(sqlite3 *db){
/* xSavepoint */ fts5SavepointMethod,
/* xRelease */ fts5ReleaseMethod,
/* xRollbackTo */ fts5RollbackToMethod,
/* xShadowName */ fts5ShadowName
};
int rc;
+17 -8
View File
@@ -115,7 +115,7 @@ static int fts5StorageGetStmt(
char *zBind;
int i;
zBind = sqlite3_malloc(1 + nCol*2);
zBind = sqlite3_malloc64(1 + nCol*2);
if( zBind ){
for(i=0; i<nCol; i++){
zBind[i*2] = '?';
@@ -136,8 +136,9 @@ static int fts5StorageGetStmt(
if( zSql==0 ){
rc = SQLITE_NOMEM;
}else{
rc = sqlite3_prepare_v3(pC->db, zSql, -1,
SQLITE_PREPARE_PERSISTENT, &p->aStmt[eStmt], 0);
int f = SQLITE_PREPARE_PERSISTENT;
if( eStmt>FTS5_STMT_LOOKUP ) f |= SQLITE_PREPARE_NO_VTAB;
rc = sqlite3_prepare_v3(pC->db, zSql, -1, f, &p->aStmt[eStmt], 0);
sqlite3_free(zSql);
if( rc!=SQLITE_OK && pzErrMsg ){
*pzErrMsg = sqlite3_mprintf("%s", sqlite3_errmsg(pC->db));
@@ -281,11 +282,11 @@ int sqlite3Fts5StorageOpen(
){
int rc = SQLITE_OK;
Fts5Storage *p; /* New object */
int nByte; /* Bytes of space to allocate */
sqlite3_int64 nByte; /* Bytes of space to allocate */
nByte = sizeof(Fts5Storage) /* Fts5Storage object */
+ pConfig->nCol * sizeof(i64); /* Fts5Storage.aTotalSize[] */
*pp = p = (Fts5Storage*)sqlite3_malloc(nByte);
*pp = p = (Fts5Storage*)sqlite3_malloc64(nByte);
if( !p ) return SQLITE_NOMEM;
memset(p, 0, nByte);
@@ -296,7 +297,7 @@ int sqlite3Fts5StorageOpen(
if( bCreate ){
if( pConfig->eContent==FTS5_CONTENT_NORMAL ){
int nDefn = 32 + pConfig->nCol*10;
char *zDefn = sqlite3_malloc(32 + pConfig->nCol * 10);
char *zDefn = sqlite3_malloc64(32 + (sqlite3_int64)pConfig->nCol * 10);
if( zDefn==0 ){
rc = SQLITE_NOMEM;
}else{
@@ -587,7 +588,7 @@ int sqlite3Fts5StorageRebuild(Fts5Storage *p){
Fts5Config *pConfig = p->pConfig;
sqlite3_stmt *pScan = 0;
Fts5InsertCtx ctx;
int rc;
int rc, rc2;
memset(&ctx, 0, sizeof(Fts5InsertCtx));
ctx.pStorage = p;
@@ -626,6 +627,8 @@ int sqlite3Fts5StorageRebuild(Fts5Storage *p){
}
}
sqlite3_free(buf.p);
rc2 = sqlite3_reset(pScan);
if( rc==SQLITE_OK ) rc = rc2;
/* Write the averages record */
if( rc==SQLITE_OK ){
@@ -875,7 +878,7 @@ int sqlite3Fts5StorageIntegrity(Fts5Storage *p){
memset(&ctx, 0, sizeof(Fts5IntegrityCtx));
ctx.pConfig = p->pConfig;
aTotalSize = (i64*)sqlite3_malloc(pConfig->nCol * (sizeof(int)+sizeof(i64)));
aTotalSize = (i64*)sqlite3_malloc64(pConfig->nCol*(sizeof(int)+sizeof(i64)));
if( !aTotalSize ) return SQLITE_NOMEM;
aColSize = (int*)&aTotalSize[pConfig->nCol];
memset(aTotalSize, 0, sizeof(i64) * pConfig->nCol);
@@ -1075,7 +1078,13 @@ int sqlite3Fts5StorageSize(Fts5Storage *p, int iCol, i64 *pnToken){
int sqlite3Fts5StorageRowCount(Fts5Storage *p, i64 *pnRow){
int rc = fts5StorageLoadTotals(p, 0);
if( rc==SQLITE_OK ){
/* nTotalRow being zero does not necessarily indicate a corrupt
** database - it might be that the FTS5 table really does contain zero
** rows. However this function is only called from the xRowCount() API,
** and there is no way for that API to be invoked if the table contains
** no rows. Hence the FTS5_CORRUPT return. */
*pnRow = p->nTotalRow;
if( p->nTotalRow<=0 ) rc = FTS5_CORRUPT;
}
return rc;
}
+2 -2
View File
@@ -309,7 +309,7 @@ static Fts5MatchinfoCtx *fts5MatchinfoNew(
int nPhrase;
int i;
int nInt;
int nByte;
sqlite3_int64 nByte;
int rc;
nCol = pApi->xColumnCount(pFts);
@@ -330,7 +330,7 @@ static Fts5MatchinfoCtx *fts5MatchinfoNew(
nByte = sizeof(Fts5MatchinfoCtx) /* The struct itself */
+ sizeof(u32) * nInt /* The p->aRet[] array */
+ (i+1); /* The p->zArg string */
p = (Fts5MatchinfoCtx*)sqlite3_malloc(nByte);
p = (Fts5MatchinfoCtx*)sqlite3_malloc64(nByte);
if( p==0 ){
sqlite3_result_error_nomem(pCtx);
return 0;
+5 -4
View File
@@ -137,7 +137,7 @@ static int fts5tokDequoteArray(
nByte += (int)(strlen(argv[i]) + 1);
}
*pazDequote = azDequote = sqlite3_malloc(sizeof(char *)*argc + nByte);
*pazDequote = azDequote = sqlite3_malloc64(sizeof(char *)*argc + nByte);
if( azDequote==0 ){
rc = SQLITE_NOMEM;
}else{
@@ -335,7 +335,7 @@ static int fts5tokCb(
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));
aNew = (Fts5tokRow*)sqlite3_realloc64(pCsr->aRow, nNew*sizeof(Fts5tokRow));
if( aNew==0 ) return SQLITE_NOMEM;
memset(&aNew[pCsr->nRow], 0, sizeof(Fts5tokRow)*(nNew-pCsr->nRow));
pCsr->aRow = aNew;
@@ -378,7 +378,7 @@ static int fts5tokFilterMethod(
if( pCsr->zInput==0 ){
rc = SQLITE_NOMEM;
}else{
memcpy(pCsr->zInput, zByte, nByte);
if( nByte>0 ) memcpy(pCsr->zInput, zByte, nByte);
pCsr->zInput[nByte] = 0;
rc = pTab->tok.xTokenize(
pTab->pTok, (void*)pCsr, 0, zByte, nByte, fts5tokCb
@@ -471,7 +471,8 @@ int sqlite3Fts5TestRegisterTok(sqlite3 *db, fts5_api *pApi){
0, /* xRename */
0, /* xSavepoint */
0, /* xRelease */
0 /* xRollbackTo */
0, /* xRollbackTo */
0 /* xShadowName */
};
int rc; /* Return code */
+23 -14
View File
@@ -152,7 +152,7 @@ static int fts5AsciiTokenize(
nByte = ie-is;
if( nByte>nFold ){
if( pFold!=aFold ) sqlite3_free(pFold);
pFold = sqlite3_malloc(nByte*2);
pFold = sqlite3_malloc64((sqlite3_int64)nByte*2);
if( pFold==0 ){
rc = SQLITE_NOMEM;
break;
@@ -234,13 +234,18 @@ struct Unicode61Tokenizer {
unsigned char aTokenChar[128]; /* ASCII range token characters */
char *aFold; /* Buffer to fold text into */
int nFold; /* Size of aFold[] in bytes */
int bRemoveDiacritic; /* True if remove_diacritics=1 is set */
int eRemoveDiacritic; /* True if remove_diacritics=1 is set */
int nException;
int *aiException;
unsigned char aCategory[32]; /* True for token char categories */
};
/* Values for eRemoveDiacritic (must match internals of fts5_unicode2.c) */
#define FTS5_REMOVE_DIACRITICS_NONE 0
#define FTS5_REMOVE_DIACRITICS_SIMPLE 1
#define FTS5_REMOVE_DIACRITICS_COMPLEX 2
static int fts5UnicodeAddExceptions(
Unicode61Tokenizer *p, /* Tokenizer object */
const char *z, /* Characters to treat as exceptions */
@@ -251,13 +256,14 @@ static int fts5UnicodeAddExceptions(
int *aNew;
if( n>0 ){
aNew = (int*)sqlite3_realloc(p->aiException, (n+p->nException)*sizeof(int));
aNew = (int*)sqlite3_realloc64(p->aiException,
(n+p->nException)*sizeof(int));
if( aNew ){
int nNew = p->nException;
const unsigned char *zCsr = (const unsigned char*)z;
const unsigned char *zTerm = (const unsigned char*)&z[n];
while( zCsr<zTerm ){
int iCode;
u32 iCode;
int bToken;
READ_UTF8(zCsr, zTerm, iCode);
if( iCode<128 ){
@@ -269,7 +275,7 @@ static int fts5UnicodeAddExceptions(
if( bToken!=bTokenChars && sqlite3Fts5UnicodeIsdiacritic(iCode)==0 ){
int i;
for(i=0; i<nNew; i++){
if( aNew[i]>iCode ) break;
if( (u32)aNew[i]>iCode ) break;
}
memmove(&aNew[i+1], &aNew[i], (nNew-i)*sizeof(int));
aNew[i] = iCode;
@@ -361,7 +367,7 @@ static int fts5UnicodeCreate(
int i;
memset(p, 0, sizeof(Unicode61Tokenizer));
p->bRemoveDiacritic = 1;
p->eRemoveDiacritic = FTS5_REMOVE_DIACRITICS_SIMPLE;
p->nFold = 64;
p->aFold = sqlite3_malloc(p->nFold * sizeof(char));
if( p->aFold==0 ){
@@ -382,10 +388,15 @@ static int fts5UnicodeCreate(
for(i=0; rc==SQLITE_OK && i<nArg; i+=2){
const char *zArg = azArg[i+1];
if( 0==sqlite3_stricmp(azArg[i], "remove_diacritics") ){
if( (zArg[0]!='0' && zArg[0]!='1') || zArg[1] ){
if( (zArg[0]!='0' && zArg[0]!='1' && zArg[0]!='2') || zArg[1] ){
rc = SQLITE_ERROR;
}else{
p->eRemoveDiacritic = (zArg[0] - '0');
assert( p->eRemoveDiacritic==FTS5_REMOVE_DIACRITICS_NONE
|| p->eRemoveDiacritic==FTS5_REMOVE_DIACRITICS_SIMPLE
|| p->eRemoveDiacritic==FTS5_REMOVE_DIACRITICS_COMPLEX
);
}
p->bRemoveDiacritic = (zArg[0]=='1');
}else
if( 0==sqlite3_stricmp(azArg[i], "tokenchars") ){
rc = fts5UnicodeAddExceptions(p, zArg, 1);
@@ -419,7 +430,7 @@ static int fts5UnicodeCreate(
*/
static int fts5UnicodeIsAlnum(Unicode61Tokenizer *p, int iCode){
return (
p->aCategory[sqlite3Fts5UnicodeCategory(iCode)]
p->aCategory[sqlite3Fts5UnicodeCategory((u32)iCode)]
^ fts5UnicodeIsException(p, iCode)
);
}
@@ -448,7 +459,7 @@ static int fts5UnicodeTokenize(
/* Each iteration of this loop gobbles up a contiguous run of separators,
** then the next token. */
while( rc==SQLITE_OK ){
int iCode; /* non-ASCII codepoint read from input */
u32 iCode; /* non-ASCII codepoint read from input */
char *zOut = aFold;
int is;
int ie;
@@ -480,7 +491,7 @@ static int fts5UnicodeTokenize(
/* Grow the output buffer so that there is sufficient space to fit the
** largest possible utf-8 character. */
if( zOut>pEnd ){
aFold = sqlite3_malloc(nFold*2);
aFold = sqlite3_malloc64((sqlite3_int64)nFold*2);
if( aFold==0 ){
rc = SQLITE_NOMEM;
goto tokenize_done;
@@ -499,7 +510,7 @@ static int fts5UnicodeTokenize(
READ_UTF8(zCsr, zTerm, iCode);
if( fts5UnicodeIsAlnum(p,iCode)||sqlite3Fts5UnicodeIsdiacritic(iCode) ){
non_ascii_tokenchar:
iCode = sqlite3Fts5UnicodeFold(iCode, p->bRemoveDiacritic);
iCode = sqlite3Fts5UnicodeFold(iCode, p->eRemoveDiacritic);
if( iCode ) WRITE_UTF8(zOut, iCode);
}else{
break;
@@ -1274,5 +1285,3 @@ int sqlite3Fts5TokenizerInit(fts5_api *pApi){
return rc;
}
+47 -35
View File
@@ -1,5 +1,5 @@
/*
** 2012 May 25
** 2012-05-25
**
** The author disclaims copyright to this source code. In place of
** a legal notice, here is a blessing:
@@ -28,32 +28,48 @@
** E"). The resuls of passing a codepoint that corresponds to an
** uppercase letter are undefined.
*/
static int fts5_remove_diacritic(int c){
static int fts5_remove_diacritic(int c, int bComplex){
unsigned short aDia[] = {
0, 1797, 1848, 1859, 1891, 1928, 1940, 1995,
2024, 2040, 2060, 2110, 2168, 2206, 2264, 2286,
2344, 2383, 2472, 2488, 2516, 2596, 2668, 2732,
2782, 2842, 2894, 2954, 2984, 3000, 3028, 3336,
3456, 3696, 3712, 3728, 3744, 3896, 3912, 3928,
3968, 4008, 4040, 4106, 4138, 4170, 4202, 4234,
4266, 4296, 4312, 4344, 4408, 4424, 4472, 4504,
6148, 6198, 6264, 6280, 6360, 6429, 6505, 6529,
61448, 61468, 61534, 61592, 61642, 61688, 61704, 61726,
61784, 61800, 61836, 61880, 61914, 61948, 61998, 62122,
62154, 62200, 62218, 62302, 62364, 62442, 62478, 62536,
62554, 62584, 62604, 62640, 62648, 62656, 62664, 62730,
62924, 63050, 63082, 63274, 63390,
3456, 3696, 3712, 3728, 3744, 3766, 3832, 3896,
3912, 3928, 3944, 3968, 4008, 4040, 4056, 4106,
4138, 4170, 4202, 4234, 4266, 4296, 4312, 4344,
4408, 4424, 4442, 4472, 4488, 4504, 6148, 6198,
6264, 6280, 6360, 6429, 6505, 6529, 61448, 61468,
61512, 61534, 61592, 61610, 61642, 61672, 61688, 61704,
61726, 61784, 61800, 61816, 61836, 61880, 61896, 61914,
61948, 61998, 62062, 62122, 62154, 62184, 62200, 62218,
62252, 62302, 62364, 62410, 62442, 62478, 62536, 62554,
62584, 62604, 62640, 62648, 62656, 62664, 62730, 62766,
62830, 62890, 62924, 62974, 63032, 63050, 63082, 63118,
63182, 63242, 63274, 63310, 63368, 63390,
};
char aChar[] = {
'\0', 'a', 'c', 'e', 'i', 'n', 'o', 'u', 'y', 'y', 'a', 'c',
'd', 'e', 'e', 'g', 'h', 'i', 'j', 'k', 'l', 'n', 'o', 'r',
's', 't', 'u', 'u', 'w', 'y', 'z', 'o', 'u', 'a', 'i', 'o',
'u', 'g', 'k', 'o', 'j', 'g', 'n', 'a', 'e', 'i', 'o', 'r',
'u', 's', 't', 'h', 'a', 'e', 'o', 'y', '\0', '\0', '\0', '\0',
'\0', '\0', '\0', '\0', 'a', 'b', 'd', 'd', 'e', 'f', 'g', 'h',
'h', 'i', 'k', 'l', 'l', 'm', 'n', 'p', 'r', 'r', 's', 't',
'u', 'v', 'w', 'w', 'x', 'y', 'z', 'h', 't', 'w', 'y', 'a',
'e', 'i', 'o', 'u', 'y',
#define HIBIT ((unsigned char)0x80)
unsigned char aChar[] = {
'\0', 'a', 'c', 'e', 'i', 'n',
'o', 'u', 'y', 'y', 'a', 'c',
'd', 'e', 'e', 'g', 'h', 'i',
'j', 'k', 'l', 'n', 'o', 'r',
's', 't', 'u', 'u', 'w', 'y',
'z', 'o', 'u', 'a', 'i', 'o',
'u', 'u'|HIBIT, 'a'|HIBIT, 'g', 'k', 'o',
'o'|HIBIT, 'j', 'g', 'n', 'a'|HIBIT, 'a',
'e', 'i', 'o', 'r', 'u', 's',
't', 'h', 'a', 'e', 'o'|HIBIT, 'o',
'o'|HIBIT, 'y', '\0', '\0', '\0', '\0',
'\0', '\0', '\0', '\0', 'a', 'b',
'c'|HIBIT, 'd', 'd', 'e'|HIBIT, 'e', 'e'|HIBIT,
'f', 'g', 'h', 'h', 'i', 'i'|HIBIT,
'k', 'l', 'l'|HIBIT, 'l', 'm', 'n',
'o'|HIBIT, 'p', 'r', 'r'|HIBIT, 'r', 's',
's'|HIBIT, 't', 'u', 'u'|HIBIT, 'v', 'w',
'w', 'x', 'y', 'z', 'h', 't',
'w', 'y', 'a', 'a'|HIBIT, 'a'|HIBIT, 'a'|HIBIT,
'e', 'e'|HIBIT, 'e'|HIBIT, 'i', 'o', 'o'|HIBIT,
'o'|HIBIT, 'o'|HIBIT, 'u', 'u'|HIBIT, 'u'|HIBIT, 'y',
};
unsigned int key = (((unsigned int)c)<<3) | 0x00000007;
@@ -70,7 +86,8 @@ static int fts5_remove_diacritic(int c){
}
}
assert( key>=aDia[iRes] );
return ((c > (aDia[iRes]>>3) + (aDia[iRes]&0x07)) ? c : (int)aChar[iRes]);
if( bComplex==0 && (aChar[iRes] & 0x80) ) return c;
return (c > (aDia[iRes]>>3) + (aDia[iRes]&0x07)) ? c : ((int)aChar[iRes] & 0x7F);
}
@@ -83,8 +100,8 @@ int sqlite3Fts5UnicodeIsdiacritic(int c){
unsigned int mask1 = 0x000361F8;
if( c<768 || c>817 ) return 0;
return (c < 768+32) ?
(mask0 & (1 << (c-768))) :
(mask1 & (1 << (c-768-32)));
(mask0 & ((unsigned int)1 << (c-768))) :
(mask1 & ((unsigned int)1 << (c-768-32)));
}
@@ -97,7 +114,7 @@ int sqlite3Fts5UnicodeIsdiacritic(int c){
** The results are undefined if the value passed to this function
** is less than zero.
*/
int sqlite3Fts5UnicodeFold(int c, int bRemoveDiacritic){
int sqlite3Fts5UnicodeFold(int c, int eRemoveDiacritic){
/* Each entry in the following array defines a rule for folding a range
** of codepoints to lower case. The rule applies to a range of nRange
** codepoints starting at codepoint iCode.
@@ -220,7 +237,9 @@ int sqlite3Fts5UnicodeFold(int c, int bRemoveDiacritic){
assert( ret>0 );
}
if( bRemoveDiacritic ) ret = fts5_remove_diacritic(ret);
if( eRemoveDiacritic ){
ret = fts5_remove_diacritic(ret, eRemoveDiacritic==2);
}
}
else if( c>=66560 && c<66600 ){
@@ -231,12 +250,6 @@ int sqlite3Fts5UnicodeFold(int c, int bRemoveDiacritic){
}
#if 0
int sqlite3Fts5UnicodeNCat(void) {
return 32;
}
#endif
int sqlite3Fts5UnicodeCatParse(const char *zCat, u8 *aArray){
aArray[0] = 1;
switch( zCat[0] ){
@@ -718,7 +731,7 @@ static u16 aFts5UnicodeData[] = {
34, 3074, 7692, 63, 63,
};
int sqlite3Fts5UnicodeCategory(int iCode) {
int sqlite3Fts5UnicodeCategory(u32 iCode) {
int iRes = -1;
int iHi;
int iLo;
@@ -756,9 +769,8 @@ void sqlite3Fts5UnicodeAscii(u8 *aArray, u8 *aAscii){
int bToken = aArray[ aFts5UnicodeData[iTbl] & 0x1F ];
int n = (aFts5UnicodeData[iTbl] >> 5) + i;
for(; i<128 && i<n; i++){
aAscii[i] = (u8)bToken;
aAscii[i] = bToken;
}
iTbl++;
}
}
+1 -2
View File
@@ -76,7 +76,7 @@ int sqlite3Fts5GetVarint32(const unsigned char *p, u32 *v){
u8 n;
p -= 2;
n = sqlite3Fts5GetVarint(p, &v64);
*v = (u32)v64;
*v = ((u32)v64) & 0x7FFFFFFF;
assert( n>3 && n<=9 );
return n;
}
@@ -342,4 +342,3 @@ int sqlite3Fts5GetVarintLen(u32 iVal){
if( iVal<(1 << 28) ) return 4;
return 5;
}
+42 -34
View File
@@ -55,7 +55,7 @@ struct Fts5VocabTable {
struct Fts5VocabCursor {
sqlite3_vtab_cursor base;
sqlite3_stmt *pStmt; /* Statement holding lock on pIndex */
Fts5Index *pIndex; /* Associated FTS5 index */
Fts5Table *pFts5; /* Associated FTS5 table */
int bEof; /* True if this cursor is at EOF */
Fts5IndexIter *pIter; /* Term/rowid iterator object */
@@ -64,7 +64,6 @@ struct Fts5VocabCursor {
char *zLeTerm; /* (term <= $zLeTerm) paramater, or NULL */
/* These are used by 'col' tables only */
Fts5Config *pConfig; /* Fts5 table configuration */
int iCol;
i64 *aCnt;
i64 *aDoc;
@@ -327,8 +326,7 @@ static int fts5VocabOpenMethod(
sqlite3_vtab_cursor **ppCsr
){
Fts5VocabTable *pTab = (Fts5VocabTable*)pVTab;
Fts5Index *pIndex = 0;
Fts5Config *pConfig = 0;
Fts5Table *pFts5 = 0;
Fts5VocabCursor *pCsr = 0;
int rc = SQLITE_OK;
sqlite3_stmt *pStmt = 0;
@@ -347,31 +345,34 @@ static int fts5VocabOpenMethod(
if( pStmt && sqlite3_step(pStmt)==SQLITE_ROW ){
i64 iId = sqlite3_column_int64(pStmt, 0);
pIndex = sqlite3Fts5IndexFromCsrid(pTab->pGlobal, iId, &pConfig);
pFts5 = sqlite3Fts5TableFromCsrid(pTab->pGlobal, iId);
}
if( rc==SQLITE_OK && pIndex==0 ){
rc = sqlite3_finalize(pStmt);
pStmt = 0;
if( rc==SQLITE_OK ){
pVTab->zErrMsg = sqlite3_mprintf(
"no such fts5 table: %s.%s", pTab->zFts5Db, pTab->zFts5Tbl
);
rc = SQLITE_ERROR;
if( rc==SQLITE_OK ){
if( pFts5==0 ){
rc = sqlite3_finalize(pStmt);
pStmt = 0;
if( rc==SQLITE_OK ){
pVTab->zErrMsg = sqlite3_mprintf(
"no such fts5 table: %s.%s", pTab->zFts5Db, pTab->zFts5Tbl
);
rc = SQLITE_ERROR;
}
}else{
rc = sqlite3Fts5FlushToDisk(pFts5);
}
}
if( rc==SQLITE_OK ){
int nByte = pConfig->nCol * sizeof(i64) * 2 + sizeof(Fts5VocabCursor);
int nByte = pFts5->pConfig->nCol * sizeof(i64)*2 + sizeof(Fts5VocabCursor);
pCsr = (Fts5VocabCursor*)sqlite3Fts5MallocZero(&rc, nByte);
}
if( pCsr ){
pCsr->pIndex = pIndex;
pCsr->pFts5 = pFts5;
pCsr->pStmt = pStmt;
pCsr->pConfig = pConfig;
pCsr->aCnt = (i64*)&pCsr[1];
pCsr->aDoc = &pCsr->aCnt[pConfig->nCol];
pCsr->aDoc = &pCsr->aCnt[pFts5->pConfig->nCol];
}else{
sqlite3_finalize(pStmt);
}
@@ -387,6 +388,7 @@ static void fts5VocabResetCursor(Fts5VocabCursor *pCsr){
sqlite3_free(pCsr->zLeTerm);
pCsr->nLeTerm = -1;
pCsr->zLeTerm = 0;
pCsr->bEof = 0;
}
/*
@@ -425,12 +427,14 @@ static int fts5VocabInstanceNewTerm(Fts5VocabCursor *pCsr){
}
static int fts5VocabInstanceNext(Fts5VocabCursor *pCsr){
int eDetail = pCsr->pConfig->eDetail;
int eDetail = pCsr->pFts5->pConfig->eDetail;
int rc = SQLITE_OK;
Fts5IndexIter *pIter = pCsr->pIter;
i64 *pp = &pCsr->iInstPos;
int *po = &pCsr->iInstOff;
assert( sqlite3Fts5IterEof(pIter)==0 );
assert( pCsr->bEof==0 );
while( eDetail==FTS5_DETAIL_NONE
|| sqlite3Fts5PoslistNext64(pIter->pData, pIter->nData, po, pp)
){
@@ -440,7 +444,7 @@ static int fts5VocabInstanceNext(Fts5VocabCursor *pCsr){
rc = sqlite3Fts5IterNextScan(pCsr->pIter);
if( rc==SQLITE_OK ){
rc = fts5VocabInstanceNewTerm(pCsr);
if( eDetail==FTS5_DETAIL_NONE ) break;
if( pCsr->bEof || eDetail==FTS5_DETAIL_NONE ) break;
}
if( rc ){
pCsr->bEof = 1;
@@ -458,7 +462,7 @@ 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;
int nCol = pCsr->pFts5->pConfig->nCol;
pCsr->rowid++;
@@ -480,6 +484,7 @@ static int fts5VocabNextMethod(sqlite3_vtab_cursor *pCursor){
int nTerm;
zTerm = sqlite3Fts5IterTerm(pCsr->pIter, &nTerm);
assert( nTerm>=0 );
if( pCsr->nLeTerm>=0 ){
int nCmp = MIN(nTerm, pCsr->nLeTerm);
int bCmp = memcmp(pCsr->zLeTerm, zTerm, nCmp);
@@ -496,7 +501,7 @@ static int fts5VocabNextMethod(sqlite3_vtab_cursor *pCursor){
assert( pTab->eType==FTS5_VOCAB_COL || pTab->eType==FTS5_VOCAB_ROW );
while( rc==SQLITE_OK ){
int eDetail = pCsr->pConfig->eDetail;
int eDetail = pCsr->pFts5->pConfig->eDetail;
const u8 *pPos; int nPos; /* Position list */
i64 iPos = 0; /* 64-bit position read from poslist */
int iOff = 0; /* Current offset within position list */
@@ -519,7 +524,6 @@ static int fts5VocabNextMethod(sqlite3_vtab_cursor *pCursor){
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;
@@ -528,6 +532,7 @@ static int fts5VocabNextMethod(sqlite3_vtab_cursor *pCursor){
pCsr->aDoc[ii]++;
iCol = ii;
}
pCsr->aCnt[ii]++;
}
}else if( eDetail==FTS5_DETAIL_COLUMNS ){
while( 0==sqlite3Fts5PoslistNext64(pPos, nPos, &iOff,&iPos) ){
@@ -556,7 +561,9 @@ static int fts5VocabNextMethod(sqlite3_vtab_cursor *pCursor){
if( rc==SQLITE_OK ){
zTerm = sqlite3Fts5IterTerm(pCsr->pIter, &nTerm);
if( nTerm!=pCsr->term.n || memcmp(zTerm, pCsr->term.p, nTerm) ){
if( nTerm!=pCsr->term.n
|| (nTerm>0 && memcmp(zTerm, pCsr->term.p, nTerm))
){
break;
}
if( sqlite3Fts5IterEof(pCsr->pIter) ) break;
@@ -567,7 +574,7 @@ static int fts5VocabNextMethod(sqlite3_vtab_cursor *pCursor){
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 );
assert( pCsr->iCol<pCsr->pFts5->pConfig->nCol );
}
return rc;
}
@@ -614,6 +621,7 @@ static int fts5VocabFilterMethod(
}
if( pLe ){
const char *zCopy = (const char *)sqlite3_value_text(pLe);
if( zCopy==0 ) zCopy = "";
pCsr->nLeTerm = sqlite3_value_bytes(pLe);
pCsr->zLeTerm = sqlite3_malloc(pCsr->nLeTerm+1);
if( pCsr->zLeTerm==0 ){
@@ -625,14 +633,15 @@ static int fts5VocabFilterMethod(
}
if( rc==SQLITE_OK ){
rc = sqlite3Fts5IndexQuery(pCsr->pIndex, zTerm, nTerm, f, 0, &pCsr->pIter);
Fts5Index *pIndex = pCsr->pFts5->pIndex;
rc = sqlite3Fts5IndexQuery(pIndex, zTerm, nTerm, f, 0, &pCsr->pIter);
}
if( rc==SQLITE_OK && eType==FTS5_VOCAB_INSTANCE ){
rc = fts5VocabInstanceNewTerm(pCsr);
}
if( rc==SQLITE_OK
&& !pCsr->bEof
&& (eType!=FTS5_VOCAB_INSTANCE || pCsr->pConfig->eDetail!=FTS5_DETAIL_NONE)
if( rc==SQLITE_OK && !pCsr->bEof
&& (eType!=FTS5_VOCAB_INSTANCE
|| pCsr->pFts5->pConfig->eDetail!=FTS5_DETAIL_NONE)
){
rc = fts5VocabNextMethod(pCursor);
}
@@ -655,7 +664,7 @@ static int fts5VocabColumnMethod(
int iCol /* Index of column to read value from */
){
Fts5VocabCursor *pCsr = (Fts5VocabCursor*)pCursor;
int eDetail = pCsr->pConfig->eDetail;
int eDetail = pCsr->pFts5->pConfig->eDetail;
int eType = ((Fts5VocabTable*)(pCursor->pVtab))->eType;
i64 iVal = 0;
@@ -667,7 +676,7 @@ static int fts5VocabColumnMethod(
assert( iCol==1 || iCol==2 || iCol==3 );
if( iCol==1 ){
if( eDetail!=FTS5_DETAIL_NONE ){
const char *z = pCsr->pConfig->azCol[pCsr->iCol];
const char *z = pCsr->pFts5->pConfig->azCol[pCsr->iCol];
sqlite3_result_text(pCtx, z, -1, SQLITE_STATIC);
}
}else if( iCol==2 ){
@@ -695,8 +704,8 @@ static int fts5VocabColumnMethod(
}else if( eDetail==FTS5_DETAIL_COLUMNS ){
ii = (int)pCsr->iInstPos;
}
if( ii>=0 && ii<pCsr->pConfig->nCol ){
const char *z = pCsr->pConfig->azCol[ii];
if( ii>=0 && ii<pCsr->pFts5->pConfig->nCol ){
const char *z = pCsr->pFts5->pConfig->azCol[ii];
sqlite3_result_text(pCtx, z, -1, SQLITE_STATIC);
}
break;
@@ -755,10 +764,9 @@ int sqlite3Fts5VocabInit(Fts5Global *pGlobal, sqlite3 *db){
/* xSavepoint */ 0,
/* xRelease */ 0,
/* xRollbackTo */ 0,
/* xShadowName */ 0
};
void *p = (void*)pGlobal;
return sqlite3_create_module_v2(db, "fts5vocab", &fts5Vocab, p, 0);
}
+2 -2
View File
@@ -38,8 +38,7 @@ do_execsql_test 1.0 {
do_execsql_test 1.1 {
DROP TABLE t1;
SELECT name, sql FROM sqlite_master;
} {
}
} {}
#-------------------------------------------------------------------------
#
@@ -409,6 +408,7 @@ do_test 14.3 {
do_execsql_test 15.0 {
INSERT INTO t1(t1) VALUES('integrity-check');
}
sqlite3_db_config db DEFENSIVE 0
do_execsql_test 15.1 {
UPDATE t1_content SET c1 = 'xyz xyz xyz xyz xyz abc' WHERE rowid = 1;
}
+6
View File
@@ -51,6 +51,12 @@ do_execsql_test 1.1 {
do_execsql_test 1.2 {
INSERT INTO t1(t1) VALUES('integrity-check');
}
do_execsql_test 1.3 {
SAVEPOINT one;
INSERT INTO t1 VALUES('v w x');
ROLLBACK TO one;
}
}
+8
View File
@@ -144,6 +144,14 @@ do_execsql_test 3.1 {
{[a b c d e]}
}
do_execsql_test 3.2 {
SELECT highlight(ft, 0, NULL, NULL) FROM ft WHERE ft MATCH 'a+b+c AND c+d+e';
} {
{a b c x c d e}
{a b c c d e}
{a b c d e}
}
}
finish_test
+80
View File
@@ -0,0 +1,80 @@
# 2018 Dec 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 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 fts5circref
# If SQLITE_ENABLE_FTS5 is not defined, omit this file.
ifcapable !fts5 {
finish_test
return
}
do_execsql_test 1.0 {
CREATE VIRTUAL TABLE tt USING fts5(a);
SELECT name FROM sqlite_master ORDER BY 1;
} {
tt tt_config tt_content tt_data tt_docsize tt_idx
}
db_save_and_close
foreach {tn schema sql} {
1 {
CREATE TRIGGER tr1 AFTER INSERT ON tt_config BEGIN
SELECT * FROM tt;
END;
} {
INSERT INTO tt(tt, rank) VALUES('usermerge', 4);
}
2 {
CREATE TRIGGER tr1 AFTER INSERT ON tt_docsize BEGIN
SELECT * FROM tt;
END;
} {
INSERT INTO tt(a) VALUES('one two three');
}
3 {
CREATE TRIGGER tr1 AFTER INSERT ON tt_content BEGIN
SELECT * FROM tt;
END;
} {
INSERT INTO tt(a) VALUES('one two three');
}
4 {
CREATE TRIGGER tr1 AFTER INSERT ON tt_data BEGIN
SELECT * FROM tt;
END;
} {
INSERT INTO tt(a) VALUES('one two three');
}
5 {
CREATE TRIGGER tr1 AFTER INSERT ON tt_idx BEGIN
SELECT * FROM tt;
END;
} {
INSERT INTO tt(a) VALUES('one two three');
}
} {
db_restore_and_reopen
do_execsql_test 1.1.$tn.1 $schema
do_catchsql_test 1.1.$tn.2 $sql {1 {SQL logic error}}
db close
}
finish_test
-1
View File
@@ -244,4 +244,3 @@ foreach {tn sql res} {
}
finish_test
+3 -1
View File
@@ -41,6 +41,7 @@ db_save
do_execsql_test 1.2 { INSERT INTO t1(t1) VALUES('integrity-check') }
set segid [lindex [fts5_level_segids t1] 0]
sqlite3_db_config db DEFENSIVE 0
do_test 1.3 {
execsql {
DELETE FROM t1_data WHERE rowid = fts5_rowid('segment', $segid, 4);
@@ -50,6 +51,7 @@ do_test 1.3 {
do_test 1.4 {
db_restore_and_reopen
sqlite3_db_config db DEFENSIVE 0
execsql {
UPDATE t1_data set block = X'00000000' || substr(block, 5) WHERE
rowid = fts5_rowid('segment', $segid, 4);
@@ -89,7 +91,7 @@ do_execsql_test 3.0 {
do_execsql_test 3.1 {
SELECT * FROM t3 WHERE t3 MATCH 'o'
} {{one o} {three o} {five o}}
sqlite3_db_config db DEFENSIVE 0
do_catchsql_test 3.1 {
DELETE FROM t3_content WHERE rowid = 3;
SELECT * FROM t3 WHERE t3 MATCH 'o';
+2
View File
@@ -99,6 +99,7 @@ foreach {tno stmt} {
set lrowid [db one {SELECT max(rowid) FROM t1_data WHERE (rowid & $mask)=0}]
set nbyte [db one {SELECT length(block) FROM t1_data WHERE rowid=$lrowid}]
set all [db eval {SELECT rowid FROM t1}]
sqlite3_db_config db DEFENSIVE 0
for {set i [expr $nbyte-2]} {$i>=0} {incr i -1} {
do_execsql_test 2.$i.1 {
BEGIN;
@@ -248,6 +249,7 @@ foreach {tn hdr} {
#--------------------------------------------------------------------
reset_db
sqlite3_db_config db DEFENSIVE 0
do_execsql_test 6.1 {
CREATE VIRTUAL TABLE x5 USING fts5(tt);
INSERT INTO x5 VALUES('a');
File diff suppressed because one or more lines are too long
-1
View File
@@ -93,4 +93,3 @@ do_catchsql_test 3.3 {
SELECT * FROM x2('^a');
} {1 {fts5: phrase queries are not supported (detail!=full)}}
finish_test
+1
View File
@@ -71,6 +71,7 @@ do_execsql_test 4.1 {
INSERT INTO aa(aa) VALUES('integrity-check');
}
sqlite3_db_config db DEFENSIVE 0
do_catchsql_test 4.2 {
BEGIN;
UPDATE aa_docsize SET sz = X'44' WHERE rowid = 3;
+67
View File
@@ -0,0 +1,67 @@
# 2019 Jan 4
#
# 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 fts5interrupt
# If SQLITE_ENABLE_FTS5 is not defined, omit this file.
ifcapable !fts5 {
finish_test
return
}
do_execsql_test 1.0 {
CREATE VIRTUAL TABLE t1 USING fts5(a);
INSERT INTO t1(t1, rank) VALUES('pgsz', 40);
}
db_save_and_close
proc progress_handler {args} {
incr ::progress_handler_delay -1
if {$::progress_handler_delay<=0} { return 1 }
return 0
}
foreach {tn sql} {
1 { INSERT INTO t1(rowid, a) VALUES(0, 'z z z z') }
2 { COMMIT }
} {
set bDone 0
for {set i 1} {$bDone==0} {incr i} {
do_test 1.$tn.$i {
db_restore_and_reopen
execsql {
BEGIN;
INSERT INTO t1(rowid, a) VALUES(1, 'a b c d');
INSERT INTO t1(rowid, a) VALUES(2, 'd e f g');
INSERT INTO t1(rowid, a) VALUES(3, 'h i j k');
INSERT INTO t1(rowid, a) VALUES(4, 'l m n o');
}
set ::progress_handler_delay $i
db progress 1 progress_handler
set res [catchsql $sql]
db close
if {$res=="0 {}"} {
set bDone 1
} else {
if {$res!="1 interrupted"} { error "got: $res" }
}
set {} {}
} {}
}
}
finish_test
-1
View File
@@ -163,4 +163,3 @@ do_execsql_test 5.1 {
} {30 31 32 33 34 35 36 37 38 39 40}
finish_test
+1
View File
@@ -39,6 +39,7 @@ do_execsql_test 1.4 {
INSERT INTO f1(f1) VALUES('integrity-check');
} {}
sqlite3_db_config db DEFENSIVE 0
do_execsql_test 1.5 {
DELETE FROM f1_data;
} {}
+1
View File
@@ -70,6 +70,7 @@ set res [db one {SELECT count(*) FROM x1_data}]
do_execsql_test 2.3 {
SELECT count(fts5_decode(rowid, block)) FROM x1_data;
} $res
sqlite3_db_config db DEFENSIVE 0
do_execsql_test 2.4 {
UPDATE x1_data SET block = X'';
SELECT count(fts5_decode(rowid, block)) FROM x1_data;
+1 -1
View File
@@ -189,7 +189,7 @@ do_catchsql_test 6.2 {
} {1 {error in tokenizer constructor}}
do_catchsql_test 6.3 {
CREATE VIRTUAL TABLE a3 USING fts5(
x, y, tokenize = 'unicode61 remove_diacritics 2'
x, y, tokenize = 'unicode61 remove_diacritics 3'
);
} {1 {error in tokenizer constructor}}
do_catchsql_test 6.4 {
+65
View File
@@ -0,0 +1,65 @@
# 2014 June 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 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 fts5umlaut
# If SQLITE_ENABLE_FTS5 is not defined, omit this file.
ifcapable !fts5 {
finish_test
return
}
do_execsql_test 1.0 {
CREATE VIRTUAL TABLE t1 USING fts5(x);
CREATE VIRTUAL TABLE t2 USING fts5(
x,
tokenize="unicode61 remove_diacritics 2"
);
}
foreach {tn q res1 res2} {
1 "Hà Nội" 0 1
2 "Hà Noi" 1 1
3 "Ha Noi" 1 1
4 "Ha N\u1ed9i" 0 1
5 "Ha N\u006fi" 1 1
6 "Ha N\u006f\u0302i" 1 1
7 "Ha N\u006f\u0323\u0302i" 1 1
} {
do_execsql_test 1.$tn.1 {
DELETE FROM t1;
INSERT INTO t1(rowid, x) VALUES (1, 'Ha Noi');
SELECT count(*) FROM t1($q)
} $res1
do_execsql_test 1.$tn.2 {
DELETE FROM t1;
INSERT INTO t1(rowid, x) VALUES (1, $q);
SELECT count(*) FROM t1('Ha Noi')
} $res1
do_execsql_test 1.$tn.2 {
DELETE FROM t2;
INSERT INTO t2(rowid, x) VALUES (1, 'Ha Noi');
SELECT count(*) FROM t2($q)
} $res2
do_execsql_test 1.$tn.2 {
DELETE FROM t2;
INSERT INTO t2(rowid, x) VALUES (1, $q);
SELECT count(*) FROM t2('Ha Noi')
} $res2
}
finish_test
+18 -6
View File
@@ -21,7 +21,7 @@ ifcapable !fts5 {
}
proc fts3_unicode_path {file} {
file join [file dirname [info script]] .. .. fts3 unicode $file
file join .. [file dirname [info script]] .. .. fts3 unicode $file
}
source [fts3_unicode_path parseunicode.tcl]
@@ -36,24 +36,26 @@ foreach x [an_load_unicodedata_text $UD] {
}
foreach {y} [rd_load_unicodedata_text $UD] {
foreach {code ascii} $y {}
foreach {code ascii f} $y {}
if {$ascii==""} {
set int 0
} else {
binary scan $ascii c int
}
set aDiacritic($code) $int
set aDiacritic($code,$f) $int
if {$f==0} { set aDiacritic($code,1) $int }
}
proc tcl_fold {i {bRemoveDiacritic 0}} {
global tl_lookup_table
global aDiacritic
set f [expr $bRemoveDiacritic==2]
if {[info exists tl_lookup_table($i)]} {
set i $tl_lookup_table($i)
}
if {$bRemoveDiacritic && [info exists aDiacritic($i)]} {
set i $aDiacritic($i)
if {$bRemoveDiacritic && [info exists aDiacritic($i,$f)]} {
set i $aDiacritic($i,$f)
}
expr $i
}
@@ -85,7 +87,7 @@ do_execsql_test 1.1 {
SELECT count(*), min(i) FROM ii WHERE fts5_fold(i)!=CAST(tcl_fold(i) AS int);
} {0 {}}
do_execsql_test 1.2 {
do_execsql_test 1.2.1 {
WITH ii(i) AS (
SELECT -1
UNION ALL
@@ -95,6 +97,16 @@ do_execsql_test 1.2 {
WHERE fts5_fold(i,1)!=CAST(tcl_fold(i,1) AS int);
} {0 {}}
do_execsql_test 1.2.2 {
WITH ii(i) AS (
SELECT -1
UNION ALL
SELECT i+1 FROM ii WHERE i<100000
)
SELECT count(*), min(i) FROM ii
WHERE fts5_fold(i,2)!=CAST(tcl_fold(i,2) AS int);
} {0 {}}
do_execsql_test 1.3 {
WITH ii(i) AS (
SELECT -1
+38
View File
@@ -115,5 +115,43 @@ do_execsql_test 2.2.integrity {
INSERT INTO x2(x2) VALUES('integrity-check');
}
#-------------------------------------------------------------------------
#
do_execsql_test 3.0 {
CREATE VIRTUAL TABLE x3 USING fts5(x, detail=%DETAIL%);
INSERT INTO x3 VALUES('one');
INSERT INTO x3 VALUES('two');
INSERT INTO x3 VALUES('one');
INSERT INTO x3 VALUES('two');
INSERT INTO x3 VALUES('one');
}
do_test 3.1 {
db eval { SELECT * FROM x3('one') } {
db eval {
INSERT INTO x3(x3) VALUES('optimize');
}
}
} {}
do_execsql_test 4.0 {
CREATE VIRTUAL TABLE x4 USING fts5(a, detail=%DETAIL%);
INSERT INTO x4 VALUES('one two three');
INSERT INTO x4(rowid, a) VALUES('2', 'one two three');
INSERT INTO x4(rowid, a) VALUES('3.0', 'one two three');
}
do_catchsql_test 4.1 {
INSERT INTO x4(rowid, a) VALUES('four', 'one two three');
} {1 {datatype mismatch}}
do_catchsql_test 4.2 {
UPDATE x4 SET rowid = 'four' WHERE rowid=1;
} {1 {datatype mismatch}}
}
reset_db
do_catchsql_test 4.0 { CREATE VIRTUAL TABLE t1 USING fts5(a,b,c); } {0 {}}
do_catchsql_test 4.1 { DELETE FROM t1 WHERE t1 MATCH 'f*'; } {0 {}}
finish_test
+3 -1
View File
@@ -36,9 +36,10 @@ do_execsql_test 1.3 {
SELECT rowid FROM t1 WHERE t1 MATCH 'a';
} {1}
sqlite3_db_config db DEFENSIVE 0
do_execsql_test 1.4 {
UPDATE t1_config set v=5 WHERE k='version';
}
}
do_test 1.5 {
db close
@@ -53,6 +54,7 @@ do_test 1.6 {
} {1 {invalid fts5 file format (found 5, expected 4) - run 'rebuild'}}
do_test 1.7 {
sqlite3_db_config db DEFENSIVE 0
execsql { DELETE FROM t1_config WHERE k='version' }
db close
sqlite3 db test.db
+64 -2
View File
@@ -79,8 +79,8 @@ do_execsql_test 1.1.2 {
3 cnt {} 0 {} 0
}
do_execsql_test 1.2.1 { SELECT * FROM v1 } { }
do_execsql_test 1.2.2 { SELECT * FROM v2 } { }
do_execsql_test 1.2.1 { SELECT * FROM v1 } {}
do_execsql_test 1.2.2 { SELECT * FROM v2 } {}
do_execsql_test 1.3 {
INSERT INTO t1 VALUES('x y z');
@@ -420,6 +420,7 @@ 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
sqlite3_db_config db DEFENSIVE 0
do_execsql_test 8.2 {
PRAGMA writable_schema = 1;
UPDATE sqlite_master
@@ -478,7 +479,68 @@ do_test 9.6 {
expr [lsearch $e2 SorterSort]<0
} 0
#-------------------------------------------------------------------------
do_execsql_test 10.0 {
CREATE VIRTUAL TABLE ft USING fts5(a, b, c);
CREATE VIRTUAL TABLE t2 USING fts5vocab('ft','row');
CREATE VIRTUAL TABLE t3 USING fts5vocab('ft','row');
}
do_execsql_test 10.1 {
BEGIN;
INSERT INTO ft(b) VALUES('x y');
}
do_execsql_test 10.2 {
SELECT t2.term FROM t2;
} {x y}
do_execsql_test 10.3 {
SELECT t2.term, t3.term FROM t2, t3;
} {x x x y y x y y}
do_execsql_test 10.4 {
COMMIT;
}
do_execsql_test 10.5 {
BEGIN;
INSERT INTO ft(a) VALUES('1 2 3');
INSERT INTO ft(a) VALUES('4 5 6');
INSERT INTO ft(a) VALUES('1 2 3');
INSERT INTO ft(a) VALUES('4 5 6');
INSERT INTO ft(a) VALUES('1 2 3');
INSERT INTO ft(a) VALUES('4 5 6');
}
do_test 10.6 {
set res [list]
db eval { SELECT rowid FROM ft('4') } x {
db eval { SELECT * FROM t2 }
lappend res $x(rowid)
}
db eval COMMIT
set res
} {3 5 7}
do_execsql_test 10.6.1 {
SELECT * FROM t2 WHERE term<NULL;
}
do_execsql_test 10.6.2 {
SELECT * FROM t2 WHERE term>NULL;
}
do_execsql_test 10.6.3 {
SELECT * FROM t2 WHERE term=NULL;
}
do_execsql_test 10.7.1 {
SELECT * FROM t2 WHERE term<?;
}
do_execsql_test 10.7.2 {
SELECT * FROM t2 WHERE term>?;
}
do_execsql_test 10.7.3 {
SELECT * FROM t2 WHERE term=?;
}
finish_test
+35 -7
View File
@@ -13,7 +13,7 @@
#
source [file join [file dirname [info script]] fts5_common.tcl]
set testprefix fts5vocab
set testprefix fts5vocab2
# If SQLITE_ENABLE_FTS5 is defined, omit this file.
ifcapable !fts5 {
@@ -80,8 +80,7 @@ do_execsql_test 1.4 {
do_execsql_test 1.5 {
DELETE FROM t1;
SELECT * FROM v1;
} {
}
} {}
#-------------------------------------------------------------------------
#
@@ -143,8 +142,7 @@ do_execsql_test 2.4 {
do_execsql_test 2.5 {
DELETE FROM t1;
SELECT * FROM v1;
} {
}
} {}
#-------------------------------------------------------------------------
#
@@ -202,8 +200,38 @@ do_execsql_test 3.4 {
do_execsql_test 3.5 {
DELETE FROM t1;
SELECT * FROM v1;
} {
} {}
#-------------------------------------------------------------------------
#
reset_db
do_execsql_test 4.0 {
CREATE VIRTUAL TABLE v1 USING fts5vocab(nosuchtable, col);
}
do_catchsql_test 4.1 {
SELECT * FROM v1 WHERE term=='nosuchterm';
} {1 {no such fts5 table: main.nosuchtable}}
do_execsql_test 4.2.1 {
CREATE TABLE nosuchtable(nosuchtable, y, z);
}
do_catchsql_test 4.2.2 {
SELECT * FROM v1 WHERE term=='nosuchterm';
} {1 {no such fts5 table: main.nosuchtable}}
ifcapable fts3 {
do_execsql_test 4.3.1 {
DROP TABLE nosuchtable;
CREATE VIRTUAL TABLE nosuchtable USING fts3(a, b);
} {}
do_catchsql_test 4.3.2 {
SELECT * FROM v1 WHERE term=='nosuchterm';
} {1 {no such fts5 table: main.nosuchtable}}
do_catchsql_test 4.3.3 {
INSERT INTO nosuchtable VALUES('id', '*id');
SELECT * FROM v1 WHERE term=='nosuchterm';
} {1 {no such fts5 table: main.nosuchtable}}
}
finish_test
+7 -6
View File
@@ -619,7 +619,7 @@ static int amatchLoadOneRule(
if( p->rDel==0 || p->rDel>rCost ) p->rDel = rCost;
}else
{
pRule = sqlite3_malloc( sizeof(*pRule) + nFrom + nTo );
pRule = sqlite3_malloc64( sizeof(*pRule) + nFrom + nTo );
if( pRule==0 ){
rc = SQLITE_NOMEM;
}else{
@@ -738,11 +738,11 @@ static int amatchLoadRules(
** `mno` becomes mno
*/
static char *amatchDequote(const char *zIn){
int nIn; /* Size of input string, in bytes */
sqlite3_int64 nIn; /* Size of input string, in bytes */
char *zOut; /* Output (dequoted) string */
nIn = (int)strlen(zIn);
zOut = sqlite3_malloc(nIn+1);
nIn = strlen(zIn);
zOut = sqlite3_malloc64(nIn+1);
if( zOut ){
char q = zIn[0]; /* Quote character (if any ) */
@@ -1069,7 +1069,7 @@ static void amatchAddWord(
}
return;
}
pWord = sqlite3_malloc( sizeof(*pWord) + nBase + nTail - 1 );
pWord = sqlite3_malloc64( sizeof(*pWord) + nBase + nTail - 1 );
if( pWord==0 ) return;
memset(pWord, 0, sizeof(*pWord));
pWord->rCost = rCost;
@@ -1473,7 +1473,8 @@ static sqlite3_module amatchModule = {
0, /* xRename */
0, /* xSavepoint */
0, /* xRelease */
0 /* xRollbackTo */
0, /* xRollbackTo */
0 /* xShadowName */
};
#endif /* SQLITE_OMIT_VIRTUALTABLE */
+1
View File
@@ -411,6 +411,7 @@ int sqlite3BinfoRegister(sqlite3 *db){
0, /* xSavepoint */
0, /* xRelease */
0, /* xRollbackTo */
0 /* xShadowName */
};
return sqlite3_create_module(db, "sqlite_btreeinfo", &binfo_module, 0);
}
+5 -4
View File
@@ -422,11 +422,11 @@ static closure_avl *queuePull(closure_queue *pQueue){
** `mno` becomes mno
*/
static char *closureDequote(const char *zIn){
int nIn; /* Size of input string, in bytes */
sqlite3_int64 nIn; /* Size of input string, in bytes */
char *zOut; /* Output (dequoted) string */
nIn = (int)strlen(zIn);
zOut = sqlite3_malloc(nIn+1);
nIn = strlen(zIn);
zOut = sqlite3_malloc64(nIn+1);
if( zOut ){
char q = zIn[0]; /* Quote character (if any ) */
@@ -938,7 +938,8 @@ static sqlite3_module closureModule = {
0, /* xRename */
0, /* xSavepoint */
0, /* xRelease */
0 /* xRollbackTo */
0, /* xRollbackTo */
0 /* xShadowName */
};
#endif /* SQLITE_OMIT_VIRTUALTABLE */
+2 -1
View File
@@ -468,7 +468,8 @@ static sqlite3_module completionModule = {
0, /* xRename */
0, /* xSavepoint */
0, /* xRelease */
0 /* xRollbackTo */
0, /* xRollbackTo */
0 /* xShadowName */
};
#endif /* SQLITE_OMIT_VIRTUALTABLE */
+96 -35
View File
@@ -19,9 +19,9 @@
** CREATE VIRTUAL TABLE temp.csv USING csv(filename=FILENAME);
** SELECT * FROM csv;
**
** The columns are named "c1", "c2", "c3", ... by default. But the
** application can define its own CREATE TABLE statement as an additional
** parameter. For example:
** The columns are named "c1", "c2", "c3", ... by default. Or the
** application can define its own CREATE TABLE statement using the
** schema= parameter, like this:
**
** CREATE VIRTUAL TABLE temp.csv2 USING csv(
** filename = "../http.log",
@@ -32,9 +32,9 @@
** the data= parameter.
**
** If the columns=N parameter is supplied, then the CSV file is assumed to have
** N columns. If the columns parameter is omitted, the CSV file is opened
** as soon as the virtual table is constructed and the first row of the CSV
** is read in order to count the tables.
** N columns. If both the columns= and schema= parameters are omitted, then
** the number and names of the columns is determined by the first line of
** the CSV input.
**
** Some extra debugging features (used for testing virtual tables) are available
** if this module is compiled with -DSQLITE_TEST.
@@ -436,6 +436,34 @@ static int csv_boolean(const char *z){
return -1;
}
/* Check to see if the string is of the form: "TAG = BOOLEAN" or just "TAG".
** If it is, set *pValue to be the value of the boolean ("true" if there is
** not "= BOOLEAN" component) and return non-zero. If the input string
** does not begin with TAG, return zero.
*/
static int csv_boolean_parameter(
const char *zTag, /* Tag we are looking for */
int nTag, /* Size of the tag in bytes */
const char *z, /* Input parameter */
int *pValue /* Write boolean value here */
){
int b;
z = csv_skip_whitespace(z);
if( strncmp(zTag, z, nTag)!=0 ) return 0;
z = csv_skip_whitespace(z + nTag);
if( z[0]==0 ){
*pValue = 1;
return 1;
}
if( z[0]!='=' ) return 0;
z = csv_skip_whitespace(z+1);
b = csv_boolean(z);
if( b>=0 ){
*pValue = b;
return 1;
}
return 0;
}
/*
** Parameters:
@@ -469,6 +497,7 @@ static int csvtabConnect(
#ifdef SQLITE_TEST
int tstFlags = 0; /* Value for testflags=N parameter */
#endif
int b; /* Value of a boolean parameter */
int nCol = -99; /* Value of the columns= parameter */
CsvReader sRdr; /* A CSV file reader used to store an error
** message and/or to count the number of columns */
@@ -493,21 +522,12 @@ static int csvtabConnect(
if( j<sizeof(azParam)/sizeof(azParam[0]) ){
if( sRdr.zErr[0] ) goto csvtab_connect_error;
}else
if( (zValue = csv_parameter("header",6,z))!=0 ){
int x;
if( csv_boolean_parameter("header",6,z,&b) ){
if( bHeader>=0 ){
csv_errmsg(&sRdr, "more than one 'header' parameter");
goto csvtab_connect_error;
}
x = csv_boolean(zValue);
if( x==1 ){
bHeader = 1;
}else if( x==0 ){
bHeader = 0;
}else{
csv_errmsg(&sRdr, "unrecognized argument to 'header': %s", zValue);
goto csvtab_connect_error;
}
bHeader = b;
}else
#ifdef SQLITE_TEST
if( (zValue = csv_parameter("testflags",9,z))!=0 ){
@@ -521,53 +541,94 @@ static int csvtabConnect(
}
nCol = atoi(zValue);
if( nCol<=0 ){
csv_errmsg(&sRdr, "must have at least one column");
csv_errmsg(&sRdr, "column= value must be positive");
goto csvtab_connect_error;
}
}else
{
csv_errmsg(&sRdr, "unrecognized parameter '%s'", z);
csv_errmsg(&sRdr, "bad parameter: '%s'", z);
goto csvtab_connect_error;
}
}
if( (CSV_FILENAME==0)==(CSV_DATA==0) ){
csv_errmsg(&sRdr, "must either filename= or data= but not both");
csv_errmsg(&sRdr, "must specify either filename= or data= but not both");
goto csvtab_connect_error;
}
if( nCol<=0 && csv_reader_open(&sRdr, CSV_FILENAME, CSV_DATA) ){
if( (nCol<=0 || bHeader==1)
&& csv_reader_open(&sRdr, CSV_FILENAME, CSV_DATA)
){
goto csvtab_connect_error;
}
pNew = sqlite3_malloc( sizeof(*pNew) );
*ppVtab = (sqlite3_vtab*)pNew;
if( pNew==0 ) goto csvtab_connect_oom;
memset(pNew, 0, sizeof(*pNew));
if( nCol>0 ){
if( CSV_SCHEMA==0 ){
sqlite3_str *pStr = sqlite3_str_new(0);
char *zSep = "";
int iCol = 0;
sqlite3_str_appendf(pStr, "CREATE TABLE x(");
if( nCol<0 && bHeader<1 ){
nCol = 0;
do{
csv_read_one_field(&sRdr);
nCol++;
}while( sRdr.cTerm==',' );
}
if( nCol>0 && bHeader<1 ){
for(iCol=0; iCol<nCol; iCol++){
sqlite3_str_appendf(pStr, "%sc%d TEXT", zSep, iCol);
zSep = ",";
}
}else{
do{
char *z = csv_read_one_field(&sRdr);
if( (nCol>0 && iCol<nCol) || (nCol<0 && bHeader) ){
sqlite3_str_appendf(pStr,"%s\"%w\" TEXT", zSep, z);
zSep = ",";
iCol++;
}
}while( sRdr.cTerm==',' );
if( nCol<0 ){
nCol = iCol;
}else{
while( iCol<nCol ){
sqlite3_str_appendf(pStr,"%sc%d TEXT", zSep, ++iCol);
zSep = ",";
}
}
}
pNew->nCol = nCol;
}else{
sqlite3_str_appendf(pStr, ")");
CSV_SCHEMA = sqlite3_str_finish(pStr);
if( CSV_SCHEMA==0 ) goto csvtab_connect_oom;
}else if( nCol<0 ){
do{
csv_read_one_field(&sRdr);
pNew->nCol++;
}while( sRdr.cTerm==',' );
}else{
pNew->nCol = nCol;
}
pNew->zFilename = CSV_FILENAME; CSV_FILENAME = 0;
pNew->zData = CSV_DATA; CSV_DATA = 0;
#ifdef SQLITE_TEST
pNew->tstFlags = tstFlags;
#endif
pNew->iStart = bHeader==1 ? ftell(sRdr.in) : 0;
csv_reader_reset(&sRdr);
if( CSV_SCHEMA==0 ){
char *zSep = "";
CSV_SCHEMA = sqlite3_mprintf("CREATE TABLE x(");
if( CSV_SCHEMA==0 ) goto csvtab_connect_oom;
for(i=0; i<pNew->nCol; i++){
CSV_SCHEMA = sqlite3_mprintf("%z%sc%d TEXT",CSV_SCHEMA, zSep, i);
zSep = ",";
}
CSV_SCHEMA = sqlite3_mprintf("%z);", CSV_SCHEMA);
if( bHeader!=1 ){
pNew->iStart = 0;
}else if( pNew->zData ){
pNew->iStart = (int)sRdr.iIn;
}else{
pNew->iStart = (int)(ftell(sRdr.in) - sRdr.nIn + sRdr.iIn);
}
csv_reader_reset(&sRdr);
rc = sqlite3_declare_vtab(db, CSV_SCHEMA);
if( rc ) goto csvtab_connect_error;
if( rc ){
csv_errmsg(&sRdr, "bad schema: '%s' - %s", CSV_SCHEMA, sqlite3_errmsg(db));
goto csvtab_connect_error;
}
for(i=0; i<sizeof(azPValue)/sizeof(azPValue[0]); i++){
sqlite3_free(azPValue[i]);
}
+1 -1
View File
@@ -195,7 +195,7 @@ static char **tableColumnList(DState *p, const char *zTab){
if( nCol>=nAlloc-2 ){
char **azNew;
nAlloc = nAlloc*2 + nCol + 10;
azNew = sqlite3_realloc(azCol, nAlloc*sizeof(azCol[0]));
azNew = sqlite3_realloc64(azCol, nAlloc*sizeof(azCol[0]));
if( azNew==0 ) goto col_oom;
azCol = azNew;
azCol[0] = 0;
+1 -1
View File
@@ -44,7 +44,7 @@ static int callback(void *pCtx, int argc, char **argv, char **colnames){
/* Using sqlite3_realloc64() would be better, but it is a recent
** addition and will cause a segfault if loaded by an older version
** of SQLite. */
zNew = p->nAlloc<=0x7fffffff ? sqlite3_realloc(p->z, (int)p->nAlloc) : 0;
zNew = p->nAlloc<=0x7fffffff ? sqlite3_realloc64(p->z, p->nAlloc) : 0;
if( zNew==0 ){
sqlite3_free(p->z);
memset(p, 0, sizeof(*p));
+24 -11
View File
@@ -18,6 +18,10 @@
** .load ./explain
** SELECT p2 FROM explain('SELECT * FROM sqlite_master')
** WHERE opcode='OpenRead';
**
** This module was originally written to help simplify SQLite testing,
** by providing an easier means of verifying certain patterns in the
** generated bytecode.
*/
#if !defined(SQLITEINT_H)
#include "sqlite3ext.h"
@@ -232,23 +236,31 @@ static int explainBestIndex(
sqlite3_vtab *tab,
sqlite3_index_info *pIdxInfo
){
int i;
int i; /* Loop counter */
int idx = -1; /* Index of a usable == constraint against SQL */
int unusable = 0; /* True if there are unusable constraints on SQL */
pIdxInfo->estimatedCost = (double)1000000;
pIdxInfo->estimatedRows = 500;
for(i=0; i<pIdxInfo->nConstraint; i++){
struct sqlite3_index_constraint *p = &pIdxInfo->aConstraint[i];
if( p->usable
&& p->iColumn==EXPLN_COLUMN_SQL
&& p->op==SQLITE_INDEX_CONSTRAINT_EQ
){
pIdxInfo->estimatedCost = 10.0;
pIdxInfo->idxNum = 1;
pIdxInfo->aConstraintUsage[i].argvIndex = 1;
pIdxInfo->aConstraintUsage[i].omit = 1;
break;
if( p->iColumn!=EXPLN_COLUMN_SQL ) continue;
if( !p->usable ){
unusable = 1;
}else if( p->op==SQLITE_INDEX_CONSTRAINT_EQ ){
idx = i;
}
}
if( idx>=0 ){
/* There exists a usable == constraint against the SQL column */
pIdxInfo->estimatedCost = 10.0;
pIdxInfo->idxNum = 1;
pIdxInfo->aConstraintUsage[idx].argvIndex = 1;
pIdxInfo->aConstraintUsage[idx].omit = 1;
}else if( unusable ){
/* There are unusable constraints against the SQL column. Do not allow
** this plan to continue forward. */
return SQLITE_CONSTRAINT;
}
return SQLITE_OK;
}
@@ -280,6 +292,7 @@ static sqlite3_module explainModule = {
0, /* xSavepoint */
0, /* xRelease */
0, /* xRollbackTo */
0, /* xShadowName */
};
#endif /* SQLITE_OMIT_VIRTUALTABLE */
+101 -32
View File
@@ -106,26 +106,62 @@ SQLITE_EXTENSION_INIT1
#include <errno.h>
/*
** Structure of the fsdir() table-valued function
*/
/* 0 1 2 3 4 5 */
#define FSDIR_SCHEMA "(name,mode,mtime,data,path HIDDEN,dir HIDDEN)"
#define FSDIR_COLUMN_NAME 0 /* Name of the file */
#define FSDIR_COLUMN_MODE 1 /* Access mode */
#define FSDIR_COLUMN_MTIME 2 /* Last modification time */
#define FSDIR_COLUMN_DATA 3 /* File content */
#define FSDIR_COLUMN_PATH 4 /* Path to top of search */
#define FSDIR_COLUMN_DIR 5 /* Path is relative to this directory */
/*
** Set the result stored by context ctx to a blob containing the
** contents of file zName.
** contents of file zName. Or, leave the result unchanged (NULL)
** if the file does not exist or is unreadable.
**
** If the file exceeds the SQLite blob size limit, through an
** SQLITE_TOOBIG error.
**
** Throw an SQLITE_IOERR if there are difficulties pulling the file
** off of disk.
*/
static void readFileContents(sqlite3_context *ctx, const char *zName){
FILE *in;
long nIn;
sqlite3_int64 nIn;
void *pBuf;
sqlite3 *db;
int mxBlob;
in = fopen(zName, "rb");
if( in==0 ) return;
if( in==0 ){
/* File does not exist or is unreadable. Leave the result set to NULL. */
return;
}
fseek(in, 0, SEEK_END);
nIn = ftell(in);
rewind(in);
pBuf = sqlite3_malloc( nIn );
if( pBuf && 1==fread(pBuf, nIn, 1, in) ){
sqlite3_result_blob(ctx, pBuf, nIn, sqlite3_free);
db = sqlite3_context_db_handle(ctx);
mxBlob = sqlite3_limit(db, SQLITE_LIMIT_LENGTH, -1);
if( nIn>mxBlob ){
sqlite3_result_error_code(ctx, SQLITE_TOOBIG);
fclose(in);
return;
}
pBuf = sqlite3_malloc64( nIn );
if( pBuf==0 ){
sqlite3_result_error_nomem(ctx);
fclose(in);
return;
}
if( 1==fread(pBuf, nIn, 1, in) ){
sqlite3_result_blob64(ctx, pBuf, nIn, sqlite3_free);
}else{
sqlite3_result_error_code(ctx, SQLITE_IOERR);
sqlite3_free(pBuf);
}
fclose(in);
@@ -635,8 +671,8 @@ static int fsdirNext(sqlite3_vtab_cursor *cur){
FsdirLevel *pLvl;
if( iNew>=pCur->nLvl ){
int nNew = iNew+1;
int nByte = nNew*sizeof(FsdirLevel);
FsdirLevel *aNew = (FsdirLevel*)sqlite3_realloc(pCur->aLvl, nByte);
sqlite3_int64 nByte = nNew*sizeof(FsdirLevel);
FsdirLevel *aNew = (FsdirLevel*)sqlite3_realloc64(pCur->aLvl, nByte);
if( aNew==0 ) return SQLITE_NOMEM;
memset(&aNew[pCur->nLvl], 0, sizeof(FsdirLevel)*(nNew-pCur->nLvl));
pCur->aLvl = aNew;
@@ -695,20 +731,20 @@ static int fsdirColumn(
){
fsdir_cursor *pCur = (fsdir_cursor*)cur;
switch( i ){
case 0: { /* name */
case FSDIR_COLUMN_NAME: {
sqlite3_result_text(ctx, &pCur->zPath[pCur->nBase], -1, SQLITE_TRANSIENT);
break;
}
case 1: /* mode */
case FSDIR_COLUMN_MODE:
sqlite3_result_int64(ctx, pCur->sStat.st_mode);
break;
case 2: /* mtime */
case FSDIR_COLUMN_MTIME:
sqlite3_result_int64(ctx, pCur->sStat.st_mtime);
break;
case 3: { /* data */
case FSDIR_COLUMN_DATA: {
mode_t m = pCur->sStat.st_mode;
if( S_ISDIR(m) ){
sqlite3_result_null(ctx);
@@ -716,7 +752,7 @@ static int fsdirColumn(
}else if( S_ISLNK(m) ){
char aStatic[64];
char *aBuf = aStatic;
int nBuf = 64;
sqlite3_int64 nBuf = 64;
int n;
while( 1 ){
@@ -724,7 +760,7 @@ static int fsdirColumn(
if( n<nBuf ) break;
if( aBuf!=aStatic ) sqlite3_free(aBuf);
nBuf = nBuf*2;
aBuf = sqlite3_malloc(nBuf);
aBuf = sqlite3_malloc64(nBuf);
if( aBuf==0 ){
sqlite3_result_error_nomem(ctx);
return SQLITE_NOMEM;
@@ -738,6 +774,12 @@ static int fsdirColumn(
readFileContents(ctx, pCur->zPath);
}
}
case FSDIR_COLUMN_PATH:
default: {
/* The FSDIR_COLUMN_PATH and FSDIR_COLUMN_DIR are input parameters.
** always return their values as NULL */
break;
}
}
return SQLITE_OK;
}
@@ -764,6 +806,9 @@ static int fsdirEof(sqlite3_vtab_cursor *cur){
/*
** xFilter callback.
**
** idxNum==1 PATH parameter only
** idxNum==2 Both PATH and DIR supplied
*/
static int fsdirFilter(
sqlite3_vtab_cursor *cur,
@@ -816,40 +861,63 @@ static int fsdirFilter(
** In this implementation idxNum is used to represent the
** query plan. idxStr is unused.
**
** The query plan is represented by bits in idxNum:
** The query plan is represented by values of idxNum:
**
** (1) start = $value -- constraint exists
** (2) stop = $value -- constraint exists
** (4) step = $value -- constraint exists
** (8) output in descending order
** (1) The path value is supplied by argv[0]
** (2) Path is in argv[0] and dir is in argv[1]
*/
static int fsdirBestIndex(
sqlite3_vtab *tab,
sqlite3_index_info *pIdxInfo
){
int i; /* Loop over constraints */
int idx4 = -1;
int idx5 = -1;
int idxPath = -1; /* Index in pIdxInfo->aConstraint of PATH= */
int idxDir = -1; /* Index in pIdxInfo->aConstraint of DIR= */
int seenPath = 0; /* True if an unusable PATH= constraint is seen */
int seenDir = 0; /* True if an unusable DIR= constraint is seen */
const struct sqlite3_index_constraint *pConstraint;
(void)tab;
pConstraint = pIdxInfo->aConstraint;
for(i=0; i<pIdxInfo->nConstraint; i++, pConstraint++){
if( pConstraint->usable==0 ) continue;
if( pConstraint->op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue;
if( pConstraint->iColumn==4 ) idx4 = i;
if( pConstraint->iColumn==5 ) idx5 = i;
switch( pConstraint->iColumn ){
case FSDIR_COLUMN_PATH: {
if( pConstraint->usable ){
idxPath = i;
seenPath = 0;
}else if( idxPath<0 ){
seenPath = 1;
}
break;
}
case FSDIR_COLUMN_DIR: {
if( pConstraint->usable ){
idxDir = i;
seenDir = 0;
}else if( idxDir<0 ){
seenDir = 1;
}
break;
}
}
}
if( seenPath || seenDir ){
/* If input parameters are unusable, disallow this plan */
return SQLITE_CONSTRAINT;
}
if( idx4<0 ){
if( idxPath<0 ){
pIdxInfo->idxNum = 0;
pIdxInfo->estimatedCost = (double)(((sqlite3_int64)1) << 50);
/* The pIdxInfo->estimatedCost should have been initialized to a huge
** number. Leave it unchanged. */
pIdxInfo->estimatedRows = 0x7fffffff;
}else{
pIdxInfo->aConstraintUsage[idx4].omit = 1;
pIdxInfo->aConstraintUsage[idx4].argvIndex = 1;
if( idx5>=0 ){
pIdxInfo->aConstraintUsage[idx5].omit = 1;
pIdxInfo->aConstraintUsage[idx5].argvIndex = 2;
pIdxInfo->aConstraintUsage[idxPath].omit = 1;
pIdxInfo->aConstraintUsage[idxPath].argvIndex = 1;
if( idxDir>=0 ){
pIdxInfo->aConstraintUsage[idxDir].omit = 1;
pIdxInfo->aConstraintUsage[idxDir].argvIndex = 2;
pIdxInfo->idxNum = 2;
pIdxInfo->estimatedCost = 10.0;
}else{
@@ -888,7 +956,8 @@ static int fsdirRegister(sqlite3 *db){
0, /* xRename */
0, /* xSavepoint */
0, /* xRelease */
0 /* xRollbackTo */
0, /* xRollbackTo */
0, /* xShadowName */
};
int rc = sqlite3_create_module(db, "fsdir", &fsdirModule, 0);
File diff suppressed because it is too large Load Diff
+8 -8
View File
@@ -337,7 +337,7 @@ static int fuzzerLoadOneRule(
rc = SQLITE_ERROR;
}else{
pRule = sqlite3_malloc( sizeof(*pRule) + nFrom + nTo );
pRule = sqlite3_malloc64( sizeof(*pRule) + nFrom + nTo );
if( pRule==0 ){
rc = SQLITE_NOMEM;
}else{
@@ -447,11 +447,11 @@ static int fuzzerLoadRules(
** `mno` becomes mno
*/
static char *fuzzerDequote(const char *zIn){
int nIn; /* Size of input string, in bytes */
sqlite3_int64 nIn; /* Size of input string, in bytes */
char *zOut; /* Output (dequoted) string */
nIn = (int)strlen(zIn);
zOut = sqlite3_malloc(nIn+1);
nIn = strlen(zIn);
zOut = sqlite3_malloc64(nIn+1);
if( zOut ){
char q = zIn[0]; /* Quote character (if any ) */
@@ -513,10 +513,10 @@ static int fuzzerConnect(
);
rc = SQLITE_ERROR;
}else{
int nModule; /* Length of zModule, in bytes */
sqlite3_int64 nModule; /* Length of zModule, in bytes */
nModule = (int)strlen(zModule);
pNew = sqlite3_malloc( sizeof(*pNew) + nModule + 1);
nModule = strlen(zModule);
pNew = sqlite3_malloc64( sizeof(*pNew) + nModule + 1);
if( pNew==0 ){
rc = SQLITE_NOMEM;
}else{
@@ -872,7 +872,7 @@ static fuzzer_stem *fuzzerNewStem(
fuzzer_rule *pRule;
unsigned int h;
pNew = sqlite3_malloc( sizeof(*pNew) + (int)strlen(zWord) + 1 );
pNew = sqlite3_malloc64( sizeof(*pNew) + strlen(zWord) + 1 );
if( pNew==0 ) return 0;
memset(pNew, 0, sizeof(*pNew));
pNew->zBasis = (char*)&pNew[1];
+47 -23
View File
@@ -691,7 +691,7 @@ static JSON_NOINLINE int jsonParseAddNodeExpand(
assert( pParse->nNode>=pParse->nAlloc );
if( pParse->oom ) return -1;
nNew = pParse->nAlloc*2 + 10;
pNew = sqlite3_realloc(pParse->aNode, sizeof(JsonNode)*nNew);
pNew = sqlite3_realloc64(pParse->aNode, sizeof(JsonNode)*nNew);
if( pNew==0 ){
pParse->oom = 1;
return -1;
@@ -965,7 +965,7 @@ static void jsonParseFillInParentage(JsonParse *pParse, u32 i, u32 iParent){
static int jsonParseFindParents(JsonParse *pParse){
u32 *aUp;
assert( pParse->aUp==0 );
aUp = pParse->aUp = sqlite3_malloc( sizeof(u32)*pParse->nNode );
aUp = pParse->aUp = sqlite3_malloc64( sizeof(u32)*pParse->nNode );
if( aUp==0 ){
pParse->oom = 1;
return SQLITE_NOMEM;
@@ -1027,7 +1027,7 @@ static JsonParse *jsonParseCached(
pMatch->iHold = iMaxHold+1;
return pMatch;
}
p = sqlite3_malloc( sizeof(*p) + nJson + 1 );
p = sqlite3_malloc64( sizeof(*p) + nJson + 1 );
if( p==0 ){
sqlite3_result_error_nomem(pCtx);
return 0;
@@ -1994,6 +1994,9 @@ static int jsonEachConnect(
#define JEACH_PARENT 5
#define JEACH_FULLKEY 6
#define JEACH_PATH 7
/* The xBestIndex method assumes that the JSON and ROOT columns are
** the last two columns in the table. Should this ever changes, be
** sure to update the xBestIndex method. */
#define JEACH_JSON 8
#define JEACH_ROOT 9
@@ -2251,35 +2254,54 @@ static int jsonEachBestIndex(
sqlite3_vtab *tab,
sqlite3_index_info *pIdxInfo
){
int i;
int jsonIdx = -1;
int rootIdx = -1;
int i; /* Loop counter or computed array index */
int aIdx[2]; /* Index of constraints for JSON and ROOT */
int unusableMask = 0; /* Mask of unusable JSON and ROOT constraints */
int idxMask = 0; /* Mask of usable == constraints JSON and ROOT */
const struct sqlite3_index_constraint *pConstraint;
/* This implementation assumes that JSON and ROOT are the last two
** columns in the table */
assert( JEACH_ROOT == JEACH_JSON+1 );
UNUSED_PARAM(tab);
aIdx[0] = aIdx[1] = -1;
pConstraint = pIdxInfo->aConstraint;
for(i=0; i<pIdxInfo->nConstraint; i++, pConstraint++){
if( pConstraint->usable==0 ) continue;
if( pConstraint->op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue;
switch( pConstraint->iColumn ){
case JEACH_JSON: jsonIdx = i; break;
case JEACH_ROOT: rootIdx = i; break;
default: /* no-op */ break;
int iCol;
int iMask;
if( pConstraint->iColumn < JEACH_JSON ) continue;
iCol = pConstraint->iColumn - JEACH_JSON;
assert( iCol==0 || iCol==1 );
iMask = 1 << iCol;
if( pConstraint->usable==0 ){
unusableMask |= iMask;
}else if( pConstraint->op==SQLITE_INDEX_CONSTRAINT_EQ ){
aIdx[iCol] = i;
idxMask |= iMask;
}
}
if( jsonIdx<0 ){
if( (unusableMask & ~idxMask)!=0 ){
/* If there are any unusable constraints on JSON or ROOT, then reject
** this entire plan */
return SQLITE_CONSTRAINT;
}
if( aIdx[0]<0 ){
/* No JSON input. Leave estimatedCost at the huge value that it was
** initialized to to discourage the query planner from selecting this
** plan. */
pIdxInfo->idxNum = 0;
pIdxInfo->estimatedCost = 1e99;
}else{
pIdxInfo->estimatedCost = 1.0;
pIdxInfo->aConstraintUsage[jsonIdx].argvIndex = 1;
pIdxInfo->aConstraintUsage[jsonIdx].omit = 1;
if( rootIdx<0 ){
pIdxInfo->idxNum = 1;
i = aIdx[0];
pIdxInfo->aConstraintUsage[i].argvIndex = 1;
pIdxInfo->aConstraintUsage[i].omit = 1;
if( aIdx[1]<0 ){
pIdxInfo->idxNum = 1; /* Only JSON supplied. Plan 1 */
}else{
pIdxInfo->aConstraintUsage[rootIdx].argvIndex = 2;
pIdxInfo->aConstraintUsage[rootIdx].omit = 1;
pIdxInfo->idxNum = 3;
i = aIdx[1];
pIdxInfo->aConstraintUsage[i].argvIndex = 2;
pIdxInfo->aConstraintUsage[i].omit = 1;
pIdxInfo->idxNum = 3; /* Both JSON and ROOT are supplied. Plan 3 */
}
}
return SQLITE_OK;
@@ -2388,7 +2410,8 @@ static sqlite3_module jsonEachModule = {
0, /* xRename */
0, /* xSavepoint */
0, /* xRelease */
0 /* xRollbackTo */
0, /* xRollbackTo */
0 /* xShadowName */
};
/* The methods of the json_tree virtual table. */
@@ -2415,7 +2438,8 @@ static sqlite3_module jsonTreeModule = {
0, /* xRename */
0, /* xSavepoint */
0, /* xRelease */
0 /* xRollbackTo */
0, /* xRollbackTo */
0 /* xShadowName */
};
#endif /* SQLITE_OMIT_VIRTUALTABLE */
+2 -1
View File
@@ -143,7 +143,7 @@ static int memstatFindSchemas(memstat_cursor *pCur){
}
while( sqlite3_step(pStmt)==SQLITE_ROW ){
char **az, *z;
az = sqlite3_realloc(pCur->azDb, sizeof(char*)*(pCur->nDb+1));
az = sqlite3_realloc64(pCur->azDb, sizeof(char*)*(pCur->nDb+1));
if( az==0 ){
memstatClearSchema(pCur);
return SQLITE_NOMEM;
@@ -395,6 +395,7 @@ static sqlite3_module memstatModule = {
0, /* xSavepoint */
0, /* xRelease */
0, /* xRollbackTo */
0, /* xShadowName */
};
#endif /* SQLITE_OMIT_VIRTUALTABLE */
+108
View File
@@ -0,0 +1,108 @@
/*
** 2019-01-21
**
** 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 an extension that uses the SQLITE_CONFIG_MALLOC
** mechanism to add a tracing layer on top of SQLite. If this extension
** is registered prior to sqlite3_initialize(), it will cause all memory
** allocation activities to be logged on standard output, or to some other
** FILE specified by the initializer.
**
** This file needs to be compiled into the application that uses it.
**
** This extension is used to implement the --memtrace option of the
** command-line shell.
*/
#include <assert.h>
#include <string.h>
#include <stdio.h>
/* The original memory allocation routines */
static sqlite3_mem_methods memtraceBase;
static FILE *memtraceOut;
/* Methods that trace memory allocations */
static void *memtraceMalloc(int n){
if( memtraceOut ){
fprintf(memtraceOut, "MEMTRACE: allocate %d bytes\n",
memtraceBase.xRoundup(n));
}
return memtraceBase.xMalloc(n);
}
static void memtraceFree(void *p){
if( p==0 ) return;
if( memtraceOut ){
fprintf(memtraceOut, "MEMTRACE: free %d bytes\n", memtraceBase.xSize(p));
}
memtraceBase.xFree(p);
}
static void *memtraceRealloc(void *p, int n){
if( p==0 ) return memtraceMalloc(n);
if( n==0 ){
memtraceFree(p);
return 0;
}
if( memtraceOut ){
fprintf(memtraceOut, "MEMTRACE: resize %d -> %d bytes\n",
memtraceBase.xSize(p), memtraceBase.xRoundup(n));
}
return memtraceBase.xRealloc(p, n);
}
static int memtraceSize(void *p){
return memtraceBase.xSize(p);
}
static int memtraceRoundup(int n){
return memtraceBase.xRoundup(n);
}
static int memtraceInit(void *p){
return memtraceBase.xInit(p);
}
static void memtraceShutdown(void *p){
memtraceBase.xShutdown(p);
}
/* The substitute memory allocator */
static sqlite3_mem_methods ersaztMethods = {
memtraceMalloc,
memtraceFree,
memtraceRealloc,
memtraceSize,
memtraceRoundup,
memtraceInit,
memtraceShutdown,
0
};
/* Begin tracing memory allocations to out. */
int sqlite3MemTraceActivate(FILE *out){
int rc = SQLITE_OK;
if( memtraceBase.xMalloc==0 ){
rc = sqlite3_config(SQLITE_CONFIG_GETMALLOC, &memtraceBase);
if( rc==SQLITE_OK ){
rc = sqlite3_config(SQLITE_CONFIG_MALLOC, &ersaztMethods);
}
}
memtraceOut = out;
return rc;
}
/* Deactivate memory tracing */
int sqlite3MemTraceDeactivate(void){
int rc = SQLITE_OK;
if( memtraceBase.xMalloc!=0 ){
rc = sqlite3_config(SQLITE_CONFIG_MALLOC, &memtraceBase);
if( rc==SQLITE_OK ){
memset(&memtraceBase, 0, sizeof(memtraceBase));
}
}
memtraceOut = 0;
return rc;
}
-1
View File
@@ -105,4 +105,3 @@ int sqlite3_mmap_warm(sqlite3 *db, const char *zDb){
return rc;
}
+2 -2
View File
@@ -85,7 +85,7 @@ static void nextCharAppend(nextCharContext *p, unsigned c){
if( p->nUsed+1 > p->nAlloc ){
unsigned int *aNew;
int n = p->nAlloc*2 + 30;
aNew = sqlite3_realloc(p->aResult, n*sizeof(unsigned int));
aNew = sqlite3_realloc64(p->aResult, n*sizeof(unsigned int));
if( aNew==0 ){
p->mallocFailed = 1;
return;
@@ -269,7 +269,7 @@ static void nextCharFunc(
sqlite3_result_error_nomem(context);
}else{
unsigned char *pRes;
pRes = sqlite3_malloc( c.nUsed*4 + 1 );
pRes = sqlite3_malloc64( c.nUsed*4 + 1 );
if( pRes==0 ){
sqlite3_result_error_nomem(context);
}else{
+1 -1
View File
@@ -151,7 +151,7 @@ static void percentStep(sqlite3_context *pCtx, int argc, sqlite3_value **argv){
/* Allocate and store the Y */
if( p->nUsed>=p->nAlloc ){
unsigned n = p->nAlloc*2 + 250;
double *a = sqlite3_realloc(p->a, sizeof(double)*n);
double *a = sqlite3_realloc64(p->a, sizeof(double)*n);
if( a==0 ){
sqlite3_free(p->a);
memset(p, 0, sizeof(*p));
+319
View File
@@ -0,0 +1,319 @@
/*
** 2018-04-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 a table-valued function:
**
** prefixes('abcdefg')
**
** The function has a single (non-HIDDEN) column named prefix that takes
** on all prefixes of the string in its argument, including an empty string
** and the input string itself. The order of prefixes is from longest
** to shortest.
*/
#if !defined(SQLITE_CORE) || !defined(SQLITE_OMIT_VIRTUALTABLE)
#if !defined(SQLITEINT_H)
#include "sqlite3ext.h"
#endif
SQLITE_EXTENSION_INIT1
#include <string.h>
#include <assert.h>
/* prefixes_vtab is a subclass of sqlite3_vtab which is
** underlying representation of the virtual table
*/
typedef struct prefixes_vtab prefixes_vtab;
struct prefixes_vtab {
sqlite3_vtab base; /* Base class - must be first */
/* No additional fields are necessary */
};
/* prefixes_cursor is a subclass of sqlite3_vtab_cursor which will
** serve as the underlying representation of a cursor that scans
** over rows of the result
*/
typedef struct prefixes_cursor prefixes_cursor;
struct prefixes_cursor {
sqlite3_vtab_cursor base; /* Base class - must be first */
sqlite3_int64 iRowid; /* The rowid */
char *zStr; /* Original string to be prefixed */
int nStr; /* Length of the string in bytes */
};
/*
** The prefixesConnect() method is invoked to create a new
** template virtual table.
**
** Think of this routine as the constructor for prefixes_vtab objects.
**
** All this routine needs to do is:
**
** (1) Allocate the prefixes_vtab object and initialize all fields.
**
** (2) Tell SQLite (via the sqlite3_declare_vtab() interface) what the
** result set of queries against the virtual table will look like.
*/
static int prefixesConnect(
sqlite3 *db,
void *pAux,
int argc, const char *const*argv,
sqlite3_vtab **ppVtab,
char **pzErr
){
prefixes_vtab *pNew;
int rc;
rc = sqlite3_declare_vtab(db,
"CREATE TABLE prefixes(prefix TEXT, original_string TEXT HIDDEN)"
);
if( rc==SQLITE_OK ){
pNew = sqlite3_malloc( sizeof(*pNew) );
*ppVtab = (sqlite3_vtab*)pNew;
if( pNew==0 ) return SQLITE_NOMEM;
memset(pNew, 0, sizeof(*pNew));
}
return rc;
}
/*
** This method is the destructor for prefixes_vtab objects.
*/
static int prefixesDisconnect(sqlite3_vtab *pVtab){
prefixes_vtab *p = (prefixes_vtab*)pVtab;
sqlite3_free(p);
return SQLITE_OK;
}
/*
** Constructor for a new prefixes_cursor object.
*/
static int prefixesOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
prefixes_cursor *pCur;
pCur = sqlite3_malloc( sizeof(*pCur) );
if( pCur==0 ) return SQLITE_NOMEM;
memset(pCur, 0, sizeof(*pCur));
*ppCursor = &pCur->base;
return SQLITE_OK;
}
/*
** Destructor for a prefixes_cursor.
*/
static int prefixesClose(sqlite3_vtab_cursor *cur){
prefixes_cursor *pCur = (prefixes_cursor*)cur;
sqlite3_free(pCur->zStr);
sqlite3_free(pCur);
return SQLITE_OK;
}
/*
** Advance a prefixes_cursor to its next row of output.
*/
static int prefixesNext(sqlite3_vtab_cursor *cur){
prefixes_cursor *pCur = (prefixes_cursor*)cur;
pCur->iRowid++;
return SQLITE_OK;
}
/*
** Return values of columns for the row at which the prefixes_cursor
** is currently pointing.
*/
static int prefixesColumn(
sqlite3_vtab_cursor *cur, /* The cursor */
sqlite3_context *ctx, /* First argument to sqlite3_result_...() */
int i /* Which column to return */
){
prefixes_cursor *pCur = (prefixes_cursor*)cur;
switch( i ){
case 0:
sqlite3_result_text(ctx, pCur->zStr, pCur->nStr - (int)pCur->iRowid,
0);
break;
default:
sqlite3_result_text(ctx, pCur->zStr, pCur->nStr, 0);
break;
}
return SQLITE_OK;
}
/*
** Return the rowid for the current row. In this implementation, the
** rowid is the same as the output value.
*/
static int prefixesRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
prefixes_cursor *pCur = (prefixes_cursor*)cur;
*pRowid = pCur->iRowid;
return SQLITE_OK;
}
/*
** Return TRUE if the cursor has been moved off of the last
** row of output.
*/
static int prefixesEof(sqlite3_vtab_cursor *cur){
prefixes_cursor *pCur = (prefixes_cursor*)cur;
return pCur->iRowid>pCur->nStr;
}
/*
** This method is called to "rewind" the prefixes_cursor object back
** to the first row of output. This method is always called at least
** once prior to any call to prefixesColumn() or prefixesRowid() or
** prefixesEof().
*/
static int prefixesFilter(
sqlite3_vtab_cursor *pVtabCursor,
int idxNum, const char *idxStr,
int argc, sqlite3_value **argv
){
prefixes_cursor *pCur = (prefixes_cursor *)pVtabCursor;
sqlite3_free(pCur->zStr);
if( argc>0 ){
pCur->zStr = sqlite3_mprintf("%s", sqlite3_value_text(argv[0]));
pCur->nStr = pCur->zStr ? (int)strlen(pCur->zStr) : 0;
}else{
pCur->zStr = 0;
pCur->nStr = 0;
}
pCur->iRowid = 0;
return SQLITE_OK;
}
/*
** SQLite will invoke this method one or more times while planning a query
** that uses the virtual table. This routine needs to create
** a query plan for each invocation and compute an estimated cost for that
** plan.
*/
static int prefixesBestIndex(
sqlite3_vtab *tab,
sqlite3_index_info *pIdxInfo
){
/* Search for a usable equality constraint against column 1
** (original_string) and use it if at all possible */
int i;
const struct sqlite3_index_constraint *p;
for(i=0, p=pIdxInfo->aConstraint; i<pIdxInfo->nConstraint; i++, p++){
if( p->iColumn!=1 ) continue;
if( p->op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue;
if( !p->usable ) continue;
pIdxInfo->aConstraintUsage[i].argvIndex = 1;
pIdxInfo->aConstraintUsage[i].omit = 1;
pIdxInfo->estimatedCost = (double)10;
pIdxInfo->estimatedRows = 10;
return SQLITE_OK;
}
pIdxInfo->estimatedCost = (double)1000000000;
pIdxInfo->estimatedRows = 1000000000;
return SQLITE_OK;
}
/*
** This following structure defines all the methods for the
** virtual table.
*/
static sqlite3_module prefixesModule = {
/* iVersion */ 0,
/* xCreate */ 0,
/* xConnect */ prefixesConnect,
/* xBestIndex */ prefixesBestIndex,
/* xDisconnect */ prefixesDisconnect,
/* xDestroy */ 0,
/* xOpen */ prefixesOpen,
/* xClose */ prefixesClose,
/* xFilter */ prefixesFilter,
/* xNext */ prefixesNext,
/* xEof */ prefixesEof,
/* xColumn */ prefixesColumn,
/* xRowid */ prefixesRowid,
/* xUpdate */ 0,
/* xBegin */ 0,
/* xSync */ 0,
/* xCommit */ 0,
/* xRollback */ 0,
/* xFindMethod */ 0,
/* xRename */ 0,
/* xSavepoint */ 0,
/* xRelease */ 0,
/* xRollbackTo */ 0,
/* xShadowName */ 0
};
/*
** This is a copy of the SQLITE_SKIP_UTF8(zIn) macro in sqliteInt.h.
**
** Assuming zIn points to the first byte of a UTF-8 character,
** advance zIn to point to the first byte of the next UTF-8 character.
*/
#define PREFIX_SKIP_UTF8(zIn) { \
if( (*(zIn++))>=0xc0 ){ \
while( (*zIn & 0xc0)==0x80 ){ zIn++; } \
} \
}
/*
** Implementation of function prefix_length(). This function accepts two
** strings as arguments and returns the length in characters (not bytes),
** of the longest prefix shared by the two strings. For example:
**
** prefix_length('abcdxxx', 'abcyy') == 3
** prefix_length('abcdxxx', 'bcyyy') == 0
** prefix_length('abcdxxx', 'ab') == 2
** prefix_length('ab', 'abcd') == 2
**
** This function assumes the input is well-formed utf-8. If it is not,
** it is possible for this function to return -1.
*/
static void prefixLengthFunc(
sqlite3_context *ctx,
int nVal,
sqlite3_value **apVal
){
int nByte; /* Number of bytes to compare */
int nRet = 0; /* Return value */
const unsigned char *zL = sqlite3_value_text(apVal[0]);
const unsigned char *zR = sqlite3_value_text(apVal[1]);
int nL = sqlite3_value_bytes(apVal[0]);
int nR = sqlite3_value_bytes(apVal[1]);
int i;
nByte = (nL > nR ? nL : nR);
for(i=0; i<nByte; i++){
if( zL[i]!=zR[i] ) break;
if( (zL[i] & 0xC0)!=0x80 ) nRet++;
}
if( (zL[i] & 0xC0)==0x80 ) nRet--;
sqlite3_result_int(ctx, nRet);
}
#ifdef _WIN32
__declspec(dllexport)
#endif
int sqlite3_prefixes_init(
sqlite3 *db,
char **pzErrMsg,
const sqlite3_api_routines *pApi
){
int rc = SQLITE_OK;
SQLITE_EXTENSION_INIT2(pApi);
rc = sqlite3_create_module(db, "prefixes", &prefixesModule, 0);
if( rc==SQLITE_OK ){
rc = sqlite3_create_function(
db, "prefix_length", 2, SQLITE_UTF8, 0, prefixLengthFunc, 0, 0
);
}
return rc;
}
#endif /* !defined(SQLITE_CORE) || !defined(SQLITE_OMIT_VIRTUALTABLE) */
+3 -3
View File
@@ -225,7 +225,7 @@ static int re_match(ReCompiled *pRe, const unsigned char *zIn, int nIn){
pToFree = 0;
aStateSet[0].aState = aSpace;
}else{
pToFree = sqlite3_malloc( sizeof(ReStateNumber)*2*pRe->nState );
pToFree = sqlite3_malloc64( sizeof(ReStateNumber)*2*pRe->nState );
if( pToFree==0 ) return -1;
aStateSet[0].aState = pToFree;
}
@@ -337,10 +337,10 @@ re_match_end:
static int re_resize(ReCompiled *p, int N){
char *aOp;
int *aArg;
aOp = sqlite3_realloc(p->aOp, N*sizeof(p->aOp[0]));
aOp = sqlite3_realloc64(p->aOp, N*sizeof(p->aOp[0]));
if( aOp==0 ) return 1;
p->aOp = aOp;
aArg = sqlite3_realloc(p->aArg, N*sizeof(p->aArg[0]));
aArg = sqlite3_realloc64(p->aArg, N*sizeof(p->aArg[0]));
if( aArg==0 ) return 1;
p->aArg = aArg;
p->nAlloc = N;
+31 -31
View File
@@ -313,44 +313,45 @@ static int seriesBestIndex(
sqlite3_vtab *tab,
sqlite3_index_info *pIdxInfo
){
int i; /* Loop over constraints */
int i, j; /* Loop over constraints */
int idxNum = 0; /* The query plan bitmask */
int startIdx = -1; /* Index of the start= constraint, or -1 if none */
int stopIdx = -1; /* Index of the stop= constraint, or -1 if none */
int stepIdx = -1; /* Index of the step= constraint, or -1 if none */
int unusableMask = 0; /* Mask of unusable constraints */
int nArg = 0; /* Number of arguments that seriesFilter() expects */
int aIdx[3]; /* Constraints on start, stop, and step */
const struct sqlite3_index_constraint *pConstraint;
/* This implementation assumes that the start, stop, and step columns
** are the last three columns in the virtual table. */
assert( SERIES_COLUMN_STOP == SERIES_COLUMN_START+1 );
assert( SERIES_COLUMN_STEP == SERIES_COLUMN_START+2 );
aIdx[0] = aIdx[1] = aIdx[2] = -1;
pConstraint = pIdxInfo->aConstraint;
for(i=0; i<pIdxInfo->nConstraint; i++, pConstraint++){
if( pConstraint->usable==0 ) continue;
if( pConstraint->op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue;
switch( pConstraint->iColumn ){
case SERIES_COLUMN_START:
startIdx = i;
idxNum |= 1;
break;
case SERIES_COLUMN_STOP:
stopIdx = i;
idxNum |= 2;
break;
case SERIES_COLUMN_STEP:
stepIdx = i;
idxNum |= 4;
break;
int iCol; /* 0 for start, 1 for stop, 2 for step */
int iMask; /* bitmask for those column */
if( pConstraint->iColumn<SERIES_COLUMN_START ) continue;
iCol = pConstraint->iColumn - SERIES_COLUMN_START;
assert( iCol>=0 && iCol<=2 );
iMask = 1 << iCol;
if( pConstraint->usable==0 ){
unusableMask |= iMask;
continue;
}else if( pConstraint->op==SQLITE_INDEX_CONSTRAINT_EQ ){
idxNum |= iMask;
aIdx[iCol] = i;
}
}
if( startIdx>=0 ){
pIdxInfo->aConstraintUsage[startIdx].argvIndex = ++nArg;
pIdxInfo->aConstraintUsage[startIdx].omit= !SQLITE_SERIES_CONSTRAINT_VERIFY;
for(i=0; i<3; i++){
if( (j = aIdx[i])>=0 ){
pIdxInfo->aConstraintUsage[j].argvIndex = ++nArg;
pIdxInfo->aConstraintUsage[j].omit = !SQLITE_SERIES_CONSTRAINT_VERIFY;
}
}
if( stopIdx>=0 ){
pIdxInfo->aConstraintUsage[stopIdx].argvIndex = ++nArg;
pIdxInfo->aConstraintUsage[stopIdx].omit = !SQLITE_SERIES_CONSTRAINT_VERIFY;
}
if( stepIdx>=0 ){
pIdxInfo->aConstraintUsage[stepIdx].argvIndex = ++nArg;
pIdxInfo->aConstraintUsage[stepIdx].omit = !SQLITE_SERIES_CONSTRAINT_VERIFY;
if( (unusableMask & ~idxNum)!=0 ){
/* The start, stop, and step columns are inputs. Therefore if there
** are unusable constraints on any of start, stop, or step then
** this plan is unusable */
return SQLITE_CONSTRAINT;
}
if( (idxNum & 3)==3 ){
/* Both start= and stop= boundaries are available. This is the
@@ -365,7 +366,6 @@ static int seriesBestIndex(
/* If either boundary is missing, we have to generate a huge span
** of numbers. Make this case very expensive so that the query
** planner will work hard to avoid it. */
pIdxInfo->estimatedCost = (double)2147483647;
pIdxInfo->estimatedRows = 2147483647;
}
pIdxInfo->idxNum = idxNum;
+1
View File
@@ -266,6 +266,7 @@ static sqlite3_module stmtModule = {
0, /* xSavepoint */
0, /* xRelease */
0, /* xRollbackTo */
0, /* xShadowName */
};
#endif /* SQLITE_OMIT_VIRTUALTABLE */
+2 -1
View File
@@ -248,7 +248,8 @@ static sqlite3_module templatevtabModule = {
/* xRename */ 0,
/* xSavepoint */ 0,
/* xRelease */ 0,
/* xRollbackTo */ 0
/* xRollbackTo */ 0,
/* xShadowName */ 0
};
+6 -5
View File
@@ -250,11 +250,11 @@ struct UnionCsr {
** is attempted but fails, NULL is returned and *pRc is set to
** SQLITE_NOMEM.
*/
static void *unionMalloc(int *pRc, int nByte){
static void *unionMalloc(int *pRc, sqlite3_int64 nByte){
void *pRet;
assert( nByte>0 );
if( *pRc==SQLITE_OK ){
pRet = sqlite3_malloc(nByte);
pRet = sqlite3_malloc64(nByte);
if( pRet ){
memset(pRet, 0, nByte);
}else{
@@ -276,7 +276,7 @@ static void *unionMalloc(int *pRc, int nByte){
static char *unionStrdup(int *pRc, const char *zIn){
char *zRet = 0;
if( zIn ){
int nByte = (int)strlen(zIn) + 1;
sqlite3_int64 nByte = strlen(zIn) + 1;
zRet = unionMalloc(pRc, nByte);
if( zRet ){
memcpy(zRet, zIn, nByte);
@@ -939,7 +939,7 @@ static int unionConnect(
/* Grow the pTab->aSrc[] array if required. */
if( nAlloc<=pTab->nSrc ){
int nNew = nAlloc ? nAlloc*2 : 8;
UnionSrc *aNew = (UnionSrc*)sqlite3_realloc(
UnionSrc *aNew = (UnionSrc*)sqlite3_realloc64(
pTab->aSrc, nNew*sizeof(UnionSrc)
);
if( aNew==0 ){
@@ -1350,7 +1350,8 @@ static int createUnionVtab(sqlite3 *db){
0, /* xRename */
0, /* xSavepoint */
0, /* xRelease */
0 /* xRollbackTo */
0, /* xRollbackTo */
0 /* xShadowName */
};
int rc;
+1 -1
View File
@@ -276,7 +276,7 @@ static VLogLog *vlogLogOpen(const char *zFilename){
&& sqlite3_strglob("-mj??????9??", zFilename+nName-12)==0 ){
return 0; /* Do not log master journal files */
}
pTemp = sqlite3_malloc( sizeof(*pLog)*2 + nName + 60 );
pTemp = sqlite3_malloc64( sizeof(*pLog)*2 + nName + 60 );
if( pTemp==0 ) return 0;
pMutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER);
sqlite3_mutex_enter(pMutex);
+6 -3
View File
@@ -783,8 +783,8 @@ static sqlite3_module VfsStatModule = {
*/
static int vstatRegister(
sqlite3 *db,
const char **pzErrMsg,
const struct sqlite3_api_routines *pThunk
char **pzErrMsg,
const sqlite3_api_routines *pThunk
){
return sqlite3_create_module(db, "vfsstat", &VfsStatModule, 0);
}
@@ -809,7 +809,10 @@ int sqlite3_vfsstat_init(
vstat_vfs.base.szOsFile = sizeof(VStatFile) + vstat_vfs.pVfs->szOsFile;
rc = sqlite3_vfs_register(&vstat_vfs.base, 1);
if( rc==SQLITE_OK ){
rc = sqlite3_auto_extension(vstatRegister);
rc = vstatRegister(db, pzErrMsg, pApi);
if( rc==SQLITE_OK ){
rc = sqlite3_auto_extension(vstatRegister);
}
}
if( rc==SQLITE_OK ) rc = SQLITE_OK_LOAD_PERMANENTLY;
return rc;
+1
View File
@@ -492,6 +492,7 @@ static sqlite3_module vtablogModule = {
0, /* xSavepoint */
0, /* xRelease */
0, /* xRollbackTo */
0, /* xShadowName */
};
#ifdef _WIN32
+24 -23
View File
@@ -358,7 +358,7 @@ static int zipfileConnect(
rc = sqlite3_declare_vtab(db, ZIPFILE_SCHEMA);
if( rc==SQLITE_OK ){
pNew = (ZipfileTab*)sqlite3_malloc(nByte+nFile);
pNew = (ZipfileTab*)sqlite3_malloc64((sqlite3_int64)nByte+nFile);
if( pNew==0 ) return SQLITE_NOMEM;
memset(pNew, 0, nByte+nFile);
pNew->db = db;
@@ -806,7 +806,7 @@ static int zipfileGetEntry(
}
if( rc==SQLITE_OK ){
int nAlloc;
sqlite3_int64 nAlloc;
ZipfileEntry *pNew;
int nFile = zipfileGetU16(&aRead[ZIPFILE_CDS_NFILE_OFF]);
@@ -818,7 +818,7 @@ static int zipfileGetEntry(
nAlloc += zipfileGetU32(&aRead[ZIPFILE_CDS_SZCOMPRESSED_OFF]);
}
pNew = (ZipfileEntry*)sqlite3_malloc(nAlloc);
pNew = (ZipfileEntry*)sqlite3_malloc64(nAlloc);
if( pNew==0 ){
rc = SQLITE_NOMEM;
}else{
@@ -981,11 +981,11 @@ static int zipfileDeflate(
u8 **ppOut, int *pnOut, /* Output */
char **pzErr /* OUT: Error message */
){
int nAlloc = (int)compressBound(nIn);
sqlite3_int64 nAlloc = compressBound(nIn);
u8 *aOut;
int rc = SQLITE_OK;
aOut = (u8*)sqlite3_malloc(nAlloc);
aOut = (u8*)sqlite3_malloc64(nAlloc);
if( aOut==0 ){
rc = SQLITE_NOMEM;
}else{
@@ -1058,7 +1058,7 @@ static int zipfileColumn(
if( pCsr->pCurrent->aData ){
aBuf = pCsr->pCurrent->aData;
}else{
aBuf = aFree = sqlite3_malloc(sz);
aBuf = aFree = sqlite3_malloc64(sz);
if( aBuf==0 ){
rc = SQLITE_NOMEM;
}else{
@@ -1296,25 +1296,26 @@ static int zipfileBestIndex(
sqlite3_index_info *pIdxInfo
){
int i;
int idx = -1;
int unusable = 0;
for(i=0; i<pIdxInfo->nConstraint; i++){
const struct sqlite3_index_constraint *pCons = &pIdxInfo->aConstraint[i];
if( pCons->usable==0 ) continue;
if( pCons->op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue;
if( pCons->iColumn!=ZIPFILE_F_COLUMN_IDX ) continue;
break;
if( pCons->usable==0 ){
unusable = 1;
}else if( pCons->op==SQLITE_INDEX_CONSTRAINT_EQ ){
idx = i;
}
}
if( i<pIdxInfo->nConstraint ){
pIdxInfo->aConstraintUsage[i].argvIndex = 1;
pIdxInfo->aConstraintUsage[i].omit = 1;
if( idx>=0 ){
pIdxInfo->aConstraintUsage[idx].argvIndex = 1;
pIdxInfo->aConstraintUsage[idx].omit = 1;
pIdxInfo->estimatedCost = 1000.0;
pIdxInfo->idxNum = 1;
}else{
pIdxInfo->estimatedCost = (double)(((sqlite3_int64)1) << 50);
pIdxInfo->idxNum = 0;
}else if( unusable ){
return SQLITE_CONSTRAINT;
}
return SQLITE_OK;
}
@@ -1896,14 +1897,14 @@ struct ZipfileCtx {
static int zipfileBufferGrow(ZipfileBuffer *pBuf, int nByte){
if( pBuf->n+nByte>pBuf->nAlloc ){
u8 *aNew;
int nNew = pBuf->n ? pBuf->n*2 : 512;
sqlite3_int64 nNew = pBuf->n ? pBuf->n*2 : 512;
int nReq = pBuf->n + nByte;
while( nNew<nReq ) nNew = nNew*2;
aNew = sqlite3_realloc(pBuf->a, nNew);
aNew = sqlite3_realloc64(pBuf->a, nNew);
if( aNew==0 ) return SQLITE_NOMEM;
pBuf->a = aNew;
pBuf->nAlloc = nNew;
pBuf->nAlloc = (int)nNew;
}
return SQLITE_OK;
}
@@ -2094,7 +2095,7 @@ void zipfileStep(sqlite3_context *pCtx, int nVal, sqlite3_value **apVal){
void zipfileFinal(sqlite3_context *pCtx){
ZipfileCtx *p;
ZipfileEOCD eocd;
int nZip;
sqlite3_int64 nZip;
u8 *aZip;
p = (ZipfileCtx*)sqlite3_aggregate_context(pCtx, sizeof(ZipfileCtx));
@@ -2107,14 +2108,14 @@ void zipfileFinal(sqlite3_context *pCtx){
eocd.iOffset = p->body.n;
nZip = p->body.n + p->cds.n + ZIPFILE_EOCD_FIXED_SZ;
aZip = (u8*)sqlite3_malloc(nZip);
aZip = (u8*)sqlite3_malloc64(nZip);
if( aZip==0 ){
sqlite3_result_error_nomem(pCtx);
}else{
memcpy(aZip, p->body.a, p->body.n);
memcpy(&aZip[p->body.n], p->cds.a, p->cds.n);
zipfileSerializeEOCD(&eocd, &aZip[p->body.n + p->cds.n]);
sqlite3_result_blob(pCtx, aZip, nZip, zipfileFree);
sqlite3_result_blob(pCtx, aZip, (int)nZip, zipfileFree);
}
}
-1
View File
@@ -670,4 +670,3 @@ foreach {tn3 create_vfs destroy_vfs} {
finish_test
-1
View File
@@ -185,4 +185,3 @@ do_test 4.3 {
finish_test
-1
View File
@@ -195,4 +195,3 @@ do_test 4.7.2 {
} {1 {SQLITE_ERROR - rbu_state mismatch error}}
finish_test
-1
View File
@@ -232,4 +232,3 @@ do_multiclient_test tn {
}
finish_test
-1
View File
@@ -62,4 +62,3 @@ do_execsql_test 1.4 {
finish_test
-1
View File
@@ -92,4 +92,3 @@ foreach {tn schema} {
finish_test
-2
View File
@@ -203,5 +203,3 @@ do_test 5.3 {
do_test 6.1 { sqlite3rbu_internal_test } {}
finish_test
-4
View File
@@ -300,7 +300,3 @@ foreach {tn idx} {
finish_test
-1
View File
@@ -100,4 +100,3 @@ for {set nStep 8} {$nStep < 20} {incr nStep} {
finish_test
-2
View File
@@ -106,5 +106,3 @@ foreach {tn tbl} {
}
finish_test
-1
View File
@@ -72,4 +72,3 @@ integrity_check 1.3.3
finish_test
-1
View File
@@ -125,4 +125,3 @@ foreach {tn idx} {
finish_test
-1
View File
@@ -80,4 +80,3 @@ do_test 2.2 {
finish_test

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