Compare commits

..

246 Commits

Author SHA1 Message Date
mistachkin cee51b4b3a Fix compiler warnings.
FossilOrigin-Name: 12e869bbac4308f859baf6c6cbf051128b7308ec
2015-10-20 23:40:19 +00:00
mistachkin 6d7734c27d Fix harmless compiler warnings in FTS5.
FossilOrigin-Name: 0a903ec26bfbbe9bfd18bc34934e689ffdb01ce5
2015-10-20 23:27:14 +00:00
dan 219f4d48a2 More optimizations for fts5 prefix queries.
FossilOrigin-Name: b8fb263ed1b36d085437131795505e53af103d26
2015-10-20 21:05:53 +00:00
dan 9cc4ae6f2a Fix #line directives added to generated file fts5.c.
FossilOrigin-Name: 1f5f5804cd394a81b1c0712ce6d1052f228d0a40
2015-10-20 19:55:35 +00:00
dan 3f9bfa740f Initialize variables in the fts5 integrity-check code to avoid compiler warnings.
FossilOrigin-Name: e979e2cccac257ad554803e6a1103558b0f159d8
2015-10-20 15:49:02 +00:00
dan 8789fbb2bd Another optimization for fts5 prefix (and other) queries.
FossilOrigin-Name: 60a8bde055a960c5b8cb4e231802c75617c942d8
2015-10-19 20:49:10 +00:00
dan 5e5b454cd8 Another tweak to improve performance of fts5 prefix queries.
FossilOrigin-Name: 69be427c864dc3de804ca3c5f1c6addcd33cd188
2015-10-19 17:43:24 +00:00
dan 3c060c2aef Fix a problem in the fts5txt2db.tcl script causing it to fail when creating tables with more than 8 columns.
FossilOrigin-Name: 68ee426a6432ac63655909ff70cb22bde33cf28c
2015-10-19 15:59:08 +00:00
dan 0206920e27 Add tests to cover new branches added to the fts5 code by the previous commit.
FossilOrigin-Name: cf618334a8a05a067e844236e4d461b2e5706da6
2015-10-17 20:34:49 +00:00
dan 05903e6a87 Handle equality and range constraints on the "term" column of fts5vocab tables. Also have the same module report columns using names instead of indexes.
FossilOrigin-Name: 6020d96ab47a0bebe41f691a3f44fd55d8b2d2b7
2015-10-17 19:49:01 +00:00
drh b0df963465 Fix a comment in expr.c and add a CORRUPT_DB to an assert() in btree.c.
FossilOrigin-Name: 0df371d1a51c2028aefa4c704707773750317689
2015-10-16 23:55:08 +00:00
mistachkin f170ea44d4 Enhancements to the MSVC makefile.
FossilOrigin-Name: 39e8a5d93fa370afb03223bf0c20ea0f3448b9fc
2015-10-16 20:13:57 +00:00
drh 04ce31fafe Merge the 3.9.1 changes into trunk. (This only updates the version number
and configure script since all the other changes in 3.9.1 were cherrypicked
from trunk.)

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

FossilOrigin-Name: ec003958359d6b69b1b1a75be2a988796268e063
2015-10-14 19:44:42 +00:00
dan 8d32e8042c Avoid exporting sqlite3_json_init() from amalgamation builds.
FossilOrigin-Name: 8463f7e7908d0a96ed036377dfa3805328c62925
2015-10-14 18:45:42 +00:00
drh b43b711587 Version 3.9.0
FossilOrigin-Name: a721fc0d89495518fe5612e2e3bbc60befd2e90d
2015-10-14 12:29:53 +00:00
dan f4f968443b Add the missing 'extern "C" {...}' blocks to fts5.h and sqlite3rbu.h.
FossilOrigin-Name: 47a2ce97d585e1760ffcf760c0de1753677d5713
2015-10-14 10:56:34 +00:00
drh cec7dec006 Remove the unused fts5ExprColsetTest() routine.
FossilOrigin-Name: 9ecafc0c94102dca6da192f400278399464086fb
2015-10-12 22:31:02 +00:00
mistachkin f2c26ed17b Fix a couple harmless compiler warnings.
FossilOrigin-Name: 7f896a971c5953d5370215ecd834d1fb711b4263
2015-10-12 22:20:29 +00:00
dan df705d8185 Further tweaks to improve fts5 prefix query performance.
FossilOrigin-Name: 1c20c1c28b56411f106cf2f6961b3ad4b4d6f6c8
2015-10-12 19:12:29 +00:00
drh 58a8a9236e Change all references to 3.8.12 into 3.9.0. Comment changes only - no
changes to code.

FossilOrigin-Name: 6f2858f6817ca70c132f0437ac2f0f74deb273d2
2015-10-12 04:56:12 +00:00
mistachkin fcbe99ae38 Remove AWK requirement from the MSVC batch build tool.
FossilOrigin-Name: 6d9cdb931cf4e2f0830184cff32e441e4966bd7e
2015-10-12 03:56:21 +00:00
mistachkin cf9fb7eb1c The TclKit batch tool should not download the TclKit SDK when the TCLKIT_NOSDK environment variable is set.
FossilOrigin-Name: 7c5d583bac89f8db94e7f73df09e1d04f0f24990
2015-10-12 03:44:39 +00:00
drh bfad7be78a Detect and report circularly defined views even if the views have the
columns defined in the CREATE VIEW statement.

FossilOrigin-Name: 9ab9c8c6d747647f8ade58c2c4812fc69a813368
2015-10-11 20:39:46 +00:00
drh 2906490b71 Remove an unreachable branch in the query flattener substitution logic.
FossilOrigin-Name: 46ee3453a31b5e793d5aaad471cec1b1a11ab2cf
2015-10-11 20:08:31 +00:00
drh d12b636330 Improved substitution logic in the query flattener. Saves code space, and
(more importantly) works correctly with table-valued functions.

FossilOrigin-Name: 3d0bd95e977db50c314d33ec292f99e0539d7b4a
2015-10-11 19:46:59 +00:00
mistachkin 5b66350ac7 Enhance TclKit batch tool (and MSVC makefile) to support targets that require the Tcl stub library.
FossilOrigin-Name: bc6223b1d6c31a47c7b734cfb8a9ecf15ab809fc
2015-10-10 23:39:55 +00:00
drh 48310f8c51 Work around a "security feature" bug in memcpy() on OpenBSD.
FossilOrigin-Name: fab6f09044d033dd09ed8a22e06bc6a7851bbabf
2015-10-10 16:41:28 +00:00
drh 72724da95a Remove another instance of strcpy() from FTS5, to mollify OpenBSD.
FossilOrigin-Name: 35e6248abb4435a8b26d270092b856beff867406
2015-10-10 15:57:20 +00:00
drh c5971cc859 Omit the use of strcpy() in FTS5 since OpenBSD hates strcpy().
FossilOrigin-Name: bc24a5bbfd95df3518611b221de69b73776111bc
2015-10-10 15:11:49 +00:00
drh 728e0f91bb Compiler warning fixes: Rename some local variables from "j1" to avoid a
name collision with the j1() bessel function in the math library.  Omit a
dummy initializer that gcc 4.6.3 does not like.

FossilOrigin-Name: 9ddef84d432813f3ece8012047d08441caa3315d
2015-10-10 14:41:28 +00:00
drh 9a4718ff73 Add some #ifdef-ery to json1.c to avoid a duplicate typedef when used in the
amalgamation, since some compilers become upset over duplicate typedefs.

FossilOrigin-Name: de28acd42f29693341feb884b7223cd3d2b96730
2015-10-10 14:00:37 +00:00
mistachkin ba461cac7b Remove a couple superfluous double quotes in the MSVC makefile.
FossilOrigin-Name: 0f9e205b28e013412b19dfd588f2a6cf341c40e8
2015-10-10 02:06:05 +00:00
mistachkin 946ef60ad0 Fix typo in the MSVC makefile. Replace remaining uses of AWK in the MSVC makefile with a Tcl script.
FossilOrigin-Name: f8c2193b64979a2fe480fcf913573b5fac06235e
2015-10-10 01:55:57 +00:00
mistachkin cc7304888f More fine-tuning to the new TclKit tools.
FossilOrigin-Name: 43addd8aa04c3faceb9d303672e330294af01a16
2015-10-10 00:53:28 +00:00
drh a0882fad7c The previous fix to JSON1 was not complete. A few more tweaks are needed
for correct handling of all oversized integers.

FossilOrigin-Name: 4a47f0177851721cdf6c981df962b6e8862372e7
2015-10-09 20:40:44 +00:00
mistachkin dfff1ffec6 Tweak batch tool added in the previous check-in to permit the base URI to be overridden.
FossilOrigin-Name: 1d2f82df6774f8d66bfc5d67d5dad9f068a1069c
2015-10-09 18:48:47 +00:00
drh 8deb4b8b17 Fix the JSON1 extension so that it renders integers outside the range
of -9223372036854775808 to +9223372036854775807 as floating-point numbers.

FossilOrigin-Name: ae736e35fb59c9aed33a8c805cf2ecdee528051f
2015-10-09 18:21:43 +00:00
dan 6cac258245 Remove fts5 sources from TESTSRC2 in main.mk as there is no SQLITE_TEST code in said files.
FossilOrigin-Name: c1840639b8ce8314602cd2396a324de8fac98dbe
2015-10-09 17:54:10 +00:00
mistachkin 80372ae248 Add tool capable of downloading a TclKit (and its associated SDK) on Windows.
FossilOrigin-Name: 50673ddaf813335777673fa8585997a7551e5323
2015-10-09 17:36:06 +00:00
dan 2572751be8 Add --enable-fts5 and --enable-json1 options to the amalgamation autoconf package.
FossilOrigin-Name: 8a4e19888f512c3ee95aa3040924fc932fbdab1a
2015-10-09 14:37:15 +00:00
mistachkin 8381be4ace In the MSVC makefile, adjust the names of two nmake variables for consistency.
FossilOrigin-Name: 92aa4b6b6fbb83f965e4c4be0aa21a8b7e330ed8
2015-10-09 14:23:56 +00:00
drh c4e6d1775e Change the version number of the next release to 3.9.0.
FossilOrigin-Name: aa8fdadf2defed00a28366a3b35a3e2eefecf0ed
2015-10-09 13:42:52 +00:00
drh b5c8d27c7d Add the JSON1 and FTS5 extensions to the amalgamation. Add new options
to ./configure: --enable-json1 and --enable-fts5.

FossilOrigin-Name: 1eb769933108cf401b25c8d784ea23f27324a0bd
2015-10-09 13:39:51 +00:00
drh 64db184efa Fix a typo in the MSVC Makefile
FossilOrigin-Name: c8a12082380991781b5ecd2f479ec65600f4f695
2015-10-09 13:29:27 +00:00
drh ce1d9f546b Add configure script options --enable-fts5 and --enable-json1. Automatically
search for -lm when using --enable-fts5.

FossilOrigin-Name: a0c44f1d46f1f31043d66f20c8dc0df53db15c30
2015-10-09 12:48:33 +00:00
dan 0008ce7cc5 Makefile and fts5 changes so that fts5 works with main.mk. Still does not work with Makefile.in.
FossilOrigin-Name: 6ebac32d8378e46f44a6eb55aaa30baf4d7dde7d
2015-10-09 11:09:47 +00:00
drh 45fac88951 Trying to get FTS5 tests to build and run using main.mk. Not yet working.
FossilOrigin-Name: 206174f9b154c590a3e2e94236db38e111d64bdb
2015-10-09 01:42:49 +00:00
drh c306e08ad5 Json1 tests are working. Builds without FTS5 enabled. Still some problems
building with FTS5.

FossilOrigin-Name: 2928f8e87d2e5d121e6e7e5993cbb773bb2b0603
2015-10-08 23:37:00 +00:00
dan d3b90a2e41 Remove calls to "load_static_extension" from fts5 test scripts.
FossilOrigin-Name: 53dd7c4c65842c5c9ed3e84edd62e24f2c9be15b
2015-10-08 21:02:29 +00:00
dan 23fda8242c Further tweaks to main.mk so that fts5 builds as part of testfixture.
FossilOrigin-Name: 97e11b79a52fb1c57f0afd2dbd6ee66cf00a922d
2015-10-08 21:00:46 +00:00
dan 56eac26897 Fix further fts5 compilation issues.
FossilOrigin-Name: 0d7f301fb03c8546a5dbce5d061a1d74e3c86bcf
2015-10-08 20:40:18 +00:00
dan 351ccb3825 Fix two more warnings in fts5 code.
FossilOrigin-Name: 5343e601fb6f0f24f4e4d5d442f7b5b074734143
2015-10-08 20:28:33 +00:00
dan 056d7acf25 Fix a couple of errors in fts5 compilation. This branch still does not build with -Wall -Werror.
FossilOrigin-Name: e9e76e12812b9b42b1142246b71cea98e26903aa
2015-10-08 20:11:42 +00:00
drh 50065656f7 First attempt to add json1 and fts5 to the amalgamation. This check-in does
not compile.

FossilOrigin-Name: d820a1bd1b8dd702d1b3a099af393530cc5a5d51
2015-10-08 19:29:18 +00:00
mistachkin b2682eb14b In the RBU extension, use MoveFile() instead of rename() on Windows CE.
FossilOrigin-Name: df9ef61f1ba2e3a3420fae84e3eaa2e0e235bc28
2015-10-08 17:35:51 +00:00
drh d7fd6aa4ba Remove two unused lines of code - discovered by scan-build.
FossilOrigin-Name: 77b707b77496a08703fe9405e8e4521a4e5b419e
2015-10-08 02:44:42 +00:00
dan 98e713bb8d Further optimizations for fts5 prefix queries without a prefix index.
FossilOrigin-Name: 83dc1ff7fa010715ca7f406a572f4ee444a967d7
2015-10-07 19:06:21 +00:00
mistachkin 08114efde4 Fix harmless compiler warning in FTS5.
FossilOrigin-Name: 13adcd038fc20dd1b6f344f79b449b4034f8f8f2
2015-10-07 17:06:17 +00:00
dan 22c7cca21f Allow the subsitute character (codepoint 26 - 0x1A) to appear in fts5 barewords.
FossilOrigin-Name: baec1b96cb64a6a6317143a8df841e502afe3914
2015-10-07 17:01:22 +00:00
drh 1dcc97cd3a Adjustments to spellfix2.test so that it works reliably on mac.
FossilOrigin-Name: d591e860d3d7c61637b4b07989bf176cb337db2c
2015-10-07 16:14:18 +00:00
dan d46cc33131 Add tests for fts5 phrase queries with column filters.
FossilOrigin-Name: f20f9f813f00cefcd427e506a09b0b973c782e3f
2015-10-07 13:24:27 +00:00
drh 48cc9a31e1 Convert the tool/tostr.awk script into tool/tostr.tcl. Remove two obsolete
Makefiles.  Purge NAWK from the configure script and from unix makefiles.
There are still two uses of NAWK in Makefile.msc.

FossilOrigin-Name: 5b6775215327a89232f5059653747a18e83b8b4b
2015-10-07 12:36:42 +00:00
drh 60a15a48c5 Change the addopcodes.awk script into tool/addopcodes.tcl.
FossilOrigin-Name: 8bbf37142ef2759274668f6da114b5c8072e42db
2015-10-07 12:21:14 +00:00
drh 7651e0a439 Convert the mkopcodec.awk script into tool/mkopcodec.tcl.
FossilOrigin-Name: 1506cb33fcf61e2ef97b35b99e58fbf21f4f5496
2015-10-07 12:11:36 +00:00
dan 92099b0753 Add further tests for fts5 prefix queries.
FossilOrigin-Name: accdc98b1291f07b802fd23f3ebc7dbc02ba09d3
2015-10-07 09:02:50 +00:00
mistachkin 6418ffab82 Fix a typo in the previous check-in.
FossilOrigin-Name: 80027709c3ba2a8c9bda4d37779f65104be1045c
2015-10-07 04:20:34 +00:00
mistachkin 6bd7456edd When running tests on Tcl 8.6 under Windows, skip tests 'uri-1.12.*' due to a change in Tcl behavior related to NTFS ADS (alternate data streams).
FossilOrigin-Name: 8a0a2aa5a6df3d7b5995457b57f051e39d6cf9e9
2015-10-07 03:07:41 +00:00
drh b15393b8d5 Change mkopcodeh.awk into tool/mkopcodeh.tcl.
FossilOrigin-Name: ed0ebc460b54939862e3bddee2bb9bcb9f69c747
2015-10-07 02:52:09 +00:00
drh ee38148785 Remove three obsolete and unused files from tool/
FossilOrigin-Name: 0abd65294e6e8db68e7ce6724f02f17ba1cb3422
2015-10-07 00:35:18 +00:00
mistachkin 91a3ecb0ad Fix typo in comments. No changes to code.
FossilOrigin-Name: a05f903c64edeba8a9748aad68f5981943e68b3c
2015-10-06 21:49:55 +00:00
drh 8b0cf38a12 Simplifications to the VDBE bytecode that handles LIMIT and OFFSET.
FossilOrigin-Name: 041df7c2f14b95868a08090354ebb3308050790e
2015-10-06 21:07:06 +00:00
dan a2507137f3 Optimizations for fts5 expressions that filter on column. More still to come.
FossilOrigin-Name: bf1607ac155018573ca40fb58aca62c5fea7e60b
2015-10-06 20:53:26 +00:00
drh 9f1ef45f6a Fix the LIMIT and OFFSET handling for UNION ALL queries that contain a
subquery with ORDER BY on the right-hand side.  Fix for ticket
[b65cb2c8d91f668584].

FossilOrigin-Name: 4b631364354068af95a01630469cb6fbfe8b52fd
2015-10-06 17:27:18 +00:00
mistachkin 8d9837acd5 Adjustments to sqlite3MemoryBarrier() when compiling with MSVC and/or WinCE.
FossilOrigin-Name: 3168326ebfa1c961d8fc6435453b02be23d910cc
2015-10-06 01:44:53 +00:00
dan 6f832d3dff Improve performance of prefix queries without a prefix index on fts5 tables.
FossilOrigin-Name: f2f0184e9e1c9f121ee2ac864cd28c8cd8efecb5
2015-10-05 19:41:16 +00:00
dan f24bebe37a Update fts3 so that expressions to the left and right of a NOT operator are balanced. This prevents relatively small expressions (a dozen terms or so) that are children of NOT operators from triggering the "expression tree is too large" error.
FossilOrigin-Name: d6b66cd7b89fbd964f798d160a34caac0ba7347a
2015-10-05 15:39:45 +00:00
dan 2c1023df09 Add fts5txt2db.tcl, a tool for creating sample fts4/5 databases from text files.
FossilOrigin-Name: 44f1ce30d1e446c9ee5f8bd8a62119e00356aa0e
2015-10-05 11:57:09 +00:00
dan a0f197b842 Update fts5 to support the table function syntax. "... FROM fts5_tbl WHERE fts5_tbl MATCH ?1 AND rank MATCH ?1" can now be written "FROM fts5_tbl(?1, ?2)".
FossilOrigin-Name: 41d17d9e24303aed6d549ea23c62b93bf2f71691
2015-10-03 15:38:57 +00:00
dan 06f8c635ef Add tests for the rtree module to verify that attempts to insert non-integer primary key values or non-numeric dimensions into an rtree table are handled correctly.
FossilOrigin-Name: f653fce90846b700441e8fa5f1930c1ec5e38e31
2015-10-03 12:23:18 +00:00
dan bca189d5d8 Update fts5 to avoid using a statement journal for UPDATE and DELETE operations that affect at most a single row.
FossilOrigin-Name: 5c83b9db46d61cfa76a1abed50467e2f02db0eb0
2015-10-02 20:04:30 +00:00
dan 5171e911f2 Fix an fts3 bug causing NEAR queries on uncommitted data to malfunction.
FossilOrigin-Name: 6f90839e91024e2006042f5eb7f21ca5b47a9b4a
2015-10-01 18:31:29 +00:00
drh 105865acf9 Add a corrupt database to test/fuzzdata3.db to validate the previous
check-in.

FossilOrigin-Name: e796c0efb6cf17444b53af75046daf7d8fa82f78
2015-09-30 14:30:19 +00:00
drh 9b5351d439 Fix an assert() in btree.c that is only true for non-corrupt databases.
FossilOrigin-Name: 29f7227ff127202c53fe7c3b6558b3c101b0a7bc
2015-09-30 14:19:08 +00:00
dan e755e10a78 Clear the BTCF_ValidNKey flag when putting a cursor into REQUIRESEEK state. Fix for [1b266395].
FossilOrigin-Name: a6d5e4e8693bea3739c35fe9769ac9abfb9ed056
2015-09-30 12:59:12 +00:00
dan d95bb39c52 Improve error handling in shell command ".tables".
FossilOrigin-Name: 31a91ee7d32af8580a170903eb857ed9222fdb0a
2015-09-30 11:19:05 +00:00
drh 4b92f98ccc Use symbolic names XN_ROWID and XN_EXPR in place of the (-1) and (-2)
magic numbers in Index.aiColumn[].  Add asserts to help verify that
Index.aiColumn[] is always used correctly.  Fix one place in FK processing
where Index.aiColumn[] was not being used correctly.

FossilOrigin-Name: 7d272aa62cd4cbbf4b5d04e3b918de27671e8301
2015-09-29 17:20:14 +00:00
dan e60856980a Add the sqlite3_index_info.idxFlags field, allowing xBestIndex() implementations to specify to SQLite that a strategy may visit at most one row. Add support for this to fts3/4. Omit the statement journal from virtual table UPDATE and DELETE operations that are guaranteed not to affect more than one row.
FossilOrigin-Name: a1d08fd3d0419da8c22355d48c6d83eed6fd7e07
2015-09-29 16:47:53 +00:00
dan 65c4f591be Ensure that the xSavepoint() virtual table method is correctly invoked if there are already open savepoints (or statement transactions) the first time a virtual table is written within a transaction.
FossilOrigin-Name: 77948b5eceab92a77c39d0864ac15ad453a76fd7
2015-09-29 16:41:23 +00:00
drh e2b7d7a0a1 Remove dead code, replacing with assert() statements that make sure the
code really was dead.

FossilOrigin-Name: 0e317dda5dfd35b742afd70dacb5bfb39aa3fc4a
2015-09-29 15:50:04 +00:00
drh c149f18f4d Create the sqlite3IsToplevel(Parse*) interface to check to see if a top-level
VDBE is being coded (versus a trigger) and use that interface.

FossilOrigin-Name: 59662cd2b65255a30e1a420331c07c51b644621a
2015-09-29 13:25:15 +00:00
drh 94f26a1e22 Fix compiler warnings.
FossilOrigin-Name: d1a0783854d2e9272320d9ddfa58362532f58d1a
2015-09-29 12:32:56 +00:00
dan 4ad0971919 Fix an off-by-one error in test function fts5_decode().
FossilOrigin-Name: 3a9f076250d9559d8ea94ba44095ba3ddbc5542d
2015-09-29 12:19:51 +00:00
dan 91742c45a9 Merge latest trunk change into this branch.
FossilOrigin-Name: b519c0d67a8fc39d65c17eccc9300a6187bd5661
2015-09-29 11:59:25 +00:00
dan b3deb4ea64 Change the name of the new sqlite3_index_info.flags field to "idxFlags". Add documentation for the same to sqlite.h.in.
FossilOrigin-Name: f61203bc0fb0b62e12d6270e8d9063e445a5a252
2015-09-29 11:57:20 +00:00
dan 354474ad6d Add tests for fts3 and onepass update/delete operations. Also fix a problem with onepass updates that do not affect any rows.
FossilOrigin-Name: 820c804468abff692742952de670c5d906a50956
2015-09-29 10:11:26 +00:00
dan 0f40037eee Also allow UPDATE on virtual tables to use the onepass strategy.
FossilOrigin-Name: 1aa27d706db9b2e21737ce4b94b47ecd12c2570f
2015-09-28 20:03:49 +00:00
drh a722821eb5 Extra information provided by .wheretrace on input flags to the query planner
and on the result of sqlite3WhereOkOnePass().

FossilOrigin-Name: c5566bb39c8d9b58f77380b81a873429575c7d5c
2015-09-28 17:05:22 +00:00
dan d943b27596 Update fts3 to use the onepass strategy for delete operations.
FossilOrigin-Name: fffab4f70f85eeb2acbb89534064a6e397c39384
2015-09-28 15:23:29 +00:00
dan 076e0f9674 Changes to allow DELETE operations on virtual tables to use the onepass strategy under some circumstances.
FossilOrigin-Name: e73f919fae1833c6ffb36eddbc76d9a8d9324214
2015-09-28 15:20:58 +00:00
drh 3169713be0 Add test cases to the ONEPASS optimization corruption problem fixed by the
previous check-in.

FossilOrigin-Name: 5c14d447055bb337428eb1fe0a2934abee381829
2015-09-28 15:08:28 +00:00
drh 63c85a7a66 Fix a database corruption bug caused by the ONEPASS optimization added
in check-in [8b93cc5937000535].  Bug detected (prior to release) by
[https://www.sqlite.org/sqllogictest|sqllogictest].  Test cases to follow.

FossilOrigin-Name: 9d057f52217e7ef9c3f3eb84117abe3365503f44
2015-09-28 14:40:20 +00:00
drh 2f20e13b83 Enable adding JSON1 by appending the json1.c source file to the amalgamation
and compiling with -DSQLITE_ENABLE_JSON1

FossilOrigin-Name: 33404b2029120d4aabe1e25d484871810777e934
2015-09-26 17:44:59 +00:00
drh 32498f1321 Fix a memory leak that can occur following a syntax error in CREATE VIEW.
FossilOrigin-Name: f4704035a6134f702c00110358e36f1579e2ea78
2015-09-26 11:15:44 +00:00
drh c4cdb29a0e Fix the title of the documentation on sqlite3_value_subtype(). This is a
comment change only.

FossilOrigin-Name: b79023542458f7e839469c5e313694f1e4cf223a
2015-09-26 03:31:47 +00:00
drh 539482b76a Expand the header comment to clarify the purpose for the
sqlite3MemoryBarrier() function.

FossilOrigin-Name: b89495ae09aa0e9652475b2ba1943dfd87c73e07
2015-09-26 03:23:29 +00:00
drh 17db155fed Remove an assert in the windows worker-thread logic that can fail in a race
condition.

FossilOrigin-Name: d7bfb96092a6b812af194f32b22283a0f6a7da96
2015-09-26 01:28:46 +00:00
drh 2ea31b1286 Fix threads.c so that setting sqlite3FaultSim(200) using the
SQLITE_TESTCTRL_FAULT_INSTALL callback causes both unix and windows worker
threads to be sequential and deterministic, so that they can be tested
reliably.

FossilOrigin-Name: 2d867c054d6d3e1e841ba9ca524e986bc6993ac3
2015-09-25 23:40:01 +00:00
drh 68391acd5f Fix PRAGMA integrity_check so that it works with a UNIQUE index over
expressions.

FossilOrigin-Name: 113181cec4db418b07640d6b1967923992efd71a
2015-09-25 20:49:16 +00:00
drh 2679f14fd9 Report an error if the number of named columns in a VIEW is different
from the number of result columns in the SELECT statement that implements
the VIEW.

FossilOrigin-Name: 6e4ac0be2de1a16fcbb2a314504122ad95aa257e
2015-09-25 13:42:55 +00:00
drh 8ffddeb708 Fix a problem computing affinities for indexes during skip-scan code
generation when SQLITE_ENABLE_STAT4 is on.  Bug introduced by
check-in [1ee089a72d789002].

FossilOrigin-Name: 1350dd42d056508337b1a07ad8b1c9c97593f8d3
2015-09-25 01:09:27 +00:00
drh dae26fe518 Enhance the query planner so that it is able to use indexed expressions
to help fulfill an ORDER BY clause.

FossilOrigin-Name: 668fc1ebaf426f9eed3ed7865e41f1023dafebfb
2015-09-24 18:47:59 +00:00
drh 76226dd28d Fix over-length source code lines in where.c. No logic changes.
FossilOrigin-Name: 1c8c5380a8b45c9e04d9663c3cb8182ef3a61b81
2015-09-24 17:38:01 +00:00
drh 22c733da64 Strengthen the implementations of xShmMemoryBarrier on both the unix and
windows VFSes, so that they likely work even if SQLITE_THREADSAFE=0 is used.

FossilOrigin-Name: c6ab807b72ddfc1462f61aa91442b6fac04ace8a
2015-09-24 12:40:43 +00:00
drh c5de2d0a05 Make sure joins work correctly when both sides of the join are connected
using indexed expressions.

FossilOrigin-Name: c2fcb03299f2872d7f97a540ea145519f8b2e5cc
2015-09-24 12:19:17 +00:00
drh 7269443281 Correctly handle the case of a WHERE-clause term with indexed expressions on
both sides of the == sign.

FossilOrigin-Name: d9b716a6bd6145b2e7733c04d86227df777cd473
2015-09-24 11:26:45 +00:00
drh b7601461e0 Fix a JSON1 test case so that it works on builds that omit virtual tables.
FossilOrigin-Name: a4444c0f662058bdd5267e616c31cef828bc1fc5
2015-09-24 11:06:26 +00:00
drh 8cb15cc5ae Another (smaller) performance optimization for the JSON parser.
FossilOrigin-Name: c43daa8c78df99f62dd4d3c83708a3a8eff92496
2015-09-24 01:40:45 +00:00
drh 9567794fd9 Performance optimizations on the JSON parser.
FossilOrigin-Name: 7dd4b07a42eb84589d34430b9d7bfa88fbd743eb
2015-09-24 01:06:37 +00:00
drh 58cb6dbe0d Take care that the number of reserved bits per page is consistent between
the source and destination databases when doing the back-copy on a VACUUM.

FossilOrigin-Name: 5b61b72f5424a2d9bb4e68eb95026cd63f003db9
2015-09-23 19:17:23 +00:00
drh 64ff56f91a Capture AFL-generated fuzz tests for json1.c into the test/fuzzdata4.db file.
FossilOrigin-Name: 10a214fdb3c13b25e0bdd15c975c21c8890c47ee
2015-09-23 11:59:50 +00:00
drh f27cd1f3aa Do not allow a comma at the end of a JSON array or object.
FossilOrigin-Name: 7c7a3f3e9bc2f7a7334d8d6eae183d83f22097be
2015-09-23 01:10:29 +00:00
drh 40e0e0dbe7 Add the --export-sql and --export-db options to the fuzzcheck utility program.
FossilOrigin-Name: 760af4455115669b934c3115d45cffe89c085faf
2015-09-22 18:51:17 +00:00
drh 9cdd1029e5 Fix a typo in the --help screen of the fuzzcheck utility.
FossilOrigin-Name: b6ae61fe3b3de3aa296b3e56cd2ec425a5141c73
2015-09-22 17:46:11 +00:00
drh 3d1d2a97a5 Futher simplifications to json1.c. Also an obscure bug-fix in the initial
output of json_tree() when using a path to an object contained within an array.

FossilOrigin-Name: fcb1e327a64134e5ac539ec3d52733422d3061fd
2015-09-22 01:15:49 +00:00
drh 8cb0c83cce Fix json_set() so that it can overwrite a value that was previously overwritten
during the same call.

FossilOrigin-Name: 0f16041647993975c316203c7e11f06e27640136
2015-09-22 00:21:03 +00:00
mistachkin 357e42d48f For MSVC, have the 'sqlite3.c' target depend on 'sqlite3ext.h' as well as other targets may depend on this behavior (e.g. extensions).
FossilOrigin-Name: 737ac3faf4e5fcb5855f5f9a1c1ddfc5424e6292
2015-09-21 23:53:42 +00:00
mistachkin c978f2d2c2 Fix compilation under older versions of MSVC.
FossilOrigin-Name: 17150ada1474e70d7c5ffe6ba5667f45671a434b
2015-09-21 23:49:35 +00:00
drh a8f39a9b5d Simplifications to the json1.c logic.
FossilOrigin-Name: 1646a2bd85f87d03a14fcaec288107f5f6411c6f
2015-09-21 22:53:16 +00:00
drh 78ac109c7f Fix an overly-strict assert() in the btree logic.
FossilOrigin-Name: 825ce3201df21c6b9d5c57dcc6726c306df05220
2015-09-20 22:57:47 +00:00
drh 6230212f4a Do not allow table-valued function syntax to be used on a view.
FossilOrigin-Name: 97cfe346e140e42a604375551f8168276bdbea11
2015-09-19 20:27:08 +00:00
drh b97ad0297c Add the --disable-lookaside option to the fuzzershell utility program.
FossilOrigin-Name: 0b04374449c8279ad038def7c18cd74f180a0515
2015-09-19 19:36:13 +00:00
drh dc38495715 Fix a memory leak in json1.c that could occur after misuse of json_object().
FossilOrigin-Name: 394b81b11f261a9b179a034bc2a2d2dff0765e3b
2015-09-19 18:54:39 +00:00
dan 80b7198f2b Add an assert() statement to delete.c.
FossilOrigin-Name: 40fce67ecf0e71db3c8f3da3f72cc80a3d0f8fb2
2015-09-19 18:11:18 +00:00
drh 8faee877cb Fix compiler warnings.
FossilOrigin-Name: 5c31ee62a196b914673384a611534fd778dc64b0
2015-09-19 18:08:13 +00:00
drh 3f81f10804 Add json1.c to the fuzzer test shells.
FossilOrigin-Name: 809d67b61164b83bbb6962f0edee1793a483ccab
2015-09-19 16:51:58 +00:00
drh 8911c0b339 Adjust Makefiles to use SQLITE_CORE when statically linking json1.c into
test shells.

FossilOrigin-Name: 91682ac39e7db6a5dc8b75695a757449f068184a
2015-09-19 16:45:43 +00:00
drh 5f4a44a439 Adjust fuzzershell so that it adds the json1 extension separately for each
no connection.

FossilOrigin-Name: ca2d1e9036387d1514fe596a0b82a3d8409797c3
2015-09-19 14:57:00 +00:00
drh d7f2beab86 Include json1.c in fuzzcheck and fuzzershell.
FossilOrigin-Name: c4b68eff7f8f5402a9abf378157767b1c96a6101
2015-09-19 14:32:51 +00:00
drh c02c4d4900 Fix a documentation typo in sqlite3_bind_parameter_index(). No code changes.
FossilOrigin-Name: 650605a820f3860b1d6e955cdda23aaff01dfdb5
2015-09-19 12:04:27 +00:00
drh 4977ccf143 Fix an off-by-one error (really off-by-2 in this case) in the buffer
resize logic of json1.

FossilOrigin-Name: d2a027372a5a6efc0f9b6f605093d865ae1c6788
2015-09-19 11:57:26 +00:00
drh 4cbc54b042 Do not allow rowid in a UNIQUE or PRIMARY KEY constraint. (This restores the
same behavior exhibited by all prior releases.)

FossilOrigin-Name: b1278301e37220a075c1bae88c0fcca2ef7a7d5c
2015-09-19 03:07:30 +00:00
drh e63e8a6c78 Fix a crash that can occur with a skip-scan on an index with
expressions when SQLITE_ENABLE_EXPLAIN_COMMENTS is defined.

FossilOrigin-Name: 25f34cb9b576a2d4250a06a7dbf88010b1c11675
2015-09-18 18:09:28 +00:00
drh e5c61f81c3 Adjustments to the spellfix2.test module so that it works reliably on
windows.

FossilOrigin-Name: 09a313fb7f2c16b0253a439edb901a7bb201d7d3
2015-09-18 15:38:07 +00:00
drh bec9d65da4 Adjust two test cases so that they conform to the current code.
FossilOrigin-Name: 228e3d7c8f37c722aee3b589bdd5cfaa4b1f6f03
2015-09-18 15:35:16 +00:00
drh 59de9c0080 Fix sqlilimits.test module so that it knows that the SELECT in a CREATE VIEW
is not checked until the view is actually used.

FossilOrigin-Name: acf5d87f9456a1d0d69fe0ebc753211e1be07eaf
2015-09-18 15:13:29 +00:00
dan ad41f5eda3 Ensure that "PRAGMA integrity_check" reports an error if the free-list count header field contains a value smaller than the actual number of pages on the database free-list.
FossilOrigin-Name: 26f64986d1ed59c554a7cb9e00e86a7f148f1fc6
2015-09-18 14:45:01 +00:00
drh 3a84411fc4 Fix the orderby9.test case so that it works with 32-bit versions of TCL
FossilOrigin-Name: 4b6af7743034546a407a3e4722645945a4efc8a1
2015-09-18 14:42:48 +00:00
drh 9df5ad58bb Remove a test made obsolete by the ONEPASS DELETE optimization.
FossilOrigin-Name: c88b62c28cc7ac31b93f7df0c732e0bb6ca24f65
2015-09-18 14:22:34 +00:00
dan 2e8f5517f7 Avoid passing (signed char) values directly to isspace(), isalnum() or isdigit() in json1.c. Cast the value to (unsigned char) first.
FossilOrigin-Name: 6713e35b8a8c997aa2717e86ce6dcd63bb993477
2015-09-17 17:21:09 +00:00
dan cf346d7a9c Fix a crash in FTS5 caused by specifying NULL as the rhs of a MATCH operator.
FossilOrigin-Name: e8ed62f82e8acc40b818bf86fafe3d480687514e
2015-09-17 09:48:01 +00:00
drh d9dfeb575e Add a "flush" to force incremental output to releasetest-out.txt while running
the test/releasetest.tcl. script.

FossilOrigin-Name: 0f3de2d337a3113dbd0765aa5545bb586b780121
2015-09-16 17:46:11 +00:00
dan ec9e8f004e Fix typo in fts5.h.
FossilOrigin-Name: 07721c6c24f651d8e281c29227b113d292f6b0de
2015-09-16 12:31:39 +00:00
dan 6609bab24d Add test cases to cover fts5 integrity-check code.
FossilOrigin-Name: 1d018c35b9e81982df036f5e62a4a42219b54e02
2015-09-15 14:39:17 +00:00
drh b77ebd828b Reformat some code to make it easier to merge with sessions. No logic changes.
FossilOrigin-Name: eade355fafec558fc13dc4b08ca0b07713a2cd84
2015-09-15 13:42:16 +00:00
dan 128ea696ea Fix a problem with fts5 "ORDER BY rowid DESC" queries and large terms.
FossilOrigin-Name: b26d8f79c62cb71b4c3ea5df9d0e09558bbbd794
2015-09-15 11:58:33 +00:00
dan dafeda754b Improve test coverage of fts5_index.c.
FossilOrigin-Name: c1f76686cee3918b1be785a4071d68cb3afda0ef
2015-09-14 19:51:05 +00:00
drh b79d5529af Testability improvements for the ONEPASS_MULTI enhancement.
FossilOrigin-Name: d2df93f26fc0cf6fe01acfeaf2946972e9d8cca2
2015-09-14 19:26:37 +00:00
drh b1ff90673c Fix a typo in an SQLITE_USER_AUTHENTICATION macro.
FossilOrigin-Name: 379455af9fdfb299a857d46f35f0a76ed6daa08a
2015-09-14 14:49:23 +00:00
drh b0264eeca1 Use symbolic names ONEPASS_OFF, ONEPASS_SINGLE, and ONEPASS_MULTI for the
various modes of the one-pass optimization.

FossilOrigin-Name: 16e56bdadef903c6439a487f2683388aeeb0c625
2015-09-14 14:45:50 +00:00
drh 66336f3755 Fix a compiler warning and providing missing VdbeCoverage() calls.
FossilOrigin-Name: 2edd2e5edd60210e18db58bce1e096dd211b6ece
2015-09-14 14:08:25 +00:00
dan e402dc57ae Use a single-pass approach for DELETE statements on non-virtual tables that do not require trigger or foreign key processing.
FossilOrigin-Name: 8b93cc5937000535c35c763c9326507a19892a6e
2015-09-14 11:09:58 +00:00
dan c6157e1971 Avoid calling sqlite3VdbeCursorMoveto() from more than one point in vdbe.c. Doing so prevents it from being inlined as part of OP_Column.
FossilOrigin-Name: 166d5af8914c6954fb24a06e9686f194c0d0acde
2015-09-14 09:23:47 +00:00
mistachkin c215322bd7 Add static VFS mutexes to the primary header file comments.
FossilOrigin-Name: 9a867d9fbe74fe2b33d55e32737a66e9a77b7466
2015-09-13 20:15:01 +00:00
dan 7210b3d1e8 Fix compiler warnings in delete.c.
FossilOrigin-Name: 0a4d285e18b78cd529483ba5c8c607ab62a443d4
2015-09-12 19:50:58 +00:00
drh 2e25a00019 Fix API documentation typos. Emphasize that the sqlite3_config() routine is
not threadsafe.

FossilOrigin-Name: 786333e05a75406bbd0b5c9c7beb8f16022eabec
2015-09-12 19:27:41 +00:00
dan f0ee1d3c12 Experimental change to use a single-pass approach for DELETE statements on non-virtual tables that do not fire triggers or require foriegn-key processing.
FossilOrigin-Name: eaeb2b80f6f8f83679c8323a81bb39570ec946fe
2015-09-12 19:26:11 +00:00
mistachkin 04abf0878f Import common changes from the mutex initialization branch.
FossilOrigin-Name: 334720c01722478af0d3dfd6fe8bafd88ba09f49
2015-09-12 18:57:45 +00:00
drh b3366b99c8 Update evidence marks due to wording changes in requirements text. No
changes to code.

FossilOrigin-Name: 86781093bdb4c4fdedd228cb1c8961db48a483bb
2015-09-11 20:54:44 +00:00
mistachkin 16a93128f8 Fix harmless compiler warnings.
FossilOrigin-Name: bfc7b84b766860d2e410702ba7c1166d7328309a
2015-09-11 18:05:01 +00:00
drh e98b6fab47 More test cases in test/json102.test corresponding to new examples in the
json1 documentation.

FossilOrigin-Name: f599a42e190b4b89d74055402143c5487985cd90
2015-09-11 15:32:33 +00:00
dan bcb04b6128 Fix some compiler warnings in fts5 code.
FossilOrigin-Name: 0dc436116e55e3fd55eb6085ada71e099069b32d
2015-09-11 14:15:46 +00:00
drh 12b3b89542 Updates to the sqlite3_value_subtype() and sqlite3_result_subtype()
documentation and to test cases for json1 dealing with those interfaces.

FossilOrigin-Name: d6cadbe9fefce9a7af6b2d0cb83362f967d7d89a
2015-09-11 01:22:41 +00:00
drh 46f76d6c3c Add new interfaces sqlite3_value_subtype() and sqlite3_result_subtype().
Update the json1.c extension to take advantages of those interfaces to avoid
the goofy '$$' path syntax and to allow nested calls to json_array() and
json_object() that work as expected.

FossilOrigin-Name: db4152aef2253ed2a33e3cad01e0c6758e03f900
2015-09-11 00:26:04 +00:00
drh f5ddb9c214 Take out the goofy '$$' path syntax. Instead, use subtypes to communicate when
a string is JSON.  Add the json() function that validates and minifies the
JSON and sets the appropriate subtype.

FossilOrigin-Name: 8a80d6459e246ec1b38325e1cbd1e862157138b3
2015-09-11 00:06:41 +00:00
drh cf94f17964 Make the sqlite3_value_subtype() and sqlite3_result_subtype() interfaces
available to loadable extensions.

FossilOrigin-Name: c6fca0be11f7414292279e2ea1b004260e6f4bb6
2015-09-10 20:40:21 +00:00
drh bcdf78a61c Experimental implementation of sqlite3_result_subtype() and
sqlite3_value_subtype() interfaces.

FossilOrigin-Name: 7b5be299c617a3d3ed327ed30ef0a66a62c85b1f
2015-09-10 20:34:56 +00:00
drh 0b19c96935 Fix a potential NULL pointer deref in the testing logic of pcache1.
NB: The -DSQLITE_TEST compile-time option is needed to hit the problem.

FossilOrigin-Name: f5580f08538636ffb1367e717a33756288ccddde
2015-09-10 19:22:25 +00:00
dan 33c47f565c Modify the fts5 leaf page format to permit faster seek operations. This is a file-format change. Any existing databases can be upgraded by running the fts5 'rebuild' command.
FossilOrigin-Name: 0c0c4ae971e54efc526eed7bd071c90dfadb95ff
2015-09-10 17:23:37 +00:00
drh 383de6918c Create separate "path" and "root" columns in the json_each() and json_tree()
virtual tables.  "Root" is the 2nd parameter and is fixed.  
"Path" varies as json_tree() walks the hierarchy.

FossilOrigin-Name: 127cce3eb96b819005832997e0a082df9fb96f0b
2015-09-10 17:20:57 +00:00
dan 204debf3a3 Increment the fts5 version value to indicate that the on-disk format has changed.
FossilOrigin-Name: 99de5e3613d557728dd196353516bc7cf64a0e6c
2015-09-10 16:39:38 +00:00
dan 56c8634853 Fix a segfault in fts5 that could occur if the database contents were corrupt.
FossilOrigin-Name: 4931e37da4d2c26d7afc5432f7f0d534b51a85fa
2015-09-10 16:19:01 +00:00
dan 40d45f8960 Merge latest changes from trunk. Including fts5_expr.c fixes.
FossilOrigin-Name: 716e7e747714d6af502f6a87ca8d789bb7ce162a
2015-09-10 15:52:42 +00:00
dan b97efa0ba3 Update description of on-disk format in fts5_index.c.
FossilOrigin-Name: 85aac7b8b6731e2f6880b80cfd62d431ea059799
2015-09-10 15:49:16 +00:00
drh 0c2750889e Make the sqlite3ext.h header file responsive to -DSQLITE_OMIT_LOAD_EXTENSION.
FossilOrigin-Name: 47a46a9fa4a96cdb96a20b6aec802661b1ee4598
2015-09-10 15:24:27 +00:00
drh e6f5278c9a Disable tests for json_each() and json_tree() on builds where
virtual tables are not supported

FossilOrigin-Name: bb8ee3b140a0a8b7c89f5debf22369f204ceef0b
2015-09-10 15:22:35 +00:00
drh b1031f05e0 Fix the --help option on test/releasetest.tcl. Also fix the final error
count so that it includes a count of subtest crashes.

FossilOrigin-Name: 9ecf684dfe0cd7e3b058d208aca7eb600bf1d21b
2015-09-10 15:20:49 +00:00
dan e712acb641 Revert an accidentally committed makefile change.
FossilOrigin-Name: 402704b13f1f246c0224f90862bed93a825575f1
2015-09-10 10:40:00 +00:00
dan f679d97d18 Fix an fts5 problem that could occur if a term and the first associated rowid are on different leaf pages.
FossilOrigin-Name: ffe2796ac9244c62325fce4960f26c653321623c
2015-09-10 10:01:30 +00:00
dan a5aa8e1db2 Change the array of 16-bit offsets at the end of each page to an array of varints.
FossilOrigin-Name: fab245bea4f283714c17bca22428d5eb4db5935a
2015-09-10 05:40:17 +00:00
drh 0e8729dbe4 Attempt to declare sqlite3MemoryBarrier() correctly for all possible
build configurations.

FossilOrigin-Name: da8a288f8ef4be34281519b4b4db9b857b9d168b
2015-09-10 04:17:06 +00:00
drh 852944eb9b Fix the json_tree() scan for the case when a path is supplied. Add new
json1 test cases.

FossilOrigin-Name: 6adc7de76acee6cfb5ff761739e7a8de7b5bf4b2
2015-09-10 03:29:11 +00:00
drh 5fb72e5f3e No-op the sqlite3_memory_alarm() interface in a different way, that does
not break legacy memory behavior.  This is a re-do of
check-in [5d3f5df4da9f40d5].

FossilOrigin-Name: 8250e2a487ee12c9a2dea5603ab60aed51e5dc7b
2015-09-10 01:22:09 +00:00
mistachkin f5eac36a64 Fix harmless compiler warning in FTS5.
FossilOrigin-Name: 86146a731d75eb25279c0e072c0bdda593de905d
2015-09-09 23:54:46 +00:00
dan 5c472d0860 Fix an assert() enabled by SQLITE_ENABLE_EXPENSIVE_ASSERT in wal.c.
FossilOrigin-Name: 8d2ed150a7a15626965cf994ef48c3ab61eca6ec
2015-09-09 19:44:33 +00:00
drh 8820250e8d Fix a possible NULL pointer deref when using SQLITE_ENABLE_MEMORY_MANAGEMENT.
FossilOrigin-Name: 89bfdbfe943adce8e02c84ede014fcfed504c5d3
2015-09-09 19:27:10 +00:00
mistachkin 3f62cb5aad Fix harmless compiler warning.
FossilOrigin-Name: 280fd3a482978b4a488a8b425721e451c2a30745
2015-09-09 17:23:48 +00:00
mistachkin 4b03efb695 Fix harmless compiler warnings in FTS5.
FossilOrigin-Name: 2cdb18778f20baa902e54f218ba26d2bacf0801e
2015-09-09 17:17:22 +00:00
drh 3c03afd3f5 When running a CREATE TABLE AS, make the initial temporary sqlite_master entry
for the new table a real record rather than a NULL, in case the query after 
the AS actually tries to read the sqlite_master table.
Fix for ticket [acd12990885d9276].

FossilOrigin-Name: 4a18d8bd4cc66eb08c6198cdf6e14f1bce0ec05a
2015-09-09 13:28:06 +00:00
dan f06bd2c132 Fix a bug in preprocessor macros within fts5_main.c.
FossilOrigin-Name: 0eb2b9521fad6fa36e6fa374c2bc1f70b5180f7c
2015-09-09 08:15:06 +00:00
drh 0c6dfaa34a Remove an unused local variable from Lemon.
FossilOrigin-Name: fe9ffe5eed7d376f3f08c78c1ce5514c886f3479
2015-09-08 21:16:46 +00:00
drh a46a4a63de Enhance the DBSTAT virtual table with a new hidden table "schema" that if
set will cause the table to report on the specified schema rather than on
"main".  Also:  Fix a faulty assert in sqlite3_context_db_handle().

FossilOrigin-Name: 6beb512c7a3c3649b56f0df1ca77855535a87ba7
2015-09-08 21:12:53 +00:00
drh b4d472f609 Eponymous virtual tables exist in the "main" schema only. Enforce this rule.
FossilOrigin-Name: 06f90bb274c4bb0c30585024c8d365d43c4162f2
2015-09-08 20:26:09 +00:00
dan fe8e2eba0a Remove the 0x00 terminators from the end of doclists stored on disk.
FossilOrigin-Name: 00d990061dec3661b0376bd167082942d5563bfe
2015-09-08 19:55:26 +00:00
drh 310a8d6668 Fix the help message that sqlite3_analyzer.exe generates for invalid
arguments.

FossilOrigin-Name: 33a14e7be1004abca7a30f675459138d7f8d72b1
2015-09-08 17:31:30 +00:00
drh 337cd0def4 Minor tweaks to Lemon.
FossilOrigin-Name: 986677224a8da5e79fbbd90673f1b595da89c5d6
2015-09-07 23:40:42 +00:00
drh 3921d8be5d Enhance the Lemon parser generator to add SHIFTREDUCE states that reduce the
sizes of some of the parser tables.

FossilOrigin-Name: 99b992fa840707711d99f8d05b62412f7008cd93
2015-09-07 20:11:30 +00:00
drh ae2a4084a2 Fix an unreachable branch in the new parse automaton.
FossilOrigin-Name: e9d604b4306a86faae315ac3cba59bf07d1b665c
2015-09-07 20:02:39 +00:00
drh a248a722cf Change the parser engine so that it (once again) waits for a lookahead token
before reducing, even in a SHIFTREDUCE action.

FossilOrigin-Name: 2c17a1358353a0845b039283be79353f033e2491
2015-09-07 19:52:55 +00:00
drh 3bd48ab213 For the Lemon-generated parser, add a new action type SHIFTREDUCE and use it
to further compress the parser tables and improve parser performance.

FossilOrigin-Name: 531c3974b3d586c1989cde905b2fb4681239a570
2015-09-07 18:23:37 +00:00
drh 7e698e9d71 In the "parse.out" output file from Lemon, show addition the complete text
of rules on reduce actions.

FossilOrigin-Name: b6ffb7e471e51ff69668154ad2c8790e466c9d37
2015-09-07 14:22:24 +00:00
dan 60f8139a96 Use macros to make the code in fts5_index.c easier to read.
FossilOrigin-Name: 67ff5ae81357eb7fa28049bb724a22cb6f52e076
2015-09-07 08:14:30 +00:00
drh c75e0166f0 Improved "Parser Statistics" output (the -s option) for the Lemon parser
generator.

FossilOrigin-Name: 809503e4efcdb498d176e8c0794a5ba0882adef2
2015-09-07 02:23:02 +00:00
drh 2d64034bc2 Improved memory barrier that should work with MinGW on older versions of
Windows.

FossilOrigin-Name: 47dc24bd1e8f76eb17ba53a883b8984b3e1b2934
2015-09-06 10:31:37 +00:00
drh 6081c1dbdf Add a memory barrier to the mutex initialization logic, try to work around
an issue reported by WebKit.

FossilOrigin-Name: 11a9a786ec06403addb47f5c6fb142b382fae522
2015-09-06 02:51:04 +00:00
drh 0b8d255c37 Omit all use of Expr nodes for TK_AS, as those nodes no longer served a useful
purpose and in fact interferred with the query planner.

FossilOrigin-Name: 7ab0b258eabfcfb7f1b0bd1b12e166d2f267823d
2015-09-05 22:36:07 +00:00
dan e386a1ba25 Experiment with a different fts5 leaf page format that allows faster seeks.
FossilOrigin-Name: a1f4c3b543eed84e808f6b901a38179786fffe16
2015-09-05 19:52:08 +00:00
drh 28b9e0fc05 Fix an unreachable conditional in the WHERE clause analysis logic.
FossilOrigin-Name: 24924a58197e558a9e8800cc5c91dc8fb32f3557
2015-09-05 19:21:00 +00:00
drh e3a7307e2d Get STAT4 range scan estimates work again when the bounds are determined
by date/time functions.

FossilOrigin-Name: d2761357a0496ec1e590c7c9e397c5b5c904f91a
2015-09-05 19:07:08 +00:00
drh 2547336dad Fix over-length source code lines in Lemon.
FossilOrigin-Name: 1efece95ff8777b89558be59277732ba2a68d5ab
2015-09-04 18:03:45 +00:00
drh 13bf8c498f Add support for CREATE INDEX statements that use deterministic expressions
rather than only column names.

FossilOrigin-Name: 2131a5ca53f0e9b0b98a9dd9a20e495d54d146a7
2015-09-04 17:32:19 +00:00
172 changed files with 8588 additions and 4051 deletions
-138
View File
@@ -1,138 +0,0 @@
#!/usr/make
#
# Makefile for SQLITE
#
# This is a template makefile for SQLite. Most people prefer to
# use the autoconf generated "configure" script to generate the
# makefile automatically. But that does not work for everybody
# and in every situation. If you are having problems with the
# "configure" script, you might want to try this makefile as an
# alternative. Create a copy of this file, edit the parameters
# below and type "make".
#
#### The directory where to find the mingw32ce tools
MINGW32CE = /opt/mingw32ce/bin
#### The target prefix of the mingw32ce tools
TARGET = arm-wince-mingw32ce
#### The toplevel directory of the source tree. This is the directory
# that contains this "Makefile.in" and the "configure.in" script.
#
TOP = ../sqlite
#### C Compiler and options for use in building executables that
# will run on the platform that is doing the build.
#
BCC = gcc -g -O2
#BCC = /opt/ancic/bin/c89 -0
#### If the target operating system supports the "usleep()" system
# call, then define the HAVE_USLEEP macro for all C modules.
#
USLEEP =
#USLEEP = -DHAVE_USLEEP=1
#### If you want the SQLite library to be safe for use within a
# multi-threaded program, then define the following macro
# appropriately:
#
THREADSAFE = -DTHREADSAFE=1
#THREADSAFE = -DTHREADSAFE=0
#### Specify any extra linker options needed to make the library
# thread safe
#
#THREADLIB = -lpthread
THREADLIB =
#### Specify any extra libraries needed to access required functions.
#
#TLIBS = -lrt # fdatasync on Solaris 8
TLIBS =
#### Leave SQLITE_DEBUG undefined for maximum speed. Use SQLITE_DEBUG=1
# to check for memory leaks. Use SQLITE_DEBUG=2 to print a log of all
# malloc()s and free()s in order to track down memory leaks.
#
# SQLite uses some expensive assert() statements in the inner loop.
# You can make the library go almost twice as fast if you compile
# with -DNDEBUG=1
#
#OPTS = -DSQLITE_DEBUG=2
#OPTS = -DSQLITE_DEBUG=1
#OPTS =
OPTS = -DNDEBUG=1 -DSQLITE_OS_WIN=1 -D_WIN32_WCE=1
#OPTS += -DHAVE_FDATASYNC=1
#### The suffix to add to executable files. ".exe" for windows.
# Nothing for unix.
#
EXE = .exe
#EXE =
#### C Compile and options for use in building executables that
# will run on the target platform. This is usually the same
# as BCC, unless you are cross-compiling.
#
#TCC = gcc -O6
#TCC = gcc -g -O0 -Wall
#TCC = gcc -g -O0 -Wall -fprofile-arcs -ftest-coverage
#TCC = /opt/mingw/bin/i386-mingw32-gcc -O6
TCC = $(MINGW32CE)/$(TARGET)-gcc -O2
#TCC = /opt/ansic/bin/c89 -O +z -Wl,-a,archive
#### Tools used to build a static library.
#
#AR = ar cr
#AR = /opt/mingw/bin/i386-mingw32-ar cr
AR = $(MINGW32CE)/$(TARGET)-ar cr
#RANLIB = ranlib
#RANLIB = /opt/mingw/bin/i386-mingw32-ranlib
RANLIB = $(MINGW32CE)/$(TARGET)-ranlib
#MKSHLIB = gcc -shared
#SO = so
#SHPREFIX = lib
MKSHLIB = $(MINGW32CE)/$(TARGET)-gcc -shared
SO = dll
SHPREFIX =
#### Extra compiler options needed for programs that use the TCL library.
#
#TCL_FLAGS =
#TCL_FLAGS = -DSTATIC_BUILD=1
TCL_FLAGS = -I/home/drh/tcltk/8.5linux
#TCL_FLAGS = -I/home/drh/tcltk/8.5win -DSTATIC_BUILD=1
#TCL_FLAGS = -I/home/drh/tcltk/8.3hpux
#### Linker options needed to link against the TCL library.
#
#LIBTCL = -ltcl -lm -ldl
LIBTCL = /home/drh/tcltk/8.5linux/libtcl8.5g.a -lm -ldl
#LIBTCL = /home/drh/tcltk/8.5win/libtcl85s.a -lmsvcrt
#LIBTCL = /home/drh/tcltk/8.3hpux/libtcl8.3.a -ldld -lm -lc
#### Additional objects for SQLite library when TCL support is enabled.
TCLOBJ =
#TCLOBJ = tclsqlite.o
#### Compiler options needed for programs that use the readline() library.
#
READLINE_FLAGS =
#READLINE_FLAGS = -DHAVE_READLINE=1 -I/usr/include/readline
#### Linker options needed by programs using readline() must link against.
#
LIBREADLINE =
#LIBREADLINE = -static -lreadline -ltermcap
#### Which "awk" program provides nawk compatibilty
#
# NAWK = nawk
NAWK = awk
# You should not have to change anything below this line
###############################################################################
include $(TOP)/main.mk
+35 -21
View File
@@ -65,7 +65,7 @@ TCC += -DSQLITE_THREADSAFE=@SQLITE_THREADSAFE@
# Any target libraries which libsqlite must be linked against
#
TLIBS = @LIBS@
TLIBS = @LIBS@ $(LIBS)
# Flags controlling use of the in memory btree implementation
#
@@ -155,9 +155,6 @@ LTCOMPILE = $(LIBTOOL) --mode=compile --tag=CC $(TCC) $(LTCOMPILE_EXTRAS)
LTLINK = $(LIBTOOL) --mode=link $(TCC) $(LTCOMPILE_EXTRAS) @LDFLAGS@ $(LTLINK_EXTRAS)
LTINSTALL = $(LIBTOOL) --mode=install $(INSTALL)
# nawk compatible awk.
NAWK = @AWK@
# You should not have to change anything below this line
###############################################################################
@@ -175,7 +172,7 @@ LIBOBJS0 = alter.lo analyze.lo attach.lo auth.lo \
fts3_unicode.lo fts3_unicode2.lo fts3_write.lo \
fts5.lo \
func.lo global.lo hash.lo \
icu.lo insert.lo journal.lo legacy.lo loadext.lo \
icu.lo insert.lo journal.lo json1.lo legacy.lo loadext.lo \
main.lo malloc.lo mem0.lo mem1.lo mem2.lo mem3.lo mem5.lo \
memjournal.lo \
mutex.lo mutex_noop.lo mutex_unix.lo mutex_w32.lo \
@@ -272,8 +269,8 @@ SRC = \
$(TOP)/src/sqliteInt.h \
$(TOP)/src/sqliteLimit.h \
$(TOP)/src/table.c \
$(TOP)/src/threads.c \
$(TOP)/src/tclsqlite.c \
$(TOP)/src/threads.c \
$(TOP)/src/tokenize.c \
$(TOP)/src/treeview.c \
$(TOP)/src/trigger.c \
@@ -347,6 +344,9 @@ SRC += \
SRC += \
$(TOP)/ext/rbu/sqlite3rbu.h \
$(TOP)/ext/rbu/sqlite3rbu.c
SRC += \
$(TOP)/ext/misc/json1.c
# Generated source code files
@@ -417,7 +417,6 @@ TESTSRC += \
$(TOP)/ext/fts5/fts5_tcl.c \
$(TOP)/ext/fts5/fts5_test_mi.c \
$(TOP)/ext/misc/ieee754.c \
$(TOP)/ext/misc/json1.c \
$(TOP)/ext/misc/nextchar.c \
$(TOP)/ext/misc/percentile.c \
$(TOP)/ext/misc/regexp.c \
@@ -538,12 +537,19 @@ TESTPROGS = \
FUZZDATA = \
$(TOP)/test/fuzzdata1.db \
$(TOP)/test/fuzzdata2.db \
$(TOP)/test/fuzzdata3.db
$(TOP)/test/fuzzdata3.db \
$(TOP)/test/fuzzdata4.db
# Standard options to testfixture
#
TESTOPTS = --verbose=file --output=test-out.txt
# Extra compiler options for various shell tools
#
SHELL_OPT = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_FTS5
FUZZERSHELL_OPT = -DSQLITE_ENABLE_JSON1
FUZZCHECK_OPT = -DSQLITE_ENABLE_JSON1
# This is the default Makefile target. The objects listed here
# are what get build when you type just "make" with no arguments.
#
@@ -566,19 +572,20 @@ libtclsqlite3.la: tclsqlite.lo libsqlite3.la
-version-info "8:6:8" \
-avoid-version
sqlite3$(TEXE): $(TOP)/src/shell.c libsqlite3.la sqlite3.h $(TOP)/ext/misc/json1.c
$(LTLINK) $(READLINE_FLAGS) -DSQLITE_ENABLE_JSON1 -o $@ \
$(TOP)/src/shell.c $(TOP)/ext/misc/json1.c libsqlite3.la \
sqlite3$(TEXE): $(TOP)/src/shell.c libsqlite3.la sqlite3.h
$(LTLINK) $(READLINE_FLAGS) $(SHELL_OPT) -o $@ \
$(TOP)/src/shell.c libsqlite3.la \
$(LIBREADLINE) $(TLIBS) -rpath "$(libdir)"
sqldiff$(TEXE): $(TOP)/tool/sqldiff.c sqlite3.c sqlite3.h
$(LTLINK) -o $@ $(TOP)/tool/sqldiff.c sqlite3.c $(TLIBS)
fuzzershell$(TEXE): $(TOP)/tool/fuzzershell.c sqlite3.c sqlite3.h
$(LTLINK) -o $@ $(TOP)/tool/fuzzershell.c sqlite3.c $(TLIBS)
$(LTLINK) -o $@ $(FUZZERSHELL_OPT) \
$(TOP)/tool/fuzzershell.c sqlite3.c $(TLIBS)
fuzzcheck$(TEXE): $(TOP)/test/fuzzcheck.c sqlite3.c sqlite3.h
$(LTLINK) -o $@ $(TOP)/test/fuzzcheck.c sqlite3.c $(TLIBS)
$(LTLINK) -o $@ $(FUZZCHECK_OPT) $(TOP)/test/fuzzcheck.c sqlite3.c $(TLIBS)
mptester$(TEXE): sqlite3.c $(TOP)/mptest/mptest.c
$(LTLINK) -o $@ -I. $(TOP)/mptest/mptest.c sqlite3.c \
@@ -604,19 +611,23 @@ mptest: mptester$(TEXE)
# files are automatically generated. This target takes care of
# all that automatic generation.
#
.target_source: $(SRC) $(TOP)/tool/vdbe-compress.tcl
.target_source: $(SRC) $(TOP)/tool/vdbe-compress.tcl fts5.c
rm -rf tsrc
mkdir tsrc
cp -f $(SRC) tsrc
rm tsrc/sqlite.h.in tsrc/parse.y
$(TCLSH_CMD) $(TOP)/tool/vdbe-compress.tcl $(OPTS) <tsrc/vdbe.c >vdbe.new
mv vdbe.new tsrc/vdbe.c
cp fts5.c fts5.h tsrc
touch .target_source
sqlite3.c: .target_source $(TOP)/tool/mksqlite3c.tcl
$(TCLSH_CMD) $(TOP)/tool/mksqlite3c.tcl
cp tsrc/shell.c tsrc/sqlite3ext.h .
sqlite3ext.h: .target_source
cp tsrc/sqlite3ext.h .
tclsqlite3.c: sqlite3.c
echo '#ifndef USE_SYSTEM_SQLITE' >tclsqlite3.c
cat sqlite3.c >>tclsqlite3.c
@@ -888,22 +899,22 @@ tclsqlite3$(TEXE): tclsqlite-shell.lo libsqlite3.la
# Rules to build opcodes.c and opcodes.h
#
opcodes.c: opcodes.h $(TOP)/mkopcodec.awk
$(NAWK) -f $(TOP)/mkopcodec.awk opcodes.h >opcodes.c
opcodes.c: opcodes.h $(TOP)/tool/mkopcodec.tcl
$(TCLSH_CMD) $(TOP)/tool/mkopcodec.tcl opcodes.h >opcodes.c
opcodes.h: parse.h $(TOP)/src/vdbe.c $(TOP)/mkopcodeh.awk
cat parse.h $(TOP)/src/vdbe.c | $(NAWK) -f $(TOP)/mkopcodeh.awk >opcodes.h
opcodes.h: parse.h $(TOP)/src/vdbe.c $(TOP)/tool/mkopcodeh.tcl
cat parse.h $(TOP)/src/vdbe.c | $(TCLSH_CMD) $(TOP)/tool/mkopcodeh.tcl >opcodes.h
# Rules to build parse.c and parse.h - the outputs of lemon.
#
parse.h: parse.c
parse.c: $(TOP)/src/parse.y lemon$(BEXE) $(TOP)/addopcodes.awk
parse.c: $(TOP)/src/parse.y lemon$(BEXE) $(TOP)/tool/addopcodes.tcl
cp $(TOP)/src/parse.y .
rm -f parse.h
./lemon$(BEXE) $(OPT_FEATURE_FLAGS) $(OPTS) parse.y
mv parse.h parse.h.temp
$(NAWK) -f $(TOP)/addopcodes.awk parse.h.temp >parse.h
$(TCLSH_CMD) $(TOP)/tool/addopcodes.tcl parse.h.temp >parse.h
sqlite3.h: $(TOP)/src/sqlite.h.in $(TOP)/manifest.uuid $(TOP)/VERSION
$(TCLSH_CMD) $(TOP)/tool/mksqlite3h.tcl $(TOP) >sqlite3.h
@@ -979,6 +990,9 @@ 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
json1.lo: $(TOP)/ext/misc/json1.c
$(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/misc/json1.c
# FTS5 things
#
FTS5_SRC = \
@@ -1085,7 +1099,7 @@ sqlite3_analyzer.c: sqlite3.c $(TOP)/src/tclsqlite.c $(TOP)/tool/spaceanal.tcl
cat sqlite3.c $(TOP)/src/tclsqlite.c >> $@
echo "static const char *tclsh_main_loop(void){" >> $@
echo "static const char *zMainloop = " >> $@
$(NAWK) -f $(TOP)/tool/tostr.awk $(TOP)/tool/spaceanal.tcl >> $@
$(TCLSH_CMD) $(TOP)/tool/tostr.tcl $(TOP)/tool/spaceanal.tcl >> $@
echo "; return zMainloop; }" >> $@
sqlite3_analyzer$(TEXE): sqlite3_analyzer.c
-5
View File
@@ -118,11 +118,6 @@ READLINE_FLAGS =
LIBREADLINE =
#LIBREADLINE = -static -lreadline -ltermcap
#### Which "awk" program provides nawk compatibilty
#
# NAWK = nawk
NAWK = awk
# You should not have to change anything below this line
###############################################################################
include $(TOP)/main.mk
+75 -50
View File
@@ -292,9 +292,9 @@ NSDKLIBPATH = $(NSDKLIBPATH:\\=\)
# will run on the platform that is doing the build.
#
!IF $(USE_FULLWARN)!=0
BCC = $(NCC) -nologo -W4
BCC = $(NCC) -nologo -W4 $(CCOPTS) $(BCCOPTS)
!ELSE
BCC = $(NCC) -nologo -W3
BCC = $(NCC) -nologo -W3 $(CCOPTS) $(BCCOPTS)
!ENDIF
# Check if assembly code listings should be generated for the source
@@ -322,13 +322,13 @@ NLTLIBPATHS = $(NLTLIBPATHS) "/LIBPATH:$(NUCRTLIBPATH)"
# same unless your are cross-compiling.)
#
!IF $(USE_FULLWARN)!=0
TCC = $(CC) -nologo -W4 -DINCLUDE_MSVC_H=1
TCC = $(CC) -nologo -W4 -DINCLUDE_MSVC_H=1 $(CCOPTS) $(TCCOPTS)
!ELSE
TCC = $(CC) -nologo -W3
TCC = $(CC) -nologo -W3 $(CCOPTS) $(TCCOPTS)
!ENDIF
TCC = $(TCC) -DSQLITE_OS_WIN=1 -I. -I$(TOP) -I$(TOP)\src -fp:precise
RCC = $(RC) -DSQLITE_OS_WIN=1 -I$(TOP) -I$(TOP)\src
RCC = $(RC) -DSQLITE_OS_WIN=1 -I$(TOP) -I$(TOP)\src $(RCOPTS) $(RCCOPTS)
# Check if we want to use the "stdcall" calling convention when compiling.
# This is not supported by the compilers for non-x86 platforms. It should
@@ -390,9 +390,9 @@ CORE_LINK_OPTS = /DEF:sqlite3.def
#
!IFNDEF SHELL_COMPILE_OPTS
!IF $(DYNAMIC_SHELL)!=0
SHELL_COMPILE_OPTS = -DSQLITE_ENABLE_JSON1 $(SHELL_CCONV_OPTS) -DSQLITE_API=__declspec(dllimport)
SHELL_COMPILE_OPTS = -DSQLITE_SHELL_JSON1 $(SHELL_CCONV_OPTS) -DSQLITE_API=__declspec(dllimport)
!ELSE
SHELL_COMPILE_OPTS = -DSQLITE_ENABLE_JSON1 $(SHELL_CCONV_OPTS)
SHELL_COMPILE_OPTS = -DSQLITE_SHELL_JSON1 $(SHELL_CCONV_OPTS)
!ENDIF
!ENDIF
@@ -569,6 +569,14 @@ TCLLIBDIR = c:\tcl\lib
LIBTCL = tcl85.lib
!ENDIF
!IFNDEF LIBTCLSTUB
LIBTCLSTUB = tclstub85.lib
!ENDIF
!IFNDEF LIBTCLPATH
LIBTCLPATH = c:\tcl\bin
!ENDIF
# The locations of the ICU header and library files. These variables
# (ICUINCDIR, ICULIBDIR, and LIBICU) may be overridden via the environment
# prior to running nmake in order to match the actual installed location on
@@ -792,7 +800,9 @@ LTLINKOPTS = $(LTLINKOPTS) "/LIBPATH:$(PSDKLIBPATH)"
# If either debugging or symbols are enabled, enable PDBs.
#
!IF $(DEBUG)>1 || $(SYMBOLS)!=0
LDFLAGS = /DEBUG
LDFLAGS = /DEBUG $(LDOPTS)
!ELSE
LDFLAGS = $(LDOPTS)
!ENDIF
# Start with the Tcl related linker options.
@@ -809,12 +819,6 @@ LTLIBPATHS = $(LTLIBPATHS) /LIBPATH:$(ICULIBDIR)
LTLIBS = $(LTLIBS) $(LIBICU)
!ENDIF
# nawk compatible awk.
#
!IFNDEF NAWK
NAWK = gawk.exe
!ENDIF
# You should not have to change anything below this line
###############################################################################
@@ -1008,7 +1012,8 @@ SRC4 = \
$(TOP)\ext\rtree\rtree.h \
$(TOP)\ext\rtree\rtree.c \
$(TOP)\ext\rbu\sqlite3rbu.h \
$(TOP)\ext\rbu\sqlite3rbu.c
$(TOP)\ext\rbu\sqlite3rbu.c \
$(TOP)\ext\misc\json1.c
# Generated source code files
@@ -1207,7 +1212,14 @@ TESTPROGS = \
FUZZDATA = \
$(TOP)\test\fuzzdata1.db \
$(TOP)\test\fuzzdata2.db \
$(TOP)\test\fuzzdata3.db
$(TOP)\test\fuzzdata3.db \
$(TOP)\test\fuzzdata4.db
# Extra compiler options for various shell tools
#
SHELL_COMPILE_OPTS = -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_FTS5
FUZZERSHELL_COMPILE_OPTS = -DSQLITE_ENABLE_JSON1
FUZZCHECK_COMPILE_OPTS = -DSQLITE_ENABLE_JSON1
# Standard options to testfixture
#
@@ -1222,24 +1234,25 @@ libsqlite3.lib: $(LIBOBJ)
$(LTLIB) $(LTLIBOPTS) /OUT:$@ $(LIBOBJ) $(TLIBS)
libtclsqlite3.lib: tclsqlite.lo libsqlite3.lib
$(LTLIB) $(LTLIBOPTS) $(LTLIBPATHS) /OUT:$@ tclsqlite.lo libsqlite3.lib $(LIBTCL:tcl=tclstub) $(TLIBS)
$(LTLIB) $(LTLIBOPTS) $(LTLIBPATHS) /OUT:$@ tclsqlite.lo libsqlite3.lib $(LIBTCLSTUB) $(TLIBS)
sqlite3.exe: $(TOP)\src\shell.c $(TOP)\ext\misc\json1.c $(SHELL_CORE_DEP) $(LIBRESOBJS) sqlite3.h
$(LTLINK) $(SHELL_COMPILE_OPTS) $(READLINE_FLAGS) $(TOP)\src\shell.c $(TOP)\ext\misc\json1.c \
/link /pdb:sqlite3sh.pdb $(LTLINKOPTS) $(SHELL_LINK_OPTS) $(LTLIBPATHS) $(LIBRESOBJS) $(LIBREADLINE) $(LTLIBS) $(TLIBS)
sqlite3.exe: $(TOP)\src\shell.c $(SHELL_CORE_DEP) $(LIBRESOBJS) sqlite3.h
$(LTLINK) $(SHELL_COMPILE_OPTS) $(SHELL_COMPILE_OPTS) $(READLINE_FLAGS) $(TOP)\src\shell.c \
/link /pdb:sqlite3sh.pdb $(LDFLAGS) $(LTLINKOPTS) $(SHELL_LINK_OPTS) $(LTLIBPATHS) $(LIBRESOBJS) $(LIBREADLINE) $(LTLIBS) $(TLIBS)
sqldiff.exe: $(TOP)\tool\sqldiff.c sqlite3.c sqlite3.h
$(LTLINK) $(NO_WARN) $(TOP)\tool\sqldiff.c sqlite3.c
$(LTLINK) $(NO_WARN) $(TOP)\tool\sqldiff.c sqlite3.c /link $(LDFLAGS) $(LTLINKOPTS)
fuzzershell.exe: $(TOP)\tool\fuzzershell.c sqlite3.c sqlite3.h
$(LTLINK) $(NO_WARN) $(TOP)\tool\fuzzershell.c sqlite3.c
$(LTLINK) $(NO_WARN) $(FUZZERSHELL_COMPILE_OPTS) \
$(TOP)\tool\fuzzershell.c sqlite3.c /link $(LDFLAGS) $(LTLINKOPTS)
fuzzcheck.exe: $(TOP)\test\fuzzcheck.c sqlite3.c sqlite3.h
$(LTLINK) $(NO_WARN) $(TOP)\test\fuzzcheck.c sqlite3.c
$(LTLINK) $(NO_WARN) $(FUZZCHECK_COMPILE_OPTS) $(TOP)\test\fuzzcheck.c sqlite3.c /link $(LDFLAGS) $(LTLINKOPTS)
mptester.exe: $(TOP)\mptest\mptest.c $(SHELL_CORE_DEP) $(LIBRESOBJS) sqlite3.h
$(LTLINK) $(NO_WARN) $(SHELL_COMPILE_OPTS) $(TOP)\mptest\mptest.c \
/link $(LTLINKOPTS) $(LTLIBPATHS) $(SHELL_LINK_OPTS) $(LIBRESOBJS) $(LIBREADLINE) $(LTLIBS) $(TLIBS)
/link $(LDFLAGS) $(LTLINKOPTS) $(LTLIBPATHS) $(SHELL_LINK_OPTS) $(LIBRESOBJS) $(LIBREADLINE) $(LTLIBS) $(TLIBS)
MPTEST1 = mptester mptest.db $(TOP)\mptest\crash01.test --repeat 20
MPTEST2 = mptester mptest.db $(TOP)\mptest\multiwrite01.test --repeat 20
@@ -1261,7 +1274,7 @@ mptest: mptester.exe
# files are automatically generated. This target takes care of
# all that automatic generation.
#
.target_source: $(SRC) $(TOP)\tool\vdbe-compress.tcl
.target_source: $(SRC) $(TOP)\tool\vdbe-compress.tcl fts5.c
-rmdir /Q/S tsrc 2>NUL
-mkdir tsrc
for %i in ($(SRC1)) do copy /Y %i tsrc
@@ -1269,15 +1282,16 @@ mptest: mptester.exe
for %i in ($(SRC3)) do copy /Y %i tsrc
for %i in ($(SRC4)) do copy /Y %i tsrc
for %i in ($(SRC5)) do copy /Y %i tsrc
copy /Y fts5.c tsrc
copy /Y fts5.h tsrc
del /Q tsrc\sqlite.h.in tsrc\parse.y 2>NUL
$(TCLSH_CMD) $(TOP)\tool\vdbe-compress.tcl $(OPTS) < tsrc\vdbe.c > vdbe.new
move vdbe.new tsrc\vdbe.c
echo > .target_source
sqlite3.c: .target_source $(TOP)\tool\mksqlite3c.tcl
sqlite3.c: .target_source sqlite3ext.h $(TOP)\tool\mksqlite3c.tcl
$(TCLSH_CMD) $(TOP)\tool\mksqlite3c.tcl $(MKSQLITE3C_ARGS)
copy tsrc\shell.c .
copy tsrc\sqlite3ext.h .
sqlite3-all.c: sqlite3.c $(TOP)\tool\split-sqlite3c.tcl
$(TCLSH_CMD) $(TOP)\tool\split-sqlite3c.tcl
@@ -1303,7 +1317,7 @@ lempar.c: $(TOP)\src\lempar.c
lemon.exe: $(TOP)\tool\lemon.c lempar.c
$(BCC) $(NO_WARN) -Daccess=_access \
-Fe$@ $(TOP)\tool\lemon.c /link $(NLTLINKOPTS) $(NLTLIBPATHS)
-Fe$@ $(TOP)\tool\lemon.c /link $(LDFLAGS) $(NLTLINKOPTS) $(NLTLIBPATHS)
# Rules to build individual *.lo files from generated *.c files. This
# applies to:
@@ -1324,7 +1338,7 @@ $(LIBRESOBJS): $(TOP)\src\sqlite3.rc $(HDR)
echo #ifndef SQLITE_RESOURCE_VERSION > sqlite3rc.h
for /F %%V in ('type "$(TOP)\VERSION"') do ( \
echo #define SQLITE_RESOURCE_VERSION %%V \
| $(NAWK) "/.*/ { gsub(/[.]/,\",\");print }" >> sqlite3rc.h \
| $(TCLSH_CMD) $(TOP)\tool\replace.tcl exact . ^, >> sqlite3rc.h \
)
echo #endif >> sqlite3rc.h
$(LTRCOMPILE) -fo $(LIBRESOBJS) $(TOP)\src\sqlite3.rc
@@ -1561,33 +1575,36 @@ tclsqlite-shell.lo: $(TOP)\src\tclsqlite.c $(HDR)
$(LTCOMPILE) $(NO_WARN) -DTCLSH=1 -DBUILD_sqlite -I$(TCLINCDIR) -c $(TOP)\src\tclsqlite.c
tclsqlite3.exe: tclsqlite-shell.lo $(SQLITE3C) $(LIBRESOBJS)
$(LTLINK) $(SQLITE3C) /link $(LTLINKOPTS) $(LTLIBPATHS) /OUT:$@ tclsqlite-shell.lo $(LIBRESOBJS) $(LTLIBS) $(TLIBS)
$(LTLINK) $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS) $(LTLIBPATHS) /OUT:$@ tclsqlite-shell.lo $(LIBRESOBJS) $(LTLIBS) $(TLIBS)
# Rules to build opcodes.c and opcodes.h
#
opcodes.c: opcodes.h $(TOP)\mkopcodec.awk
$(NAWK) -f $(TOP)\mkopcodec.awk opcodes.h > opcodes.c
opcodes.c: opcodes.h $(TOP)\tool\mkopcodec.tcl
$(TCLSH_CMD) $(TOP)\tool\mkopcodec.tcl opcodes.h > opcodes.c
opcodes.h: parse.h $(TOP)\src\vdbe.c $(TOP)\mkopcodeh.awk
type parse.h $(TOP)\src\vdbe.c | $(NAWK) -f $(TOP)\mkopcodeh.awk > opcodes.h
opcodes.h: parse.h $(TOP)\src\vdbe.c $(TOP)\tool\mkopcodeh.tcl
type parse.h $(TOP)\src\vdbe.c | $(TCLSH_CMD) $(TOP)\tool\mkopcodeh.tcl > opcodes.h
# Rules to build parse.c and parse.h - the outputs of lemon.
#
parse.h: parse.c
parse.c: $(TOP)\src\parse.y lemon.exe $(TOP)\addopcodes.awk
parse.c: $(TOP)\src\parse.y lemon.exe $(TOP)\tool\addopcodes.tcl
del /Q parse.y parse.h parse.h.temp 2>NUL
copy $(TOP)\src\parse.y .
.\lemon.exe $(REQ_FEATURE_FLAGS) $(OPT_FEATURE_FLAGS) $(OPTS) parse.y
move parse.h parse.h.temp
$(NAWK) -f $(TOP)\addopcodes.awk parse.h.temp > parse.h
$(TCLSH_CMD) $(TOP)\tool\addopcodes.tcl parse.h.temp > parse.h
sqlite3.h: $(TOP)\src\sqlite.h.in $(TOP)\manifest.uuid $(TOP)\VERSION
$(TCLSH_CMD) $(TOP)\tool\mksqlite3h.tcl $(TOP:\=/) > sqlite3.h
sqlite3ext.h: .target_source
copy tsrc\sqlite3ext.h .
mkkeywordhash.exe: $(TOP)\tool\mkkeywordhash.c
$(BCC) $(NO_WARN) -Fe$@ $(REQ_FEATURE_FLAGS) $(OPT_FEATURE_FLAGS) $(OPTS) \
$(TOP)\tool\mkkeywordhash.c /link $(NLTLINKOPTS) $(NLTLIBPATHS)
$(TOP)\tool\mkkeywordhash.c /link $(LDFLAGS) $(NLTLINKOPTS) $(NLTLIBPATHS)
keywordhash.h: $(TOP)\tool\mkkeywordhash.c mkkeywordhash.exe
.\mkkeywordhash.exe > keywordhash.h
@@ -1721,21 +1738,26 @@ testfixture.exe: $(TESTFIXTURE_SRC) $(LIBRESOBJS) $(HDR)
$(LTLINK) -DSQLITE_NO_SYNC=1 $(TESTFIXTURE_FLAGS) \
-DBUILD_sqlite -I$(TCLINCDIR) \
$(TESTFIXTURE_SRC) \
/link $(LTLINKOPTS) $(LTLIBPATHS) $(LIBRESOBJS) $(LTLIBS) $(TLIBS)
/link $(LDFLAGS) $(LTLINKOPTS) $(LTLIBPATHS) $(LIBRESOBJS) $(LTLIBS) $(TLIBS)
extensiontest: testfixture.exe testloadext.dll
@set PATH=$(LIBTCLPATH);$(PATH)
.\testfixture.exe $(TOP)\test\loadext.test $(TESTOPTS)
fulltest: $(TESTPROGS) fuzztest
@set PATH=$(LIBTCLPATH);$(PATH)
.\testfixture.exe $(TOP)\test\all.test $(TESTOPTS)
soaktest: $(TESTPROGS)
@set PATH=$(LIBTCLPATH);$(PATH)
.\testfixture.exe $(TOP)\test\all.test -soak=1 $(TESTOPTS)
fulltestonly: $(TESTPROGS) fuzztest
@set PATH=$(LIBTCLPATH);$(PATH)
.\testfixture.exe $(TOP)\test\full.test
queryplantest: testfixture.exe sqlite3.exe
@set PATH=$(LIBTCLPATH);$(PATH)
.\testfixture.exe $(TOP)\test\permutations.test queryplanner $(TESTOPTS)
fuzztest: fuzzcheck.exe
@@ -1747,15 +1769,18 @@ fastfuzztest: fuzzcheck.exe
# Minimal testing that runs in less than 3 minutes (on a fast machine)
#
quicktest: testfixture.exe
@set PATH=$(LIBTCLPATH);$(PATH)
.\testfixture.exe $(TOP)\test\extraquick.test $(TESTOPTS)
# This is the common case. Run many tests that do not take too long,
# including fuzzcheck, sqlite3_analyzer, and sqldiff tests.
#
test: $(TESTPROGS) fastfuzztest
@set PATH=$(LIBTCLPATH);$(PATH)
.\testfixture.exe $(TOP)\test\veryquick.test $(TESTOPTS)
smoketest: $(TESTPROGS)
@set PATH=$(LIBTCLPATH);$(PATH)
.\testfixture.exe $(TOP)\test\main.test $(TESTOPTS)
sqlite3_analyzer.c: $(SQLITE3C) $(TOP)\src\tclsqlite.c $(TOP)\tool\spaceanal.tcl
@@ -1764,12 +1789,12 @@ sqlite3_analyzer.c: $(SQLITE3C) $(TOP)\src\tclsqlite.c $(TOP)\tool\spaceanal.tcl
copy $@ + $(SQLITE3C) + $(TOP)\src\tclsqlite.c $@
echo static const char *tclsh_main_loop(void){ >> $@
echo static const char *zMainloop = >> $@
$(NAWK) -f $(TOP)\tool\tostr.awk $(TOP)\tool\spaceanal.tcl >> $@
$(TCLSH_CMD) $(TOP)\tool\tostr.tcl $(TOP)\tool\spaceanal.tcl >> $@
echo ; return zMainloop; } >> $@
sqlite3_analyzer.exe: sqlite3_analyzer.c $(LIBRESOBJS)
$(LTLINK) $(NO_WARN) -DBUILD_sqlite -I$(TCLINCDIR) sqlite3_analyzer.c \
/link $(LTLINKOPTS) $(LTLIBPATHS) $(LIBRESOBJS) $(LTLIBS) $(TLIBS)
/link $(LDFLAGS) $(LTLINKOPTS) $(LTLIBPATHS) $(LIBRESOBJS) $(LTLIBS) $(TLIBS)
testloadext.lo: $(TOP)\src\test_loadext.c
$(LTCOMPILE) $(NO_WARN) -c $(TOP)\src\test_loadext.c
@@ -1779,38 +1804,38 @@ testloadext.dll: testloadext.lo
showdb.exe: $(TOP)\tool\showdb.c $(SQLITE3C)
$(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -Fe$@ \
$(TOP)\tool\showdb.c $(SQLITE3C)
$(TOP)\tool\showdb.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
showstat4.exe: $(TOP)\tool\showstat4.c $(SQLITE3C)
$(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -Fe$@ \
$(TOP)\tool\showstat4.c $(SQLITE3C)
$(TOP)\tool\showstat4.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
showjournal.exe: $(TOP)\tool\showjournal.c $(SQLITE3C)
$(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -Fe$@ \
$(TOP)\tool\showjournal.c $(SQLITE3C)
$(TOP)\tool\showjournal.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
showwal.exe: $(TOP)\tool\showwal.c $(SQLITE3C)
$(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -Fe$@ \
$(TOP)\tool\showwal.c $(SQLITE3C)
$(TOP)\tool\showwal.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
fts3view.exe: $(TOP)\ext\fts3\tool\fts3view.c $(SQLITE3C)
$(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -Fe$@ \
$(TOP)\ext\fts3\tool\fts3view.c $(SQLITE3C)
$(TOP)\ext\fts3\tool\fts3view.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
rollback-test.exe: $(TOP)\tool\rollback-test.c $(SQLITE3C)
$(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -Fe$@ \
$(TOP)\tool\rollback-test.c $(SQLITE3C)
$(TOP)\tool\rollback-test.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
LogEst.exe: $(TOP)\tool\logest.c sqlite3.h
$(LTLINK) $(NO_WARN) -Fe$@ $(TOP)\tool\LogEst.c
$(LTLINK) $(NO_WARN) -Fe$@ $(TOP)\tool\LogEst.c /link $(LDFLAGS) $(LTLINKOPTS)
wordcount.exe: $(TOP)\test\wordcount.c $(SQLITE3C)
$(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -Fe$@ \
$(TOP)\test\wordcount.c $(SQLITE3C)
$(TOP)\test\wordcount.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
speedtest1.exe: $(TOP)\test\speedtest1.c $(SQLITE3C)
$(LTLINK) $(NO_WARN) -DSQLITE_OMIT_LOAD_EXTENSION -Fe$@ \
$(TOP)\test\speedtest1.c $(SQLITE3C)
$(TOP)\test\speedtest1.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
clean:
del /Q *.exp *.lo *.ilk *.lib *.obj *.ncb *.pdb *.sdf *.suo 2>NUL
@@ -1848,7 +1873,7 @@ dll: sqlite3.dll
sqlite3.def: libsqlite3.lib
echo EXPORTS > sqlite3.def
dumpbin /all libsqlite3.lib \
| $(NAWK) "/ 1 _?sqlite3_/ { sub(/^.* _?/,\"\");print }" \
| $(TCLSH_CMD) $(TOP)\tool\replace.tcl include "^\s+1 _?(sqlite3_.*)$$" \1 \
| sort >> sqlite3.def
sqlite3.dll: $(LIBOBJ) $(LIBRESOBJS) $(CORE_LINK_DEP)
-673
View File
@@ -1,673 +0,0 @@
#!/usr/make
#
# Makefile for SQLITE on VxWorks
ifeq ($(FORCPU),)
FORCPU = SH32gnule
endif
TOOL_FAMILY = gnu
include $(WIND_USR)/tool/gnu/make.$(FORCPU)
#### The toplevel directory of the source tree. This is the directory
# that contains this "Makefile.in" and the "configure.in" script.
#
TOP = .
#### C Compiler and options for use in building executables that
# will run on the platform that is doing the build.
#
BCC = gcc -g -O2
#BCC = /opt/ancic/bin/c89 -0
#### If the target operating system supports the "usleep()" system
# call, then define the HAVE_USLEEP macro for all C modules.
#
USLEEP =
#USLEEP = -DHAVE_USLEEP=1
#### If you want the SQLite library to be safe for use within a
# multi-threaded program, then define the following macro
# appropriately:
#
THREADSAFE = -DSQLITE_THREADSAFE=1
#THREADSAFE = -DSQLITE_THREADSAFE=0
#### Specify any extra linker options needed to make the library
# thread safe
#
#THREADLIB = -lpthread
THREADLIB =
#### Specify any extra libraries needed to access required functions.
#
ifeq ($(CPU),SH32)
# for SH4 shared library
TLIBS_SHARED += -L$(WIND_USR)/lib/sh/SH32/commonle/PIC
else
# for all other CPUs shared library
TLIBS_SHARED += $(LD_LINK_PATH_ATEND) $(LD_PARTIAL_LAST_FLAGS)
endif
# for static library
TLIBS += $(LD_LINK_PATH_ATEND) $(LD_PARTIAL_LAST_FLAGS)
#### Leave SQLITE_DEBUG undefined for maximum speed. Use SQLITE_DEBUG=1
# to check for memory leaks. Use SQLITE_DEBUG=2 to print a log of all
# malloc()s and free()s in order to track down memory leaks.
#
# SQLite uses some expensive assert() statements in the inner loop.
# You can make the library go almost twice as fast if you compile
# with -DNDEBUG=1
#
#OPTS = -DSQLITE_DEBUG=2
#OPTS = -DSQLITE_DEBUG=1
#OPTS =
OPTS = -DNDEBUG=1 -DSQLITE_OS_UNIX=1 $(THREADSAFE)
OPTS += -DSQLITE_OMIT_LOAD_EXTENSION=1
OPTS += -DSQLITE_ENABLE_LOCKING_STYLE=1
OPTS += -DSQLITE_THREAD_OVERRIDE_LOCK=0
OPTS += -DSQLITE_ENABLE_COLUMN_METADATA=1
OPTS += -DHAVE_FDATASYNC=1
#### The suffix to add to executable files. ".exe" for windows.
# Nothing for unix.
#
EXE = .vxe
#EXE =
#### C Compile and options for use in building executables that
# will run on the target platform. This is usually the same
# as BCC, unless you are cross-compiling.
#
#TCC = gcc -O6
#TCC = gcc -g -O0 -Wall
#TCC = gcc -g -O0 -Wall -fprofile-arcs -ftest-coverage
#TCC = /opt/mingw/bin/i386-mingw32-gcc -O6
TCC = $(CC) $(DEFINE_CC) -O2 -g -mrtp $(CC_ARCH_SPEC) -D_REENTRANT=1 -D_VX_CPU=_VX_$(CPU) -D_VX_TOOL_FAMILY=$(TOOL_FAMILY) -D_VX_TOOL=$(TOOL)
TCC += -I$(WIND_USR)/h -I$(WIND_USR)/h/wrn/coreip
#TCC = /opt/ansic/bin/c89 -O +z -Wl,-a,archive
#TCC_SHARED = $(TCC) -fPIC
TCC_SHARED = $(TCC)
#### Tools used to build a static library.
#
#ARX = ar cr
#ARX = /opt/mingw/bin/i386-mingw32-ar cr
AR += cr
#RANLIB = ranlib
#RANLIB = /opt/mingw/bin/i386-mingw32-ranlib
#MKSHLIB = gcc -shared
#SO = so
#SHPREFIX = lib
MKSHLIB = $(CC) $(DEFINE_CC) -mrtp -shared $(CC_ARCH_SPEC) -D_VX_CPU=_VX_$(CPU) -D_VX_TOOL_FAMILY=$(TOOL_FAMILY) -D_VX_TOOL=$(TOOL)
SO = so
SHPREFIX = lib
#### Extra compiler options needed for programs that use the TCL library.
#
#TCL_FLAGS =
#TCL_FLAGS = -DSTATIC_BUILD=1
TCL_FLAGS = -I/home/drh/tcltk/8.5linux
#TCL_FLAGS = -I/home/drh/tcltk/8.5win -DSTATIC_BUILD=1
#TCL_FLAGS = -I/home/drh/tcltk/8.3hpux
#### Linker options needed to link against the TCL library.
#
#LIBTCL = -ltcl -lm -ldl
LIBTCL = /home/drh/tcltk/8.5linux/libtcl8.5g.a -lm -ldl
#LIBTCL = /home/drh/tcltk/8.5win/libtcl85s.a -lmsvcrt
#LIBTCL = /home/drh/tcltk/8.3hpux/libtcl8.3.a -ldld -lm -lc
#### Additional objects for SQLite library when TCL support is enabled.
TCLOBJ =
#TCLOBJ = tclsqlite.o
#### Compiler options needed for programs that use the readline() library.
#
READLINE_FLAGS =
#READLINE_FLAGS = -DHAVE_READLINE=1 -I/usr/include/readline
#### Linker options needed by programs using readline() must link against.
#
LIBREADLINE =
#LIBREADLINE = -static -lreadline -ltermcap
#### Which "awk" program provides nawk compatibilty
#
# NAWK = nawk
NAWK = awk
#### Pasted and adapted main.mk file
###############################################################################
# The following macros should be defined before this script is
# invoked:
#
# TOP The toplevel directory of the source tree. This is the
# directory that contains this "Makefile.in" and the
# "configure.in" script.
#
# BCC C Compiler and options for use in building executables that
# will run on the platform that is doing the build.
#
# THREADLIB Specify any extra linker options needed to make the library
# thread safe
#
# OPTS Extra compiler command-line options.
#
# EXE The suffix to add to executable files. ".exe" for windows
# and "" for Unix.
#
# TCC C Compiler and options for use in building executables that
# will run on the target platform. This is usually the same
# as BCC, unless you are cross-compiling.
#
# AR Tools used to build a static library.
# RANLIB
#
# TCL_FLAGS Extra compiler options needed for programs that use the
# TCL library.
#
# LIBTCL Linker options needed to link against the TCL library.
#
# READLINE_FLAGS Compiler options needed for programs that use the
# readline() library.
#
# LIBREADLINE Linker options needed by programs using readline() must
# link against.
#
# NAWK Nawk compatible awk program. Older (obsolete?) solaris
# systems need this to avoid using the original AT&T AWK.
#
# Once the macros above are defined, the rest of this make script will
# build the SQLite library and testing tools.
################################################################################
# This is how we compile
#
TCCX = $(TCC) $(OPTS) -I. -I$(TOP)/src -I$(TOP)
TCCX_SHARED = $(TCC_SHARED) $(OPTS) -I. -I$(TOP)/src -I$(TOP) \
-I$(TOP)/ext/rtree -I$(TOP)/ext/icu -I$(TOP)/ext/fts3 \
-I$(TOP)/ext/async
# Object files for the SQLite library.
#
LIBOBJ+= alter.o analyze.o attach.o auth.o \
backup.o bitvec.o btmutex.o btree.o build.o \
callback.o complete.o date.o delete.o expr.o fault.o \
fts3.o fts3_expr.o fts3_hash.o fts3_icu.o fts3_porter.o \
fts3_tokenizer.o fts3_tokenizer1.o \
func.o global.o hash.o \
icu.o insert.o journal.o legacy.o loadext.o \
main.o malloc.o mem0.o mem1.o mem2.o mem3.o mem5.o \
memjournal.o \
mutex.o mutex_noop.o mutex_unix.o mutex_w32.o \
notify.o opcodes.o os.o os_unix.o os_win.o \
pager.o parse.o pcache.o pcache1.o pragma.o prepare.o printf.o \
random.o resolve.o rowset.o rtree.o select.o status.o \
table.o tokenize.o trigger.o \
update.o util.o vacuum.o \
vdbe.o vdbeapi.o vdbeaux.o vdbeblob.o vdbemem.o \
walker.o where.o utf.o vtab.o
# All of the source code files.
#
SRC = \
$(TOP)/src/alter.c \
$(TOP)/src/analyze.c \
$(TOP)/src/attach.c \
$(TOP)/src/auth.c \
$(TOP)/src/backup.c \
$(TOP)/src/bitvec.c \
$(TOP)/src/btmutex.c \
$(TOP)/src/btree.c \
$(TOP)/src/btree.h \
$(TOP)/src/btreeInt.h \
$(TOP)/src/build.c \
$(TOP)/src/callback.c \
$(TOP)/src/complete.c \
$(TOP)/src/ctime.c \
$(TOP)/src/date.c \
$(TOP)/src/delete.c \
$(TOP)/src/expr.c \
$(TOP)/src/fault.c \
$(TOP)/src/func.c \
$(TOP)/src/global.c \
$(TOP)/src/hash.c \
$(TOP)/src/hash.h \
$(TOP)/src/hwtime.h \
$(TOP)/src/insert.c \
$(TOP)/src/journal.c \
$(TOP)/src/legacy.c \
$(TOP)/src/loadext.c \
$(TOP)/src/main.c \
$(TOP)/src/malloc.c \
$(TOP)/src/mem0.c \
$(TOP)/src/mem1.c \
$(TOP)/src/mem2.c \
$(TOP)/src/mem3.c \
$(TOP)/src/mem5.c \
$(TOP)/src/memjournal.c \
$(TOP)/src/msvc.h \
$(TOP)/src/mutex.c \
$(TOP)/src/mutex.h \
$(TOP)/src/mutex_noop.c \
$(TOP)/src/mutex_unix.c \
$(TOP)/src/mutex_w32.c \
$(TOP)/src/notify.c \
$(TOP)/src/os.c \
$(TOP)/src/os.h \
$(TOP)/src/os_common.h \
$(TOP)/src/os_setup.h \
$(TOP)/src/os_unix.c \
$(TOP)/src/os_win.c \
$(TOP)/src/os_win.h \
$(TOP)/src/pager.c \
$(TOP)/src/pager.h \
$(TOP)/src/parse.y \
$(TOP)/src/pcache.c \
$(TOP)/src/pcache.h \
$(TOP)/src/pcache1.c \
$(TOP)/src/pragma.c \
$(TOP)/src/prepare.c \
$(TOP)/src/printf.c \
$(TOP)/src/random.c \
$(TOP)/src/resolve.c \
$(TOP)/src/rowset.c \
$(TOP)/src/select.c \
$(TOP)/src/status.c \
$(TOP)/src/shell.c \
$(TOP)/src/sqlite.h.in \
$(TOP)/src/sqlite3ext.h \
$(TOP)/src/sqliteInt.h \
$(TOP)/src/sqliteLimit.h \
$(TOP)/src/table.c \
$(TOP)/src/tclsqlite.c \
$(TOP)/src/tokenize.c \
$(TOP)/src/trigger.c \
$(TOP)/src/utf.c \
$(TOP)/src/update.c \
$(TOP)/src/util.c \
$(TOP)/src/vacuum.c \
$(TOP)/src/vdbe.c \
$(TOP)/src/vdbe.h \
$(TOP)/src/vdbeapi.c \
$(TOP)/src/vdbeaux.c \
$(TOP)/src/vdbeblob.c \
$(TOP)/src/vdbemem.c \
$(TOP)/src/vdbeInt.h \
$(TOP)/src/vtab.c \
$(TOP)/src/walker.c \
$(TOP)/src/where.c
# Source code for extensions
#
SRC += \
$(TOP)/ext/fts1/fts1.c \
$(TOP)/ext/fts1/fts1.h \
$(TOP)/ext/fts1/fts1_hash.c \
$(TOP)/ext/fts1/fts1_hash.h \
$(TOP)/ext/fts1/fts1_porter.c \
$(TOP)/ext/fts1/fts1_tokenizer.h \
$(TOP)/ext/fts1/fts1_tokenizer1.c
SRC += \
$(TOP)/ext/fts2/fts2.c \
$(TOP)/ext/fts2/fts2.h \
$(TOP)/ext/fts2/fts2_hash.c \
$(TOP)/ext/fts2/fts2_hash.h \
$(TOP)/ext/fts2/fts2_icu.c \
$(TOP)/ext/fts2/fts2_porter.c \
$(TOP)/ext/fts2/fts2_tokenizer.h \
$(TOP)/ext/fts2/fts2_tokenizer.c \
$(TOP)/ext/fts2/fts2_tokenizer1.c
SRC += \
$(TOP)/ext/fts3/fts3.c \
$(TOP)/ext/fts3/fts3.h \
$(TOP)/ext/fts3/fts3_expr.c \
$(TOP)/ext/fts3/fts3_expr.h \
$(TOP)/ext/fts3/fts3_hash.c \
$(TOP)/ext/fts3/fts3_hash.h \
$(TOP)/ext/fts3/fts3_icu.c \
$(TOP)/ext/fts3/fts3_porter.c \
$(TOP)/ext/fts3/fts3_tokenizer.h \
$(TOP)/ext/fts3/fts3_tokenizer.c \
$(TOP)/ext/fts3/fts3_tokenizer1.c
SRC += \
$(TOP)/ext/icu/sqliteicu.h \
$(TOP)/ext/icu/icu.c
SRC += \
$(TOP)/ext/rtree/rtree.h \
$(TOP)/ext/rtree/rtree.c
# Generated source code files
#
SRC += \
keywordhash.h \
opcodes.c \
opcodes.h \
parse.c \
parse.h \
sqlite3.h
# Source code to the test files.
#
TESTSRC = \
$(TOP)/src/test1.c \
$(TOP)/src/test2.c \
$(TOP)/src/test3.c \
$(TOP)/src/test4.c \
$(TOP)/src/test5.c \
$(TOP)/src/test6.c \
$(TOP)/src/test7.c \
$(TOP)/src/test8.c \
$(TOP)/src/test9.c \
$(TOP)/src/test_autoext.c \
$(TOP)/src/test_async.c \
$(TOP)/src/test_backup.c \
$(TOP)/src/test_btree.c \
$(TOP)/src/test_config.c \
$(TOP)/src/test_devsym.c \
$(TOP)/src/test_func.c \
$(TOP)/src/test_hexio.c \
$(TOP)/src/test_journal.c \
$(TOP)/src/test_malloc.c \
$(TOP)/src/test_md5.c \
$(TOP)/src/test_mutex.c \
$(TOP)/src/test_onefile.c \
$(TOP)/src/test_osinst.c \
$(TOP)/src/test_pcache.c \
$(TOP)/src/test_schema.c \
$(TOP)/src/test_server.c \
$(TOP)/src/test_tclvar.c \
$(TOP)/src/test_thread.c \
$(TOP)/src/test_vfs.c \
$(TOP)/src/test_wsd.c \
#TESTSRC += $(TOP)/ext/fts2/fts2_tokenizer.c
#TESTSRC += $(TOP)/ext/fts3/fts3_tokenizer.c
TESTSRC2 = \
$(TOP)/src/attach.c $(TOP)/src/backup.c $(TOP)/src/btree.c \
$(TOP)/src/build.c $(TOP)/src/ctime.c $(TOP)/src/date.c \
$(TOP)/src/expr.c $(TOP)/src/func.c $(TOP)/src/insert.c $(TOP)/src/os.c \
$(TOP)/src/os_unix.c $(TOP)/src/os_win.c \
$(TOP)/src/pager.c $(TOP)/src/pragma.c $(TOP)/src/prepare.c \
$(TOP)/src/printf.c $(TOP)/src/random.c $(TOP)/src/pcache.c \
$(TOP)/src/pcache1.c $(TOP)/src/select.c $(TOP)/src/tokenize.c \
$(TOP)/src/utf.c $(TOP)/src/util.c $(TOP)/src/vdbeapi.c $(TOP)/src/vdbeaux.c \
$(TOP)/src/vdbe.c $(TOP)/src/vdbemem.c $(TOP)/src/where.c parse.c \
$(TOP)/ext/fts3/fts3.c $(TOP)/ext/fts3/fts3_expr.c \
$(TOP)/ext/fts3/fts3_tokenizer.c \
$(TOP)/ext/async/sqlite3async.c
# Header files used by all library source files.
#
HDR = \
$(TOP)/src/btree.h \
$(TOP)/src/btreeInt.h \
$(TOP)/src/hash.h \
$(TOP)/src/hwtime.h \
keywordhash.h \
$(TOP)/src/msvc.h \
$(TOP)/src/mutex.h \
opcodes.h \
$(TOP)/src/os.h \
$(TOP)/src/os_common.h \
$(TOP)/src/os_setup.h \
$(TOP)/src/os_win.h \
$(TOP)/src/pager.h \
$(TOP)/src/pcache.h \
parse.h \
sqlite3.h \
$(TOP)/src/sqlite3ext.h \
$(TOP)/src/sqliteInt.h \
$(TOP)/src/sqliteLimit.h \
$(TOP)/src/vdbe.h \
$(TOP)/src/vdbeInt.h
# Header files used by extensions
#
EXTHDR += \
$(TOP)/ext/fts1/fts1.h \
$(TOP)/ext/fts1/fts1_hash.h \
$(TOP)/ext/fts1/fts1_tokenizer.h
EXTHDR += \
$(TOP)/ext/fts2/fts2.h \
$(TOP)/ext/fts2/fts2_hash.h \
$(TOP)/ext/fts2/fts2_tokenizer.h
EXTHDR += \
$(TOP)/ext/fts3/fts3.h \
$(TOP)/ext/fts3/fts3_expr.h \
$(TOP)/ext/fts3/fts3_hash.h \
$(TOP)/ext/fts3/fts3_tokenizer.h
EXTHDR += \
$(TOP)/ext/rtree/rtree.h
EXTHDR += \
$(TOP)/ext/icu/sqliteicu.h
# This is the default Makefile target. The objects listed here
# are what get build when you type just "make" with no arguments.
#
all: sqlite3.h libsqlite3.a sqlite3$(EXE)
libsqlite3.a: $(LIBOBJ)
$(AR) libsqlite3.a $(LIBOBJ)
$(RANLIB) libsqlite3.a
$(SHPREFIX)sqlite3.$(SO): $(LIBOBJ)
$(MKSHLIB) -o $(SHPREFIX)sqlite3.$(SO) $(LIBOBJ) $(TLIBS_SHARED)
sqlite3$(EXE): $(TOP)/src/shell.c libsqlite3.a sqlite3.h
$(TCCX) $(READLINE_FLAGS) -o sqlite3$(EXE) \
$(TOP)/src/shell.c \
$(LIBREADLINE) $(TLIBS) $(THREADLIB) -L. -lsqlite3
# This target creates a directory named "tsrc" and fills it with
# copies of all of the C source code and header files needed to
# build on the target system. Some of the C source code and header
# files are automatically generated. This target takes care of
# all that automatic generation.
#
target_source: $(SRC)
rm -rf tsrc
mkdir tsrc
cp -f $(SRC) tsrc
rm tsrc/sqlite.h.in tsrc/parse.y
touch target_source
sqlite3.c: target_source $(TOP)/tool/mksqlite3c.tcl
tclsh $(TOP)/tool/mksqlite3c.tcl
cp sqlite3.c tclsqlite3.c
cat $(TOP)/src/tclsqlite.c >>tclsqlite3.c
fts2amal.c: target_source $(TOP)/ext/fts2/mkfts2amal.tcl
tclsh $(TOP)/ext/fts2/mkfts2amal.tcl
fts3amal.c: target_source $(TOP)/ext/fts3/mkfts3amal.tcl
tclsh $(TOP)/ext/fts3/mkfts3amal.tcl
# Rules to build the LEMON compiler generator
#
lemon: $(TOP)/tool/lemon.c $(TOP)/src/lempar.c
$(BCC) -o lemon $(TOP)/tool/lemon.c
cp $(TOP)/src/lempar.c .
# Rules to build individual *.o files from generated *.c files. This
# applies to:
#
# parse.o
# opcodes.o
#
%.o: %.c $(HDR)
$(TCCX_SHARED) -c $<
# Rules to build individual *.o files from files in the src directory.
#
%.o: $(TOP)/src/%.c $(HDR)
$(TCCX_SHARED) -c $<
tclsqlite.o: $(TOP)/src/tclsqlite.c $(HDR)
$(TCCX_SHARED) $(TCL_FLAGS) -c $(TOP)/src/tclsqlite.c
# Rules to build opcodes.c and opcodes.h
#
opcodes.c: opcodes.h $(TOP)/mkopcodec.awk
$(NAWK) -f $(TOP)/mkopcodec.awk opcodes.h >opcodes.c
opcodes.h: parse.h $(TOP)/src/vdbe.c $(TOP)/mkopcodeh.awk
cat parse.h $(TOP)/src/vdbe.c | \
$(NAWK) -f $(TOP)/mkopcodeh.awk >opcodes.h
# Rules to build parse.c and parse.h - the outputs of lemon.
#
parse.h: parse.c
parse.c: $(TOP)/src/parse.y lemon $(TOP)/addopcodes.awk
cp $(TOP)/src/parse.y .
rm -f parse.h
./lemon $(OPTS) parse.y
mv parse.h parse.h.temp
awk -f $(TOP)/addopcodes.awk parse.h.temp >parse.h
sqlite3.h: $(TOP)/src/sqlite.h.in
sed -e s/--VERS--/`cat ${TOP}/VERSION`/ \
-e s/--VERSION-NUMBER--/`cat ${TOP}/VERSION | sed 's/[^0-9]/ /g' | $(NAWK) '{printf "%d%03d%03d",$$1,$$2,$$3}'`/ \
$(TOP)/src/sqlite.h.in >sqlite3.h
keywordhash.h: $(TOP)/tool/mkkeywordhash.c
$(BCC) -o mkkeywordhash $(OPTS) $(TOP)/tool/mkkeywordhash.c
./mkkeywordhash >keywordhash.h
# Rules to build the extension objects.
#
icu.o: $(TOP)/ext/icu/icu.c $(HDR) $(EXTHDR)
$(TCCX_SHARED) -DSQLITE_CORE -c $(TOP)/ext/icu/icu.c
fts2.o: $(TOP)/ext/fts2/fts2.c $(HDR) $(EXTHDR)
$(TCCX_SHARED) -DSQLITE_CORE -c $(TOP)/ext/fts2/fts2.c
fts2_hash.o: $(TOP)/ext/fts2/fts2_hash.c $(HDR) $(EXTHDR)
$(TCCX_SHARED) -DSQLITE_CORE -c $(TOP)/ext/fts2/fts2_hash.c
fts2_icu.o: $(TOP)/ext/fts2/fts2_icu.c $(HDR) $(EXTHDR)
$(TCCX_SHARED) -DSQLITE_CORE -c $(TOP)/ext/fts2/fts2_icu.c
fts2_porter.o: $(TOP)/ext/fts2/fts2_porter.c $(HDR) $(EXTHDR)
$(TCCX_SHARED) -DSQLITE_CORE -c $(TOP)/ext/fts2/fts2_porter.c
fts2_tokenizer.o: $(TOP)/ext/fts2/fts2_tokenizer.c $(HDR) $(EXTHDR)
$(TCCX_SHARED) -DSQLITE_CORE -c $(TOP)/ext/fts2/fts2_tokenizer.c
fts2_tokenizer1.o: $(TOP)/ext/fts2/fts2_tokenizer1.c $(HDR) $(EXTHDR)
$(TCCX_SHARED) -DSQLITE_CORE -c $(TOP)/ext/fts2/fts2_tokenizer1.c
fts3.o: $(TOP)/ext/fts3/fts3.c $(HDR) $(EXTHDR)
$(TCCX_SHARED) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3.c
fts3_expr.o: $(TOP)/ext/fts3/fts3_expr.c $(HDR) $(EXTHDR)
$(TCCX_SHARED) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_expr.c
fts3_hash.o: $(TOP)/ext/fts3/fts3_hash.c $(HDR) $(EXTHDR)
$(TCCX_SHARED) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_hash.c
fts3_icu.o: $(TOP)/ext/fts3/fts3_icu.c $(HDR) $(EXTHDR)
$(TCCX_SHARED) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_icu.c
fts3_porter.o: $(TOP)/ext/fts3/fts3_porter.c $(HDR) $(EXTHDR)
$(TCCX_SHARED) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_porter.c
fts3_tokenizer.o: $(TOP)/ext/fts3/fts3_tokenizer.c $(HDR) $(EXTHDR)
$(TCCX_SHARED) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_tokenizer.c
fts3_tokenizer1.o: $(TOP)/ext/fts3/fts3_tokenizer1.c $(HDR) $(EXTHDR)
$(TCCX_SHARED) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_tokenizer1.c
rtree.o: $(TOP)/ext/rtree/rtree.c $(HDR) $(EXTHDR)
$(TCCX_SHARED) -DSQLITE_CORE -c $(TOP)/ext/rtree/rtree.c
# Rules for building test programs and for running tests
#
tclsqlite3: $(TOP)/src/tclsqlite.c libsqlite3.a
$(TCCX_SHARED) $(TCL_FLAGS) -DTCLSH=1 -o tclsqlite3 \
$(TOP)/src/tclsqlite.c libsqlite3.a $(LIBTCL) $(THREADLIB)
# Rules to build the 'testfixture' application.
#
TESTFIXTURE_FLAGS = -DTCLSH=1 -DSQLITE_TEST=1 -DSQLITE_CRASH_TEST=1
TESTFIXTURE_FLAGS += -DSQLITE_SERVER=1 -DSQLITE_PRIVATE="" -DSQLITE_CORE
testfixture$(EXE): $(TESTSRC2) libsqlite3.a $(TESTSRC) $(TOP)/src/tclsqlite.c
$(TCCX) $(TCL_FLAGS) $(TESTFIXTURE_FLAGS) \
$(TESTSRC) $(TESTSRC2) $(TOP)/src/tclsqlite.c \
-o testfixture$(EXE) $(LIBTCL) $(THREADLIB) libsqlite3.a
amalgamation-testfixture$(EXE): sqlite3.c $(TESTSRC) $(TOP)/src/tclsqlite.c
$(TCCX) $(TCL_FLAGS) $(TESTFIXTURE_FLAGS) \
$(TESTSRC) $(TOP)/src/tclsqlite.c sqlite3.c \
-o testfixture$(EXE) $(LIBTCL) $(THREADLIB)
fts3-testfixture$(EXE): sqlite3.c fts3amal.c $(TESTSRC) $(TOP)/src/tclsqlite.c
$(TCCX) $(TCL_FLAGS) $(TESTFIXTURE_FLAGS) \
-DSQLITE_ENABLE_FTS3=1 \
$(TESTSRC) $(TOP)/src/tclsqlite.c sqlite3.c fts3amal.c \
-o testfixture$(EXE) $(LIBTCL) $(THREADLIB)
fulltest: testfixture$(EXE) sqlite3$(EXE)
./testfixture$(EXE) $(TOP)/test/all.test
soaktest: testfixture$(EXE) sqlite3$(EXE)
./testfixture$(EXE) $(TOP)/test/all.test -soak=1
fulltestonly: testfixture$(EXE) sqlite3$(EXE)
./testfixture$(EXE) $(TOP)/test/full.test
test: testfixture$(EXE) sqlite3$(EXE)
./testfixture$(EXE) $(TOP)/test/veryquick.test
sqlite3_analyzer$(EXE): $(TOP)/src/tclsqlite.c sqlite3.c $(TESTSRC) \
$(TOP)/tool/spaceanal.tcl
sed \
-e '/^#/d' \
-e 's,\\,\\\\,g' \
-e 's,",\\",g' \
-e 's,^,",' \
-e 's,$$,\\n",' \
$(TOP)/tool/spaceanal.tcl >spaceanal_tcl.h
$(TCCX) $(TCL_FLAGS) $(TESTFIXTURE_FLAGS) \
-DTCLSH=2 -DSQLITE_TEST=1 -DSQLITE_DEBUG=1 -DSQLITE_PRIVATE="" \
$(TESTSRC) $(TOP)/src/tclsqlite.c sqlite3.c \
-o sqlite3_analyzer$(EXE) \
$(LIBTCL) $(THREADLIB)
TEST_EXTENSION = $(SHPREFIX)testloadext.$(SO)
$(TEST_EXTENSION): $(TOP)/src/test_loadext.c
$(MKSHLIB) $(TOP)/src/test_loadext.c -o $(TEST_EXTENSION)
extensiontest: testfixture$(EXE) $(TEST_EXTENSION)
./testfixture$(EXE) $(TOP)/test/loadext.test
clean:
rm -f *.o sqlite3$(EXE) libsqlite3.a sqlite3.h opcodes.*
rm -f lemon lempar.c parse.* sqlite*.tar.gz mkkeywordhash keywordhash.h
rm -f $(PUBLISH)
rm -f *.da *.bb *.bbg gmon.out
rm -rf quota2a quota2b quota2c
rm -rf tsrc target_source
rm -f testloadext.dll libtestloadext.so
rm -f sqlite3.c fts?amal.c tclsqlite3.c
rm -f sqlite3rc.h
rm -f shell.c sqlite3ext.h
rm -f $(SHPREFIX)sqlite3.$(SO)
+1 -1
View File
@@ -1 +1 @@
3.8.12
3.9.1
-34
View File
@@ -1,34 +0,0 @@
#!/usr/bin/awk
#
# This script appends additional token codes to the end of the
# parse.h file that lemon generates. These extra token codes are
# not used by the parser. But they are used by the tokenizer and/or
# the code generator.
#
#
BEGIN {
max = 0
}
/^#define TK_/ {
print $0
if( max<$3 ) max = $3
}
END {
printf "#define TK_%-29s %4d\n", "TO_TEXT", ++max
printf "#define TK_%-29s %4d\n", "TO_BLOB", ++max
printf "#define TK_%-29s %4d\n", "TO_NUMERIC", ++max
printf "#define TK_%-29s %4d\n", "TO_INT", ++max
printf "#define TK_%-29s %4d\n", "TO_REAL", ++max
printf "#define TK_%-29s %4d\n", "ISNOT", ++max
printf "#define TK_%-29s %4d\n", "END_OF_FILE", ++max
printf "#define TK_%-29s %4d\n", "ILLEGAL", ++max
printf "#define TK_%-29s %4d\n", "SPACE", ++max
printf "#define TK_%-29s %4d\n", "UNCLOSED_STRING", ++max
printf "#define TK_%-29s %4d\n", "FUNCTION", ++max
printf "#define TK_%-29s %4d\n", "COLUMN", ++max
printf "#define TK_%-29s %4d\n", "AGG_FUNCTION", ++max
printf "#define TK_%-29s %4d\n", "AGG_COLUMN", ++max
printf "#define TK_%-29s %4d\n", "UMINUS", ++max
printf "#define TK_%-29s %4d\n", "UPLUS", ++max
printf "#define TK_%-29s %4d\n", "REGISTER", ++max
}
+1 -1
View File
@@ -1,5 +1,5 @@
AM_CFLAGS = @THREADSAFE_FLAGS@ @DYNAMIC_EXTENSION_FLAGS@ -DSQLITE_ENABLE_FTS3 -DSQLITE_ENABLE_RTREE
AM_CFLAGS = @THREADSAFE_FLAGS@ @DYNAMIC_EXTENSION_FLAGS@ @FTS5_FLAGS@ @JSON1_FLAGS@ -DSQLITE_ENABLE_FTS3 -DSQLITE_ENABLE_RTREE
lib_LTLIBRARIES = libsqlite3.la
libsqlite3_la_SOURCES = sqlite3.c
+25
View File
@@ -78,6 +78,31 @@ AC_MSG_RESULT($enable_dynamic_extensions)
AC_SUBST(DYNAMIC_EXTENSION_FLAGS)
#-----------------------------------------------------------------------
#-----------------------------------------------------------------------
# --enable-fts5
#
AC_ARG_ENABLE(fts5, [AS_HELP_STRING(
[--enable-fts5], [include fts5 support [default=no]])],
[], [enable_fts5=no])
if test x"$enable_fts5" == "xyes"; then
AC_SEARCH_LIBS(log, m)
FTS5_FLAGS=-DSQLITE_ENABLE_FTS5
fi
AC_SUBST(FTS5_FLAGS)
#-----------------------------------------------------------------------
#-----------------------------------------------------------------------
# --enable-json1
#
AC_ARG_ENABLE(json1, [AS_HELP_STRING(
[--enable-json1], [include json1 support [default=no]])],
[], [enable_json1=no])
if test x"$enable_json1" == "xyes"; then
JSON1_FLAGS=-DSQLITE_ENABLE_JSON1
fi
AC_SUBST(JSON1_FLAGS)
#-----------------------------------------------------------------------
AC_CHECK_FUNCS(posix_fallocate)
#-----------------------------------------------------------------------
Vendored
+204 -67
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.8.12.
# Generated by GNU Autoconf 2.69 for sqlite 3.9.1.
#
#
# 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.8.12'
PACKAGE_STRING='sqlite 3.8.12'
PACKAGE_VERSION='3.9.1'
PACKAGE_STRING='sqlite 3.9.1'
PACKAGE_BUGREPORT=''
PACKAGE_URL=''
@@ -803,7 +803,6 @@ VERSION
program_prefix
TCLLIBDIR
TCLSH_CMD
AWK
INSTALL_DATA
INSTALL_SCRIPT
INSTALL_PROGRAM
@@ -902,6 +901,11 @@ with_readline_inc
enable_debug
enable_amalgamation
enable_load_extension
enable_fts3
enable_fts4
enable_fts5
enable_json1
enable_rtree
enable_gcov
'
ac_precious_vars='build_alias
@@ -1454,7 +1458,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.8.12 to adapt to many kinds of systems.
\`configure' configures sqlite 3.9.1 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1519,7 +1523,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
short | recursive ) echo "Configuration of sqlite 3.8.12:";;
short | recursive ) echo "Configuration of sqlite 3.9.1:";;
esac
cat <<\_ACEOF
@@ -1544,6 +1548,11 @@ Optional Features:
separately
--disable-load-extension
Disable loading of external extensions
--enable-fts3 Enable the FTS3 extension
--enable-fts4 Enable the FTS4 extension
--enable-fts5 Enable the FTS5 extension
--enable-json1 Enable the JSON1 extension
--enable-rtree Enable the RTREE extension
--enable-gcov Enable coverage testing using gcov
Optional Packages:
@@ -1634,7 +1643,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
sqlite configure 3.8.12
sqlite configure 3.9.1
generated by GNU Autoconf 2.69
Copyright (C) 2012 Free Software Foundation, Inc.
@@ -2053,7 +2062,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.8.12, which was
It was created by sqlite $as_me 3.9.1, which was
generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@
@@ -3911,13 +3920,13 @@ if ${lt_cv_nm_interface+:} false; then :
else
lt_cv_nm_interface="BSD nm"
echo "int some_variable = 0;" > conftest.$ac_ext
(eval echo "\"\$as_me:3914: $ac_compile\"" >&5)
(eval echo "\"\$as_me:3923: $ac_compile\"" >&5)
(eval "$ac_compile" 2>conftest.err)
cat conftest.err >&5
(eval echo "\"\$as_me:3917: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
(eval echo "\"\$as_me:3926: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
(eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out)
cat conftest.err >&5
(eval echo "\"\$as_me:3920: output\"" >&5)
(eval echo "\"\$as_me:3929: output\"" >&5)
cat conftest.out >&5
if $GREP 'External.*some_variable' conftest.out > /dev/null; then
lt_cv_nm_interface="MS dumpbin"
@@ -5123,7 +5132,7 @@ ia64-*-hpux*)
;;
*-*-irix6*)
# Find out which ABI we are using.
echo '#line 5126 "configure"' > conftest.$ac_ext
echo '#line 5135 "configure"' > conftest.$ac_ext
if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
(eval $ac_compile) 2>&5
ac_status=$?
@@ -6648,11 +6657,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
(eval echo "\"\$as_me:6651: $lt_compile\"" >&5)
(eval echo "\"\$as_me:6660: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
echo "$as_me:6655: \$? = $ac_status" >&5
echo "$as_me:6664: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings other than the usual output.
@@ -6987,11 +6996,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
(eval echo "\"\$as_me:6990: $lt_compile\"" >&5)
(eval echo "\"\$as_me:6999: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
echo "$as_me:6994: \$? = $ac_status" >&5
echo "$as_me:7003: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings other than the usual output.
@@ -7092,11 +7101,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
(eval echo "\"\$as_me:7095: $lt_compile\"" >&5)
(eval echo "\"\$as_me:7104: $lt_compile\"" >&5)
(eval "$lt_compile" 2>out/conftest.err)
ac_status=$?
cat out/conftest.err >&5
echo "$as_me:7099: \$? = $ac_status" >&5
echo "$as_me:7108: \$? = $ac_status" >&5
if (exit $ac_status) && test -s out/conftest2.$ac_objext
then
# The compiler can only warn and ignore the option if not recognized
@@ -7147,11 +7156,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
(eval echo "\"\$as_me:7150: $lt_compile\"" >&5)
(eval echo "\"\$as_me:7159: $lt_compile\"" >&5)
(eval "$lt_compile" 2>out/conftest.err)
ac_status=$?
cat out/conftest.err >&5
echo "$as_me:7154: \$? = $ac_status" >&5
echo "$as_me:7163: \$? = $ac_status" >&5
if (exit $ac_status) && test -s out/conftest2.$ac_objext
then
# The compiler can only warn and ignore the option if not recognized
@@ -9527,7 +9536,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
#line 9530 "configure"
#line 9539 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -9623,7 +9632,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
#line 9626 "configure"
#line 9635 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -9943,48 +9952,6 @@ test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}'
test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
for ac_prog in gawk mawk nawk awk
do
# Extract the first word of "$ac_prog", so it can be a program name with args.
set dummy $ac_prog; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
if ${ac_cv_prog_AWK+:} false; then :
$as_echo_n "(cached) " >&6
else
if test -n "$AWK"; then
ac_cv_prog_AWK="$AWK" # Let the user override the test.
else
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_AWK="$ac_prog"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
fi
done
done
IFS=$as_save_IFS
fi
fi
AWK=$ac_cv_prog_AWK
if test -n "$AWK"; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5
$as_echo "$AWK" >&6; }
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi
test -n "$AWK" && break
done
#########
# Enable large file support (if special flags are necessary)
@@ -11223,6 +11190,177 @@ else
OPT_FEATURE_FLAGS="-DSQLITE_OMIT_LOAD_EXTENSION=1"
fi
#########
# See whether we should enable Full Text Search extensions
# Check whether --enable-fts3 was given.
if test "${enable_fts3+set}" = set; then :
enableval=$enable_fts3; enable_fts3=yes
else
enable_fts3=no
fi
if test "${enable_fts3}" = "yes" ; then
OPT_FEATURE_FLAGS+=" -DSQLITE_ENABLE_FTS3"
fi
# Check whether --enable-fts4 was given.
if test "${enable_fts4+set}" = set; then :
enableval=$enable_fts4; enable_fts4=yes
else
enable_fts4=no
fi
if test "${enable_fts4}" = "yes" ; then
OPT_FEATURE_FLAGS+=" -DSQLITE_ENABLE_FTS4"
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing log" >&5
$as_echo_n "checking for library containing log... " >&6; }
if ${ac_cv_search_log+:} false; then :
$as_echo_n "(cached) " >&6
else
ac_func_search_save_LIBS=$LIBS
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
/* Override any GCC internal prototype to avoid an error.
Use char because int might match the return type of a GCC
builtin and then its argument prototype would still apply. */
#ifdef __cplusplus
extern "C"
#endif
char log ();
int
main ()
{
return log ();
;
return 0;
}
_ACEOF
for ac_lib in '' m; do
if test -z "$ac_lib"; then
ac_res="none required"
else
ac_res=-l$ac_lib
LIBS="-l$ac_lib $ac_func_search_save_LIBS"
fi
if ac_fn_c_try_link "$LINENO"; then :
ac_cv_search_log=$ac_res
fi
rm -f core conftest.err conftest.$ac_objext \
conftest$ac_exeext
if ${ac_cv_search_log+:} false; then :
break
fi
done
if ${ac_cv_search_log+:} false; then :
else
ac_cv_search_log=no
fi
rm conftest.$ac_ext
LIBS=$ac_func_search_save_LIBS
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_log" >&5
$as_echo "$ac_cv_search_log" >&6; }
ac_res=$ac_cv_search_log
if test "$ac_res" != no; then :
test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
fi
fi
# Check whether --enable-fts5 was given.
if test "${enable_fts5+set}" = set; then :
enableval=$enable_fts5; enable_fts5=yes
else
enable_fts5=no
fi
if test "${enable_fts5}" = "yes" ; then
OPT_FEATURE_FLAGS+=" -DSQLITE_ENABLE_FTS5"
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing log" >&5
$as_echo_n "checking for library containing log... " >&6; }
if ${ac_cv_search_log+:} false; then :
$as_echo_n "(cached) " >&6
else
ac_func_search_save_LIBS=$LIBS
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
/* Override any GCC internal prototype to avoid an error.
Use char because int might match the return type of a GCC
builtin and then its argument prototype would still apply. */
#ifdef __cplusplus
extern "C"
#endif
char log ();
int
main ()
{
return log ();
;
return 0;
}
_ACEOF
for ac_lib in '' m; do
if test -z "$ac_lib"; then
ac_res="none required"
else
ac_res=-l$ac_lib
LIBS="-l$ac_lib $ac_func_search_save_LIBS"
fi
if ac_fn_c_try_link "$LINENO"; then :
ac_cv_search_log=$ac_res
fi
rm -f core conftest.err conftest.$ac_objext \
conftest$ac_exeext
if ${ac_cv_search_log+:} false; then :
break
fi
done
if ${ac_cv_search_log+:} false; then :
else
ac_cv_search_log=no
fi
rm conftest.$ac_ext
LIBS=$ac_func_search_save_LIBS
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_log" >&5
$as_echo "$ac_cv_search_log" >&6; }
ac_res=$ac_cv_search_log
if test "$ac_res" != no; then :
test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
fi
fi
#########
# See whether we should enable JSON1
# Check whether --enable-json1 was given.
if test "${enable_json1+set}" = set; then :
enableval=$enable_json1; enable_json1=yes
else
enable_json1=no
fi
if test "${enable_json1}" = "yes" ; then
OPT_FEATURE_FLAGS+=" -DSQLITE_ENABLE_JSON1"
fi
#########
# See whether we should enable RTREE
# Check whether --enable-rtree was given.
if test "${enable_rtree+set}" = set; then :
enableval=$enable_rtree; enable_rtree=yes
else
enable_rtree=no
fi
if test "${enable_rtree}" = "yes" ; then
OPT_FEATURE_FLAGS+=" -DSQLITE_ENABLE_RTREE"
fi
#########
# attempt to duplicate any OMITS and ENABLES into the $(OPT_FEATURE_FLAGS) parameter
for option in $CFLAGS $CPPFLAGS
@@ -11808,7 +11946,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.8.12, which was
This file was extended by sqlite $as_me 3.9.1, which was
generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -11874,7 +12012,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.8.12
sqlite config.status 3.9.1
configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\"
@@ -11885,7 +12023,6 @@ gives unlimited permission to copy, distribute and modify it."
ac_pwd='$ac_pwd'
srcdir='$srcdir'
INSTALL='$INSTALL'
AWK='$AWK'
test -n "\$AWK" || AWK=awk
_ACEOF
+41 -1
View File
@@ -90,7 +90,6 @@ fi
#
AC_PROG_LIBTOOL
AC_PROG_INSTALL
AC_PROG_AWK
#########
# Enable large file support (if special flags are necessary)
@@ -560,6 +559,47 @@ else
OPT_FEATURE_FLAGS="-DSQLITE_OMIT_LOAD_EXTENSION=1"
fi
#########
# See whether we should enable Full Text Search extensions
AC_ARG_ENABLE(fts3, AC_HELP_STRING([--enable-fts3],
[Enable the FTS3 extension]),
[enable_fts3=yes],[enable_fts3=no])
if test "${enable_fts3}" = "yes" ; then
OPT_FEATURE_FLAGS+=" -DSQLITE_ENABLE_FTS3"
fi
AC_ARG_ENABLE(fts4, AC_HELP_STRING([--enable-fts4],
[Enable the FTS4 extension]),
[enable_fts4=yes],[enable_fts4=no])
if test "${enable_fts4}" = "yes" ; then
OPT_FEATURE_FLAGS+=" -DSQLITE_ENABLE_FTS4"
AC_SEARCH_LIBS([log],[m])
fi
AC_ARG_ENABLE(fts5, AC_HELP_STRING([--enable-fts5],
[Enable the FTS5 extension]),
[enable_fts5=yes],[enable_fts5=no])
if test "${enable_fts5}" = "yes" ; then
OPT_FEATURE_FLAGS+=" -DSQLITE_ENABLE_FTS5"
AC_SEARCH_LIBS([log],[m])
fi
#########
# See whether we should enable JSON1
AC_ARG_ENABLE(json1, AC_HELP_STRING([--enable-json1],
[Enable the JSON1 extension]),
[enable_json1=yes],[enable_json1=no])
if test "${enable_json1}" = "yes" ; then
OPT_FEATURE_FLAGS+=" -DSQLITE_ENABLE_JSON1"
fi
#########
# See whether we should enable RTREE
AC_ARG_ENABLE(rtree, AC_HELP_STRING([--enable-rtree],
[Enable the RTREE extension]),
[enable_rtree=yes],[enable_rtree=no])
if test "${enable_rtree}" = "yes" ; then
OPT_FEATURE_FLAGS+=" -DSQLITE_ENABLE_RTREE"
fi
#########
# attempt to duplicate any OMITS and ENABLES into the $(OPT_FEATURE_FLAGS) parameter
for option in $CFLAGS $CPPFLAGS
+16
View File
@@ -1517,6 +1517,19 @@ static void fts3SetEstimatedRows(sqlite3_index_info *pIdxInfo, i64 nRow){
#endif
}
/*
** Set the SQLITE_INDEX_SCAN_UNIQUE flag in pIdxInfo->flags. Unless this
** extension is currently being used by a version of SQLite too old to
** support index-info flags. In that case this function is a no-op.
*/
static void fts3SetUniqueFlag(sqlite3_index_info *pIdxInfo){
#if SQLITE_VERSION_NUMBER>=3008012
if( sqlite3_libversion_number()>=3008012 ){
pIdxInfo->idxFlags |= SQLITE_INDEX_SCAN_UNIQUE;
}
#endif
}
/*
** Implementation of the xBestIndex method for FTS3 tables. There
** are three possible strategies, in order of preference:
@@ -1607,6 +1620,9 @@ static int fts3BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){
}
}
/* If using a docid=? or rowid=? strategy, set the UNIQUE flag. */
if( pInfo->idxNum==FTS3_DOCID_SEARCH ) fts3SetUniqueFlag(pInfo);
iIdx = 1;
if( iCons>=0 ){
pInfo->aConstraintUsage[iCons].argvIndex = iIdx++;
+1
View File
@@ -264,6 +264,7 @@ struct Fts3Table {
int nPendingData; /* Current bytes of pending data */
sqlite_int64 iPrevDocid; /* Docid of most recently inserted document */
int iPrevLangid; /* Langid of recently inserted document */
int bPrevDelete; /* True if last operation was a delete */
#if defined(SQLITE_DEBUG) || defined(SQLITE_COVERAGE_TEST)
/* State variables used for validating that the transaction control
+126 -100
View File
@@ -793,125 +793,151 @@ static int fts3ExprBalance(Fts3Expr **pp, int nMaxDepth){
rc = SQLITE_ERROR;
}
if( rc==SQLITE_OK && (eType==FTSQUERY_AND || eType==FTSQUERY_OR) ){
Fts3Expr **apLeaf;
apLeaf = (Fts3Expr **)sqlite3_malloc(sizeof(Fts3Expr *) * nMaxDepth);
if( 0==apLeaf ){
rc = SQLITE_NOMEM;
}else{
memset(apLeaf, 0, sizeof(Fts3Expr *) * nMaxDepth);
}
if( rc==SQLITE_OK ){
int i;
Fts3Expr *p;
/* Set $p to point to the left-most leaf in the tree of eType nodes. */
for(p=pRoot; p->eType==eType; p=p->pLeft){
assert( p->pParent==0 || p->pParent->pLeft==p );
assert( p->pLeft && p->pRight );
}
/* This loop runs once for each leaf in the tree of eType nodes. */
while( 1 ){
int iLvl;
Fts3Expr *pParent = p->pParent; /* Current parent of p */
assert( pParent==0 || pParent->pLeft==p );
p->pParent = 0;
if( pParent ){
pParent->pLeft = 0;
}else{
pRoot = 0;
}
rc = fts3ExprBalance(&p, nMaxDepth-1);
if( rc!=SQLITE_OK ) break;
for(iLvl=0; p && iLvl<nMaxDepth; iLvl++){
if( apLeaf[iLvl]==0 ){
apLeaf[iLvl] = p;
p = 0;
}else{
assert( pFree );
pFree->pLeft = apLeaf[iLvl];
pFree->pRight = p;
pFree->pLeft->pParent = pFree;
pFree->pRight->pParent = pFree;
p = pFree;
pFree = pFree->pParent;
p->pParent = 0;
apLeaf[iLvl] = 0;
}
}
if( p ){
sqlite3Fts3ExprFree(p);
rc = SQLITE_TOOBIG;
break;
}
/* If that was the last leaf node, break out of the loop */
if( pParent==0 ) break;
/* Set $p to point to the next leaf in the tree of eType nodes */
for(p=pParent->pRight; p->eType==eType; p=p->pLeft);
/* Remove pParent from the original tree. */
assert( pParent->pParent==0 || pParent->pParent->pLeft==pParent );
pParent->pRight->pParent = pParent->pParent;
if( pParent->pParent ){
pParent->pParent->pLeft = pParent->pRight;
}else{
assert( pParent==pRoot );
pRoot = pParent->pRight;
}
/* Link pParent into the free node list. It will be used as an
** internal node of the new tree. */
pParent->pParent = pFree;
pFree = pParent;
if( rc==SQLITE_OK ){
if( (eType==FTSQUERY_AND || eType==FTSQUERY_OR) ){
Fts3Expr **apLeaf;
apLeaf = (Fts3Expr **)sqlite3_malloc(sizeof(Fts3Expr *) * nMaxDepth);
if( 0==apLeaf ){
rc = SQLITE_NOMEM;
}else{
memset(apLeaf, 0, sizeof(Fts3Expr *) * nMaxDepth);
}
if( rc==SQLITE_OK ){
p = 0;
for(i=0; i<nMaxDepth; i++){
if( apLeaf[i] ){
if( p==0 ){
p = apLeaf[i];
p->pParent = 0;
int i;
Fts3Expr *p;
/* Set $p to point to the left-most leaf in the tree of eType nodes. */
for(p=pRoot; p->eType==eType; p=p->pLeft){
assert( p->pParent==0 || p->pParent->pLeft==p );
assert( p->pLeft && p->pRight );
}
/* This loop runs once for each leaf in the tree of eType nodes. */
while( 1 ){
int iLvl;
Fts3Expr *pParent = p->pParent; /* Current parent of p */
assert( pParent==0 || pParent->pLeft==p );
p->pParent = 0;
if( pParent ){
pParent->pLeft = 0;
}else{
pRoot = 0;
}
rc = fts3ExprBalance(&p, nMaxDepth-1);
if( rc!=SQLITE_OK ) break;
for(iLvl=0; p && iLvl<nMaxDepth; iLvl++){
if( apLeaf[iLvl]==0 ){
apLeaf[iLvl] = p;
p = 0;
}else{
assert( pFree!=0 );
assert( pFree );
pFree->pLeft = apLeaf[iLvl];
pFree->pRight = p;
pFree->pLeft = apLeaf[i];
pFree->pLeft->pParent = pFree;
pFree->pRight->pParent = pFree;
p = pFree;
pFree = pFree->pParent;
p->pParent = 0;
apLeaf[iLvl] = 0;
}
}
if( p ){
sqlite3Fts3ExprFree(p);
rc = SQLITE_TOOBIG;
break;
}
/* If that was the last leaf node, break out of the loop */
if( pParent==0 ) break;
/* Set $p to point to the next leaf in the tree of eType nodes */
for(p=pParent->pRight; p->eType==eType; p=p->pLeft);
/* Remove pParent from the original tree. */
assert( pParent->pParent==0 || pParent->pParent->pLeft==pParent );
pParent->pRight->pParent = pParent->pParent;
if( pParent->pParent ){
pParent->pParent->pLeft = pParent->pRight;
}else{
assert( pParent==pRoot );
pRoot = pParent->pRight;
}
/* Link pParent into the free node list. It will be used as an
** internal node of the new tree. */
pParent->pParent = pFree;
pFree = pParent;
}
pRoot = p;
}else{
/* An error occurred. Delete the contents of the apLeaf[] array
** and pFree list. Everything else is cleaned up by the call to
** sqlite3Fts3ExprFree(pRoot) below. */
Fts3Expr *pDel;
for(i=0; i<nMaxDepth; i++){
sqlite3Fts3ExprFree(apLeaf[i]);
}
while( (pDel=pFree)!=0 ){
pFree = pDel->pParent;
sqlite3_free(pDel);
if( rc==SQLITE_OK ){
p = 0;
for(i=0; i<nMaxDepth; i++){
if( apLeaf[i] ){
if( p==0 ){
p = apLeaf[i];
p->pParent = 0;
}else{
assert( pFree!=0 );
pFree->pRight = p;
pFree->pLeft = apLeaf[i];
pFree->pLeft->pParent = pFree;
pFree->pRight->pParent = pFree;
p = pFree;
pFree = pFree->pParent;
p->pParent = 0;
}
}
}
pRoot = p;
}else{
/* An error occurred. Delete the contents of the apLeaf[] array
** and pFree list. Everything else is cleaned up by the call to
** sqlite3Fts3ExprFree(pRoot) below. */
Fts3Expr *pDel;
for(i=0; i<nMaxDepth; i++){
sqlite3Fts3ExprFree(apLeaf[i]);
}
while( (pDel=pFree)!=0 ){
pFree = pDel->pParent;
sqlite3_free(pDel);
}
}
assert( pFree==0 );
sqlite3_free( apLeaf );
}
}else if( eType==FTSQUERY_NOT ){
Fts3Expr *pLeft = pRoot->pLeft;
Fts3Expr *pRight = pRoot->pRight;
pRoot->pLeft = 0;
pRoot->pRight = 0;
pLeft->pParent = 0;
pRight->pParent = 0;
rc = fts3ExprBalance(&pLeft, nMaxDepth-1);
if( rc==SQLITE_OK ){
rc = fts3ExprBalance(&pRight, nMaxDepth-1);
}
assert( pFree==0 );
sqlite3_free( apLeaf );
if( rc!=SQLITE_OK ){
sqlite3Fts3ExprFree(pRight);
sqlite3Fts3ExprFree(pLeft);
}else{
assert( pLeft && pRight );
pRoot->pLeft = pLeft;
pLeft->pParent = pRoot;
pRoot->pRight = pRight;
pRight->pParent = pRoot;
}
}
}
if( rc!=SQLITE_OK ){
sqlite3Fts3ExprFree(pRoot);
pRoot = 0;
+24 -12
View File
@@ -860,10 +860,12 @@ static int fts3PendingTermsAdd(
*/
static int fts3PendingTermsDocid(
Fts3Table *p, /* Full-text table handle */
int bDelete, /* True if this op is a delete */
int iLangid, /* Language id of row being written */
sqlite_int64 iDocid /* Docid of row being written */
){
assert( iLangid>=0 );
assert( bDelete==1 || bDelete==0 );
/* TODO(shess) Explore whether partially flushing the buffer on
** forced-flush would provide better performance. I suspect that if
@@ -871,7 +873,8 @@ static int fts3PendingTermsDocid(
** buffer was half empty, that would let the less frequent terms
** generate longer doclists.
*/
if( iDocid<=p->iPrevDocid
if( iDocid<p->iPrevDocid
|| (iDocid==p->iPrevDocid && p->bPrevDelete==0)
|| p->iPrevLangid!=iLangid
|| p->nPendingData>p->nMaxPendingData
){
@@ -880,6 +883,7 @@ static int fts3PendingTermsDocid(
}
p->iPrevDocid = iDocid;
p->iPrevLangid = iLangid;
p->bPrevDelete = bDelete;
return SQLITE_OK;
}
@@ -1069,7 +1073,8 @@ static void fts3DeleteTerms(
if( SQLITE_ROW==sqlite3_step(pSelect) ){
int i;
int iLangid = langidFromSelect(p, pSelect);
rc = fts3PendingTermsDocid(p, iLangid, sqlite3_column_int64(pSelect, 0));
i64 iDocid = sqlite3_column_int64(pSelect, 0);
rc = fts3PendingTermsDocid(p, 1, iLangid, iDocid);
for(i=1; rc==SQLITE_OK && i<=p->nColumn; i++){
int iCol = i-1;
if( p->abNotindexed[iCol]==0 ){
@@ -1317,14 +1322,19 @@ static int fts3SegReaderNext(
if( fts3SegReaderIsPending(pReader) ){
Fts3HashElem *pElem = *(pReader->ppNextElem);
if( pElem==0 ){
pReader->aNode = 0;
}else{
sqlite3_free(pReader->aNode);
pReader->aNode = 0;
if( pElem ){
char *aCopy;
PendingList *pList = (PendingList *)fts3HashData(pElem);
int nCopy = pList->nData+1;
pReader->zTerm = (char *)fts3HashKey(pElem);
pReader->nTerm = fts3HashKeysize(pElem);
pReader->nNode = pReader->nDoclist = pList->nData + 1;
pReader->aNode = pReader->aDoclist = pList->aData;
aCopy = (char*)sqlite3_malloc(nCopy);
if( !aCopy ) return SQLITE_NOMEM;
memcpy(aCopy, pList->aData, nCopy);
pReader->nNode = pReader->nDoclist = nCopy;
pReader->aNode = pReader->aDoclist = aCopy;
pReader->ppNextElem++;
assert( pReader->aNode );
}
@@ -1564,12 +1574,14 @@ int sqlite3Fts3MsrOvfl(
** second argument.
*/
void sqlite3Fts3SegReaderFree(Fts3SegReader *pReader){
if( pReader && !fts3SegReaderIsPending(pReader) ){
sqlite3_free(pReader->zTerm);
if( pReader ){
if( !fts3SegReaderIsPending(pReader) ){
sqlite3_free(pReader->zTerm);
}
if( !fts3SegReaderIsRootOnly(pReader) ){
sqlite3_free(pReader->aNode);
sqlite3_blob_close(pReader->pBlob);
}
sqlite3_blob_close(pReader->pBlob);
}
sqlite3_free(pReader);
}
@@ -3512,7 +3524,7 @@ static int fts3DoRebuild(Fts3Table *p){
while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){
int iCol;
int iLangid = langidFromSelect(p, pStmt);
rc = fts3PendingTermsDocid(p, iLangid, sqlite3_column_int64(pStmt, 0));
rc = fts3PendingTermsDocid(p, 0, iLangid, sqlite3_column_int64(pStmt, 0));
memset(aSz, 0, sizeof(aSz[0]) * (p->nColumn+1));
for(iCol=0; rc==SQLITE_OK && iCol<p->nColumn; iCol++){
if( p->abNotindexed[iCol]==0 ){
@@ -5617,7 +5629,7 @@ int sqlite3Fts3UpdateMethod(
}
}
if( rc==SQLITE_OK && (!isRemove || *pRowid!=p->iPrevDocid ) ){
rc = fts3PendingTermsDocid(p, iLangid, *pRowid);
rc = fts3PendingTermsDocid(p, 0, iLangid, *pRowid);
}
if( rc==SQLITE_OK ){
assert( p->iPrevDocid==*pRowid );
+9 -1
View File
@@ -23,6 +23,10 @@
#include "sqlite3.h"
#ifdef __cplusplus
extern "C" {
#endif
/*************************************************************************
** CUSTOM AUXILIARY FUNCTIONS
**
@@ -384,7 +388,7 @@ struct Fts5ExtensionApi {
** FTS index corresponding to both forms of the first token.
** </ol>
**
** Whether is is parsing document or query text, any call to xToken that
** Whether it is parsing document or query text, any call to xToken that
** specifies a <i>tflags</i> argument with the FTS5_TOKEN_COLOCATED bit
** is considered to supply a synonym for the previous token. For example,
** when parsing the document "I won first place", a tokenizer that supports
@@ -508,5 +512,9 @@ struct fts5_api {
** END OF REGISTRATION API
*************************************************************************/
#ifdef __cplusplus
} /* end of the 'extern "C"' block */
#endif
#endif /* _FTS5_H */
+51 -30
View File
@@ -81,6 +81,20 @@ extern int sqlite3_fts5_may_be_corrupt;
#endif
typedef struct Fts5Global Fts5Global;
typedef struct Fts5Colset Fts5Colset;
/* If a NEAR() clump or phrase may only match a specific set of columns,
** then an object of the following type is used to record the set of columns.
** Each entry in the aiCol[] array is a column that may be matched.
**
** This object is used by fts5_expr.c and fts5_index.c.
*/
struct Fts5Colset {
int nCol;
int aiCol[1];
};
/**************************************************************************
** Interface to code in fts5_config.c. fts5_config.c contains contains code
@@ -117,6 +131,12 @@ typedef struct Fts5Config Fts5Config;
** bColumnsize:
** True if the %_docsize table is created.
**
** bPrefixIndex:
** This is only used for debugging. If set to false, any prefix indexes
** are ignored. This value is configured using:
**
** INSERT INTO tbl(tbl, rank) VALUES('prefix-index', $bPrefixIndex);
**
*/
struct Fts5Config {
sqlite3 *db; /* Database handle */
@@ -145,10 +165,14 @@ struct Fts5Config {
/* If non-NULL, points to sqlite3_vtab.base.zErrmsg. Often NULL. */
char **pzErrmsg;
#ifdef SQLITE_DEBUG
int bPrefixIndex; /* True to use prefix-indexes */
#endif
};
/* Current expected value of %_config table 'version' field */
#define FTS5_CURRENT_VERSION 3
#define FTS5_CURRENT_VERSION 4
#define FTS5_CONTENT_NORMAL 0
#define FTS5_CONTENT_NONE 1
@@ -200,6 +224,7 @@ struct Fts5Buffer {
int nSpace;
};
int sqlite3Fts5BufferSize(int*, Fts5Buffer*, int);
int sqlite3Fts5BufferGrow(int*, Fts5Buffer*, int);
void sqlite3Fts5BufferAppendVarint(int*, Fts5Buffer*, i64);
void sqlite3Fts5BufferAppendBlob(int*, Fts5Buffer*, int, const u8*);
@@ -213,13 +238,17 @@ void sqlite3Fts5BufferAppend32(int*, Fts5Buffer*, int);
char *sqlite3Fts5Mprintf(int *pRc, const char *zFmt, ...);
#define fts5BufferZero(x) sqlite3Fts5BufferZero(x)
#define fts5BufferGrow(a,b,c) sqlite3Fts5BufferGrow(a,b,c)
#define fts5BufferAppendVarint(a,b,c) sqlite3Fts5BufferAppendVarint(a,b,c)
#define fts5BufferFree(a) sqlite3Fts5BufferFree(a)
#define fts5BufferAppendBlob(a,b,c,d) sqlite3Fts5BufferAppendBlob(a,b,c,d)
#define fts5BufferSet(a,b,c,d) sqlite3Fts5BufferSet(a,b,c,d)
#define fts5BufferAppend32(a,b,c) sqlite3Fts5BufferAppend32(a,b,c)
#define fts5BufferGrow(pRc,pBuf,nn) ( \
(pBuf)->n + (nn) <= (pBuf)->nSpace ? 0 : \
sqlite3Fts5BufferSize((pRc),(pBuf),(nn)+(pBuf)->n) \
)
/* Write and decode big-endian 32-bit integer values */
void sqlite3Fts5Put32(u8*, int);
int sqlite3Fts5Get32(const u8*);
@@ -230,7 +259,6 @@ int sqlite3Fts5Get32(const u8*);
typedef struct Fts5PoslistReader Fts5PoslistReader;
struct Fts5PoslistReader {
/* Variables used only by sqlite3Fts5PoslistIterXXX() functions. */
int iCol; /* If (iCol>=0), this column only */
const u8 *a; /* Position list to iterate through */
int n; /* Size of buffer at a[] in bytes */
int i; /* Current offset in a[] */
@@ -242,7 +270,6 @@ struct Fts5PoslistReader {
i64 iPos; /* (iCol<<32) + iPos */
};
int sqlite3Fts5PoslistReaderInit(
int iCol, /* If (iCol>=0), this column only */
const u8 *a, int n, /* Poslist buffer to iterate through */
Fts5PoslistReader *pIter /* Iterator object to initialize */
);
@@ -295,7 +322,7 @@ int sqlite3Fts5IndexClose(Fts5Index *p);
/*
** for(
** pIter = sqlite3Fts5IndexQuery(p, "token", 5, 0);
** sqlite3Fts5IndexQuery(p, "token", 5, 0, 0, &pIter);
** 0==sqlite3Fts5IterEof(pIter);
** sqlite3Fts5IterNext(pIter)
** ){
@@ -311,7 +338,8 @@ int sqlite3Fts5IndexQuery(
Fts5Index *p, /* FTS index to query */
const char *pToken, int nToken, /* Token (or prefix) to query for */
int flags, /* Mask of FTS5INDEX_QUERY_X flags */
Fts5IndexIter **ppIter
Fts5Colset *pColset, /* Match these columns only */
Fts5IndexIter **ppIter /* OUT: New iterator object */
);
/*
@@ -322,7 +350,7 @@ int sqlite3Fts5IterEof(Fts5IndexIter*);
int sqlite3Fts5IterNext(Fts5IndexIter*);
int sqlite3Fts5IterNextFrom(Fts5IndexIter*, i64 iMatch);
i64 sqlite3Fts5IterRowid(Fts5IndexIter*);
int sqlite3Fts5IterPoslist(Fts5IndexIter*, const u8 **pp, int *pn, i64 *pi);
int sqlite3Fts5IterPoslist(Fts5IndexIter*,Fts5Colset*, const u8**, int*, i64*);
int sqlite3Fts5IterPoslistBuffer(Fts5IndexIter *pIter, Fts5Buffer *pBuf);
/*
@@ -360,6 +388,7 @@ int sqlite3Fts5IndexWrite(
*/
int sqlite3Fts5IndexBeginWrite(
Fts5Index *p, /* Index to write to */
int bDelete, /* True if current operation is a delete */
i64 iDocid /* Docid to add or remove data from */
);
@@ -377,12 +406,6 @@ int sqlite3Fts5IndexSync(Fts5Index *p, int bCommit);
*/
int sqlite3Fts5IndexRollback(Fts5Index *p);
/*
** Retrieve and clear the current error code, respectively.
*/
int sqlite3Fts5IndexErrcode(Fts5Index*);
void sqlite3Fts5IndexReset(Fts5Index*);
/*
** Get or set the "averages" values.
*/
@@ -430,6 +453,15 @@ int sqlite3Fts5PutVarint(unsigned char *p, u64 v);
#define fts5GetVarint32(a,b) sqlite3Fts5GetVarint32(a,(u32*)&b)
#define fts5GetVarint sqlite3Fts5GetVarint
#define fts5FastGetVarint32(a, iOff, nVal) { \
nVal = (a)[iOff++]; \
if( nVal & 0x80 ){ \
iOff--; \
iOff += fts5GetVarint32(&(a)[iOff], nVal); \
} \
}
/*
** End of interface to code in fts5_varint.c.
**************************************************************************/
@@ -448,7 +480,7 @@ int sqlite3Fts5GetTokenizer(
char **pzErr
);
Fts5Index *sqlite3Fts5IndexFromCsrid(Fts5Global*, i64, int*);
Fts5Index *sqlite3Fts5IndexFromCsrid(Fts5Global*, i64, Fts5Config **);
/*
** End of interface to code in fts5.c.
@@ -522,7 +554,8 @@ int sqlite3Fts5DropAll(Fts5Config*);
int sqlite3Fts5CreateTable(Fts5Config*, const char*, const char*, int, char **);
int sqlite3Fts5StorageDelete(Fts5Storage *p, i64);
int sqlite3Fts5StorageInsert(Fts5Storage *p, sqlite3_value **apVal, int, i64*);
int sqlite3Fts5StorageContentInsert(Fts5Storage *p, sqlite3_value**, i64*);
int sqlite3Fts5StorageIndexInsert(Fts5Storage *p, sqlite3_value**, i64);
int sqlite3Fts5StorageIntegrity(Fts5Storage *p);
@@ -561,7 +594,6 @@ typedef struct Fts5Parse Fts5Parse;
typedef struct Fts5Token Fts5Token;
typedef struct Fts5ExprPhrase Fts5ExprPhrase;
typedef struct Fts5ExprNearset Fts5ExprNearset;
typedef struct Fts5ExprColset Fts5ExprColset;
struct Fts5Token {
const char *p; /* Token text (not NULL terminated) */
@@ -629,9 +661,9 @@ Fts5ExprNearset *sqlite3Fts5ParseNearset(
Fts5ExprPhrase*
);
Fts5ExprColset *sqlite3Fts5ParseColset(
Fts5Colset *sqlite3Fts5ParseColset(
Fts5Parse*,
Fts5ExprColset*,
Fts5Colset*,
Fts5Token *
);
@@ -640,7 +672,7 @@ void sqlite3Fts5ParseNearsetFree(Fts5ExprNearset*);
void sqlite3Fts5ParseNodeFree(Fts5ExprNode*);
void sqlite3Fts5ParseSetDistance(Fts5Parse*, Fts5ExprNearset*, Fts5Token*);
void sqlite3Fts5ParseSetColset(Fts5Parse*, Fts5ExprNearset*, Fts5ExprColset*);
void sqlite3Fts5ParseSetColset(Fts5Parse*, Fts5ExprNearset*, Fts5Colset*);
void sqlite3Fts5ParseFinished(Fts5Parse *pParse, Fts5ExprNode *p);
void sqlite3Fts5ParseNear(Fts5Parse *pParse, Fts5Token*);
@@ -668,17 +700,6 @@ int sqlite3Fts5TokenizerInit(fts5_api*);
** End of interface to code in fts5_tokenizer.c.
**************************************************************************/
/**************************************************************************
** Interface to code in fts5_sorter.c.
*/
typedef struct Fts5Sorter Fts5Sorter;
int sqlite3Fts5SorterNew(Fts5Expr *pExpr, Fts5Sorter **pp);
/*
** End of interface to code in fts5_sorter.c.
**************************************************************************/
/**************************************************************************
** Interface to code in fts5_vocab.c.
*/
+2 -2
View File
@@ -13,7 +13,7 @@
#include "fts5Int.h"
#include <math.h>
#include <math.h> /* amalgamator: keep */
/*
** Object used to iterate through all "coalesced phrase instances" in
@@ -137,7 +137,7 @@ static void fts5HighlightAppend(
const char *z, int n
){
if( *pRc==SQLITE_OK ){
if( n<0 ) n = strlen(z);
if( n<0 ) n = (int)strlen(z);
p->zOut = sqlite3_mprintf("%z%.*s", p->zOut, n, z);
if( p->zOut==0 ) *pRc = SQLITE_NOMEM;
}
+34 -41
View File
@@ -15,34 +15,30 @@
#include "fts5Int.h"
int sqlite3Fts5BufferGrow(int *pRc, Fts5Buffer *pBuf, int nByte){
/* A no-op if an error has already occurred */
if( *pRc ) return 1;
if( (pBuf->n + nByte) > pBuf->nSpace ){
u8 *pNew;
int nNew = pBuf->nSpace ? pBuf->nSpace*2 : 64;
while( nNew<(pBuf->n + nByte) ){
nNew = nNew * 2;
}
pNew = sqlite3_realloc(pBuf->p, nNew);
if( pNew==0 ){
*pRc = SQLITE_NOMEM;
return 1;
}else{
pBuf->nSpace = nNew;
pBuf->p = pNew;
}
int sqlite3Fts5BufferSize(int *pRc, Fts5Buffer *pBuf, int nByte){
int nNew = pBuf->nSpace ? pBuf->nSpace*2 : 64;
u8 *pNew;
while( nNew<nByte ){
nNew = nNew * 2;
}
pNew = sqlite3_realloc(pBuf->p, nNew);
if( pNew==0 ){
*pRc = SQLITE_NOMEM;
return 1;
}else{
pBuf->nSpace = nNew;
pBuf->p = pNew;
}
return 0;
}
/*
** Encode value iVal as an SQLite varint and append it to the buffer object
** pBuf. If an OOM error occurs, set the error code in p.
*/
void sqlite3Fts5BufferAppendVarint(int *pRc, Fts5Buffer *pBuf, i64 iVal){
if( sqlite3Fts5BufferGrow(pRc, pBuf, 9) ) return;
if( fts5BufferGrow(pRc, pBuf, 9) ) return;
pBuf->n += sqlite3Fts5PutVarint(&pBuf->p[pBuf->n], iVal);
}
@@ -58,7 +54,7 @@ int sqlite3Fts5Get32(const u8 *aBuf){
}
void sqlite3Fts5BufferAppend32(int *pRc, Fts5Buffer *pBuf, int iVal){
if( sqlite3Fts5BufferGrow(pRc, pBuf, 4) ) return;
if( fts5BufferGrow(pRc, pBuf, 4) ) return;
sqlite3Fts5Put32(&pBuf->p[pBuf->n], iVal);
pBuf->n += 4;
}
@@ -75,7 +71,7 @@ void sqlite3Fts5BufferAppendBlob(
const u8 *pData
){
assert( *pRc || nData>=0 );
if( sqlite3Fts5BufferGrow(pRc, pBuf, nData) ) return;
if( fts5BufferGrow(pRc, pBuf, nData) ) return;
memcpy(&pBuf->p[pBuf->n], pData, nData);
pBuf->n += nData;
}
@@ -90,7 +86,7 @@ void sqlite3Fts5BufferAppendString(
Fts5Buffer *pBuf,
const char *zStr
){
int nStr = strlen(zStr);
int nStr = (int)strlen(zStr);
sqlite3Fts5BufferAppendBlob(pRc, pBuf, nStr+1, (const u8*)zStr);
pBuf->n--;
}
@@ -183,11 +179,11 @@ int sqlite3Fts5PoslistNext64(
}else{
i64 iOff = *piOff;
int iVal;
i += fts5GetVarint32(&a[i], iVal);
fts5FastGetVarint32(a, i, iVal);
if( iVal==1 ){
i += fts5GetVarint32(&a[i], iVal);
fts5FastGetVarint32(a, i, iVal);
iOff = ((i64)iVal) << 32;
i += fts5GetVarint32(&a[i], iVal);
fts5FastGetVarint32(a, i, iVal);
}
*piOff = iOff + (iVal-2);
*pi = i;
@@ -201,26 +197,20 @@ int sqlite3Fts5PoslistNext64(
** if the iterator reaches EOF, or false otherwise.
*/
int sqlite3Fts5PoslistReaderNext(Fts5PoslistReader *pIter){
if( sqlite3Fts5PoslistNext64(pIter->a, pIter->n, &pIter->i, &pIter->iPos)
|| (pIter->iCol>=0 && (pIter->iPos >> 32) > pIter->iCol)
){
if( sqlite3Fts5PoslistNext64(pIter->a, pIter->n, &pIter->i, &pIter->iPos) ){
pIter->bEof = 1;
}
return pIter->bEof;
}
int sqlite3Fts5PoslistReaderInit(
int iCol, /* If (iCol>=0), this column only */
const u8 *a, int n, /* Poslist buffer to iterate through */
Fts5PoslistReader *pIter /* Iterator object to initialize */
){
memset(pIter, 0, sizeof(*pIter));
pIter->a = a;
pIter->n = n;
pIter->iCol = iCol;
do {
sqlite3Fts5PoslistReaderNext(pIter);
}while( pIter->bEof==0 && (pIter->iPos >> 32)<iCol );
sqlite3Fts5PoslistReaderNext(pIter);
return pIter->bEof;
}
@@ -231,13 +221,15 @@ int sqlite3Fts5PoslistWriterAppend(
){
static const i64 colmask = ((i64)(0x7FFFFFFF)) << 32;
int rc = SQLITE_OK;
if( (iPos & colmask) != (pWriter->iPrev & colmask) ){
fts5BufferAppendVarint(&rc, pBuf, 1);
fts5BufferAppendVarint(&rc, pBuf, (iPos >> 32));
pWriter->iPrev = (iPos & colmask);
if( 0==fts5BufferGrow(&rc, pBuf, 5+5+5) ){
if( (iPos & colmask) != (pWriter->iPrev & colmask) ){
pBuf->p[pBuf->n++] = 1;
pBuf->n += sqlite3Fts5PutVarint(&pBuf->p[pBuf->n], (iPos>>32));
pWriter->iPrev = (iPos & colmask);
}
pBuf->n += sqlite3Fts5PutVarint(&pBuf->p[pBuf->n], (iPos-pWriter->iPrev)+2);
pWriter->iPrev = iPos;
}
fts5BufferAppendVarint(&rc, pBuf, (iPos - pWriter->iPrev) + 2);
pWriter->iPrev = iPos;
return rc;
}
@@ -266,7 +258,7 @@ char *sqlite3Fts5Strndup(int *pRc, const char *pIn, int nIn){
char *zRet = 0;
if( *pRc==SQLITE_OK ){
if( nIn<0 ){
nIn = strlen(pIn);
nIn = (int)strlen(pIn);
}
zRet = (char*)sqlite3_malloc(nIn+1);
if( zRet ){
@@ -288,11 +280,12 @@ char *sqlite3Fts5Strndup(int *pRc, const char *pIn, int nIn){
** * The 52 upper and lower case ASCII characters, and
** * The 10 integer ASCII characters.
** * The underscore character "_" (0x5F).
** * The unicode "subsitute" character (0x1A).
*/
int sqlite3Fts5IsBareword(char t){
u8 aBareword[128] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x00 .. 0x0F */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x10 .. 0x1F */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, /* 0x10 .. 0x1F */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x20 .. 0x2F */
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, /* 0x30 .. 0x3F */
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x40 .. 0x4F */
+6 -3
View File
@@ -211,7 +211,7 @@ static int fts5ConfigParseSpecial(
char **pzErr /* OUT: Error message */
){
int rc = SQLITE_OK;
int nCmd = strlen(zCmd);
int nCmd = (int)strlen(zCmd);
if( sqlite3_strnicmp("prefix", zCmd, nCmd)==0 ){
const int nByte = sizeof(int) * FTS5_MAX_PREFIX_INDEXES;
const char *p;
@@ -248,7 +248,7 @@ static int fts5ConfigParseSpecial(
if( sqlite3_strnicmp("tokenize", zCmd, nCmd)==0 ){
const char *p = (const char*)zArg;
int nArg = strlen(zArg) + 1;
int nArg = (int)strlen(zArg) + 1;
char **azArg = sqlite3Fts5MallocZero(&rc, sizeof(char*) * nArg);
char *pDel = sqlite3Fts5MallocZero(&rc, nArg * 2);
char *pSpace = pDel;
@@ -364,7 +364,7 @@ static const char *fts5ConfigGobbleWord(
){
const char *zRet = 0;
int nIn = strlen(zIn);
int nIn = (int)strlen(zIn);
char *zOut = sqlite3_malloc(nIn+1);
assert( *pRc==SQLITE_OK );
@@ -480,6 +480,9 @@ int sqlite3Fts5ConfigParse(
pRet->zDb = sqlite3Fts5Strndup(&rc, azArg[1], -1);
pRet->zName = sqlite3Fts5Strndup(&rc, azArg[2], -1);
pRet->bColumnsize = 1;
#ifdef SQLITE_DEBUG
pRet->bPrefixIndex = 1;
#endif
if( rc==SQLITE_OK && sqlite3_stricmp(pRet->zName, FTS5_RANK_NAME)==0 ){
*pzErr = sqlite3_mprintf("reserved fts5 table name: %s", pRet->zName);
rc = SQLITE_ERROR;
+43 -136
View File
@@ -32,6 +32,11 @@ typedef struct Fts5ExprTerm Fts5ExprTerm;
void *sqlite3Fts5ParserAlloc(void *(*mallocProc)(u64));
void sqlite3Fts5ParserFree(void*, void (*freeProc)(void*));
void sqlite3Fts5Parser(void*, int, Fts5Token, Fts5Parse*);
#ifndef NDEBUG
#include <stdio.h>
void sqlite3Fts5ParserTrace(FILE*, char*);
#endif
struct Fts5Expr {
Fts5Index *pIndex;
@@ -89,23 +94,13 @@ struct Fts5ExprPhrase {
Fts5ExprTerm aTerm[1]; /* Terms that make up this phrase */
};
/*
** If a NEAR() clump may only match a specific set of columns, then
** Fts5ExprNearset.pColset points to an object of the following type.
** Each entry in the aiCol[] array
*/
struct Fts5ExprColset {
int nCol;
int aiCol[1];
};
/*
** One or more phrases that must appear within a certain token distance of
** each other within each matching document.
*/
struct Fts5ExprNearset {
int nNear; /* NEAR parameter */
Fts5ExprColset *pColset; /* Columns to search (NULL -> all columns) */
Fts5Colset *pColset; /* Columns to search (NULL -> all columns) */
int nPhrase; /* Number of entries in aPhrase[] array */
Fts5ExprPhrase *apPhrase[1]; /* Array of phrase pointers */
};
@@ -276,14 +271,6 @@ void sqlite3Fts5ExprFree(Fts5Expr *p){
}
}
static int fts5ExprColsetTest(Fts5ExprColset *pColset, int iCol){
int i;
for(i=0; i<pColset->nCol; i++){
if( pColset->aiCol[i]==iCol ) return 1;
}
return 0;
}
/*
** Argument pTerm must be a synonym iterator. Return the current rowid
** that it points to.
@@ -314,11 +301,11 @@ static i64 fts5ExprSynonymRowid(Fts5ExprTerm *pTerm, int bDesc, int *pbEof){
*/
static int fts5ExprSynonymPoslist(
Fts5ExprTerm *pTerm,
Fts5Colset *pColset,
i64 iRowid,
int *pbDel, /* OUT: Caller should sqlite3_free(*pa) */
u8 **pa, int *pn
){
Fts5PoslistWriter writer = {0};
Fts5PoslistReader aStatic[4];
Fts5PoslistReader *aIter = aStatic;
int nIter = 0;
@@ -333,7 +320,7 @@ static int fts5ExprSynonymPoslist(
const u8 *a;
int n;
i64 dummy;
rc = sqlite3Fts5IterPoslist(pIter, &a, &n, &dummy);
rc = sqlite3Fts5IterPoslist(pIter, pColset, &a, &n, &dummy);
if( rc!=SQLITE_OK ) goto synonym_poslist_out;
if( nIter==nAlloc ){
int nByte = sizeof(Fts5PoslistReader) * nAlloc * 2;
@@ -347,7 +334,7 @@ static int fts5ExprSynonymPoslist(
if( aIter!=aStatic ) sqlite3_free(aIter);
aIter = aNew;
}
sqlite3Fts5PoslistReaderInit(-1, a, n, &aIter[nIter]);
sqlite3Fts5PoslistReaderInit(a, n, &aIter[nIter]);
assert( aIter[nIter].bEof==0 );
nIter++;
}
@@ -406,7 +393,7 @@ static int fts5ExprSynonymPoslist(
*/
static int fts5ExprPhraseIsMatch(
Fts5ExprNode *pNode, /* Node pPhrase belongs to */
Fts5ExprColset *pColset, /* Restrict matches to these columns */
Fts5Colset *pColset, /* Restrict matches to these columns */
Fts5ExprPhrase *pPhrase, /* Phrase object to initialize */
int *pbMatch /* OUT: Set to true if really a match */
){
@@ -415,13 +402,7 @@ static int fts5ExprPhraseIsMatch(
Fts5PoslistReader *aIter = aStatic;
int i;
int rc = SQLITE_OK;
int iCol = -1;
if( pColset && pColset->nCol==1 ){
iCol = pColset->aiCol[0];
pColset = 0;
}
fts5BufferZero(&pPhrase->poslist);
/* If the aStatic[] array is not large enough, allocate a large array
@@ -441,12 +422,14 @@ static int fts5ExprPhraseIsMatch(
int bFlag = 0;
const u8 *a = 0;
if( pTerm->pSynonym ){
rc = fts5ExprSynonymPoslist(pTerm, pNode->iRowid, &bFlag, (u8**)&a, &n);
rc = fts5ExprSynonymPoslist(
pTerm, pColset, pNode->iRowid, &bFlag, (u8**)&a, &n
);
}else{
rc = sqlite3Fts5IterPoslist(pTerm->pIter, &a, &n, &dummy);
rc = sqlite3Fts5IterPoslist(pTerm->pIter, pColset, &a, &n, &dummy);
}
if( rc!=SQLITE_OK ) goto ismatch_out;
sqlite3Fts5PoslistReaderInit(iCol, a, n, &aIter[i]);
sqlite3Fts5PoslistReaderInit(a, n, &aIter[i]);
aIter[i].bFlag = bFlag;
if( aIter[i].bEof ) goto ismatch_out;
}
@@ -469,11 +452,9 @@ static int fts5ExprPhraseIsMatch(
}
}while( bMatch==0 );
if( pColset==0 || fts5ExprColsetTest(pColset, FTS5_POS2COLUMN(iPos)) ){
/* Append position iPos to the output */
rc = sqlite3Fts5PoslistWriterAppend(&pPhrase->poslist, &writer, iPos);
if( rc!=SQLITE_OK ) goto ismatch_out;
}
/* Append position iPos to the output */
rc = sqlite3Fts5PoslistWriterAppend(&pPhrase->poslist, &writer, iPos);
if( rc!=SQLITE_OK ) goto ismatch_out;
for(i=0; i<pPhrase->nTerm; i++){
if( sqlite3Fts5PoslistReaderNext(&aIter[i]) ) goto ismatch_out;
@@ -653,7 +634,7 @@ static int fts5ExprNearAdvanceFirst(
i64 iFrom
){
Fts5ExprTerm *pTerm = &pNode->pNear->apPhrase[0]->aTerm[0];
int rc;
int rc = SQLITE_OK;
if( pTerm->pSynonym ){
int bEof = 1;
@@ -768,61 +749,6 @@ static int fts5ExprSynonymAdvanceto(
return bEof;
}
/*
** IN/OUT parameter (*pa) points to a position list n bytes in size. If
** the position list contains entries for column iCol, then (*pa) is set
** to point to the sub-position-list for that column and the number of
** bytes in it returned. Or, if the argument position list does not
** contain any entries for column iCol, return 0.
*/
static int fts5ExprExtractCol(
const u8 **pa, /* IN/OUT: Pointer to poslist */
int n, /* IN: Size of poslist in bytes */
int iCol /* Column to extract from poslist */
){
int iCurrent = 0;
const u8 *p = *pa;
const u8 *pEnd = &p[n]; /* One byte past end of position list */
u8 prev = 0;
while( iCol!=iCurrent ){
/* Advance pointer p until it points to pEnd or an 0x01 byte that is
** not part of a varint */
while( (prev & 0x80) || *p!=0x01 ){
prev = *p++;
if( p==pEnd ) return 0;
}
*pa = p++;
p += fts5GetVarint32(p, iCurrent);
}
/* Advance pointer p until it points to pEnd or an 0x01 byte that is
** not part of a varint */
assert( (prev & 0x80)==0 );
while( p<pEnd && ((prev & 0x80) || *p!=0x01) ){
prev = *p++;
}
return p - (*pa);
}
static int fts5ExprExtractColset (
Fts5ExprColset *pColset, /* Colset to filter on */
const u8 *pPos, int nPos, /* Position list */
Fts5Buffer *pBuf /* Output buffer */
){
int rc = SQLITE_OK;
int i;
fts5BufferZero(pBuf);
for(i=0; i<pColset->nCol; i++){
const u8 *pSub = pPos;
int nSub = fts5ExprExtractCol(&pSub, nPos, pColset->aiCol[i]);
if( nSub ){
fts5BufferAppendBlob(&rc, pBuf, nSub, pSub);
}
}
return rc;
}
static int fts5ExprNearTest(
int *pRc,
@@ -869,35 +795,16 @@ static int fts5ExprTokenTest(
Fts5ExprNearset *pNear = pNode->pNear;
Fts5ExprPhrase *pPhrase = pNear->apPhrase[0];
Fts5IndexIter *pIter = pPhrase->aTerm[0].pIter;
Fts5ExprColset *pColset = pNear->pColset;
const u8 *pPos;
int nPos;
Fts5Colset *pColset = pNear->pColset;
int rc;
assert( pNode->eType==FTS5_TERM );
assert( pNear->nPhrase==1 && pPhrase->nTerm==1 );
assert( pPhrase->aTerm[0].pSynonym==0 );
rc = sqlite3Fts5IterPoslist(pIter, &pPos, &nPos, &pNode->iRowid);
/* If the term may match any column, then this must be a match.
** Return immediately in this case. Otherwise, try to find the
** part of the poslist that corresponds to the required column.
** If it can be found, return. If it cannot, the next iteration
** of the loop will test the next rowid in the database for this
** term. */
if( pColset==0 ){
assert( pPhrase->poslist.nSpace==0 );
pPhrase->poslist.p = (u8*)pPos;
pPhrase->poslist.n = nPos;
}else if( pColset->nCol==1 ){
assert( pPhrase->poslist.nSpace==0 );
pPhrase->poslist.n = fts5ExprExtractCol(&pPos, nPos, pColset->aiCol[0]);
pPhrase->poslist.p = (u8*)pPos;
}else if( rc==SQLITE_OK ){
rc = fts5ExprExtractColset(pColset, pPos, nPos, &pPhrase->poslist);
}
rc = sqlite3Fts5IterPoslist(pIter, pColset,
(const u8**)&pPhrase->poslist.p, &pPhrase->poslist.n, &pNode->iRowid
);
pNode->bNomatch = (pPhrase->poslist.n==0);
return rc;
}
@@ -948,8 +855,6 @@ static int fts5ExprNearNextMatch(
for(j=0; j<pPhrase->nTerm; j++){
Fts5ExprTerm *pTerm = &pPhrase->aTerm[j];
if( pTerm->pSynonym ){
Fts5ExprTerm *p;
int bEof = 1;
i64 iRowid = fts5ExprSynonymRowid(pTerm, bDesc, 0);
if( iRowid==iLast ) continue;
bMatch = 0;
@@ -1002,9 +907,10 @@ static int fts5ExprNearInitAll(
p->pIter = 0;
}
rc = sqlite3Fts5IndexQuery(
pExpr->pIndex, p->zTerm, strlen(p->zTerm),
pExpr->pIndex, p->zTerm, (int)strlen(p->zTerm),
(pTerm->bPrefix ? FTS5INDEX_QUERY_PREFIX : 0) |
(pExpr->bDesc ? FTS5INDEX_QUERY_DESC : 0),
pNear->pColset,
&p->pIter
);
assert( rc==SQLITE_OK || p->pIter==0 );
@@ -1612,7 +1518,7 @@ Fts5ExprPhrase *sqlite3Fts5ParseTerm(
int flags = FTS5_TOKENIZE_QUERY | (bPrefix ? FTS5_TOKENIZE_QUERY : 0);
int n;
sqlite3Fts5Dequote(z);
n = strlen(z);
n = (int)strlen(z);
rc = sqlite3Fts5Tokenize(pConfig, flags, z, n, &sCtx, fts5ParseTokenize);
}
sqlite3_free(z);
@@ -1657,13 +1563,9 @@ int sqlite3Fts5ExprClonePhrase(
){
int rc = SQLITE_OK; /* Return code */
Fts5ExprPhrase *pOrig; /* The phrase extracted from pExpr */
Fts5ExprPhrase *pCopy; /* Copy of pOrig */
int i; /* Used to iterate through phrase terms */
Fts5Expr *pNew = 0; /* Expression to return via *ppNew */
Fts5ExprPhrase **apPhrase; /* pNew->apPhrase */
Fts5ExprNode *pNode; /* pNew->pRoot */
Fts5ExprNearset *pNear; /* pNew->pRoot->pNear */
TokenCtx sCtx = {0,0}; /* Context object for fts5ParseTokenize */
@@ -1689,7 +1591,8 @@ int sqlite3Fts5ExprClonePhrase(
Fts5ExprTerm *p;
for(p=&pOrig->aTerm[i]; p && rc==SQLITE_OK; p=p->pSynonym){
const char *zTerm = p->zTerm;
rc = fts5ParseTokenize((void*)&sCtx, tflags, zTerm, strlen(zTerm), 0, 0);
rc = fts5ParseTokenize((void*)&sCtx, tflags, zTerm, (int)strlen(zTerm),
0, 0);
tflags = FTS5_TOKEN_COLOCATED;
}
if( rc==SQLITE_OK ){
@@ -1761,25 +1664,25 @@ void sqlite3Fts5ParseSetDistance(
/*
** The second argument passed to this function may be NULL, or it may be
** an existing Fts5ExprColset object. This function returns a pointer to
** an existing Fts5Colset object. This function returns a pointer to
** a new colset object containing the contents of (p) with new value column
** number iCol appended.
**
** If an OOM error occurs, store an error code in pParse and return NULL.
** The old colset object (if any) is not freed in this case.
*/
static Fts5ExprColset *fts5ParseColset(
static Fts5Colset *fts5ParseColset(
Fts5Parse *pParse, /* Store SQLITE_NOMEM here if required */
Fts5ExprColset *p, /* Existing colset object */
Fts5Colset *p, /* Existing colset object */
int iCol /* New column to add to colset object */
){
int nCol = p ? p->nCol : 0; /* Num. columns already in colset object */
Fts5ExprColset *pNew; /* New colset object to return */
Fts5Colset *pNew; /* New colset object to return */
assert( pParse->rc==SQLITE_OK );
assert( iCol>=0 && iCol<pParse->pConfig->nCol );
pNew = sqlite3_realloc(p, sizeof(Fts5ExprColset) + sizeof(int)*nCol);
pNew = sqlite3_realloc(p, sizeof(Fts5Colset) + sizeof(int)*nCol);
if( pNew==0 ){
pParse->rc = SQLITE_NOMEM;
}else{
@@ -1804,12 +1707,12 @@ static Fts5ExprColset *fts5ParseColset(
return pNew;
}
Fts5ExprColset *sqlite3Fts5ParseColset(
Fts5Colset *sqlite3Fts5ParseColset(
Fts5Parse *pParse, /* Store SQLITE_NOMEM here if required */
Fts5ExprColset *pColset, /* Existing colset object */
Fts5Colset *pColset, /* Existing colset object */
Fts5Token *p
){
Fts5ExprColset *pRet = 0;
Fts5Colset *pRet = 0;
int iCol;
char *z; /* Dequoted copy of token p */
@@ -1839,7 +1742,7 @@ Fts5ExprColset *sqlite3Fts5ParseColset(
void sqlite3Fts5ParseSetColset(
Fts5Parse *pParse,
Fts5ExprNearset *pNear,
Fts5ExprColset *pColset
Fts5Colset *pColset
){
if( pNear ){
pNear->pColset = pColset;
@@ -1931,7 +1834,7 @@ static char *fts5ExprTermPrint(Fts5ExprTerm *pTerm){
/* Determine the maximum amount of space required. */
for(p=pTerm; p; p=p->pSynonym){
nByte += strlen(pTerm->zTerm) * 2 + 3 + 2;
nByte += (int)strlen(pTerm->zTerm) * 2 + 3 + 2;
}
zQuoted = sqlite3_malloc(nByte);
@@ -2292,6 +2195,11 @@ int sqlite3Fts5ExprInit(Fts5Global *pGlobal, sqlite3 *db){
rc = sqlite3_create_function(db, p->z, -1, SQLITE_UTF8, pCtx, p->x, 0, 0);
}
/* Avoid a warning indicating that sqlite3Fts5ParserTrace() is unused */
#ifndef NDEBUG
(void)sqlite3Fts5ParserTrace;
#endif
return rc;
}
@@ -2327,4 +2235,3 @@ int sqlite3Fts5ExprPoslist(Fts5Expr *pExpr, int iPhrase, const u8 **pa){
}
return nRet;
}
+2 -2
View File
@@ -170,7 +170,7 @@ static int fts5HashResize(Fts5Hash *pHash){
int iHash;
Fts5HashEntry *p = apOld[i];
apOld[i] = p->pHashNext;
iHash = fts5HashKey(nNew, (u8*)p->zKey, strlen(p->zKey));
iHash = fts5HashKey(nNew, (u8*)p->zKey, (int)strlen(p->zKey));
p->pHashNext = apNew[iHash];
apNew[iHash] = p;
}
@@ -458,7 +458,7 @@ void sqlite3Fts5HashScanEntry(
){
Fts5HashEntry *p;
if( (p = pHash->pScan) ){
int nTerm = strlen(p->zKey);
int nTerm = (int)strlen(p->zKey);
fts5HashAddPoslistSize(p);
*pzTerm = p->zKey;
*ppDoclist = (const u8*)&p->zKey[nTerm+1];
+919 -531
View File
File diff suppressed because it is too large Load Diff
+186 -72
View File
@@ -25,11 +25,11 @@
int sqlite3_fts5_may_be_corrupt = 1;
typedef struct Fts5Table Fts5Table;
typedef struct Fts5Cursor Fts5Cursor;
typedef struct Fts5Auxiliary Fts5Auxiliary;
typedef struct Fts5Auxdata Fts5Auxdata;
typedef struct Fts5Auxiliary Fts5Auxiliary;
typedef struct Fts5Cursor Fts5Cursor;
typedef struct Fts5Sorter Fts5Sorter;
typedef struct Fts5Table Fts5Table;
typedef struct Fts5TokenizerModule Fts5TokenizerModule;
/*
@@ -440,6 +440,22 @@ static int fts5CreateMethod(
#define FTS5_PLAN_SCAN 5 /* No usable constraint */
#define FTS5_PLAN_ROWID 6 /* (rowid = ?) */
/*
** Set the SQLITE_INDEX_SCAN_UNIQUE flag in pIdxInfo->flags. Unless this
** extension is currently being used by a version of SQLite too old to
** support index-info flags. In that case this function is a no-op.
*/
static void fts5SetUniqueFlag(sqlite3_index_info *pIdxInfo){
#if SQLITE_VERSION_NUMBER>=3008012
#ifndef SQLITE_CORE
if( sqlite3_libversion_number()>=3008012 )
#endif
{
pIdxInfo->idxFlags |= SQLITE_INDEX_SCAN_UNIQUE;
}
#endif
}
/*
** Implementation of the xBestIndex method for FTS5 tables. Within the
** WHERE constraint, it searches for the following:
@@ -492,8 +508,10 @@ static int fts5BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){
int omit; /* True to omit this if found */
int iConsIndex; /* Index in pInfo->aConstraint[] */
} aConstraint[] = {
{SQLITE_INDEX_CONSTRAINT_MATCH, FTS5_BI_MATCH, 1, 1, -1},
{SQLITE_INDEX_CONSTRAINT_MATCH, FTS5_BI_RANK, 2, 1, -1},
{SQLITE_INDEX_CONSTRAINT_MATCH|SQLITE_INDEX_CONSTRAINT_EQ,
FTS5_BI_MATCH, 1, 1, -1},
{SQLITE_INDEX_CONSTRAINT_MATCH|SQLITE_INDEX_CONSTRAINT_EQ,
FTS5_BI_RANK, 2, 1, -1},
{SQLITE_INDEX_CONSTRAINT_EQ, FTS5_BI_ROWID_EQ, 0, 0, -1},
{SQLITE_INDEX_CONSTRAINT_LT|SQLITE_INDEX_CONSTRAINT_LE,
FTS5_BI_ROWID_LE, 0, 0, -1},
@@ -546,6 +564,7 @@ static int fts5BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){
bHasMatch = BitFlagTest(idxFlags, FTS5_BI_MATCH);
if( BitFlagTest(idxFlags, FTS5_BI_ROWID_EQ) ){
pInfo->estimatedCost = bHasMatch ? 100.0 : 10.0;
if( bHasMatch==0 ) fts5SetUniqueFlag(pInfo);
}else if( BitFlagAllTest(idxFlags, FTS5_BI_ROWID_LE|FTS5_BI_ROWID_GE) ){
pInfo->estimatedCost = bHasMatch ? 500.0 : 250000.0;
}else if( BitFlagTest(idxFlags, FTS5_BI_ROWID_LE|FTS5_BI_ROWID_GE) ){
@@ -1116,6 +1135,7 @@ static int fts5FilterMethod(
rc = fts5CursorFirst(pTab, pCsr, bDesc);
}else if( pMatch ){
const char *zExpr = (const char*)sqlite3_value_text(apVal[0]);
if( zExpr==0 ) zExpr = "";
rc = fts5CursorParseRank(pConfig, pCsr, pRank);
if( rc==SQLITE_OK ){
@@ -1283,15 +1303,14 @@ static void fts5SetVtabError(Fts5Table *p, const char *zFormat, ...){
*/
static int fts5SpecialInsert(
Fts5Table *pTab, /* Fts5 table object */
sqlite3_value *pCmd, /* Value inserted into special column */
const char *zCmd, /* Text inserted into table-name column */
sqlite3_value *pVal /* Value inserted into rank column */
){
Fts5Config *pConfig = pTab->pConfig;
const char *z = (const char*)sqlite3_value_text(pCmd);
int rc = SQLITE_OK;
int bError = 0;
if( 0==sqlite3_stricmp("delete-all", z) ){
if( 0==sqlite3_stricmp("delete-all", zCmd) ){
if( pConfig->eContent==FTS5_CONTENT_NORMAL ){
fts5SetVtabError(pTab,
"'delete-all' may only be used with a "
@@ -1301,7 +1320,7 @@ static int fts5SpecialInsert(
}else{
rc = sqlite3Fts5StorageDeleteAll(pTab->pStorage);
}
}else if( 0==sqlite3_stricmp("rebuild", z) ){
}else if( 0==sqlite3_stricmp("rebuild", zCmd) ){
if( pConfig->eContent==FTS5_CONTENT_NONE ){
fts5SetVtabError(pTab,
"'rebuild' may not be used with a contentless fts5 table"
@@ -1310,23 +1329,27 @@ static int fts5SpecialInsert(
}else{
rc = sqlite3Fts5StorageRebuild(pTab->pStorage);
}
}else if( 0==sqlite3_stricmp("optimize", z) ){
}else if( 0==sqlite3_stricmp("optimize", zCmd) ){
rc = sqlite3Fts5StorageOptimize(pTab->pStorage);
}else if( 0==sqlite3_stricmp("merge", z) ){
}else if( 0==sqlite3_stricmp("merge", zCmd) ){
int nMerge = sqlite3_value_int(pVal);
rc = sqlite3Fts5StorageMerge(pTab->pStorage, nMerge);
}else if( 0==sqlite3_stricmp("integrity-check", z) ){
}else if( 0==sqlite3_stricmp("integrity-check", zCmd) ){
rc = sqlite3Fts5StorageIntegrity(pTab->pStorage);
#ifdef SQLITE_DEBUG
}else if( 0==sqlite3_stricmp("prefix-index", zCmd) ){
pConfig->bPrefixIndex = sqlite3_value_int(pVal);
#endif
}else{
rc = sqlite3Fts5IndexLoadConfig(pTab->pIndex);
if( rc==SQLITE_OK ){
rc = sqlite3Fts5ConfigSetValue(pTab->pConfig, z, pVal, &bError);
rc = sqlite3Fts5ConfigSetValue(pTab->pConfig, zCmd, pVal, &bError);
}
if( rc==SQLITE_OK ){
if( bError ){
rc = SQLITE_ERROR;
}else{
rc = sqlite3Fts5StorageConfigValue(pTab->pStorage, z, pVal, 0);
rc = sqlite3Fts5StorageConfigValue(pTab->pStorage, zCmd, pVal, 0);
}
}
}
@@ -1347,10 +1370,35 @@ static int fts5SpecialDelete(
return rc;
}
static void fts5StorageInsert(
int *pRc,
Fts5Table *pTab,
sqlite3_value **apVal,
i64 *piRowid
){
int rc = *pRc;
if( rc==SQLITE_OK ){
rc = sqlite3Fts5StorageContentInsert(pTab->pStorage, apVal, piRowid);
}
if( rc==SQLITE_OK ){
rc = sqlite3Fts5StorageIndexInsert(pTab->pStorage, apVal, *piRowid);
}
*pRc = rc;
}
/*
** This function is the implementation of the xUpdate callback used by
** FTS3 virtual tables. It is invoked by SQLite each time a row is to be
** inserted, updated or deleted.
**
** A delete specifies a single argument - the rowid of the row to remove.
**
** Update and insert operations pass:
**
** 1. The "old" rowid, or NULL.
** 2. The "new" rowid.
** 3. Values for each of the nCol matchable columns.
** 4. Values for the two hidden columns (<tablename> and "rank").
*/
static int fts5UpdateMethod(
sqlite3_vtab *pVtab, /* Virtual table handle */
@@ -1361,65 +1409,108 @@ static int fts5UpdateMethod(
Fts5Table *pTab = (Fts5Table*)pVtab;
Fts5Config *pConfig = pTab->pConfig;
int eType0; /* value_type() of apVal[0] */
int eConflict; /* ON CONFLICT for this DML */
int rc = SQLITE_OK; /* Return code */
/* A transaction must be open when this is called. */
assert( pTab->ts.eState==1 );
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( pTab->pConfig->pzErrmsg==0 );
pTab->pConfig->pzErrmsg = &pTab->base.zErrMsg;
/* A delete specifies a single argument - the rowid of the row to remove.
** Update and insert operations pass:
**
** 1. The "old" rowid, or NULL.
** 2. The "new" rowid.
** 3. Values for each of the nCol matchable columns.
** 4. Values for the two hidden columns (<tablename> and "rank").
*/
/* Put any active cursors into REQUIRE_SEEK state. */
fts5TripCursors(pTab);
eType0 = sqlite3_value_type(apVal[0]);
eConflict = sqlite3_vtab_on_conflict(pConfig->db);
if( eType0==SQLITE_NULL
&& sqlite3_value_type(apVal[2+pConfig->nCol])!=SQLITE_NULL
){
/* A "special" INSERT op. These are handled separately. */
const char *z = (const char*)sqlite3_value_text(apVal[2+pConfig->nCol]);
if( pConfig->eContent!=FTS5_CONTENT_NORMAL
&& 0==sqlite3_stricmp("delete", z)
){
rc = fts5SpecialDelete(pTab, apVal, pRowid);
}else{
rc = fts5SpecialInsert(pTab, z, apVal[2 + pConfig->nCol + 1]);
}
}else{
/* A regular INSERT, UPDATE or DELETE statement. The trick here is that
** any conflict on the rowid value must be detected before any
** modifications are made to the database file. There are 4 cases:
**
** 1) DELETE
** 2) UPDATE (rowid not modified)
** 3) UPDATE (rowid modified)
** 4) INSERT
**
** Cases 3 and 4 may violate the rowid constraint.
*/
int eConflict = sqlite3_vtab_on_conflict(pConfig->db);
assert( eType0==SQLITE_INTEGER || eType0==SQLITE_NULL );
assert( pVtab->zErrMsg==0 );
assert( (nArg==1 && eType0==SQLITE_INTEGER) || nArg==(2+pConfig->nCol+2) );
assert( eType0==SQLITE_INTEGER || eType0==SQLITE_NULL );
assert( nArg!=1 || eType0==SQLITE_INTEGER );
fts5TripCursors(pTab);
if( eType0==SQLITE_INTEGER ){
if( fts5IsContentless(pTab) ){
/* 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(
"cannot %s contentless fts5 table: %s",
(nArg>1 ? "UPDATE" : "DELETE from"), pConfig->zName
);
rc = SQLITE_ERROR;
}else{
}
/* Case 1: DELETE */
else if( nArg==1 ){
i64 iDel = sqlite3_value_int64(apVal[0]); /* Rowid to delete */
rc = sqlite3Fts5StorageDelete(pTab->pStorage, iDel);
}
}else{
sqlite3_value *pCmd = apVal[2 + pConfig->nCol];
assert( nArg>1 );
if( SQLITE_NULL!=sqlite3_value_type(pCmd) ){
const char *z = (const char*)sqlite3_value_text(pCmd);
if( pConfig->eContent!=FTS5_CONTENT_NORMAL
&& 0==sqlite3_stricmp("delete", z)
/* Case 2: 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
){
rc = fts5SpecialDelete(pTab, apVal, pRowid);
}else{
rc = fts5SpecialInsert(pTab, pCmd, apVal[2 + pConfig->nCol + 1]);
i64 iNew = sqlite3_value_int64(apVal[1]); /* Rowid to delete */
rc = sqlite3Fts5StorageDelete(pTab->pStorage, iNew);
}
fts5StorageInsert(&rc, pTab, apVal, pRowid);
}
/* Case 2: 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);
if( rc==SQLITE_OK ){
rc = sqlite3Fts5StorageDelete(pTab->pStorage, iNew);
}
fts5StorageInsert(&rc, pTab, apVal, pRowid);
}else{
rc = sqlite3Fts5StorageContentInsert(pTab->pStorage, apVal, pRowid);
if( rc==SQLITE_OK ){
rc = sqlite3Fts5StorageDelete(pTab->pStorage, iOld);
}
if( rc==SQLITE_OK ){
rc = sqlite3Fts5StorageIndexInsert(pTab->pStorage, apVal, *pRowid);
}
}
}else{
rc = sqlite3Fts5StorageDelete(pTab->pStorage, iOld);
fts5StorageInsert(&rc, pTab, apVal, pRowid);
}
goto update_method_out;
}
}
if( rc==SQLITE_OK && nArg>1 ){
rc = sqlite3Fts5StorageInsert(pTab->pStorage, apVal, eConflict, pRowid);
}
update_method_out:
pTab->pConfig->pzErrmsg = 0;
return rc;
}
@@ -1555,7 +1646,7 @@ static int fts5CacheInstArray(Fts5Cursor *pCsr){
for(i=0; i<nIter; i++){
const u8 *a;
int n = fts5CsrPoslist(pCsr, i, &a);
sqlite3Fts5PoslistReaderInit(-1, a, n, &aIter[i]);
sqlite3Fts5PoslistReaderInit(a, n, &aIter[i]);
}
while( 1 ){
@@ -1930,20 +2021,20 @@ static void fts5ApiCallback(
** Given cursor id iId, return a pointer to the corresponding Fts5Index
** object. Or NULL If the cursor id does not exist.
**
** If successful, set *pnCol to the number of indexed columns in the
** table before returning.
** If successful, set *ppConfig to point to the associated config object
** before returning.
*/
Fts5Index *sqlite3Fts5IndexFromCsrid(
Fts5Global *pGlobal,
i64 iCsrId,
int *pnCol
Fts5Global *pGlobal, /* FTS5 global context for db handle */
i64 iCsrId, /* Id of cursor to find */
Fts5Config **ppConfig /* OUT: Configuration object */
){
Fts5Cursor *pCsr;
Fts5Table *pTab;
pCsr = fts5CursorFromCsrid(pGlobal, iCsrId);
pTab = (Fts5Table*)pCsr->base.pVtab;
*pnCol = pTab->pConfig->nCol;
*ppConfig = pTab->pConfig;
return pTab->pIndex;
}
@@ -2127,14 +2218,16 @@ static int fts5CreateAux(
int rc = sqlite3_overload_function(pGlobal->db, zName, -1);
if( rc==SQLITE_OK ){
Fts5Auxiliary *pAux;
int nName; /* Size of zName in bytes, including \0 */
int nByte; /* Bytes of space to allocate */
nByte = sizeof(Fts5Auxiliary) + strlen(zName) + 1;
nName = (int)strlen(zName) + 1;
nByte = sizeof(Fts5Auxiliary) + nName;
pAux = (Fts5Auxiliary*)sqlite3_malloc(nByte);
if( pAux ){
memset(pAux, 0, nByte);
pAux->zFunc = (char*)&pAux[1];
strcpy(pAux->zFunc, zName);
memcpy(pAux->zFunc, zName, nName);
pAux->pGlobal = pGlobal;
pAux->pUserData = pUserData;
pAux->xFunc = xFunc;
@@ -2162,15 +2255,17 @@ static int fts5CreateTokenizer(
){
Fts5Global *pGlobal = (Fts5Global*)pApi;
Fts5TokenizerModule *pNew;
int nName; /* Size of zName and its \0 terminator */
int nByte; /* Bytes of space to allocate */
int rc = SQLITE_OK;
nByte = sizeof(Fts5TokenizerModule) + strlen(zName) + 1;
nName = (int)strlen(zName) + 1;
nByte = sizeof(Fts5TokenizerModule) + nName;
pNew = (Fts5TokenizerModule*)sqlite3_malloc(nByte);
if( pNew ){
memset(pNew, 0, nByte);
pNew->zName = (char*)&pNew[1];
strcpy(pNew->zName, zName);
memcpy(pNew->zName, zName, nName);
pNew->pUserData = pUserData;
pNew->x = *pTokenizer;
pNew->xDestroy = xDestroy;
@@ -2305,14 +2400,7 @@ static void fts5SourceIdFunc(
sqlite3_result_text(pCtx, "--FTS5-SOURCE-ID--", -1, SQLITE_TRANSIENT);
}
#ifdef _WIN32
__declspec(dllexport)
#endif
int sqlite3_fts5_init(
sqlite3 *db,
char **pzErrMsg,
const sqlite3_api_routines *pApi
){
static int fts5Init(sqlite3 *db){
static const sqlite3_module fts5Mod = {
/* iVersion */ 2,
/* xCreate */ fts5CreateMethod,
@@ -2342,8 +2430,6 @@ int sqlite3_fts5_init(
int rc;
Fts5Global *pGlobal = 0;
SQLITE_EXTENSION_INIT2(pApi);
pGlobal = (Fts5Global*)sqlite3_malloc(sizeof(Fts5Global));
if( pGlobal==0 ){
rc = SQLITE_NOMEM;
@@ -2375,6 +2461,16 @@ int sqlite3_fts5_init(
return rc;
}
/*
** The following functions are used to register the module with SQLite. If
** this module is being built as part of the SQLite core (SQLITE_CORE is
** defined), then sqlite3_open() will call sqlite3Fts5Init() directly.
**
** Or, if this module is being built as a loadable extension,
** sqlite3Fts5Init() is omitted and the two standard entry points
** sqlite3_fts_init() and sqlite3_fts5_init() defined instead.
*/
#ifndef SQLITE_CORE
#ifdef _WIN32
__declspec(dllexport)
#endif
@@ -2383,7 +2479,25 @@ int sqlite3_fts_init(
char **pzErrMsg,
const sqlite3_api_routines *pApi
){
return sqlite3_fts5_init(db, pzErrMsg, pApi);
SQLITE_EXTENSION_INIT2(pApi);
(void)pzErrMsg; /* Unused parameter */
return fts5Init(db);
}
#ifdef _WIN32
__declspec(dllexport)
#endif
int sqlite3_fts5_init(
sqlite3 *db,
char **pzErrMsg,
const sqlite3_api_routines *pApi
){
SQLITE_EXTENSION_INIT2(pApi);
(void)pzErrMsg; /* Unused parameter */
return fts5Init(db);
}
#else
int sqlite3Fts5Init(sqlite3 *db){
return fts5Init(db);
}
#endif
+50 -49
View File
@@ -297,10 +297,10 @@ int sqlite3Fts5StorageOpen(
int i;
int iOff;
sqlite3_snprintf(nDefn, zDefn, "id INTEGER PRIMARY KEY");
iOff = strlen(zDefn);
iOff = (int)strlen(zDefn);
for(i=0; i<pConfig->nCol; i++){
sqlite3_snprintf(nDefn-iOff, &zDefn[iOff], ", c%d", i);
iOff += strlen(&zDefn[iOff]);
iOff += (int)strlen(&zDefn[iOff]);
}
rc = sqlite3Fts5CreateTable(pConfig, "content", zDefn, 0, pzErr);
}
@@ -392,7 +392,7 @@ static int fts5StorageDeleteFromIndex(Fts5Storage *p, i64 iDel){
Fts5InsertCtx ctx;
ctx.pStorage = p;
ctx.iCol = -1;
rc = sqlite3Fts5IndexBeginWrite(p->pIndex, iDel);
rc = sqlite3Fts5IndexBeginWrite(p->pIndex, 1, iDel);
for(iCol=1; rc==SQLITE_OK && iCol<=pConfig->nCol; iCol++){
if( pConfig->abUnindexed[iCol-1] ) continue;
ctx.szCol = 0;
@@ -549,7 +549,7 @@ int sqlite3Fts5StorageSpecialDelete(
ctx.pStorage = p;
ctx.iCol = -1;
rc = sqlite3Fts5IndexBeginWrite(p->pIndex, iDel);
rc = sqlite3Fts5IndexBeginWrite(p->pIndex, 1, iDel);
for(iCol=0; rc==SQLITE_OK && iCol<pConfig->nCol; iCol++){
if( pConfig->abUnindexed[iCol] ) continue;
ctx.szCol = 0;
@@ -639,7 +639,7 @@ int sqlite3Fts5StorageRebuild(Fts5Storage *p){
i64 iRowid = sqlite3_column_int64(pScan, 0);
sqlite3Fts5BufferZero(&buf);
rc = sqlite3Fts5IndexBeginWrite(p->pIndex, iRowid);
rc = sqlite3Fts5IndexBeginWrite(p->pIndex, 0, iRowid);
for(ctx.iCol=0; rc==SQLITE_OK && ctx.iCol<pConfig->nCol; ctx.iCol++){
ctx.szCol = 0;
if( pConfig->abUnindexed[ctx.iCol]==0 ){
@@ -705,58 +705,59 @@ static int fts5StorageNewRowid(Fts5Storage *p, i64 *piRowid){
}
/*
** Insert a new row into the FTS table.
** Insert a new row into the FTS content table.
*/
int sqlite3Fts5StorageInsert(
Fts5Storage *p, /* Storage module to write to */
sqlite3_value **apVal, /* Array of values passed to xUpdate() */
int eConflict, /* on conflict clause */
i64 *piRowid /* OUT: rowid of new record */
int sqlite3Fts5StorageContentInsert(
Fts5Storage *p,
sqlite3_value **apVal,
i64 *piRowid
){
Fts5Config *pConfig = p->pConfig;
int rc = SQLITE_OK;
/* Insert the new row into the %_content table. */
if( pConfig->eContent!=FTS5_CONTENT_NORMAL ){
if( sqlite3_value_type(apVal[1])==SQLITE_INTEGER ){
*piRowid = sqlite3_value_int64(apVal[1]);
}else{
rc = fts5StorageNewRowid(p, piRowid);
}
}else{
sqlite3_stmt *pInsert = 0; /* Statement to write %_content table */
int i; /* Counter variable */
rc = fts5StorageGetStmt(p, FTS5_STMT_INSERT_CONTENT, &pInsert, 0);
for(i=1; rc==SQLITE_OK && i<=pConfig->nCol+1; i++){
rc = sqlite3_bind_value(pInsert, i, apVal[i]);
}
if( rc==SQLITE_OK ){
sqlite3_step(pInsert);
rc = sqlite3_reset(pInsert);
}
*piRowid = sqlite3_last_insert_rowid(pConfig->db);
}
return rc;
}
/*
** Insert new entries into the FTS index and %_docsize table.
*/
int sqlite3Fts5StorageIndexInsert(
Fts5Storage *p,
sqlite3_value **apVal,
i64 iRowid
){
Fts5Config *pConfig = p->pConfig;
int rc = SQLITE_OK; /* Return code */
sqlite3_stmt *pInsert = 0; /* Statement used to write %_content table */
int eStmt = 0; /* Type of statement used on %_content */
int i; /* Counter variable */
Fts5InsertCtx ctx; /* Tokenization callback context object */
Fts5Buffer buf; /* Buffer used to build up %_docsize blob */
memset(&buf, 0, sizeof(Fts5Buffer));
ctx.pStorage = p;
rc = fts5StorageLoadTotals(p, 1);
/* Insert the new row into the %_content table. */
if( rc==SQLITE_OK ){
if( pConfig->eContent!=FTS5_CONTENT_NORMAL ){
if( sqlite3_value_type(apVal[1])==SQLITE_INTEGER ){
*piRowid = sqlite3_value_int64(apVal[1]);
}else{
rc = fts5StorageNewRowid(p, piRowid);
}
}else{
if( eConflict==SQLITE_REPLACE ){
eStmt = FTS5_STMT_REPLACE_CONTENT;
rc = fts5StorageDeleteFromIndex(p, sqlite3_value_int64(apVal[1]));
}else{
eStmt = FTS5_STMT_INSERT_CONTENT;
}
if( rc==SQLITE_OK ){
rc = fts5StorageGetStmt(p, eStmt, &pInsert, 0);
}
for(i=1; rc==SQLITE_OK && i<=pConfig->nCol+1; i++){
rc = sqlite3_bind_value(pInsert, i, apVal[i]);
}
if( rc==SQLITE_OK ){
sqlite3_step(pInsert);
rc = sqlite3_reset(pInsert);
}
*piRowid = sqlite3_last_insert_rowid(pConfig->db);
}
}
/* Add new entries to the FTS index */
if( rc==SQLITE_OK ){
rc = sqlite3Fts5IndexBeginWrite(p->pIndex, *piRowid);
ctx.pStorage = p;
rc = sqlite3Fts5IndexBeginWrite(p->pIndex, 0, iRowid);
}
for(ctx.iCol=0; rc==SQLITE_OK && ctx.iCol<pConfig->nCol; ctx.iCol++){
ctx.szCol = 0;
@@ -776,7 +777,7 @@ int sqlite3Fts5StorageInsert(
/* Write the %_docsize record */
if( rc==SQLITE_OK ){
rc = fts5StorageInsertDocsize(p, *piRowid, &buf);
rc = fts5StorageInsertDocsize(p, iRowid, &buf);
}
sqlite3_free(buf.p);
@@ -913,12 +914,12 @@ int sqlite3Fts5StorageIntegrity(Fts5Storage *p){
/* Check that the %_docsize and %_content tables contain the expected
** number of rows. */
if( rc==SQLITE_OK && pConfig->eContent==FTS5_CONTENT_NORMAL ){
i64 nRow;
i64 nRow = 0;
rc = fts5StorageCount(p, "content", &nRow);
if( rc==SQLITE_OK && nRow!=p->nTotalRow ) rc = FTS5_CORRUPT;
}
if( rc==SQLITE_OK && pConfig->bColumnsize ){
i64 nRow;
i64 nRow = 0;
rc = fts5StorageCount(p, "docsize", &nRow);
if( rc==SQLITE_OK && nRow!=p->nTotalRow ) rc = FTS5_CORRUPT;
}
-1
View File
@@ -976,7 +976,6 @@ static int f5tTokenHash(
int objc,
Tcl_Obj *CONST objv[]
){
int bOld = sqlite3_fts5_may_be_corrupt;
char *z;
int n;
unsigned int iVal;
+1 -1
View File
@@ -242,7 +242,7 @@ static int fts5UnicodeAddExceptions(
int bTokenChars /* 1 for 'tokenchars', 0 for 'separators' */
){
int rc = SQLITE_OK;
int n = strlen(z);
int n = (int)strlen(z);
int *aNew;
if( n>0 ){
+149 -37
View File
@@ -55,16 +55,18 @@ struct Fts5VocabCursor {
int bEof; /* True if this cursor is at EOF */
Fts5IndexIter *pIter; /* Term/rowid iterator object */
int nLeTerm; /* Size of zLeTerm in bytes */
char *zLeTerm; /* (term <= $zLeTerm) paramater, or NULL */
/* These are used by 'col' tables only */
int nCol;
Fts5Config *pConfig; /* Fts5 table configuration */
int iCol;
i64 *aCnt;
i64 *aDoc;
/* Output values */
/* Output values used by 'row' and 'col' tables */
i64 rowid; /* This table's current rowid value */
Fts5Buffer term; /* Current value of 'term' column */
i64 aVal[3]; /* Up to three columns left of 'term' */
};
#define FTS5_VOCAB_COL 0
@@ -73,6 +75,14 @@ struct Fts5VocabCursor {
#define FTS5_VOCAB_COL_SCHEMA "term, col, doc, cnt"
#define FTS5_VOCAB_ROW_SCHEMA "term, doc, cnt"
/*
** Bits for the mask used as the idxNum value by xBestIndex/xFilter.
*/
#define FTS5_VOCAB_TERM_EQ 0x01
#define FTS5_VOCAB_TERM_GE 0x02
#define FTS5_VOCAB_TERM_LE 0x04
/*
** Translate a string containing an fts5vocab table type to an
** FTS5_VOCAB_XXX constant. If successful, set *peType to the output
@@ -168,8 +178,8 @@ static int fts5VocabInitVtab(
const char *zDb = bDb ? argv[3] : argv[1];
const char *zTab = bDb ? argv[4] : argv[3];
const char *zType = bDb ? argv[5] : argv[4];
int nDb = strlen(zDb)+1;
int nTab = strlen(zTab)+1;
int nDb = (int)strlen(zDb)+1;
int nTab = (int)strlen(zTab)+1;
int eType;
rc = fts5VocabTableType(zType, pzErr, &eType);
@@ -230,6 +240,45 @@ static int fts5VocabBestIndexMethod(
sqlite3_vtab *pVTab,
sqlite3_index_info *pInfo
){
int i;
int iTermEq = -1;
int iTermGe = -1;
int iTermLe = -1;
int idxNum = 0;
int nArg = 0;
for(i=0; i<pInfo->nConstraint; i++){
struct sqlite3_index_constraint *p = &pInfo->aConstraint[i];
if( p->usable==0 ) continue;
if( p->iColumn==0 ){ /* term column */
if( p->op==SQLITE_INDEX_CONSTRAINT_EQ ) iTermEq = i;
if( p->op==SQLITE_INDEX_CONSTRAINT_LE ) iTermLe = i;
if( p->op==SQLITE_INDEX_CONSTRAINT_LT ) iTermLe = i;
if( p->op==SQLITE_INDEX_CONSTRAINT_GE ) iTermGe = i;
if( p->op==SQLITE_INDEX_CONSTRAINT_GT ) iTermGe = i;
}
}
if( iTermEq>=0 ){
idxNum |= FTS5_VOCAB_TERM_EQ;
pInfo->aConstraintUsage[iTermEq].argvIndex = ++nArg;
pInfo->estimatedCost = 100;
}else{
pInfo->estimatedCost = 1000000;
if( iTermGe>=0 ){
idxNum |= FTS5_VOCAB_TERM_GE;
pInfo->aConstraintUsage[iTermGe].argvIndex = ++nArg;
pInfo->estimatedCost = pInfo->estimatedCost / 2;
}
if( iTermLe>=0 ){
idxNum |= FTS5_VOCAB_TERM_LE;
pInfo->aConstraintUsage[iTermLe].argvIndex = ++nArg;
pInfo->estimatedCost = pInfo->estimatedCost / 2;
}
}
pInfo->idxNum = idxNum;
return SQLITE_OK;
}
@@ -242,12 +291,11 @@ static int fts5VocabOpenMethod(
){
Fts5VocabTable *pTab = (Fts5VocabTable*)pVTab;
Fts5Index *pIndex = 0;
int nCol = 0;
Fts5Config *pConfig = 0;
Fts5VocabCursor *pCsr = 0;
int rc = SQLITE_OK;
sqlite3_stmt *pStmt = 0;
char *zSql = 0;
int nByte;
zSql = sqlite3Fts5Mprintf(&rc,
"SELECT t.%Q FROM %Q.%Q AS t WHERE t.%Q MATCH '*id'",
@@ -262,7 +310,7 @@ static int fts5VocabOpenMethod(
if( pStmt && sqlite3_step(pStmt)==SQLITE_ROW ){
i64 iId = sqlite3_column_int64(pStmt, 0);
pIndex = sqlite3Fts5IndexFromCsrid(pTab->pGlobal, iId, &nCol);
pIndex = sqlite3Fts5IndexFromCsrid(pTab->pGlobal, iId, &pConfig);
}
if( rc==SQLITE_OK && pIndex==0 ){
@@ -276,14 +324,17 @@ static int fts5VocabOpenMethod(
}
}
nByte = nCol * sizeof(i64) * 2 + sizeof(Fts5VocabCursor);
pCsr = (Fts5VocabCursor*)sqlite3Fts5MallocZero(&rc, nByte);
if( rc==SQLITE_OK ){
int nByte = pConfig->nCol * sizeof(i64) * 2 + sizeof(Fts5VocabCursor);
pCsr = (Fts5VocabCursor*)sqlite3Fts5MallocZero(&rc, nByte);
}
if( pCsr ){
pCsr->pIndex = pIndex;
pCsr->pStmt = pStmt;
pCsr->nCol = nCol;
pCsr->pConfig = pConfig;
pCsr->aCnt = (i64*)&pCsr[1];
pCsr->aDoc = &pCsr->aCnt[nCol];
pCsr->aDoc = &pCsr->aCnt[pConfig->nCol];
}else{
sqlite3_finalize(pStmt);
}
@@ -296,6 +347,9 @@ static void fts5VocabResetCursor(Fts5VocabCursor *pCsr){
pCsr->rowid = 0;
sqlite3Fts5IterClose(pCsr->pIter);
pCsr->pIter = 0;
sqlite3_free(pCsr->zLeTerm);
pCsr->nLeTerm = -1;
pCsr->zLeTerm = 0;
}
/*
@@ -319,16 +373,17 @@ static int fts5VocabNextMethod(sqlite3_vtab_cursor *pCursor){
Fts5VocabCursor *pCsr = (Fts5VocabCursor*)pCursor;
Fts5VocabTable *pTab = (Fts5VocabTable*)pCursor->pVtab;
int rc = SQLITE_OK;
int nCol = pCsr->pConfig->nCol;
pCsr->rowid++;
if( pTab->eType==FTS5_VOCAB_COL ){
for(pCsr->iCol++; pCsr->iCol<pCsr->nCol; pCsr->iCol++){
for(pCsr->iCol++; pCsr->iCol<nCol; pCsr->iCol++){
if( pCsr->aCnt[pCsr->iCol] ) break;
}
}
if( pTab->eType==FTS5_VOCAB_ROW || pCsr->iCol>=pCsr->nCol ){
if( pTab->eType==FTS5_VOCAB_ROW || pCsr->iCol>=nCol ){
if( sqlite3Fts5IterEof(pCsr->pIter) ){
pCsr->bEof = 1;
}else{
@@ -336,10 +391,18 @@ static int fts5VocabNextMethod(sqlite3_vtab_cursor *pCursor){
int nTerm;
zTerm = sqlite3Fts5IterTerm(pCsr->pIter, &nTerm);
if( pCsr->nLeTerm>=0 ){
int nCmp = MIN(nTerm, pCsr->nLeTerm);
int bCmp = memcmp(pCsr->zLeTerm, zTerm, nCmp);
if( bCmp<0 || (bCmp==0 && pCsr->nLeTerm<nTerm) ){
pCsr->bEof = 1;
return SQLITE_OK;
}
}
sqlite3Fts5BufferSet(&rc, &pCsr->term, nTerm, (const u8*)zTerm);
memset(pCsr->aVal, 0, sizeof(pCsr->aVal));
memset(pCsr->aCnt, 0, pCsr->nCol * sizeof(i64));
memset(pCsr->aDoc, 0, pCsr->nCol * sizeof(i64));
memset(pCsr->aCnt, 0, nCol * sizeof(i64));
memset(pCsr->aDoc, 0, nCol * sizeof(i64));
pCsr->iCol = 0;
assert( pTab->eType==FTS5_VOCAB_COL || pTab->eType==FTS5_VOCAB_ROW );
@@ -349,13 +412,13 @@ static int fts5VocabNextMethod(sqlite3_vtab_cursor *pCursor){
i64 iPos = 0; /* 64-bit position read from poslist */
int iOff = 0; /* Current offset within position list */
rc = sqlite3Fts5IterPoslist(pCsr->pIter, &pPos, &nPos, &dummy);
rc = sqlite3Fts5IterPoslist(pCsr->pIter, 0, &pPos, &nPos, &dummy);
if( rc==SQLITE_OK ){
if( pTab->eType==FTS5_VOCAB_ROW ){
while( 0==sqlite3Fts5PoslistNext64(pPos, nPos, &iOff, &iPos) ){
pCsr->aVal[1]++;
pCsr->aCnt[0]++;
}
pCsr->aVal[0]++;
pCsr->aDoc[0]++;
}else{
int iCol = -1;
while( 0==sqlite3Fts5PoslistNext64(pPos, nPos, &iOff, &iPos) ){
@@ -369,9 +432,12 @@ static int fts5VocabNextMethod(sqlite3_vtab_cursor *pCursor){
}
rc = sqlite3Fts5IterNextScan(pCsr->pIter);
}
if( rc==SQLITE_OK ){
zTerm = sqlite3Fts5IterTerm(pCsr->pIter, &nTerm);
if( nTerm!=pCsr->term.n || memcmp(zTerm, pCsr->term.p, nTerm) ) break;
if( nTerm!=pCsr->term.n || memcmp(zTerm, pCsr->term.p, nTerm) ){
break;
}
if( sqlite3Fts5IterEof(pCsr->pIter) ) break;
}
}
@@ -380,9 +446,7 @@ static int fts5VocabNextMethod(sqlite3_vtab_cursor *pCursor){
if( pCsr->bEof==0 && pTab->eType==FTS5_VOCAB_COL ){
while( pCsr->aCnt[pCsr->iCol]==0 ) pCsr->iCol++;
pCsr->aVal[0] = pCsr->iCol;
pCsr->aVal[1] = pCsr->aDoc[pCsr->iCol];
pCsr->aVal[2] = pCsr->aCnt[pCsr->iCol];
assert( pCsr->iCol<pCsr->pConfig->nCol );
}
return rc;
}
@@ -398,11 +462,47 @@ static int fts5VocabFilterMethod(
sqlite3_value **apVal /* Arguments for the indexing scheme */
){
Fts5VocabCursor *pCsr = (Fts5VocabCursor*)pCursor;
int rc;
const int flags = FTS5INDEX_QUERY_SCAN;
int rc = SQLITE_OK;
int iVal = 0;
int f = FTS5INDEX_QUERY_SCAN;
const char *zTerm = 0;
int nTerm = 0;
sqlite3_value *pEq = 0;
sqlite3_value *pGe = 0;
sqlite3_value *pLe = 0;
fts5VocabResetCursor(pCsr);
rc = sqlite3Fts5IndexQuery(pCsr->pIndex, 0, 0, flags, &pCsr->pIter);
if( idxNum & FTS5_VOCAB_TERM_EQ ) pEq = apVal[iVal++];
if( idxNum & FTS5_VOCAB_TERM_GE ) pGe = apVal[iVal++];
if( idxNum & FTS5_VOCAB_TERM_LE ) pLe = apVal[iVal++];
if( pEq ){
zTerm = (const char *)sqlite3_value_text(pEq);
nTerm = sqlite3_value_bytes(pEq);
f = 0;
}else{
if( pGe ){
zTerm = (const char *)sqlite3_value_text(pGe);
nTerm = sqlite3_value_bytes(pGe);
}
if( pLe ){
const char *zCopy = (const char *)sqlite3_value_text(pLe);
pCsr->nLeTerm = sqlite3_value_bytes(pLe);
pCsr->zLeTerm = sqlite3_malloc(pCsr->nLeTerm+1);
if( pCsr->zLeTerm==0 ){
rc = SQLITE_NOMEM;
}else{
memcpy(pCsr->zLeTerm, zCopy, pCsr->nLeTerm+1);
}
}
}
if( rc==SQLITE_OK ){
rc = sqlite3Fts5IndexQuery(pCsr->pIndex, zTerm, nTerm, f, 0, &pCsr->pIter);
}
if( rc==SQLITE_OK ){
rc = fts5VocabNextMethod(pCursor);
}
@@ -425,17 +525,29 @@ static int fts5VocabColumnMethod(
int iCol /* Index of column to read value from */
){
Fts5VocabCursor *pCsr = (Fts5VocabCursor*)pCursor;
switch( iCol ){
case 0: /* term */
sqlite3_result_text(
pCtx, (const char*)pCsr->term.p, pCsr->term.n, SQLITE_TRANSIENT
);
break;
default:
assert( iCol<4 && iCol>0 );
sqlite3_result_int64(pCtx, pCsr->aVal[iCol-1]);
break;
if( iCol==0 ){
sqlite3_result_text(
pCtx, (const char*)pCsr->term.p, pCsr->term.n, SQLITE_TRANSIENT
);
}
else if( ((Fts5VocabTable*)(pCursor->pVtab))->eType==FTS5_VOCAB_COL ){
assert( iCol==1 || iCol==2 || iCol==3 );
if( iCol==1 ){
const char *z = pCsr->pConfig->azCol[pCsr->iCol];
sqlite3_result_text(pCtx, z, -1, SQLITE_STATIC);
}else if( iCol==2 ){
sqlite3_result_int64(pCtx, pCsr->aDoc[pCsr->iCol]);
}else{
sqlite3_result_int64(pCtx, pCsr->aCnt[pCsr->iCol]);
}
}else{
assert( iCol==1 || iCol==2 );
if( iCol==1 ){
sqlite3_result_int64(pCtx, pCsr->aDoc[0]);
}else{
sqlite3_result_int64(pCtx, pCsr->aCnt[0]);
}
}
return SQLITE_OK;
}
+3 -2
View File
@@ -67,6 +67,7 @@
%left COLON.
input ::= expr(X). { sqlite3Fts5ParseFinished(pParse, X); }
%destructor input { (void)pParse; }
%type cnearset {Fts5ExprNode*}
%type expr {Fts5ExprNode*}
@@ -101,9 +102,9 @@ cnearset(A) ::= colset(X) COLON nearset(Y). {
A = sqlite3Fts5ParseNode(pParse, FTS5_STRING, 0, 0, Y);
}
%type colset {Fts5ExprColset*}
%type colset {Fts5Colset*}
%destructor colset { sqlite3_free($$); }
%type colsetlist {Fts5ExprColset*}
%type colsetlist {Fts5Colset*}
%destructor colsetlist { sqlite3_free($$); }
colset(A) ::= LCP colsetlist(X) RCP. { A = X; }
-1
View File
@@ -17,7 +17,6 @@ source $testdir/tester.tcl
catch {
sqlite3_fts5_may_be_corrupt 0
append G(perm:dbconfig) "; load_static_extension \$::dbhandle fts5"
reset_db
}
+13 -2
View File
@@ -51,7 +51,7 @@ do_execsql_test 2.1 {
do_test 2.2 {
execsql { SELECT fts5_decode(id, block) FROM t1_data WHERE id==10 }
} {/{{structure} {lvl=0 nMerge=0 nSeg=1 {id=[0123456789]* h=0 leaves=1..1}}}/}
} {/{{structure} {lvl=0 nMerge=0 nSeg=1 {id=[0123456789]* leaves=1..1}}}/}
foreach w {a b c d e f} {
do_execsql_test 2.3.$w.asc {
@@ -139,7 +139,6 @@ foreach {i x y} {
#-------------------------------------------------------------------------
#
breakpoint
reset_db
do_execsql_test 6.0 {
CREATE VIRTUAL TABLE t1 USING fts5(x,y);
@@ -160,9 +159,20 @@ do_execsql_test 6.3 {
}
do_execsql_test 6.4 {
REPLACE INTO t1(x, y) VALUES('x y z', 'x y z');
}
do_execsql_test 6.5 {
INSERT INTO t1(t1) VALUES('integrity-check')
}
do_execsql_test 6.6 {
SELECT rowid, * FROM t1;
} {
22 {l l l} {l l l}
23 {x y z} {x y z}
}
#-------------------------------------------------------------------------
#
reset_db
@@ -201,6 +211,7 @@ for {set i 1} {$i <= 10} {incr i} {
}
execsql { INSERT INTO t1(t1) VALUES('integrity-check'); }
} {}
if {[set_test_counter errors]} break
}
#-------------------------------------------------------------------------
+3
View File
@@ -205,6 +205,9 @@ foreach {T create} {
return $ret
}
do_execsql_test $T.integrity {
INSERT INTO t1(t1) VALUES('integrity-check');
}
foreach {bAsc sql} {
1 {SELECT rowid FROM t1 WHERE t1 MATCH $prefix}
+16 -4
View File
@@ -26,17 +26,17 @@ ifcapable !fts5 {
do_execsql_test 1.1 {
CREATE VIRTUAL TABLE ft1 USING fts5(x);
SELECT * FROM ft1_config;
} {version 3}
} {version 4}
do_execsql_test 1.2 {
INSERT INTO ft1(ft1, rank) VALUES('pgsz', 32);
SELECT * FROM ft1_config;
} {pgsz 32 version 3}
} {pgsz 32 version 4}
do_execsql_test 1.3 {
INSERT INTO ft1(ft1, rank) VALUES('pgsz', 64);
SELECT * FROM ft1_config;
} {pgsz 64 version 3}
} {pgsz 64 version 4}
#--------------------------------------------------------------------------
# Test the logic for parsing the rank() function definition.
@@ -251,7 +251,6 @@ do_execsql_test 4.3.1 {
INSERT INTO t3 VALUES('a five');
INSERT INTO t3(t3, rank) VALUES('rank', 'bm25()');
}
breakpoint
do_execsql_test 4.3.2 {
SELECT * FROM t3
@@ -260,6 +259,7 @@ do_execsql_test 4.3.2 {
} {
{a four} {a one} {a five} {a two} {a three}
}
do_execsql_test 4.3.3 {
SELECT *, rank FROM t3
WHERE t3 MATCH 'a' AND rank MATCH 'rowidmod(3)'
@@ -268,6 +268,18 @@ do_execsql_test 4.3.3 {
{a three} 0 {a one} 1 {a four} 1 {a two} 2 {a five} 2
}
do_execsql_test 4.3.4 {
SELECT * FROM t3('a', 'rowidmod(4)') ORDER BY rank ASC;
} {
{a four} {a one} {a five} {a two} {a three}
}
do_execsql_test 4.3.5 {
SELECT *, rank FROM t3('a', 'rowidmod(3)') ORDER BY rank ASC
} {
{a three} 0 {a one} 1 {a four} 1 {a two} 2 {a five} 2
}
do_catchsql_test 4.4.3 {
SELECT *, rank FROM t3 WHERE t3 MATCH 'a' AND rank MATCH 'xyz(3)'
} {1 {no such function: xyz}}
+2 -2
View File
@@ -43,7 +43,7 @@ set segid [lindex [fts5_level_segids t1] 0]
do_test 1.3 {
execsql {
DELETE FROM t1_data WHERE rowid = fts5_rowid('segment', $segid, 0, 4);
DELETE FROM t1_data WHERE rowid = fts5_rowid('segment', $segid, 4);
}
catchsql { INSERT INTO t1(t1) VALUES('integrity-check') }
} {1 {database disk image is malformed}}
@@ -52,7 +52,7 @@ do_test 1.4 {
db_restore_and_reopen
execsql {
UPDATE t1_data set block = X'00000000' || substr(block, 5) WHERE
rowid = fts5_rowid('segment', $segid, 0, 4);
rowid = fts5_rowid('segment', $segid, 4);
}
catchsql { INSERT INTO t1(t1) VALUES('integrity-check') }
} {1 {database disk image is malformed}}
+5 -5
View File
@@ -209,13 +209,13 @@ foreach {tn nCut} {
execsql ROLLBACK
}
do_test 4.$tn.x { expr $nCorrupt>0 } 1
# do_test 4.$tn.x { expr $nCorrupt>0 } 1
}
}
set doc [string repeat "A B C " 1000]
do_execsql_test 4.0 {
do_execsql_test 5.0 {
CREATE VIRTUAL TABLE x5 USING fts5(tt);
INSERT INTO x5(x5, rank) VALUES('pgsz', 32);
WITH ii(i) AS (SELECT 1 UNION ALL SELECT i+1 FROM ii WHERE i<10)
@@ -230,7 +230,7 @@ foreach {tn hdr} {
foreach rowid [db eval {SELECT rowid FROM x5_data WHERE rowid>10}] {
if {$rowid & $mask} continue
incr tn2
do_test 4.$tn.$tn2 {
do_test 5.$tn.$tn2 {
execsql BEGIN
set fd [db incrblob main x5_data block $rowid]
@@ -248,7 +248,7 @@ foreach {tn hdr} {
#--------------------------------------------------------------------
reset_db
do_execsql_test 5.1 {
do_execsql_test 6.1 {
CREATE VIRTUAL TABLE x5 USING fts5(tt);
INSERT INTO x5 VALUES('a');
INSERT INTO x5 VALUES('a a');
@@ -262,7 +262,7 @@ proc colsize {cmd i} {
}
sqlite3_fts5_create_function db colsize colsize
do_catchsql_test 5.2 {
do_catchsql_test 6.2 {
SELECT colsize(x5, 0) FROM x5 WHERE x5 MATCH 'a'
} {1 SQLITE_CORRUPT_VTAB}
+305 -9
View File
@@ -24,18 +24,23 @@ ifcapable !fts5 {
}
sqlite3_fts5_may_be_corrupt 1
proc create_t1 {} {
expr srand(0)
db func rnddoc fts5_rnddoc
db eval {
CREATE VIRTUAL TABLE t1 USING fts5(x);
INSERT INTO t1(t1, rank) VALUES('pgsz', 64);
WITH ii(i) AS (SELECT 1 UNION SELECT i+1 FROM ii WHERE i<100)
INSERT INTO t1 SELECT rnddoc(10) FROM ii;
}
}
if 1 {
# Create a simple FTS5 table containing 100 documents. Each document
# contains 10 terms, each of which start with the character "x".
#
expr srand(0)
db func rnddoc fts5_rnddoc
do_execsql_test 1.0 {
CREATE VIRTUAL TABLE t1 USING fts5(x);
INSERT INTO t1(t1, rank) VALUES('pgsz', 64);
WITH ii(i) AS (SELECT 1 UNION SELECT i+1 FROM ii WHERE i<100)
INSERT INTO t1 SELECT rnddoc(10) FROM ii;
}
set mask [expr 31 << 31]
do_test 1.0 { create_t1 } {}
do_test 1.1 {
# Pick out the rowid of the right-most b-tree leaf in the new segment.
@@ -75,6 +80,297 @@ do_execsql_test 2.2 {
SELECT length(block) FROM t2_data WHERE id=1;
} {2}
#-------------------------------------------------------------------------
# Test that missing leaf pages are recognized as corruption.
#
reset_db
do_test 3.0 { create_t1 } {}
do_execsql_test 3.1 {
SELECT count(*) FROM t1_data;
} {105}
proc do_3_test {tn} {
set i 0
foreach ::rowid [db eval "SELECT rowid FROM t1_data WHERE rowid>100"] {
incr i
do_test $tn.$i {
db eval BEGIN
db eval {DELETE FROM t1_data WHERE rowid = $::rowid}
list [
catch { db eval {SELECT rowid FROM t1 WHERE t1 MATCH 'x*'} } msg
] $msg
} {1 {database disk image is malformed}}
catch { db eval ROLLBACK }
}
}
do_3_test 3.2
do_execsql_test 3.3 {
INSERT INTO t1(t1, rank) VALUES('pgsz', 32);
INSERT INTO t1 SELECT x FROM t1;
INSERT INTO t1(t1) VALUES('optimize');
} {}
do_3_test 3.4
do_test 3.5 {
execsql {
DELETE FROM t1;
INSERT INTO t1(t1, rank) VALUES('pgsz', 40);
}
for {set i 0} {$i < 1000} {incr i} {
set rnd [expr int(rand() * 1000)]
set doc [string repeat "x$rnd " [expr int(rand() * 3) + 1]]
execsql { INSERT INTO t1(rowid, x) VALUES($i, $doc) }
}
} {}
do_3_test 3.6
do_test 3.7 {
execsql {
INSERT INTO t1(t1, rank) VALUES('pgsz', 40);
INSERT INTO t1 SELECT x FROM t1;
INSERT INTO t1(t1) VALUES('optimize');
}
} {}
do_3_test 3.8
do_test 3.9 {
execsql {
DELETE FROM t1;
INSERT INTO t1(t1, rank) VALUES('pgsz', 32);
}
for {set i 0} {$i < 100} {incr i} {
set rnd [expr int(rand() * 100)]
set doc "x[string repeat $rnd 20]"
execsql { INSERT INTO t1(rowid, x) VALUES($i, $doc) }
}
} {}
do_3_test 3.10
#-------------------------------------------------------------------------
# Test that segments that end unexpectedly are identified as corruption.
#
reset_db
do_test 4.0 {
execsql {
CREATE VIRTUAL TABLE t1 USING fts5(x);
INSERT INTO t1(t1, rank) VALUES('pgsz', 32);
}
for {set i 0} {$i < 100} {incr i} {
set rnd [expr int(rand() * 100)]
set doc "x[string repeat $rnd 20]"
execsql { INSERT INTO t1(rowid, x) VALUES($i, $doc) }
}
execsql { INSERT INTO t1(t1) VALUES('optimize') }
} {}
set nErr 0
for {set i 1} {1} {incr i} {
set struct [db one {SELECT block FROM t1_data WHERE id=10}]
binary scan $struct c* var
set end [lindex $var end]
if {$end<=$i} break
lset var end [expr $end - $i]
set struct [binary format c* $var]
db eval {
BEGIN;
UPDATE t1_data SET block = $struct WHERE id=10;
}
do_test 4.1.$i {
incr nErr [catch { db eval { SELECT rowid FROM t1 WHERE t1 MATCH 'x*' } }]
set {} {}
} {}
catch { db eval ROLLBACK }
}
do_test 4.1.x { expr $nErr>45 } 1
#-------------------------------------------------------------------------
#
# The first argument passed to this command must be a binary blob
# containing an FTS5 leaf page. This command returns a copy of this
# blob, with the pgidx of the leaf page replaced by a single varint
# containing value $iVal.
#
proc rewrite_pgidx {blob iVal} {
binary scan $blob SS off1 szLeaf
if {$iVal<0 || $iVal>=128} {
error "$iVal out of range!"
} else {
set pgidx [binary format c $iVal]
}
binary format a${szLeaf}a* $blob $pgidx
}
reset_db
do_execsql_test 5.1 {
CREATE VIRTUAL TABLE x1 USING fts5(x);
INSERT INTO x1(x1, rank) VALUES('pgsz', 40);
BEGIN;
INSERT INTO x1 VALUES('xaaa xabb xccc xcdd xeee xeff xggg xghh xiii xijj');
INSERT INTO x1 SELECT x FROM x1;
INSERT INTO x1 SELECT x FROM x1;
INSERT INTO x1 SELECT x FROM x1;
INSERT INTO x1 SELECT x FROM x1;
INSERT INTO x1(x1) VALUES('optimize');
COMMIT;
}
#db eval { SELECT fts5_decode(id, block) b from x1_data } { puts $b }
#
db func rewrite_pgidx rewrite_pgidx
set i 0
foreach rowid [db eval {SELECT rowid FROM x1_data WHERE rowid>100}] {
foreach val {2 100} {
do_test 5.2.$val.[incr i] {
catchsql {
BEGIN;
UPDATE x1_data SET block=rewrite_pgidx(block, $val) WHERE id=$rowid;
SELECT rowid FROM x1 WHERE x1 MATCH 'xa*';
SELECT rowid FROM x1 WHERE x1 MATCH 'xb*';
SELECT rowid FROM x1 WHERE x1 MATCH 'xc*';
SELECT rowid FROM x1 WHERE x1 MATCH 'xd*';
SELECT rowid FROM x1 WHERE x1 MATCH 'xe*';
SELECT rowid FROM x1 WHERE x1 MATCH 'xf*';
SELECT rowid FROM x1 WHERE x1 MATCH 'xg*';
SELECT rowid FROM x1 WHERE x1 MATCH 'xh*';
SELECT rowid FROM x1 WHERE x1 MATCH 'xi*';
}
set {} {}
} {}
catch { db eval ROLLBACK }
}
}
#------------------------------------------------------------------------
#
reset_db
do_execsql_test 6.1.0 {
CREATE VIRTUAL TABLE t1 USING fts5(a);
INSERT INTO t1 VALUES('bbbbb ccccc');
SELECT quote(block) FROM t1_data WHERE rowid>100;
} {X'000000180630626262626201020201056363636363010203040A'}
do_execsql_test 6.1.1 {
UPDATE t1_data SET block =
X'000000180630626262626201020201056161616161010203040A'
WHERE rowid>100;
}
do_catchsql_test 6.1.2 {
INSERT INTO t1(t1) VALUES('integrity-check');
} {1 {database disk image is malformed}}
#-------
reset_db
do_execsql_test 6.2.0 {
CREATE VIRTUAL TABLE t1 USING fts5(a);
INSERT INTO t1(t1, rank) VALUES('pgsz', 32);
INSERT INTO t1 VALUES('aa bb cc dd ee');
SELECT pgno, quote(term) FROM t1_idx;
} {2 X'' 4 X'3064'}
do_execsql_test 6.2.1 {
UPDATE t1_idx SET term = X'3065' WHERE pgno=4;
}
do_catchsql_test 6.2.2 {
INSERT INTO t1(t1) VALUES('integrity-check');
} {1 {database disk image is malformed}}
#-------
reset_db
do_execsql_test 6.3.0 {
CREATE VIRTUAL TABLE t1 USING fts5(a);
INSERT INTO t1 VALUES('abc abcdef abcdefghi');
SELECT quote(block) FROM t1_data WHERE id>100;
} {X'0000001C043061626301020204036465660102030703676869010204040808'}
do_execsql_test 6.3.1 {
BEGIN;
UPDATE t1_data SET block =
X'0000001C043061626301020204036465660102035003676869010204040808'
------------------------------------------^^---------------------
WHERE id>100;
}
do_catchsql_test 6.3.2 {
INSERT INTO t1(t1) VALUES('integrity-check');
} {1 {database disk image is malformed}}
do_execsql_test 6.3.3 {
ROLLBACK;
BEGIN;
UPDATE t1_data SET block =
X'0000001C043061626301020204036465660102030750676869010204040808'
--------------------------------------------^^-------------------
WHERE id>100;
}
do_catchsql_test 6.3.3 {
INSERT INTO t1(t1) VALUES('integrity-check');
} {1 {database disk image is malformed}}
do_execsql_test 6.3.4 {
ROLLBACK;
BEGIN;
UPDATE t1_data SET block =
X'0000001C043061626301020204036465660102030707676869010204040850'
--------------------------------------------------------------^^-
WHERE id>100;
}
do_catchsql_test 6.3.5 {
INSERT INTO t1(t1) VALUES('integrity-check');
} {1 {database disk image is malformed}}
do_execsql_test 6.3.6 {
ROLLBACK;
BEGIN;
UPDATE t1_data SET block =
X'0000001C503061626301020204036465660102030707676869010204040808'
----------^^-----------------------------------------------------
WHERE id>100;
}
do_catchsql_test 6.3.5 {
INSERT INTO t1(t1) VALUES('integrity-check');
} {1 {database disk image is malformed}}
}
#------------------------------------------------------------------------
#
reset_db
reset_db
proc rnddoc {n} {
set map [list a b c d]
set doc [list]
for {set i 0} {$i < $n} {incr i} {
lappend doc "x[lindex $map [expr int(rand()*4)]]"
}
set doc
}
db func rnddoc rnddoc
do_test 7.0 {
execsql {
CREATE VIRTUAL TABLE t5 USING fts5(x);
INSERT INTO t5 VALUES( rnddoc(10000) );
INSERT INTO t5 VALUES( rnddoc(10000) );
INSERT INTO t5 VALUES( rnddoc(10000) );
INSERT INTO t5 VALUES( rnddoc(10000) );
INSERT INTO t5(t5) VALUES('optimize');
}
} {}
do_test 7.1 {
foreach i [db eval { SELECT rowid FROM t5_data WHERE rowid>100 }] {
db eval BEGIN
db eval {DELETE FROM t5_data WHERE rowid = $i}
set r [catchsql { INSERT INTO t5(t5) VALUES('integrity-check')} ]
if {$r != "1 {database disk image is malformed}"} { error $r }
db eval ROLLBACK
}
} {}
sqlite3_fts5_may_be_corrupt 0
finish_test
+65
View File
@@ -26,6 +26,8 @@ if { $tcl_platform(wordSize)<8 } {
return
}
if 1 {
proc do_fb_test {tn sql res} {
set res2 [lsort -integer -decr $res]
uplevel [list do_execsql_test $tn.1 $sql $res]
@@ -128,5 +130,68 @@ proc do_dlidx_test2 {tn nEntry iFirst nStep} {
do_dlidx_test2 2.1 [expr 20] [expr 1<<57] [expr (1<<57) + 128]
}
#--------------------------------------------------------------------
#
reset_db
set ::vocab [list \
IteratorpItercurrentlypointstothefirstrowidofadoclist \
Thereisadoclistindexassociatedwiththefinaltermonthecurrent \
pageIfthecurrenttermisthelasttermonthepageloadthe \
doclistindexfromdiskandinitializeaniteratoratpIterpDlidx \
IteratorpItercurrentlypointstothefirstrowidofadoclist \
Thereisadoclistindexassociatedwiththefinaltermonthecurrent \
pageIfthecurrenttermisthelasttermonthepageloadthe \
doclistindexfromdiskandinitializeaniteratoratpIterpDlidx \
]
proc rnddoc {} {
global vocab
set nVocab [llength $vocab]
set ret [list]
for {set i 0} {$i < 64} {incr i} {
lappend ret [lindex $vocab [expr $i % $nVocab]]
}
set ret
}
db func rnddoc rnddoc
do_execsql_test 3.1 {
CREATE VIRTUAL TABLE abc USING fts5(a);
INSERT INTO abc(abc, rank) VALUES('pgsz', 32);
INSERT INTO abc VALUES ( rnddoc() );
INSERT INTO abc VALUES ( rnddoc() );
INSERT INTO abc VALUES ( rnddoc() );
INSERT INTO abc VALUES ( rnddoc() );
INSERT INTO abc SELECT rnddoc() FROM abc;
INSERT INTO abc SELECT rnddoc() FROM abc;
}
do_execsql_test 3.2 {
SELECT rowid FROM abc WHERE abc
MATCH 'IteratorpItercurrentlypointstothefirstrowidofadoclist'
ORDER BY rowid DESC;
} {16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1}
do_execsql_test 3.2 {
INSERT INTO abc(abc) VALUES('integrity-check');
INSERT INTO abc(abc) VALUES('optimize');
INSERT INTO abc(abc) VALUES('integrity-check');
}
set v [lindex $vocab 0]
set i 0
foreach v $vocab {
do_execsql_test 3.3.[incr i] {
SELECT rowid FROM abc WHERE abc MATCH $v
} {1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16}
}
finish_test
+8
View File
@@ -90,6 +90,14 @@ do_faultsim_test 3.1 -faults oom-t* -body {
faultsim_test_result {0 {0 1 10 11 12 13 14 15 16 17 18 19 2 3 4 5 6 7 8 9}}
}
do_faultsim_test 3.2 -faults oom-t* -body {
db eval {
SELECT term FROM tv WHERE term BETWEEN '1' AND '2';
}
} -test {
faultsim_test_result {0 {1 10 11 12 13 14 15 16 17 18 19 2}}
}
finish_test
-2
View File
@@ -284,8 +284,6 @@ breakpoint
do_faultsim_test 6 -faults oom* -prep {
sqlite_orig db test.db
sqlite3_db_config_lookaside db 0 0 0
} -body {
load_static_extension db fts5
} -test {
faultsim_test_result {0 {}} {1 {initialization of fts5 failed: }}
if {$testrc==0} {
+68 -1
View File
@@ -14,7 +14,7 @@
source [file join [file dirname [info script]] fts5_common.tcl]
source $testdir/malloc_common.tcl
set testprefix fts5fault2
set testprefix fts5fault7
# If SQLITE_ENABLE_FTS3 is defined, omit this file.
ifcapable !fts5 {
@@ -22,6 +22,8 @@ ifcapable !fts5 {
return
}
if 1 {
#-------------------------------------------------------------------------
# Test fault-injection on a query that uses xColumnSize() on columnsize=0
# table.
@@ -41,5 +43,70 @@ do_faultsim_test 1 -faults oom* -body {
faultsim_test_result {0 {7 4 10}} {1 SQLITE_NOMEM}
}
}
#-------------------------------------------------------------------------
# Test fault-injection when a segment is promoted.
#
do_execsql_test 1.0 {
CREATE VIRTUAL TABLE t2 USING fts5(a);
INSERT INTO t2(t2, rank) VALUES('automerge', 0);
INSERT INTO t2(t2, rank) VALUES('crisismerge', 4);
INSERT INTO t2(t2, rank) VALUES('pgsz', 40);
INSERT INTO t2 VALUES('a b c');
INSERT INTO t2 VALUES('d e f');
INSERT INTO t2 VALUES('f e d');
INSERT INTO t2 VALUES('c b a');
INSERT INTO t2 VALUES('a b c');
INSERT INTO t2 VALUES('d e f');
INSERT INTO t2 VALUES('f e d');
INSERT INTO t2 VALUES('c b a');
} {}
faultsim_save_and_close
do_faultsim_test 1 -faults oom-t* -prep {
faultsim_restore_and_reopen
db eval {
BEGIN;
INSERT INTO t2 VALUES('c d c g g f');
INSERT INTO t2 VALUES('c d g b f d');
INSERT INTO t2 VALUES('c c f d e d');
INSERT INTO t2 VALUES('e a f c e f');
INSERT INTO t2 VALUES('c g f b b d');
INSERT INTO t2 VALUES('d a g a b b');
INSERT INTO t2 VALUES('e f a b c e');
INSERT INTO t2 VALUES('e c a g c d');
INSERT INTO t2 VALUES('g b d d e b');
INSERT INTO t2 VALUES('e a d a e d');
}
} -body {
db eval COMMIT
} -test {
faultsim_test_result {0 {}}
}
#-------------------------------------------------------------------------
# Test fault-injection when a segment is promoted.
#
reset_db
do_execsql_test 2.0 {
CREATE VIRTUAL TABLE xy USING fts5(x);
INSERT INTO xy(rowid, x) VALUES(1, '1 2 3');
INSERT INTO xy(rowid, x) VALUES(2, '2 3 4');
INSERT INTO xy(rowid, x) VALUES(3, '3 4 5');
}
faultsim_save_and_close
do_faultsim_test 2 -faults oom-* -prep {
faultsim_restore_and_reopen
} -body {
db eval { UPDATE OR REPLACE xy SET rowid=3 WHERE rowid = 2 }
} -test {
faultsim_test_result {0 {}}
}
finish_test
+6 -4
View File
@@ -84,11 +84,13 @@ lappend vocab xyz
do_execsql_test 1.1 {
CREATE VIRTUAL TABLE vocab USING fts5vocab(eee, 'row');
BEGIN;
WITH ii(i) AS (SELECT 1 UNION ALL SELECT i+1 FROM ii WHERE i<100)
INSERT INTO eee SELECT r($vocab, 5), r($vocab, 7) FROM ii;
INSERT INTO eee(eee) VALUES('integrity-check');
}
do_test 1.2 {
for {set i 1} {$i <= 100} {incr i} {
execsql { INSERT INTO eee VALUES( r($vocab, 5), r($vocab, 7) ) }
}
} {}
do_test 1.2 {
db eval { SELECT term, doc FROM vocab } {
set nRow [db one {SELECT count(*) FROM eee WHERE eee MATCH $term}]
+181
View File
@@ -0,0 +1,181 @@
# 2015 Sep 27
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
# May you find forgiveness for yourself and forgive others.
# May you share freely, never taking more than you give.
#
#*************************************************************************
#
source [file join [file dirname [info script]] fts5_common.tcl]
set testprefix fts5onepass
# If SQLITE_ENABLE_FTS3 is defined, omit this file.
ifcapable !fts5 {
finish_test
return
}
do_execsql_test 1.0 {
CREATE VIRTUAL TABLE ft USING fts5(content);
INSERT INTO ft(rowid, content) VALUES(1, '1 2 3');
INSERT INTO ft(rowid, content) VALUES(2, '4 5 6');
INSERT INTO ft(rowid, content) VALUES(3, '7 8 9');
}
#-------------------------------------------------------------------------
# Check that UPDATE and DELETE statements that feature "WHERE rowid=?" or
# or "WHERE rowid=?" clauses do not use statement journals. But that other
# DELETE and UPDATE statements do.
#
# Note: "MATCH ? AND rowid=?" does use a statement journal.
#
foreach {tn sql uses} {
1.1 { DELETE FROM ft } 1
1.2 { DELETE FROM ft WHERE rowid=? } 0
1.3 { DELETE FROM ft WHERE rowid=? } 0
1.4 { DELETE FROM ft WHERE ft MATCH '1' } 1
1.5 { DELETE FROM ft WHERE ft MATCH '1' AND rowid=? } 1
1.6 { DELETE FROM ft WHERE ft MATCH '1' AND rowid=? } 1
2.1 { UPDATE ft SET content='a b c' } 1
2.2 { UPDATE ft SET content='a b c' WHERE rowid=? } 0
2.3 { UPDATE ft SET content='a b c' WHERE rowid=? } 0
2.4 { UPDATE ft SET content='a b c' WHERE ft MATCH '1' } 1
2.5 { UPDATE ft SET content='a b c' WHERE ft MATCH '1' AND rowid=? } 1
2.6 { UPDATE ft SET content='a b c' WHERE ft MATCH '1' AND rowid=? } 1
} {
do_test 1.$tn { sql_uses_stmt db $sql } $uses
}
#-------------------------------------------------------------------------
# Check that putting a "DELETE/UPDATE ... WHERE rowid=?" statement in a
# trigger program does not prevent the VM from using a statement
# transaction. Even if the calling statement cannot hit a constraint.
#
do_execsql_test 2.0 {
CREATE TABLE t1(x);
CREATE TRIGGER t1_ai AFTER INSERT ON t1 BEGIN
DELETE FROM ft WHERE rowid=new.x;
END;
CREATE TRIGGER t1_ad AFTER DELETE ON t1 BEGIN
UPDATE ft SET content = 'a b c' WHERE rowid=old.x;
END;
CREATE TRIGGER t1_bu BEFORE UPDATE ON t1 BEGIN
DELETE FROM ft WHERE rowid=old.x;
END;
}
foreach {tn sql uses} {
1 { INSERT INTO t1 VALUES(1) } 1
2 { DELETE FROM t1 WHERE x=4 } 1
3 { UPDATE t1 SET x=10 WHERE x=11 } 1
} {
do_test 2.$tn { sql_uses_stmt db $sql } $uses
}
#-------------------------------------------------------------------------
# Test that an "UPDATE ... WHERE rowid=?" works and does not corrupt the
# index when it strikes a constraint. Both inside and outside a
# transaction.
#
foreach {tn tcl1 tcl2} {
1 {} {}
2 {
execsql BEGIN
} {
if {[sqlite3_get_autocommit db]==1} { error "transaction rolled back!" }
execsql COMMIT
}
} {
do_execsql_test 3.$tn.0 {
DROP TABLE IF EXISTS ft2;
CREATE VIRTUAL TABLE ft2 USING fts5(content);
INSERT INTO ft2(rowid, content) VALUES(1, 'a b c');
INSERT INTO ft2(rowid, content) VALUES(2, 'a b d');
INSERT INTO ft2(rowid, content) VALUES(3, 'a b e');
}
eval $tcl1
foreach {tn2 sql content} {
1 { UPDATE ft2 SET rowid=2 WHERE rowid=1 }
{ 1 {a b c} 2 {a b d} 3 {a b e} }
2 {
INSERT INTO ft2(rowid, content) VALUES(4, 'a b f');
UPDATE ft2 SET rowid=5 WHERE rowid=4;
UPDATE ft2 SET rowid=3 WHERE rowid=5;
} { 1 {a b c} 2 {a b d} 3 {a b e} 5 {a b f} }
3 {
UPDATE ft2 SET rowid=3 WHERE rowid=4; -- matches 0 rows
UPDATE ft2 SET rowid=2 WHERE rowid=3;
} { 1 {a b c} 2 {a b d} 3 {a b e} 5 {a b f} }
4 {
INSERT INTO ft2(rowid, content) VALUES(4, 'a b g');
UPDATE ft2 SET rowid=-1 WHERE rowid=4;
UPDATE ft2 SET rowid=3 WHERE rowid=-1;
} {-1 {a b g} 1 {a b c} 2 {a b d} 3 {a b e} 5 {a b f} }
5 {
DELETE FROM ft2 WHERE rowid=451;
DELETE FROM ft2 WHERE rowid=-1;
UPDATE ft2 SET rowid = 2 WHERE rowid = 1;
} {1 {a b c} 2 {a b d} 3 {a b e} 5 {a b f} }
} {
do_catchsql_test 3.$tn.$tn2.a $sql {1 {constraint failed}}
do_execsql_test 3.$tn.$tn2.b { SELECT rowid, content FROM ft2 } $content
do_execsql_test 3.$tn.$tn2.c {
INSERT INTO ft2(ft2) VALUES('integrity-check');
}
}
eval $tcl2
}
#-------------------------------------------------------------------------
# Check that DELETE and UPDATE operations can be done without flushing
# the in-memory hash table to disk.
#
reset_db
do_execsql_test 4.1.1 {
CREATE VIRTUAL TABLE ttt USING fts5(x);
BEGIN;
INSERT INTO ttt(rowid, x) VALUES(1, 'a b c');
INSERT INTO ttt(rowid, x) VALUES(2, 'a b c');
INSERT INTO ttt(rowid, x) VALUES(3, 'a b c');
COMMIT
}
do_test 4.1.2 { fts5_level_segs ttt } {1}
do_execsql_test 4.2.1 {
BEGIN;
DELETE FROM ttt WHERE rowid=1;
DELETE FROM ttt WHERE rowid=3;
INSERT INTO ttt(rowid, x) VALUES(4, 'd e f');
INSERT INTO ttt(rowid, x) VALUES(5, 'd e f');
COMMIT;
} {}
do_test 4.2.2 { fts5_level_segs ttt } {2}
do_execsql_test 4.3.1 {
BEGIN;
UPDATE ttt SET x = 'd e f' WHERE rowid = 2;
UPDATE ttt SET x = 'A B C' WHERE rowid = 4;
INSERT INTO ttt(rowid, x) VALUES(6, 'd e f');
COMMIT;
} {}
do_test 4.2.2 { fts5_level_segs ttt } {3}
finish_test
+119
View File
@@ -0,0 +1,119 @@
# 2014 Jan 08
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
# May you find forgiveness for yourself and forgive others.
# May you share freely, never taking more than you give.
#
#***********************************************************************
#
# Tests focused on phrase queries.
#
source [file join [file dirname [info script]] fts5_common.tcl]
set testprefix fts5phrase
# If SQLITE_ENABLE_FTS5 is defined, omit this file.
ifcapable !fts5 {
finish_test
return
}
do_execsql_test 1.0 {
CREATE VIRTUAL TABLE t3 USING fts5(a, b, c);
INSERT INTO t3 VALUES('d e a', 'd i j j f', 'i j i e b f h'); -- 1
INSERT INTO t3 VALUES('g a e', 'f g i g a', 'h d g i g h c'); -- 2
INSERT INTO t3 VALUES('e a d', 'e i h a f', 'c e h i f b i'); -- 3
INSERT INTO t3 VALUES('a g c', 'd j d j c', 'c d f j i g j'); -- 4
INSERT INTO t3 VALUES('b c b', 'j g c d f', 'j c j d g f b'); -- 5
INSERT INTO t3 VALUES('j a d', 'e b i h h', 'c c f g d i d'); -- 6
INSERT INTO t3 VALUES('a d f', 'h g i i i', 'e a g c i f b'); -- 7
INSERT INTO t3 VALUES('g f d', 'f c g b j', 'b b h h h j j'); -- 8
INSERT INTO t3 VALUES('f h g', 'c j f g j', 'd h d f e b h'); -- 9
INSERT INTO t3 VALUES('f h d', 'c i a d b', 'g b j b a d e'); -- 10
INSERT INTO t3 VALUES('j h h', 'j i h a g', 'd e i e a g j'); -- 11
INSERT INTO t3 VALUES('a b e', 'h g a g c', 'h c a a d e g'); -- 12
INSERT INTO t3 VALUES('a j g', 'i h i f i', 'a g h j g i b'); -- 13
INSERT INTO t3 VALUES('j h e', 'f e d i e', 'i d c f e d c'); -- 14
INSERT INTO t3 VALUES('d j d', 'd b i a c', 'g d h i d b e'); -- 15
INSERT INTO t3 VALUES('h j e', 'e b b c f', 'j a f g h d j'); -- 16
INSERT INTO t3 VALUES('c b j', 'c a b a i', 'h f i d a d c'); -- 17
INSERT INTO t3 VALUES('e e d', 'i d f c c', 'g i d a f e a'); -- 18
INSERT INTO t3 VALUES('e i g', 'e a b i h', 'i f d d a d f'); -- 19
INSERT INTO t3 VALUES('h g f', 'b h h j d', 'i f d e g j a'); -- 20
INSERT INTO t3 VALUES('e h f', 'j c b c f', 'j a j g h a c'); -- 21
INSERT INTO t3 VALUES('d c h', 'b g i c e', 'i i c d e h i'); -- 22
INSERT INTO t3 VALUES('a h i', 'a g d f f', 'e f i i b b h'); -- 23
INSERT INTO t3 VALUES('d d g', 'c c b c g', 'g c h e b c e'); -- 24
INSERT INTO t3 VALUES('a b b', 'b f a d i', 'd a h a b c i'); -- 25
INSERT INTO t3 VALUES('a f d', 'a j e a h', 'j i h j a i f'); -- 26
INSERT INTO t3 VALUES('d j d', 'h a d i a', 'h h f j h g a'); -- 27
INSERT INTO t3 VALUES('g a e', 'd g f a g', 'i d b c g g j'); -- 28
INSERT INTO t3 VALUES('j e h', 'g h j h g', 'd a e j a a h'); -- 29
INSERT INTO t3 VALUES('e j e', 'g e j g c', 'f c e b e e a'); -- 30
INSERT INTO t3 VALUES('h f f', 'i j g e c', 'j j f c a i j'); -- 31
INSERT INTO t3 VALUES('a g c', 'c g d b i', 'g h c b a a f'); -- 32
INSERT INTO t3 VALUES('c h i', 'j d h e e', 'a h i d c c j'); -- 33
INSERT INTO t3 VALUES('d a c', 'e d d b j', 'c e b b h i h'); -- 34
INSERT INTO t3 VALUES('d f h', 'c a f c c', 'j b b c c j f'); -- 35
INSERT INTO t3 VALUES('b g h', 'g c c c f', 'c g c f h e e'); -- 36
INSERT INTO t3 VALUES('f e a', 'b h f j h', 'j g h f d g f'); -- 37
INSERT INTO t3 VALUES('h f a', 'a e i j g', 'f d a f d f c'); -- 38
INSERT INTO t3 VALUES('f i c', 'f i i i i', 'e c f d h j f'); -- 39
INSERT INTO t3 VALUES('h h d', 'd i e d i', 'd f e i a h a'); -- 40
INSERT INTO t3 VALUES('f g c', 'd a f c h', 'b b g j c e g'); -- 41
INSERT INTO t3 VALUES('h i h', 'h d j d e', 'e d b b i e g'); -- 42
INSERT INTO t3 VALUES('b h i', 'j e i d a', 'j j h e e c a'); -- 43
INSERT INTO t3 VALUES('g i g', 'f c c f d', 'a c i c a d a'); -- 44
INSERT INTO t3 VALUES('c c f', 'a b j d b', 'c a e g f e c'); -- 45
INSERT INTO t3 VALUES('d h j', 'g c b j d', 'e a h f h j g'); -- 46
INSERT INTO t3 VALUES('a a d', 'j e j a i', 'i d c f f f b'); -- 47
INSERT INTO t3 VALUES('b g j', 'e c i h f', 'd d h b g a d'); -- 48
INSERT INTO t3 VALUES('c i a', 'a c c c c', 'e h i e h i e'); -- 49
INSERT INTO t3 VALUES('f f c', 'f f b i i', 'f f a j e c i'); -- 50
}
proc pmatch {col expr} {
return [expr {[string first $expr $col]>=0}]
}
db func pmatch pmatch
foreach {tn cols tokens} {
1 a "c c"
2 b "c c"
3 c "c c"
4 {a b c} "c c"
5 {a b c} "b h"
6 {a b} "b h"
7 {a c} "b h"
8 {c a} "b h"
9 {c} "i e"
10 {b} "i e"
11 {a} "i e"
} {
set fts "{$cols}:[join $tokens +]"
set where [list]
foreach c $cols { lappend where "pmatch($c, '$tokens')" }
set where [join $where " OR "]
set res [db eval "SELECT rowid FROM t3 WHERE $where"]
do_execsql_test "1.$tn.$fts->([llength $res] rows)" {
SELECT rowid FROM t3($fts)
} $res
}
do_execsql_test 2.0 {
SELECT rowid,
highlight(t3, 0, '*', '*'),
highlight(t3, 1, '*', '*'),
highlight(t3, 2, '*', '*')
FROM t3('a:f+f')
} {
31 {h *f f*} {i j g e c} {j j f c a i j}
50 {*f f* c} {f f b i i} {f f a j e c i}
}
finish_test
+236
View File
@@ -62,6 +62,242 @@ foreach {tn q res} {
do_execsql_test 2.3.$tn $q $res
}
#-------------------------------------------------------------------------
# Check that prefix queries with:
#
# * a column filter, and
# * no prefix index.
#
# work Ok.
#
do_execsql_test 3.0 {
CREATE VIRTUAL TABLE t3 USING fts5(a, b, c);
INSERT INTO t3(t3, rank) VALUES('pgsz', 32);
BEGIN;
INSERT INTO t3 VALUES('acb ccc bba', 'cca bba bca', 'bbc ccc bca'); -- 1
INSERT INTO t3 VALUES('cbb cac cab', 'abb aac bba', 'aab ccc cac'); -- 2
INSERT INTO t3 VALUES('aac bcb aac', 'acb bcb caa', 'aca bab bca'); -- 3
INSERT INTO t3 VALUES('aab ccb ccc', 'aca cba cca', 'aca aac cbb'); -- 4
INSERT INTO t3 VALUES('bac aab bab', 'ccb bac cba', 'acb aba abb'); -- 5
INSERT INTO t3 VALUES('bab abc ccb', 'acb cba abb', 'cbb aaa cab'); -- 6
INSERT INTO t3 VALUES('cbb bbc baa', 'aab aca baa', 'bcc cca aca'); -- 7
INSERT INTO t3 VALUES('abc bba abb', 'cac abc cba', 'acc aac cac'); -- 8
INSERT INTO t3 VALUES('bbc bbc cab', 'bcb ccb cba', 'bcc cac acb'); -- 9
COMMIT;
}
foreach {tn match res} {
1 "a : c*" {1 2 4 6 7 9}
2 "b : c*" {1 3 4 5 6 8 9}
3 "c : c*" {1 2 4 6 7 8 9}
4 "a : b*" {1 3 5 6 7 8 9}
5 "b : b*" {1 2 3 5 7 9}
6 "c : b*" {1 3 7 9}
7 "a : a*" {1 3 4 5 6 8}
8 "b : a*" {2 3 4 6 7 8}
9 "c : a*" {2 3 4 5 6 7 8 9}
} {
do_execsql_test 3.1.$tn {
SELECT rowid FROM t3($match)
} $res
}
do_test 3.2 {
expr srand(0)
execsql { DELETE FROM t3 }
for {set i 0} {$i < 1000} {incr i} {
set a [fts5_rnddoc 3]
set b [fts5_rnddoc 8]
set c [fts5_rnddoc 20]
execsql { INSERT INTO t3 VALUES($a, $b, $c) }
}
execsql { INSERT INTO t3(t3) VALUES('integrity-check') }
} {}
proc gmatch {col pattern} {
expr {[lsearch -glob $col $pattern]>=0}
}
db func gmatch gmatch
proc ghl {col pattern} {
foreach t $col {
if {[string match $pattern $t]} {
lappend res "*$t*"
} else {
lappend res $t
}
}
set res
}
db func ghl ghl
set COLS(a) 0
set COLS(b) 1
set COLS(c) 2
for {set x 0} {$x<2} {incr x} {
foreach {tn pattern} {
1 {xa*}
2 {xb*}
3 {xc*}
4 {xd*}
5 {xe*}
6 {xf*}
7 {xg*}
8 {xh*}
9 {xi*}
10 {xj*}
} {
foreach col {a b c} {
# Check that the list of returned rowids is correct.
#
set res [db eval "SELECT rowid FROM t3 WHERE gmatch($col, '$pattern')"]
set query "$col : $pattern"
do_execsql_test 3.3.$x.$tn.$col.rowid {
SELECT rowid FROM t3($query);
} $res
# Check that the highlight() function works.
#
set res [db eval \
"SELECT ghl($col, '$pattern') FROM t3 WHERE gmatch($col, '$pattern')"
]
set idx $COLS($col)
do_execsql_test 3.3.$x.$tn.$col.highlight {
SELECT highlight(t3, $idx, '*', '*') FROM t3($query);
} $res
}
foreach colset {{a b} {b c} {c a} {a c} {b a}} {
# Check that the list of returned rowids is correct.
#
foreach {col1 col2} $colset {}
set expr "gmatch($col1, '$pattern') OR gmatch($col2, '$pattern')"
set res [db eval "SELECT rowid FROM t3 WHERE $expr"]
set query "{$colset} : $pattern"
do_execsql_test 3.3.$x.$tn.{$colset}.rowid {
SELECT rowid FROM t3($query);
} $res
set resq "SELECT ghl($col1, '$pattern'), ghl($col2, '$pattern')"
append resq " FROM t3 WHERE $expr"
set res [db eval $resq]
set idx1 $COLS($col1)
set idx2 $COLS($col2)
do_execsql_test 3.3.$x.$tn.{$colset}.highlight {
SELECT highlight(t3, $idx1, '*', '*'), highlight(t3, $idx2, '*', '*')
FROM t3($query)
} $res
}
}
execsql { INSERT INTO t3(t3) VALUES('optimize') }
execsql { INSERT INTO t3(t3) VALUES('integrity-check') }
}
#-------------------------------------------------------------------------
#
reset_db
do_execsql_test 4.0 {
CREATE VIRTUAL TABLE t2 USING fts5(c1, c2);
INSERT INTO t2 VALUES('xa xb', 'xb xa');
INSERT INTO t2 SELECT c1||' '||c1, c2||' '||c2 FROM t2; -- 2
INSERT INTO t2 SELECT c1||' '||c1, c2||' '||c2 FROM t2; -- 4
INSERT INTO t2 SELECT c1||' '||c1, c2||' '||c2 FROM t2; -- 8
INSERT INTO t2 SELECT c1||' '||c1, c2||' '||c2 FROM t2; -- 16
INSERT INTO t2 SELECT c1||' '||c1, c2||' '||c2 FROM t2; -- 32
INSERT INTO t2 SELECT c1||' '||c1, c2||' '||c2 FROM t2; -- 64
INSERT INTO t2 SELECT c1||' '||c1, c2||' '||c2 FROM t2; -- 128
INSERT INTO t2 SELECT c1||' '||c1, c2||' '||c2 FROM t2; -- 256
INSERT INTO t2 SELECT c1||' '||c1, c2||' '||c2 FROM t2; -- 512
INSERT INTO t2 SELECT c1||' '||c1, c2||' '||c2 FROM t2; -- 1024
INSERT INTO t2 SELECT c1||' '||c1, c2||' '||c2 FROM t2; -- 2048
INSERT INTO t2 SELECT c1||' '||c1, c2||' '||c2 FROM t2; -- 4096
SELECT count(*) FROM t2('x*');
} {4096}
do_execsql_test 4.1 {
UPDATE t2 SET c2 = 'ya yb';
SELECT count(*) FROM t2('c1:x*');
SELECT count(*) FROM t2('c2:x*');
} {4096 0}
do_execsql_test 4.2 {
UPDATE t2 SET c2 = 'xa';
SELECT count(*) FROM t2('c1:x*');
SELECT count(*) FROM t2('c2:x*');
} {4096 4096}
#-------------------------------------------------------------------------
#
reset_db
proc rnddoc {n} {
set map [list a b c d]
set doc [list]
for {set i 0} {$i < $n} {incr i} {
lappend doc "x[lindex $map [expr int(rand()*4)]]"
}
set doc
}
set cols [list]
for {set i 1} {$i<250} {incr i} {
lappend cols "c$i"
lappend vals "'[rnddoc 10]'"
}
do_test 5.0 {
execsql "CREATE VIRTUAL TABLE t4 USING fts5([join $cols ,])"
execsql {INSERT INTO t4(t4, rank) VALUES('pgsz', 32)}
execsql "INSERT INTO t4 VALUES([join $vals ,])"
execsql "INSERT INTO t4 VALUES([join $vals ,])"
execsql "INSERT INTO t4 VALUES([join $vals ,])"
execsql "INSERT INTO t4 VALUES([join $vals ,])"
} {}
proc gmatch {col pattern} {
expr {[lsearch -glob $col $pattern]>=0}
}
db func gmatch gmatch
foreach {tn col pattern} {
1 c100 {xa*}
2 c200 {xb*}
} {
set res [db eval "SELECT rowid FROM t4 WHERE gmatch($col, \$pattern)"]
set query "$col : $pattern"
do_execsql_test 5.$tn { SELECT rowid FROM t4($query) } $res
}
reset_db
db func fts5_rnddoc fts5_rnddoc
do_test 6.0 {
execsql {
CREATE VIRTUAL TABLE t5 USING fts5(x, y);
INSERT INTO t5 VALUES( fts5_rnddoc(10000), fts5_rnddoc(10000) );
INSERT INTO t5 VALUES( fts5_rnddoc(10000), fts5_rnddoc(10000) );
INSERT INTO t5 VALUES( fts5_rnddoc(10000), fts5_rnddoc(10000) );
INSERT INTO t5 VALUES( fts5_rnddoc(10000), fts5_rnddoc(10000) );
}
} {}
proc gmatch {col pattern} {
expr {[lsearch -glob $col $pattern]>=0}
}
db func gmatch gmatch
foreach {tn col pattern} {
1 y {xa*}
2 y {xb*}
3 y {xc*}
4 x {xa*}
5 x {xb*}
6 x {xc*}
} {
set res [db eval "SELECT rowid FROM t5 WHERE gmatch($col, \$pattern)"]
set query "$col : $pattern"
do_execsql_test 6.$tn { SELECT rowid FROM t5($query) } $res
}
finish_test
+8 -4
View File
@@ -27,15 +27,15 @@ do_catchsql_test 1.1 {
do_catchsql_test 1.2 {
SELECT fts5_rowid('segment')
} {1 {should be: fts5_rowid('segment', segid, height, pgno))}}
} {1 {should be: fts5_rowid('segment', segid, pgno))}}
do_execsql_test 1.3 {
SELECT fts5_rowid('segment', 1, 1, 1)
} {139586437121}
SELECT fts5_rowid('segment', 1, 1)
} {137438953473}
do_catchsql_test 1.4 {
SELECT fts5_rowid('nosucharg');
} {1 {first arg to fts5_rowid() must be 'segment' or 'start-of-index'}}
} {1 {first arg to fts5_rowid() must be 'segment'}}
#-------------------------------------------------------------------------
@@ -91,6 +91,10 @@ do_execsql_test 2.6 {
# SELECT count(fts5_decode(rowid, block)) FROM x1_data;
#} $res
do_execsql_test 2.8 {
SELECT fts5_decode(fts5_rowid('segment', 1000, 1), X'AB')
} {corrupt}
#-------------------------------------------------------------------------
# Tests with very large tokens.
#
+326
View File
@@ -0,0 +1,326 @@
# 2015 September 05
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
# May you find forgiveness for yourself and forgive others.
# May you share freely, never taking more than you give.
#
#*************************************************************************
#
source [file join [file dirname [info script]] fts5_common.tcl]
set testprefix fts5simple
# If SQLITE_ENABLE_FTS5 is defined, omit this file.
ifcapable !fts5 {
finish_test
return
}
#-------------------------------------------------------------------------
#
set doc "x x [string repeat {y } 50]z z"
do_execsql_test 1.0 {
CREATE VIRTUAL TABLE t1 USING fts5(x);
INSERT INTO t1(t1, rank) VALUES('pgsz', 32);
BEGIN;
INSERT INTO t1 VALUES($doc);
COMMIT;
}
do_execsql_test 1.1 {
INSERT INTO t1(t1) VALUES('integrity-check');
}
#-------------------------------------------------------------------------
#
reset_db
do_execsql_test 2.0 {
CREATE VIRTUAL TABLE t1 USING fts5(x);
INSERT INTO t1(t1, rank) VALUES('pgsz', 32);
INSERT INTO t1 VALUES('a b c');
INSERT INTO t1 VALUES('d e f');
INSERT INTO t1(t1) VALUES('optimize');
}
do_execsql_test 2.1 {
INSERT INTO t1(t1) VALUES('integrity-check');
} {}
#-------------------------------------------------------------------------
#
reset_db
do_execsql_test 3.0 {
CREATE VIRTUAL TABLE t1 USING fts5(x, prefix='1,2');
INSERT INTO t1(t1, rank) VALUES('pgsz', 32);
BEGIN;
INSERT INTO t1 VALUES('one');
SELECT * FROM t1 WHERE t1 MATCH 'o*';
} {one}
do_execsql_test 3.1 {
INSERT INTO t1(t1) VALUES('integrity-check');
} {}
#-------------------------------------------------------------------------
reset_db
do_execsql_test 4.1 {
CREATE VIRTUAL TABLE t11 USING fts5(content);
INSERT INTO t11(t11, rank) VALUES('pgsz', 32);
INSERT INTO t11 VALUES('another');
INSERT INTO t11 VALUES('string');
INSERT INTO t11 VALUES('of');
INSERT INTO t11 VALUES('text');
}
do_test 4.2 {
execsql { INSERT INTO t11(t11) VALUES('optimize') }
} {}
do_execsql_test 4.3 {
INSERT INTO t11(t11) VALUES('integrity-check');
} {}
#db eval { SELECT fts5_decode(rowid, block) as x FROM t11_data } { puts $x }
#-------------------------------------------------------------------------
reset_db
set doc [string repeat "x y " 5]
do_execsql_test 5.1 {
CREATE VIRTUAL TABLE yy USING fts5(content);
INSERT INTO yy(yy, rank) VALUES('pgsz', 32);
BEGIN;
INSERT INTO yy VALUES($doc);
INSERT INTO yy VALUES($doc);
INSERT INTO yy VALUES($doc);
INSERT INTO yy VALUES($doc);
INSERT INTO yy VALUES($doc);
INSERT INTO yy VALUES($doc);
INSERT INTO yy VALUES($doc);
INSERT INTO yy VALUES($doc);
COMMIT;
}
do_execsql_test 5.2 {
SELECT rowid FROM yy WHERE yy MATCH 'y' ORDER BY rowid ASC
} {1 2 3 4 5 6 7 8}
do_execsql_test 5.3 {
SELECT rowid FROM yy WHERE yy MATCH 'y' ORDER BY rowid DESC
} {8 7 6 5 4 3 2 1}
#db eval { SELECT fts5_decode(rowid, block) as x FROM yy_data } { puts $x }
#-------------------------------------------------------------------------
reset_db
do_execsql_test 5.1 {
CREATE VIRTUAL TABLE tt USING fts5(content);
INSERT INTO tt(tt, rank) VALUES('pgsz', 32);
INSERT INTO tt VALUES('aa');
}
do_execsql_test 5.2 {
SELECT rowid FROM tt WHERE tt MATCH 'a*';
} {1}
do_execsql_test 5.3 {
DELETE FROM tt;
BEGIN;
INSERT INTO tt VALUES('aa');
INSERT INTO tt VALUES('ab');
COMMIT;
} {}
do_execsql_test 5.4 {
SELECT rowid FROM tt WHERE tt MATCH 'a*';
} {1 2}
do_execsql_test 5.5 {
DELETE FROM tt;
BEGIN;
INSERT INTO tt VALUES('aa');
INSERT INTO tt VALUES('ab');
INSERT INTO tt VALUES('aa');
INSERT INTO tt VALUES('ab');
INSERT INTO tt VALUES('aa');
INSERT INTO tt VALUES('ab');
INSERT INTO tt VALUES('aa');
INSERT INTO tt VALUES('ab');
COMMIT;
SELECT rowid FROM tt WHERE tt MATCH 'a*';
} {1 2 3 4 5 6 7 8}
do_execsql_test 5.6 {
INSERT INTO tt(tt) VALUES('integrity-check');
}
reset_db
do_execsql_test 5.7 {
CREATE VIRTUAL TABLE tt USING fts5(content);
INSERT INTO tt(tt, rank) VALUES('pgsz', 32);
INSERT INTO tt VALUES('aa ab ac ad ae af');
}
do_execsql_test 5.8 {
SELECT rowid FROM tt WHERE tt MATCH 'a*';
} {1}
#-------------------------------------------------------------------------
reset_db
do_execsql_test 6.1 {
CREATE VIRTUAL TABLE xyz USING fts5(x, y, z);
INSERT INTO xyz VALUES('x', 'y', 'z');
}
do_catchsql_test 6.2 {
SELECT * FROM xyz WHERE xyz MATCH ''
} {1 {fts5: syntax error near ""}}
do_catchsql_test 6.3 {
SELECT * FROM xyz WHERE xyz MATCH NULL
} {1 {fts5: syntax error near ""}}
#-------------------------------------------------------------------------
do_execsql_test 7.1 {
CREATE VIRTUAL TABLE ft2 USING fts5(content);
INSERT INTO ft2(rowid, content) VALUES(1, 'a b c');
INSERT INTO ft2(rowid, content) VALUES(2, 'a b d');
}
do_catchsql_test 7.2 {
BEGIN;
UPDATE ft2 SET rowid=2 WHERE rowid=1;
} {1 {constraint failed}}
do_execsql_test 7.3 {
COMMIT;
INSERT INTO ft2(ft2) VALUES('integrity-check');
} {}
do_execsql_test 7.4 {
SELECT * FROM ft2;
} {{a b c} {a b d}}
#-------------------------------------------------------------------------
#
reset_db
do_execsql_test 8.1 {
CREATE VIRTUAL TABLE ft2 USING fts5(content);
INSERT INTO ft2(rowid, content) VALUES(1, 'a b');
}
do_execsql_test 8.2 {
BEGIN;
INSERT INTO ft2(rowid, content) VALUES(4, 'a x');
}
do_execsql_test 8.3 {
INSERT INTO ft2(ft2) VALUES('integrity-check');
}
#-------------------------------------------------------------------------
# Check that the "table function" syntax works.
#
reset_db
do_execsql_test 9.1 {
CREATE VIRTUAL TABLE ft2 USING fts5(content);
INSERT INTO ft2(rowid, content) VALUES(1, 'a b');
INSERT INTO ft2(rowid, content) VALUES(2, 'a b c d');
INSERT INTO ft2(rowid, content) VALUES(3, 'c d e f');
}
do_execsql_test 9.2 {
SELECT rowid FROM ft2('a');
} {1 2}
do_execsql_test 9.3 {
SELECT rowid FROM ft2('b AND c');
} {2}
#-------------------------------------------------------------------------
#
do_execsql_test 10.0 {
CREATE VIRTUAL TABLE t3 USING fts5(a, b, c);
INSERT INTO t3 VALUES('bac aab bab', 'c bac c', 'acb aba abb'); -- 1
INSERT INTO t3 VALUES('bab abc c', 'acb c abb', 'c aaa c'); -- 2
}
do_execsql_test 10.1 {
SELECT rowid FROM t3('c: c*');
} {2}
do_execsql_test 10.2 {
SELECT rowid FROM t3('b: acb');
} {2}
#-------------------------------------------------------------------------
# Test that character 0x1A is allowed in fts5 barewords.
#
do_test 11.0 {
execsql "CREATE VIRTUAL TABLE t4 USING fts5(x, tokenize=\"ascii tokenchars '\x1A'\")"
execsql "
INSERT INTO t4 VALUES('a b c \x1A');
INSERT INTO t4 VALUES('a b c d\x1A');
INSERT INTO t4 VALUES('a b c \x1Ad');
INSERT INTO t4 VALUES('a b c d');
"
} {}
do_test 11.1 {
execsql "SELECT rowid FROM t4('\x1A')"
} {1}
do_test 11.2 {
execsql "SELECT rowid FROM t4('\x1A*')"
} {1 3}
do_test 11.3 {
execsql "SELECT rowid FROM t4('d\x1A')"
} {2}
do_test 11.4 {
catchsql "SELECT rowid FROM t4('d\x1B')"
} {/fts5: syntax error/}
do_test 11.5 {
catchsql "SELECT rowid FROM t4('d\x19')"
} {/fts5: syntax error/}
#-------------------------------------------------------------------------
#
do_test 12.1 {
execsql {
CREATE VIRTUAL TABLE xx USING fts5(x,y);
BEGIN;
INSERT INTO xx VALUES('1 2 3', 'a b c');
}
} {}
do_execsql_test 12.2 {
SELECT rowid FROM xx('x:a');
COMMIT;
} {}
#-------------------------------------------------------------------------
# Try an UPDATE OR REPLACE query.
#
do_execsql_test 13.1 {
CREATE VIRTUAL TABLE xy USING fts5(x);
INSERT INTO xy(rowid, x) VALUES(1, '1 2 3');
INSERT INTO xy(rowid, x) VALUES(2, '2 3 4');
INSERT INTO xy(rowid, x) VALUES(3, '3 4 5');
}
do_execsql_test 13.2 {
UPDATE OR REPLACE xy SET rowid=3 WHERE rowid = 2;
SELECT rowid, x FROM xy;
} {
1 {1 2 3}
3 {2 3 4}
}
do_execsql_test 13.3 {
INSERT INTO xy(xy) VALUES('integrity-check');
}
finish_test
+5 -5
View File
@@ -30,34 +30,34 @@ do_execsql_test 1.1 {
do_execsql_test 1.2 {
SELECT * FROM t1_config WHERE k='version'
} {version 3}
} {version 4}
do_execsql_test 1.3 {
SELECT rowid FROM t1 WHERE t1 MATCH 'a';
} {1}
do_execsql_test 1.4 {
UPDATE t1_config set v=4 WHERE k='version';
UPDATE t1_config set v=5 WHERE k='version';
}
do_test 1.5 {
db close
sqlite3 db test.db
catchsql { SELECT * FROM t1 WHERE t1 MATCH 'a' }
} {1 {invalid fts5 file format (found 4, expected 3) - run 'rebuild'}}
} {1 {invalid fts5 file format (found 5, expected 4) - run 'rebuild'}}
do_test 1.6 {
db close
sqlite3 db test.db
catchsql { INSERT INTO t1 VALUES('x y z') }
} {1 {invalid fts5 file format (found 4, expected 3) - run 'rebuild'}}
} {1 {invalid fts5 file format (found 5, expected 4) - run 'rebuild'}}
do_test 1.7 {
execsql { DELETE FROM t1_config WHERE k='version' }
db close
sqlite3 db test.db
catchsql { SELECT * FROM t1 WHERE t1 MATCH 'a' }
} {1 {invalid fts5 file format (found 0, expected 3) - run 'rebuild'}}
} {1 {invalid fts5 file format (found 0, expected 4) - run 'rebuild'}}
finish_test
+142 -10
View File
@@ -56,7 +56,7 @@ do_execsql_test 1.4.1 {
do_execsql_test 1.4.2 {
SELECT * FROM v2;
} {x 0 2 4 y 0 1 1 z 0 1 1}
} {x one 2 4 y one 1 1 z one 1 1}
do_execsql_test 1.5.1 {
BEGIN;
@@ -67,7 +67,7 @@ do_execsql_test 1.5.1 {
do_execsql_test 1.5.2 {
SELECT * FROM v2 WHERE term<'d';
COMMIT;
} {a 0 1 1 b 0 1 1 c 0 1 1}
} {a one 1 1 b one 1 1 c one 1 1}
do_execsql_test 1.6 {
DELETE FROM t1 WHERE one = 'a b c';
@@ -91,14 +91,14 @@ do_execsql_test 2.0 {
}
set res_col {
a 0 6 11 a 1 7 9
b 0 6 7 b 1 7 7
c 0 6 12 c 1 5 8
d 0 4 6 d 1 9 13
e 0 6 7 e 1 6 6
f 0 9 10 f 1 7 10
g 0 5 7 g 1 5 7
x 0 1 1 y 1 1 1
a a 6 11 a b 7 9
b a 6 7 b b 7 7
c a 6 12 c b 5 8
d a 4 6 d b 9 13
e a 6 7 e b 6 6
f a 9 10 f b 7 10
g a 5 7 g b 5 7
x a 1 1 y b 1 1
}
set res_row {
a 10 20 b 9 14 c 9 20 d 9 19
@@ -213,5 +213,137 @@ do_catchsql_test 6.2 {
SELECT * FROM vocab3;
} {1 {no such fts5 table: main.lll}}
#-------------------------------------------------------------------------
# Test single term queries on fts5vocab tables (i.e. those with term=?
# constraints in the WHERE clause).
#
do_execsql_test 7.0 {
CREATE VIRTUAL TABLE tx USING fts5(one, two);
INSERT INTO tx VALUES('g a ggg g a b eee', 'cc d aa ff g ee');
INSERT INTO tx VALUES('dd fff i a i jjj', 'f fff hh jj e f');
INSERT INTO tx VALUES('ggg a f f fff dd aa', 'd ggg f f j gg ddd');
INSERT INTO tx VALUES('e bb h jjj ii gg', 'e aa e f c fff');
INSERT INTO tx VALUES('j ff aa a h', 'h a j bbb bb');
INSERT INTO tx VALUES('cc i ff c d f', 'dd ii fff f c cc d');
INSERT INTO tx VALUES('jjj g i bb cc eee', 'hhh iii aaa b bbb aaa');
INSERT INTO tx VALUES('hhh hhh hhh bb fff f', 'fff gg aa ii h a');
INSERT INTO tx VALUES('b c cc aaa iii ggg f', 'iii ff ee a ff c cc');
INSERT INTO tx VALUES('hhh b hhh aaa j i i', 'dd ee ee aa bbb iii');
INSERT INTO tx VALUES('hh dd h b g ff i', 'ccc bb cc ccc f a d');
INSERT INTO tx VALUES('g d b ggg jj', 'fff jj ff jj g gg ee');
INSERT INTO tx VALUES('g ee ggg ggg cc bb eee', 'aa j jjj bbb dd eee ff');
INSERT INTO tx VALUES('c jjj hh ddd dd h', 'e aaa h jjj gg');
CREATE VIRTUAL TABLE txr USING fts5vocab(tx, row);
CREATE VIRTUAL TABLE txc USING fts5vocab(tx, col);
}
proc cont {L elem} {
set n 0
foreach e $L { if {$elem==$e} {incr n} }
set n
}
db func cont cont
foreach {term} {
a aa aaa
b bb bbb
c cc ccc
d dd ddd
e ee eee
f ff fff
g gg ggg
h hh hhh
i ii iii
j jj jjj
} {
set resr [db eval {
SELECT $term,
sum(cont(one || ' ' || two, $term) > 0),
sum(cont(one || ' ' || two, $term))
FROM tx
}]
if {[lindex $resr 1]==0} {set resr [list]}
set r1 [db eval {
SELECT $term, 'one', sum(cont(one, $term)>0), sum(cont(one, $term)) FROM tx
}]
if {[lindex $r1 2]==0} {set r1 [list]}
set r2 [db eval {
SELECT $term, 'two', sum(cont(two, $term)>0), sum(cont(two, $term)) FROM tx
}]
if {[lindex $r2 2]==0} {set r2 [list]}
set resc [concat $r1 $r2]
do_execsql_test 7.$term.1 {SELECT * FROM txc WHERE term=$term} $resc
do_execsql_test 7.$term.2 {SELECT * FROM txr WHERE term=$term} $resr
}
do_execsql_test 7.1 {
CREATE TABLE txr_c AS SELECT * FROM txr;
CREATE TABLE txc_c AS SELECT * FROM txc;
}
# Test range queries on the fts5vocab tables created above.
#
foreach {tn a b} {
1 a jjj
2 bb j
3 ccc ddd
4 dd xyz
5 xzy dd
6 h hh
} {
do_execsql_test 7.2.$tn.1 {
SELECT * FROM txr WHERE term>=$a
} [db eval {SELECT * FROM txr_c WHERE term>=$a}]
do_execsql_test 7.2.$tn.2 {
SELECT * FROM txr WHERE term<=$b
} [db eval {SELECT * FROM txr_c WHERE term <=$b}]
do_execsql_test 7.2.$tn.3 {
SELECT * FROM txr WHERE term>=$a AND term<=$b
} [db eval {SELECT * FROM txr_c WHERE term>=$a AND term <=$b}]
do_execsql_test 7.2.$tn.4 {
SELECT * FROM txc WHERE term>=$a
} [db eval {SELECT * FROM txc_c WHERE term>=$a}]
do_execsql_test 7.2.$tn.5 {
SELECT * FROM txc WHERE term<=$b
} [db eval {SELECT * FROM txc_c WHERE term <=$b}]
do_execsql_test 7.2.$tn.6 {
SELECT * FROM txc WHERE term>=$a AND term<=$b
} [db eval {SELECT * FROM txc_c WHERE term>=$a AND term <=$b}]
do_execsql_test 7.2.$tn.7 {
SELECT * FROM txr WHERE term>$a
} [db eval {SELECT * FROM txr_c WHERE term>$a}]
do_execsql_test 7.2.$tn.8 {
SELECT * FROM txr WHERE term<$b
} [db eval {SELECT * FROM txr_c WHERE term<$b}]
do_execsql_test 7.2.$tn.9 {
SELECT * FROM txr WHERE term>$a AND term<$b
} [db eval {SELECT * FROM txr_c WHERE term>$a AND term <$b}]
do_execsql_test 7.2.$tn.10 {
SELECT * FROM txc WHERE term>$a
} [db eval {SELECT * FROM txc_c WHERE term>$a}]
do_execsql_test 7.2.$tn.11 {
SELECT * FROM txc WHERE term<$b
} [db eval {SELECT * FROM txc_c WHERE term<$b}]
do_execsql_test 7.2.$tn.12 {
SELECT * FROM txc WHERE term>$a AND term<$b
} [db eval {SELECT * FROM txc_c WHERE term>$a AND term <$b}]
}
do_execsql_test 7.3.1 {
SELECT count(*) FROM txr, txr_c WHERE txr.term = txr_c.term;
} {30}
do_execsql_test 7.3.2 {
SELECT count(*) FROM txc, txc_c
WHERE txc.term = txc_c.term AND txc.col=txc_c.col;
} {57}
finish_test
+120
View File
@@ -0,0 +1,120 @@
proc usage {} {
puts stderr "$::argv0 ?OPTIONS? DATABASE FILE1..."
puts stderr ""
puts stderr "Options are"
puts stderr " -fts5"
puts stderr " -fts4"
puts stderr " -colsize <list of column sizes>"
puts stderr {
This script is designed to create fts4/5 tables with more than one column.
The -colsize option should be set to a Tcl list of integer values, one for
each column in the table. Each value is the number of tokens that will be
inserted into the column value for each row. For example, setting the -colsize
option to "5 10" creates an FTS table with 2 columns, with roughly 5 and 10
tokens per row in each, respectively.
Each "FILE" argument should be a text file. The contents of these text files is
split on whitespace characters to form a list of tokens. The first N1 tokens
are used for the first column of the first row, where N1 is the first element
of the -colsize list. The next N2 are used for the second column of the first
row, and so on. Rows are added to the table until the entire list of tokens
is exhausted.
}
exit -1
}
set O(aColSize) [list 10 10 10]
set O(tblname) t1
set O(fts) fts5
set options_with_values {-colsize}
for {set i 0} {$i < [llength $argv]} {incr i} {
set opt [lindex $argv $i]
if {[string range $opt 0 0]!="-"} break
if {[lsearch $options_with_values $opt]>=0} {
incr i
if {$i==[llength $argv]} usage
set val [lindex $argv $i]
}
switch -- $opt {
-colsize {
set O(aColSize) $val
}
-fts4 {
set O(fts) fts4
}
-fts5 {
set O(fts) fts5
}
}
}
if {$i > [llength $argv]-2} usage
set O(db) [lindex $argv $i]
set O(files) [lrange $argv [expr $i+1] end]
sqlite3 db $O(db)
# Create the FTS table in the db. Return a list of the table columns.
#
proc create_table {} {
global O
set cols [list a b c d e f g h i j k l m n o p q r s t u v w x y z]
set nCol [llength $O(aColSize)]
set cols [lrange $cols 0 [expr $nCol-1]]
set sql "CREATE VIRTUAL TABLE IF NOT EXISTS $O(tblname) USING $O(fts) ("
append sql [join $cols ,]
append sql ");"
db eval $sql
return $cols
}
# Return a list of tokens from the named file.
#
proc readfile {file} {
set fd [open $file]
set data [read $fd]
close $fd
split $data
}
# Load all the data into a big list of tokens.
#
set tokens [list]
foreach f $O(files) {
set tokens [concat $tokens [readfile $f]]
}
set N [llength $tokens]
set i 0
set cols [create_table]
set sql "INSERT INTO $O(tblname) VALUES(\$[lindex $cols 0]"
foreach c [lrange $cols 1 end] {
append sql ", \$A($c)"
}
append sql ")"
db eval BEGIN
while {$i < $N} {
foreach c $cols s $O(aColSize) {
set A($c) [lrange $tokens $i [expr $i+$s-1]]
incr i $s
}
db eval $sql
}
db eval COMMIT
+16 -2
View File
@@ -19,6 +19,12 @@ proc load_hierachy {dir} {
db eval { INSERT INTO t1 VALUES($f, loadfile($f)) }
incr ::nRow
if {$::O(trans) && ($::nRow % $::O(trans))==0} {
db eval { COMMIT }
db eval { INSERT INTO t1(t1) VALUES('integrity-check') }
db eval { BEGIN }
}
if {($::nRow % $::nRowPerDot)==0} {
puts -nonewline .
if {($::nRow % (65*$::nRowPerDot))==0} { puts "" }
@@ -41,6 +47,7 @@ proc usage {} {
puts stderr " -automerge N (set the automerge parameter to N)"
puts stderr " -crisismerge N (set the crisismerge parameter to N)"
puts stderr " -prefix PREFIX (comma separated prefix= argument)"
puts stderr " -trans N (commit after N inserts - 0 == never)"
exit 1
}
@@ -51,6 +58,7 @@ set O(delete) 0
set O(automerge) -1
set O(crisismerge) -1
set O(prefix) ""
set O(trans) 0
if {[llength $argv]<2} usage
set nOpt [expr {[llength $argv]-2}]
@@ -77,6 +85,11 @@ for {set i 0} {$i < $nOpt} {incr i} {
if { [incr i]>=$nOpt } usage
set O(limit) [lindex $argv $i]
}
-trans {
if { [incr i]>=$nOpt } usage
set O(trans) [lindex $argv $i]
}
-automerge {
if { [incr i]>=$nOpt } usage
@@ -104,8 +117,9 @@ if {$O(delete)} { file delete -force $dbfile }
sqlite3 db $dbfile
catch { load_static_extension db fts5 }
db func loadfile loadfile
db eval "PRAGMA page_size=4096"
db transaction {
db eval BEGIN
set pref ""
if {$O(prefix)!=""} { set pref ", prefix='$O(prefix)'" }
catch {
@@ -126,7 +140,7 @@ db transaction {
}
}
load_hierachy [lindex $argv end]
}
db eval COMMIT
+10 -10
View File
@@ -7,6 +7,7 @@ set G(src) [string map [list %dir% $srcdir] {
%dir%/fts5.h
%dir%/fts5Int.h
fts5parse.h
fts5parse.c
%dir%/fts5_aux.c
%dir%/fts5_buffer.c
%dir%/fts5_config.c
@@ -19,12 +20,11 @@ set G(src) [string map [list %dir% $srcdir] {
%dir%/fts5_unicode2.c
%dir%/fts5_varint.c
%dir%/fts5_vocab.c
fts5parse.c
}]
set G(hdr) {
#if !defined(SQLITE_TEST) || defined(SQLITE_ENABLE_FTS5)
#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS5)
#if !defined(NDEBUG) && !defined(SQLITE_DEBUG)
# define NDEBUG 1
@@ -37,7 +37,7 @@ set G(hdr) {
set G(footer) {
#endif /* !defined(SQLITE_TEST) || defined(SQLITE_ENABLE_FTS5) */
#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS5) */
}
#-------------------------------------------------------------------------
@@ -78,7 +78,7 @@ proc fts5c_printfile {zIn} {
global G
set data [readfile $zIn]
set zTail [file tail $zIn]
puts $G(fd) "#line 2 \"$zTail\""
puts $G(fd) "#line 1 \"$zTail\""
set sub_map [list --FTS5-SOURCE-ID-- [fts5_source_id $::srcdir]]
if {$zTail=="fts5parse.c"} {
@@ -86,8 +86,12 @@ proc fts5c_printfile {zIn} {
}
foreach line [split $data "\n"] {
if {[regexp {^#include.*fts5} $line]} continue
if {[regexp {^(const )?[a-zA-Z][a-zA-Z0-9]* [*]?sqlite3Fts5} $line]} {
if {[regexp {^#include.*fts5} $line]} {
set line "/* $line */"
} elseif {
![regexp { sqlite3Fts5Init\(} $line]
&& [regexp {^(const )?[a-zA-Z][a-zA-Z0-9]* [*]?sqlite3Fts5} $line]
} {
set line "static $line"
}
set line [string map $sub_map $line]
@@ -107,7 +111,3 @@ proc fts5c_close {} {
fts5c_init fts5.c
foreach f $G(src) { fts5c_printfile $f }
fts5c_close
+385 -279
View File
File diff suppressed because it is too large Load Diff
+57 -2
View File
@@ -89,6 +89,10 @@
#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_RBU)
#include "sqlite3rbu.h"
#if defined(_WIN32_WCE)
#include "windows.h"
#endif
/* Maximum number of prepared UPDATE statements held by this module */
#define SQLITE_RBU_UPDATE_CACHESIZE 16
@@ -2382,6 +2386,30 @@ static void rbuLockDatabase(sqlite3rbu *p){
}
}
#if defined(_WIN32_WCE)
static LPWSTR rbuWinUtf8ToUnicode(const char *zFilename){
int nChar;
LPWSTR zWideFilename;
nChar = MultiByteToWideChar(CP_UTF8, 0, zFilename, -1, NULL, 0);
if( nChar==0 ){
return 0;
}
zWideFilename = sqlite3_malloc( nChar*sizeof(zWideFilename[0]) );
if( zWideFilename==0 ){
return 0;
}
memset(zWideFilename, 0, nChar*sizeof(zWideFilename[0]));
nChar = MultiByteToWideChar(CP_UTF8, 0, zFilename, -1, zWideFilename,
nChar);
if( nChar==0 ){
sqlite3_free(zWideFilename);
zWideFilename = 0;
}
return zWideFilename;
}
#endif
/*
** The RBU handle is currently in RBU_STAGE_OAL state, with a SHARED lock
** on the database file. This proc moves the *-oal file to the *-wal path,
@@ -2416,10 +2444,37 @@ static void rbuMoveOalFile(sqlite3rbu *p){
rbuObjIterFinalize(&p->objiter);
sqlite3_close(p->dbMain);
sqlite3_close(p->dbRbu);
p->dbMain = 0;
p->dbRbu = 0;
#if defined(_WIN32_WCE)
{
LPWSTR zWideOal;
LPWSTR zWideWal;
zWideOal = rbuWinUtf8ToUnicode(zOal);
if( zWideOal ){
zWideWal = rbuWinUtf8ToUnicode(zWal);
if( zWideWal ){
if( MoveFileW(zWideOal, zWideWal) ){
p->rc = SQLITE_OK;
}else{
p->rc = SQLITE_IOERR;
}
sqlite3_free(zWideWal);
}else{
p->rc = SQLITE_IOERR_NOMEM;
}
sqlite3_free(zWideOal);
}else{
p->rc = SQLITE_IOERR_NOMEM;
}
}
#else
p->rc = rename(zOal, zWal) ? SQLITE_IOERR : SQLITE_OK;
#endif
if( p->rc==SQLITE_OK ){
p->dbMain = 0;
p->dbRbu = 0;
rbuOpenDatabase(p);
rbuSetupCheckpoint(p, 0);
}
+8
View File
@@ -269,6 +269,10 @@
#include "sqlite3.h" /* Required for error code definitions */
#ifdef __cplusplus
extern "C" {
#endif
typedef struct sqlite3rbu sqlite3rbu;
/*
@@ -447,4 +451,8 @@ int sqlite3rbu_create_vfs(const char *zName, const char *zParent);
*/
void sqlite3rbu_destroy_vfs(const char *zName);
#ifdef __cplusplus
} /* end of the 'extern "C"' block */
#endif
#endif /* _SQLITE3RBU_H */
+55
View File
@@ -34,6 +34,11 @@ set testprefix rtree1
#
# rtree-12.*: Test that on-conflict clauses are supported.
# rtree-13.*: Test that bug [d2889096e7bdeac6d] has been fixed.
# rtree-14.*: Test if a non-integer is inserted into the PK column of an
# r-tree table, it is converted to an integer before being
# inserted. Also that if a non-numeric is inserted into one
# of the min/max dimension columns, it is converted to the
# required type before being inserted.
#
ifcapable !rtree {
@@ -535,4 +540,54 @@ do_execsql_test 13.2 {
SELECT * FROM r CROSS JOIN t9 WHERE id=x;
} {1 1 0.0 0.0 2 2 0.0 0.0}
#-------------------------------------------------------------------------
# Test if a non-integer is inserted into the PK column of an r-tree
# table, it is converted to an integer before being inserted. Also
# that if a non-numeric is inserted into one of the min/max dimension
# columns, it is converted to the required type before being inserted.
#
do_execsql_test 14.1 {
CREATE VIRTUAL TABLE t10 USING rtree(ii, x1, x2);
}
do_execsql_test 14.2 {
INSERT INTO t10 VALUES(NULL, 1, 2);
INSERT INTO t10 VALUES(NULL, 2, 3);
INSERT INTO t10 VALUES('4xxx', 3, 4);
INSERT INTO t10 VALUES(5.0, 4, 5);
INSERT INTO t10 VALUES(6.4, 5, 6);
}
do_execsql_test 14.3 {
SELECT * FROM t10;
} {
1 1.0 2.0 2 2.0 3.0 4 3.0 4.0 5 4.0 5.0 6 5.0 6.0
}
do_execsql_test 14.4 {
DELETE FROM t10;
INSERT INTO t10 VALUES(1, 'one', 'two');
INSERT INTO t10 VALUES(2, '52xyz', '81...');
}
do_execsql_test 14.5 {
SELECT * FROM t10;
} {
1 0.0 0.0
2 52.0 81.0
}
do_execsql_test 14.4 {
DROP TABLE t10;
CREATE VIRTUAL TABLE t10 USING rtree_i32(ii, x1, x2);
INSERT INTO t10 VALUES(1, 'one', 'two');
INSERT INTO t10 VALUES(2, '52xyz', '81...');
INSERT INTO t10 VALUES(3, 42.3, 49.9);
}
do_execsql_test 14.5 {
SELECT * FROM t10;
} {
1 0 0
2 52 81
3 42 49
}
finish_test
+48 -29
View File
@@ -12,6 +12,8 @@
# THREADLIB Specify any extra linker options needed to make the library
# thread safe
#
# LIBS Extra libraries options
#
# OPTS Extra compiler command-line options.
#
# EXE The suffix to add to executable files. ".exe" for windows
@@ -35,9 +37,6 @@
# LIBREADLINE Linker options needed by programs using readline() must
# link against.
#
# NAWK Nawk compatible awk program. Older (obsolete?) solaris
# systems need this to avoid using the original AT&T AWK.
#
# Once the macros above are defined, the rest of this make script will
# build the SQLite library and testing tools.
################################################################################
@@ -48,19 +47,21 @@ TCCX = $(TCC) $(OPTS) -I. -I$(TOP)/src -I$(TOP)
TCCX += -I$(TOP)/ext/rtree -I$(TOP)/ext/icu -I$(TOP)/ext/fts3
TCCX += -I$(TOP)/ext/async -I$(TOP)/ext/userauth
TCCX += -I$(TOP)/ext/fts5
THREADLIB += $(LIBS)
# Object files for the SQLite library.
#
LIBOBJ+= vdbe.o parse.o \
alter.o analyze.o attach.o auth.o \
backup.o bitvec.o btmutex.o btree.o build.o \
callback.o complete.o ctime.o date.o dbstat.o delete.o expr.o fault.o fkey.o \
callback.o complete.o ctime.o date.o dbstat.o delete.o expr.o \
fault.o fkey.o \
fts3.o fts3_aux.o fts3_expr.o fts3_hash.o fts3_icu.o fts3_porter.o \
fts3_snippet.o fts3_tokenizer.o fts3_tokenizer1.o \
fts3_tokenize_vtab.o \
fts3_unicode.o fts3_unicode2.o \
fts3_write.o func.o global.o hash.o \
icu.o insert.o journal.o legacy.o loadext.o \
fts3_write.o fts5.o func.o global.o hash.o \
icu.o insert.o journal.o json1.o legacy.o loadext.o \
main.o malloc.o mem0.o mem1.o mem2.o mem3.o mem5.o \
memjournal.o \
mutex.o mutex_noop.o mutex_unix.o mutex_w32.o \
@@ -225,10 +226,11 @@ SRC += \
SRC += \
$(TOP)/ext/userauth/userauth.c \
$(TOP)/ext/userauth/sqlite3userauth.h
SRC += \
$(TOP)/ext/rbu/sqlite3rbu.c \
$(TOP)/ext/rbu/sqlite3rbu.h
SRC += \
$(TOP)/ext/misc/json1.c
# FTS5 things
@@ -321,7 +323,6 @@ TESTSRC += \
$(TOP)/ext/misc/fileio.c \
$(TOP)/ext/misc/fuzzer.c \
$(TOP)/ext/misc/ieee754.c \
$(TOP)/ext/misc/json1.c \
$(TOP)/ext/misc/nextchar.c \
$(TOP)/ext/misc/percentile.c \
$(TOP)/ext/misc/regexp.c \
@@ -331,8 +332,7 @@ TESTSRC += \
$(TOP)/ext/misc/wholenumber.c \
$(TOP)/ext/misc/vfslog.c \
$(TOP)/ext/fts5/fts5_tcl.c \
$(TOP)/ext/fts5/fts5_test_mi.c \
fts5.c
$(TOP)/ext/fts5/fts5_test_mi.c
#TESTSRC += $(TOP)/ext/fts2/fts2_tokenizer.c
@@ -379,7 +379,7 @@ TESTSRC2 = \
$(TOP)/ext/fts3/fts3_expr.c \
$(TOP)/ext/fts3/fts3_tokenizer.c \
$(TOP)/ext/fts3/fts3_write.c \
$(TOP)/ext/async/sqlite3async.c
$(TOP)/ext/async/sqlite3async.c
# Header files used by all library source files.
#
@@ -448,12 +448,19 @@ TESTPROGS = \
FUZZDATA = \
$(TOP)/test/fuzzdata1.db \
$(TOP)/test/fuzzdata2.db \
$(TOP)/test/fuzzdata3.db
$(TOP)/test/fuzzdata3.db \
$(TOP)/test/fuzzdata4.db
# Standard options to testfixture
#
TESTOPTS = --verbose=file --output=test-out.txt
# Extra compiler options for various shell tools
#
SHELL_OPT = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_FTS5
FUZZERSHELL_OPT = -DSQLITE_ENABLE_JSON1
FUZZCHECK_OPT = -DSQLITE_ENABLE_JSON1
# This is the default Makefile target. The objects listed here
# are what get build when you type just "make" with no arguments.
#
@@ -463,10 +470,9 @@ libsqlite3.a: $(LIBOBJ)
$(AR) libsqlite3.a $(LIBOBJ)
$(RANLIB) libsqlite3.a
sqlite3$(EXE): $(TOP)/src/shell.c libsqlite3.a sqlite3.h $(TOP)/ext/misc/json1.c
$(TCCX) $(READLINE_FLAGS) -DSQLITE_ENABLE_JSON1 -o sqlite3$(EXE) \
$(TOP)/src/shell.c $(TOP)/ext/misc/json1.c \
libsqlite3.a $(LIBREADLINE) $(TLIBS) $(THREADLIB)
sqlite3$(EXE): $(TOP)/src/shell.c libsqlite3.a sqlite3.h
$(TCCX) $(READLINE_FLAGS) -o sqlite3$(EXE) $(SHELL_OPT) \
$(TOP)/src/shell.c libsqlite3.a $(LIBREADLINE) $(TLIBS) $(THREADLIB)
sqldiff$(EXE): $(TOP)/tool/sqldiff.c sqlite3.c sqlite3.h
$(TCCX) -o sqldiff$(EXE) -DSQLITE_THREADSAFE=0 \
@@ -474,11 +480,12 @@ sqldiff$(EXE): $(TOP)/tool/sqldiff.c sqlite3.c sqlite3.h
fuzzershell$(EXE): $(TOP)/tool/fuzzershell.c sqlite3.c sqlite3.h
$(TCCX) -o fuzzershell$(EXE) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION \
$(TOP)/tool/fuzzershell.c sqlite3.c $(TLIBS) $(THREADLIB)
$(FUZZERSHELL_OPT) $(TOP)/tool/fuzzershell.c sqlite3.c \
$(TLIBS) $(THREADLIB)
fuzzcheck$(EXE): $(TOP)/test/fuzzcheck.c sqlite3.c sqlite3.h
$(TCCX) -o fuzzcheck$(EXE) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION \
-DSQLITE_ENABLE_MEMSYS5 \
-DSQLITE_ENABLE_MEMSYS5 $(FUZZCHECK_OPT) \
$(TOP)/test/fuzzcheck.c sqlite3.c $(TLIBS) $(THREADLIB)
mptester$(EXE): sqlite3.c $(TOP)/mptest/mptest.c
@@ -507,13 +514,14 @@ sqlite3.o: sqlite3.c
# files are automatically generated. This target takes care of
# all that automatic generation.
#
target_source: $(SRC) $(TOP)/tool/vdbe-compress.tcl
target_source: $(SRC) $(TOP)/tool/vdbe-compress.tcl fts5.c
rm -rf tsrc
mkdir tsrc
cp -f $(SRC) tsrc
rm tsrc/sqlite.h.in tsrc/parse.y
tclsh $(TOP)/tool/vdbe-compress.tcl $(OPTS) <tsrc/vdbe.c >vdbe.new
mv vdbe.new tsrc/vdbe.c
cp fts5.c fts5.h tsrc
touch target_source
sqlite3.c: target_source $(TOP)/tool/mksqlite3c.tcl
@@ -524,6 +532,9 @@ sqlite3.c: target_source $(TOP)/tool/mksqlite3c.tcl
echo '#endif /* USE_SYSTEM_SQLITE */' >>tclsqlite3.c
cat $(TOP)/src/tclsqlite.c >>tclsqlite3.c
sqlite3ext.h: target_source
cp tsrc/sqlite3ext.h .
sqlite3.c-debug: target_source $(TOP)/tool/mksqlite3c.tcl
tclsh $(TOP)/tool/mksqlite3c.tcl --linemacros
echo '#ifndef USE_SYSTEM_SQLITE' >tclsqlite3.c
@@ -568,23 +579,23 @@ tclsqlite.o: $(TOP)/src/tclsqlite.c $(HDR)
# Rules to build opcodes.c and opcodes.h
#
opcodes.c: opcodes.h $(TOP)/mkopcodec.awk
$(NAWK) -f $(TOP)/mkopcodec.awk opcodes.h >opcodes.c
opcodes.c: opcodes.h $(TOP)/tool/mkopcodec.tcl
tclsh $(TOP)/tool/mkopcodec.tcl opcodes.h >opcodes.c
opcodes.h: parse.h $(TOP)/src/vdbe.c $(TOP)/mkopcodeh.awk
opcodes.h: parse.h $(TOP)/src/vdbe.c $(TOP)/tool/mkopcodeh.tcl
cat parse.h $(TOP)/src/vdbe.c | \
$(NAWK) -f $(TOP)/mkopcodeh.awk >opcodes.h
tclsh $(TOP)/tool/mkopcodeh.tcl >opcodes.h
# Rules to build parse.c and parse.h - the outputs of lemon.
#
parse.h: parse.c
parse.c: $(TOP)/src/parse.y lemon $(TOP)/addopcodes.awk
parse.c: $(TOP)/src/parse.y lemon $(TOP)/tool/addopcodes.tcl
cp $(TOP)/src/parse.y .
rm -f parse.h
./lemon $(OPTS) parse.y
./lemon -s $(OPTS) parse.y
mv parse.h parse.h.temp
$(NAWK) -f $(TOP)/addopcodes.awk parse.h.temp >parse.h
tclsh $(TOP)/tool/addopcodes.tcl parse.h.temp >parse.h
sqlite3.h: $(TOP)/src/sqlite.h.in $(TOP)/manifest.uuid $(TOP)/VERSION $(TOP)/ext/rtree/sqlite3rtree.h
tclsh $(TOP)/tool/mksqlite3h.tcl $(TOP) >sqlite3.h
@@ -657,9 +668,17 @@ fts3_unicode2.o: $(TOP)/ext/fts3/fts3_unicode2.c $(HDR) $(EXTHDR)
fts3_write.o: $(TOP)/ext/fts3/fts3_write.c $(HDR) $(EXTHDR)
$(TCCX) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_write.c
fts5.o: fts5.c
$(TCCX) -DSQLITE_CORE -c fts5.c
json1.o: $(TOP)/ext/misc/json1.c
$(TCCX) -DSQLITE_CORE -c $(TOP)/ext/misc/json1.c
rtree.o: $(TOP)/ext/rtree/rtree.c $(HDR) $(EXTHDR)
$(TCCX) -DSQLITE_CORE -c $(TOP)/ext/rtree/rtree.c
fts5parse.c: $(TOP)/ext/fts5/fts5parse.y lemon
cp $(TOP)/ext/fts5/fts5parse.y .
rm -f fts5parse.h
@@ -690,7 +709,7 @@ sqlite3_analyzer.c: sqlite3.c $(TOP)/src/tclsqlite.c $(TOP)/tool/spaceanal.tcl
cat sqlite3.c $(TOP)/src/tclsqlite.c >> $@
echo "static const char *tclsh_main_loop(void){" >> $@
echo "static const char *zMainloop = " >> $@
$(NAWK) -f $(TOP)/tool/tostr.awk $(TOP)/tool/spaceanal.tcl >> $@
tclsh $(TOP)/tool/tostr.tcl $(TOP)/tool/spaceanal.tcl >> $@
echo "; return zMainloop; }" >> $@
sqlite3_analyzer$(EXE): sqlite3_analyzer.c
@@ -706,9 +725,9 @@ testfixture$(EXE): $(TESTSRC2) libsqlite3.a $(TESTSRC) $(TOP)/src/tclsqlite.c
$(TESTSRC) $(TESTSRC2) $(TOP)/src/tclsqlite.c \
-o testfixture$(EXE) $(LIBTCL) libsqlite3.a $(THREADLIB)
amalgamation-testfixture$(EXE): sqlite3.c fts5.c $(TESTSRC) $(TOP)/src/tclsqlite.c
amalgamation-testfixture$(EXE): sqlite3.c $(TESTSRC) $(TOP)/src/tclsqlite.c
$(TCCX) $(TCL_FLAGS) -DTCLSH=1 $(TESTFIXTURE_FLAGS) \
$(TESTSRC) $(TOP)/src/tclsqlite.c sqlite3.c fts5.c \
$(TESTSRC) $(TOP)/src/tclsqlite.c sqlite3.c \
-o testfixture$(EXE) $(LIBTCL) $(THREADLIB)
fts3-testfixture$(EXE): sqlite3.c fts3amal.c $(TESTSRC) $(TOP)/src/tclsqlite.c
+170 -159
View File
@@ -1,24 +1,21 @@
C Merge\strunk\senhancements,\sand\sespeically\sthe\sfix\sfor\sallowing\sstrings\s\nas\scolumn\sidentifers\sin\sCREATE\sINDEX\sstatements.
D 2015-09-04T13:02:21.922
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in f85066ce844a28b671aaeeff320921cd0ce36239
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
F Makefile.msc b268d8be2e800b9d35f074b1ed6b2f698deebdd6
F Makefile.vxworks e1b65dea203f054e71653415bd8f96dcaed47858
C Fix\scompiler\swarnings.
D 2015-10-20T23:40:19.437
F Makefile.in 2ea961bc09e441874eb3d1bf7398e04feb24f3ee
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
F Makefile.msc 4eb750e0fdf52050a06d881e1b060f4bb116ed7e
F README.md 8ecc12493ff9f820cdea6520a9016001cb2e59b7
F VERSION ccfc4d1576dbfdeece0a4372a2e6a2e37d3e7975
F VERSION a47917b59f38b632b3a8662d14fd20f94956bdd0
F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50
F addopcodes.awk 9eb448a552d5c0185cf62c463f9c173cedae3811
F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2
F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90
F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2
F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903
F autoconf/Makefile.am 27de1af382c82e81f1fe36a7f38528fba004eb1a
F autoconf/Makefile.am bd4a90972aa87f079af6624ddea3df3d58f26d2f
F autoconf/README 14458f1046c118efa721aadec5f227e876d3cd38
F autoconf/README.first 6c4f34fe115ff55d4e8dbfa3cecf04a0188292f7
F autoconf/config.guess 94cc57e2a3fdb9c235b362ace86d77e89d188cad x
F autoconf/config.sub 1efb390a8fb4bfafd74783a15a8fb5311c84300e x
F autoconf/configure.ac ba3e99ba1a8171d0682b68443517088fc5d6f13a
F autoconf/configure.ac a1fe4eee429fd9d3170be41941514a2b7120ba4e
F autoconf/depcomp 0b26f101e3bc9fd1ff0be1da9fb4a82371142f92 x
F autoconf/install-sh 06ee6336e63bb845c8439d777c32eb2eccc4fbf1 x
F autoconf/ltmain.sh 7a658a24028f02331c1d2446562758083c5eadd1
@@ -38,8 +35,8 @@ F autoconf/tea/win/rules.vc c511f222b80064096b705dbeb97060ee1d6b6d63
F config.guess 226d9a188c6196f3033ffc651cbc9dcee1a42977
F config.h.in 42b71ad3fe21c9e88fa59e8458ca1a6bc72eb0c0
F config.sub 9ebe4c3b3dab6431ece34f16828b594fb420da55
F configure 2f61915a1bdfbc589244334401cf97d3401e6a39 x
F configure.ac 713de38000413e469188db2cb85bed759b56f322
F configure 762a66c6eb9331f8af21f5d00b610bd61eaf8e14 x
F configure.ac f36bd4fb8c53eed8374c5a5ef319807c08c23fa9
F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad
F doc/lemon.html 334dbf6621b8fb8790297ec1abf3cfa4621709d1
F doc/pager-invariants.txt 27fed9a70ddad2088750c4a2b493b63853da2710
@@ -78,11 +75,11 @@ F ext/fts3/README.content fdc666a70d5257a64fee209f97cf89e0e6e32b51
F ext/fts3/README.syntax a19711dc5458c20734b8e485e75fb1981ec2427a
F ext/fts3/README.tokenizers e0a8b81383ea60d0334d274fadf305ea14a8c314
F ext/fts3/README.txt 8c18f41574404623b76917b9da66fcb0ab38328d
F ext/fts3/fts3.c b04b0c57761fdba2ae562d9d9ba50c7c4a95d9ea
F ext/fts3/fts3.c e028eb13432f108d2e22cded019fc980700e4e00
F ext/fts3/fts3.h 3a10a0af180d502cecc50df77b1b22df142817fe
F ext/fts3/fts3Int.h 601743955ac43a0e82e6828a931c07bb3b0c95ff
F ext/fts3/fts3Int.h c84125c666ee54cef6efce6ff64abb0d0e2f4535
F ext/fts3/fts3_aux.c 9edc3655fcb287f0467d0a4b886a01c6185fe9f1
F ext/fts3/fts3_expr.c 71c063da9c2a4167fb54aec089dd5ef33a58c9cb
F ext/fts3/fts3_expr.c dfd571a24412779ac01f25c01d888c6ef7b2d0ef
F ext/fts3/fts3_hash.c 29b986e43f4e9dd40110eafa377dc0d63c422c60
F ext/fts3/fts3_hash.h 39cf6874dc239d6b4e30479b1975fe5b22a3caaf
F ext/fts3/fts3_icu.c deb46f7020d87ea7a14a433fb7a7f4bef42a9652
@@ -96,7 +93,7 @@ F ext/fts3/fts3_tokenizer.h 64c6ef6c5272c51ebe60fc607a896e84288fcbc3
F ext/fts3/fts3_tokenizer1.c 5c98225a53705e5ee34824087478cf477bdb7004
F ext/fts3/fts3_unicode.c a93f5edc0aff44ef8b06d7cb55b52026541ca145
F ext/fts3/fts3_unicode2.c c3d01968d497bd7001e7dc774ba75b372738c057
F ext/fts3/fts3_write.c 4f005f78592a1447ca96c8475ef5342ab7dbe02a
F ext/fts3/fts3_write.c f442223e4a1914dc1fc12b65af7e4f2c255fa47c
F ext/fts3/fts3speed.tcl b54caf6a18d38174f1a6e84219950d85e98bb1e9
F ext/fts3/mkfts3amal.tcl 252ecb7fe6467854f2aa237bf2c390b74e71f100
F ext/fts3/tool/fts3view.c 8e53d0190a7b3443764bbd32ad47be2bd852026d
@@ -105,29 +102,29 @@ F ext/fts3/unicode/UnicodeData.txt cd07314edb62d49fde34debdaf92fa2aa69011e7
F ext/fts3/unicode/mkunicode.tcl 95cf7ec186e48d4985e433ff8a1c89090a774252
F ext/fts3/unicode/parseunicode.tcl da577d1384810fb4e2b209bf3313074353193e95
F ext/fts5/extract_api_docs.tcl a36e54ec777172ddd3f9a88daf593b00848368e0
F ext/fts5/fts5.h f04659e0df5af83731b102189a32280f74f4a6bc
F ext/fts5/fts5Int.h f65d41f66accad0a289d6bd66b13c07d2932f9be
F ext/fts5/fts5_aux.c 7a307760a9c57c750d043188ec0bad59f5b5ec7e
F ext/fts5/fts5_buffer.c 80f9ba4431848cb857e3d2158f5280093dcd8015
F ext/fts5/fts5_config.c 80b61fd2c6844b64a3e72a64572d50a812da9384
F ext/fts5/fts5_expr.c 1c24e1a2ffb286bfe37e537a43b7fadabfe993d4
F ext/fts5/fts5_hash.c 4bf4b99708848357b8a2b5819e509eb6d3df9246
F ext/fts5/fts5_index.c 950e37028cc81ae21534819e79c73aea7efa6c8e
F ext/fts5/fts5_main.c e9d0892424bb7f0a8b58613d4ff75cb650cf286e
F ext/fts5/fts5_storage.c 120f7b143688b5b7710dacbd48cff211609b8059
F ext/fts5/fts5_tcl.c 6da58d6e8f42a93c4486b5ba9b187a7f995dee37
F ext/fts5/fts5.h 8b9a13b309b180e9fb88ea5666c0d8d73c6102d9
F ext/fts5/fts5Int.h db1d5a18bae953c749198fe6d87862055ef55a1d
F ext/fts5/fts5_aux.c 1f384972d606375b8fa078319f25ab4b5feb1b35
F ext/fts5/fts5_buffer.c 6d4082daa71eef87812b8caa9d60ae57a6a9ebc0
F ext/fts5/fts5_config.c 88a77f5d5e4dfbb2355b8f6cc9969b7f02d94685
F ext/fts5/fts5_expr.c 28b15c9ae296204bc0a2e5cf7a667d840a9d2900
F ext/fts5/fts5_hash.c a9d4c1efebc2a91d26ad7ebdfcbf2678ceac405f
F ext/fts5/fts5_index.c d3503c75d329f027140b855149566c97c078c18d
F ext/fts5/fts5_main.c 520a29136ba07448331f73bdc36d0ffa1e9dcfef
F ext/fts5/fts5_storage.c 8038a54a88d3beb94dc7f9db6428a3bc08b718bb
F ext/fts5/fts5_tcl.c 3bf445e66de32137d4693694ff7b1fd6074e32bd
F ext/fts5/fts5_test_mi.c e96be827aa8f571031e65e481251dc1981d608bf
F ext/fts5/fts5_tokenize.c f380f46f341af9c9a9908e1aade685ba1eaa157a
F ext/fts5/fts5_tokenize.c 12c5d925286491a71bb3dad7c8924ce9cfd18320
F ext/fts5/fts5_unicode2.c 78273fbd588d1d9bd0a7e4e0ccc9207348bae33c
F ext/fts5/fts5_varint.c 3f86ce09cab152e3d45490d7586b7ed2e40c13f1
F ext/fts5/fts5_vocab.c 4622e0b7d84a488a1585aaa56eb214ee67a988bc
F ext/fts5/fts5parse.y 833db1101b78c0c47686ab1b84918e38c36e9452
F ext/fts5/fts5_vocab.c fc319264ebbf1b4518afd9cacd3801ac526536d8
F ext/fts5/fts5parse.y e83dca6028e3309178d05b5bd920e372dc295d35
F ext/fts5/mkportersteps.tcl 5acf962d2e0074f701620bb5308155fa1e4a63ba
F ext/fts5/test/fts5_common.tcl b6e6a40ef5d069c8e86ca4fbad491e1195485dbc
F ext/fts5/test/fts5aa.test f558e1e5ccffa75d69e9a4814245d468ec6b6608
F ext/fts5/test/fts5_common.tcl 51f7ef3af444b89c6f6ce3896a0ac349ff4e996d
F ext/fts5/test/fts5aa.test 34ad813e9e958115d388658b2c4a8dde6b1474a5
F ext/fts5/test/fts5ab.test 6fe3a56731d15978afbb74ae51b355fc9310f2ad
F ext/fts5/test/fts5ac.test 9737992d08c56bfd4803e933744d2d764e23795c
F ext/fts5/test/fts5ad.test b2edee8b7de0c21d2c88f8a18c195034aad6952d
F ext/fts5/test/fts5ad.test e3dfb150fce971b4fd832498c29f56924d451b63
F ext/fts5/test/fts5ae.test 0a9984fc3479f89f8c63d9848d6ed0c465dfcebe
F ext/fts5/test/fts5af.test c2501ec2b61d6b179c305f5d2b8782ab3d4f832a
F ext/fts5/test/fts5ag.test ec3e119b728196620a31507ef503c455a7a73505
@@ -135,7 +132,7 @@ F ext/fts5/test/fts5ah.test e592c4978622dbc4de552cd0f9395df60ac5d54c
F ext/fts5/test/fts5ai.test f20e53bbf0c55bc596f1fd47f2740dae028b8f37
F ext/fts5/test/fts5aj.test 05b569f5c16ea3098fb1984eec5cf50dbdaae5d8
F ext/fts5/test/fts5ak.test 7b8c5df96df599293f920b7e5521ebc79f647592
F ext/fts5/test/fts5al.test 440d77c0b39ba73bad2ceb8986c2bb1093570735
F ext/fts5/test/fts5al.test a1b7b6393376bc2adc216527a28f5ae5594069df
F ext/fts5/test/fts5alter.test 6022c61467a82aa11c70822ccad22b328dcf0d04
F ext/fts5/test/fts5auto.test caa5bcf917db11944655a2a9bd38c67c520376ca
F ext/fts5/test/fts5aux.test 8c687c948cc98e9a94be014df7d518acc1b3b74f
@@ -144,10 +141,10 @@ F ext/fts5/test/fts5bigpl.test 04ee0d7eebbebf17c31f5a0b5c5f9494eac3a0cb
F ext/fts5/test/fts5columnsize.test a8cfef21ffa1c264b9f670a7d94eeaccb5341c07
F ext/fts5/test/fts5config.test ad2ff42ddc856aed2d05bf89dc1c578c8a39ea3b
F ext/fts5/test/fts5content.test 9a952c95518a14182dc3b59e3c8fa71cda82a4e1
F ext/fts5/test/fts5corrupt.test 928c9c91d40690d301f943a7ed0ffc19e0d0e7b6
F ext/fts5/test/fts5corrupt2.test 1a830ccd6dbe1b601c7e3f5bbc1cf77bd8c8803b
F ext/fts5/test/fts5corrupt3.test 1ccf575f5126e79f9fec7979fd02a1f40a076be3
F ext/fts5/test/fts5dlidx.test 59b80bbe34169a082c575d9c26f0a7019a7b79c1
F ext/fts5/test/fts5corrupt.test c2ad090192708150d50d961278df10ae7a4b8b62
F ext/fts5/test/fts5corrupt2.test 26c0a39dd9ff73207e6229f83b50b21d37c7658c
F ext/fts5/test/fts5corrupt3.test a2b537c120bdd43c79c42fe2438d7b8c81fe5599
F ext/fts5/test/fts5dlidx.test ecba5e62ea8b26c33829961602069c546228046d
F ext/fts5/test/fts5doclist.test 8edb5b57e5f144030ed74ec00ef6fa4294fed79b
F ext/fts5/test/fts5ea.test b01e3a18cdfabbff8104a96a5242a06a68a998a0
F ext/fts5/test/fts5eb.test 3e5869af2008cbc4ad03a175a0b6f6e58134cd43
@@ -155,34 +152,38 @@ F ext/fts5/test/fts5fault1.test 7a562367cb4a735b57b410dbdb62dcc8d971faec
F ext/fts5/test/fts5fault2.test 28c36c843bb39ae855ba79827417ecc37f114341
F ext/fts5/test/fts5fault3.test d6e9577d4312e331a913c72931bf131704efc8f3
F ext/fts5/test/fts5fault4.test 762991d526ee67c2b374351a17248097ea38bee7
F ext/fts5/test/fts5fault5.test 54da9fd4c3434a1d4f6abdcb6469299d91cf5875
F ext/fts5/test/fts5fault6.test 97bce1a36b7a64e3203fea504ae8e5cfd5ada423
F ext/fts5/test/fts5fault7.test f4a9b796f8b20c78ec7cf9f4e11144d15d7c3fd4
F ext/fts5/test/fts5fault5.test f2b8645053d48982e8979749e93994c43011c118
F ext/fts5/test/fts5fault6.test 9682664d679643ac6736e90c225526cc84073cda
F ext/fts5/test/fts5fault7.test 01be274bfc8d9bf22451a3bf5892e9399d044f1b
F ext/fts5/test/fts5full.test 6f6143af0c6700501d9fd597189dfab1555bb741
F ext/fts5/test/fts5hash.test 42eb066f667e9a389a63437cb7038c51974d4fc6
F ext/fts5/test/fts5hash.test 7cf4607b8657c383f0b520668a99971e95d8b139
F ext/fts5/test/fts5integrity.test 29f41d2c7126c6122fbb5d54e556506456876145
F ext/fts5/test/fts5matchinfo.test 2163b0013e824bba65499da9e34ea4da41349cc2
F ext/fts5/test/fts5merge.test 8f3cdba2ec9c5e7e568246e81b700ad37f764367
F ext/fts5/test/fts5near.test b214cddb1c1f1bddf45c75af768f20145f7e71cc
F ext/fts5/test/fts5onepass.test 7ed9608e258132cb8d55e7c479b08676ad68810c
F ext/fts5/test/fts5optimize.test 42741e7c085ee0a1276140a752d4407d97c2c9f5
F ext/fts5/test/fts5phrase.test f6d1d464da5beb25dc56277aa4f1d6102f0d9a2f
F ext/fts5/test/fts5plan.test 6a55ecbac9890765b0e16f8c421c7e0888cfe436
F ext/fts5/test/fts5porter.test 7cdc07bef301d70eebbfa75dcaf45c3680e1d0e1
F ext/fts5/test/fts5porter2.test 2e65633d58a1c525d5af0f6c01e5a59155bb3487
F ext/fts5/test/fts5prefix.test 552a462f0e8595676611f41643de217fb4ac2808
F ext/fts5/test/fts5prefix.test 7ccbdf180ed561a912acef520519e85af8642239
F ext/fts5/test/fts5rank.test 11dcebba31d822f7e99685b4ea2c2ae3ec0b16f1
F ext/fts5/test/fts5rebuild.test 03935f617ace91ed23a6099c7c74d905227ff29b
F ext/fts5/test/fts5restart.test c17728fdea26e7d0f617d22ad5b4b2862b994c17
F ext/fts5/test/fts5rowid.test 6f9833b23b176dc4aa15b7fc02afeb2b220fd460
F ext/fts5/test/fts5rowid.test 400384798349d658eaf06aefa1e364957d5d4821
F ext/fts5/test/fts5simple.test 41333e267c6145efc3620342af53dfe65d5676b7
F ext/fts5/test/fts5synonym.test cf88c0a56d5ea9591e3939ef1f6e294f7f2d0671
F ext/fts5/test/fts5tokenizer.test ea4df698b35cc427ebf2ba22829d0e28386d8c89
F ext/fts5/test/fts5unicode.test fbef8d8a3b4b88470536cc57604a82ca52e51841
F ext/fts5/test/fts5unicode2.test c1dd890ba32b7609adba78e420faa847abe43b59
F ext/fts5/test/fts5unicode3.test 35c3d02aa7acf7d43d8de3bfe32c15ba96e8928e
F ext/fts5/test/fts5unindexed.test e9539d5b78c677315e7ed8ea911d4fd25437c680
F ext/fts5/test/fts5version.test 205beb2a67d9496af64df959e6a19238f69b83e8
F ext/fts5/test/fts5vocab.test cdf97b9678484e9bad5062edf9c9106e5c3b0c5c
F ext/fts5/tool/loadfts5.tcl 95edf0b6b92a09f9ed85595038b1108127987556
F ext/fts5/tool/mkfts5c.tcl 5745072c7de346e18c7f491e4c3281fe8a1cfe51
F ext/fts5/test/fts5version.test 978f59541d8cef7e8591f8be2115ec5ccb863e2e
F ext/fts5/test/fts5vocab.test c88a5554d0409494da95ba647bbdb4879b2624b0
F ext/fts5/tool/fts5txt2db.tcl c374c4c4797e8cdfadabdfaeeb5412dcd6686e84
F ext/fts5/tool/loadfts5.tcl 58e90407cc5c2b1770460119488fd7c0090d4dd3
F ext/fts5/tool/mkfts5c.tcl d1c2a9ab8e0ec690a52316f33dd9b1d379942f45
F ext/fts5/tool/showfts5.tcl 9eaf6c3df352f98a2ab5ce1921dd94128ab1381d
F ext/icu/README.txt d9fbbad0c2f647c3fdf715fc9fd64af53aedfc43
F ext/icu/icu.c b2732aef0b076e4276d9b39b5a33cec7a05e1413
@@ -194,7 +195,7 @@ F ext/misc/eval.c f971962e92ebb8b0a4e6b62949463ee454d88fa2
F ext/misc/fileio.c d4171c815d6543a9edef8308aab2951413cd8d0f
F ext/misc/fuzzer.c 4c84635c71c26cfa7c2e5848cf49fe2d2cfcd767
F ext/misc/ieee754.c b0362167289170627659e84173f5d2e8fee8566e
F ext/misc/json1.c bd51e8c1e8ce580e6f21493bd8e94ed5aca3d777
F ext/misc/json1.c 4f45afd9dbcd6feca8c528251efbb7fc09299a09
F ext/misc/nextchar.c 35c8b8baacb96d92abbb34a83a997b797075b342
F ext/misc/percentile.c bcbee3c061b884eccb80e21651daaae8e1e43c63
F ext/misc/regexp.c af92cdaa5058fcec1451e49becc7ba44dba023dc
@@ -228,13 +229,13 @@ F ext/rbu/rbufault.test cc0be8d5d392d98b0c2d6a51be377ea989250a89
F ext/rbu/rbufault2.test 9a7f19edd6ea35c4c9f807d8a3db0a03a5670c06
F ext/rbu/rbufts.test 828cd689da825f0a7b7c53ffc1f6f7fdb6fa5bda
F ext/rbu/rbusave.test 0f43b6686084f426ddd040b878426452fd2c2f48
F ext/rbu/sqlite3rbu.c 4ba82bd850aa012f73c31dd242d570f18c9cc35a
F ext/rbu/sqlite3rbu.h 5357f070cd8c0bcad459b620651ec1656859e4d0
F ext/rbu/sqlite3rbu.c ea47de615e911b3a69a8e7fb3be3866298403a25
F ext/rbu/sqlite3rbu.h 1d568cb33738d7900975cc5c72e6f68049f15914
F ext/rbu/test_rbu.c 2a3652241fa45d5eaa141775e4ae68c1d3582c03
F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761
F ext/rtree/rtree.c 0f9b595bd0debcbedf1d7a63d0e0678d619e6c9c
F ext/rtree/rtree.h 834dbcb82dc85b2481cde6a07cdadfddc99e9b9e
F ext/rtree/rtree1.test 541bbcab74613907fea08b2ecdcdd5b7aa724cc9
F ext/rtree/rtree1.test 96a80c08440c932cd72aac50660e7af2612d2cda
F ext/rtree/rtree2.test acbb3a4ce0f4fbc2c304d2b4b784cfa161856bba
F ext/rtree/rtree3.test a494da55c30ee0bc9b01a91c80c81b387b22d2dc
F ext/rtree/rtree4.test c8fe384f60ebd49540a5fecc990041bf452eb6e0
@@ -260,9 +261,7 @@ F ext/userauth/userauth.c 5fa3bdb492f481bbc1709fc83c91ebd13460c69e
F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x
F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8
F magic.txt 8273bf49ba3b0c8559cb2774495390c31fd61c60
F main.mk 61821e43596648bfacce2d6283377bee35986131
F mkopcodec.awk c2ff431854d702cdd2d779c9c0d1f58fa16fa4ea
F mkopcodeh.awk 0e7f04a8eb90f92259e47d80110e4e98d7ce337a
F main.mk 47b879ad92fe896895dcfc1bbec5c119ee2aa690
F mkso.sh fd21c06b063bb16a5d25deea1752c2da6ac3ed83
F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271
F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504
@@ -274,82 +273,82 @@ F spec.template 86a4a43b99ebb3e75e6b9a735d5fd293a24e90ca
F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b
F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786
F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a
F src/alter.c 4911e1f18fc11b60edbc6410643e938762969a6a
F src/alter.c 9d649e46c780166e416fb11dbd23f8d49aab8267
F src/analyze.c 4c308880cf53c558070cb8513bdff4ffb1a38a77
F src/attach.c e944d0052b577703b9b83aac1638452ff42a8395
F src/auth.c b56c78ebe40a2110fd361379f7e8162d23f92240
F src/backup.c 4d9134dc988a87838c06056c89c0e8c4700a0452
F src/backup.c c3a9c4209439b806c44cf30daf466955727bf46c
F src/bitvec.c d1f21d7d91690747881f03940584f4cc548c9d3d
F src/btmutex.c 45a968cc85afed9b5e6cf55bf1f42f8d18107f79
F src/btree.c 4084d9eed2817331f6e6a82230ba30e448cad497
F src/btree.h 969adc948e89e449220ff0ff724c94bb2a52e9f1
F src/btree.c ea8c62f65e57e49bd6b0988cd681aca7246b51af
F src/btree.h 40189aefdc2b830d25c8b58fd7d56538481bfdd7
F src/btreeInt.h 8177c9ab90d772d6d2c6c517e05bed774b7c92c0
F src/build.c 5566b3410080a54e5c302c55d3de53fd080cfc7d
F src/build.c d6162335d690396dfc5c4bd59e8b2b0c14ba6285
F src/callback.c 7b44ce59674338ad48b0e84e7b72f935ea4f68b0
F src/complete.c addcd8160b081131005d5bc2d34adf20c1c5c92f
F src/ctime.c 5a0b735dc95604766f5dac73973658eef782ee8b
F src/ctime.c 509ef9c64d1321f42448f111da86400b1799218a
F src/date.c fb1c99172017dcc8e237339132c91a21a0788584
F src/dbstat.c f402e77e25089c6003d0c60b3233b9b3947d599a
F src/delete.c 6792c80d7fb54c4df9f7680413952600e7439492
F src/expr.c f3c4d165dea72b268a7b922d00035af1d510dd78
F src/dbstat.c e637e7a7ff40ef32132a418c6fdf1cfb63aa27c7
F src/delete.c 35c939eb8bacc9dd8a6715964e5f69feb8c20e44
F src/expr.c d9896fda47a8f67d0ed203e1fa981444424200c6
F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
F src/fkey.c 83e1baba999bed3144ea5a2143fc922edf51135f
F src/fkey.c 31900763094a3736a5fc887469202eb579fef2d0
F src/func.c ecdd69ec6a1e406f04cc73324be2ebbf6354197f
F src/global.c 508e4087f7b41d688e4762dcf4d4fe28cfbc87f9
F src/hash.c 4263fbc955f26c2e8cdc0cf214bc42435aa4e4f5
F src/hash.h c8f3c31722cf3277d03713909761e152a5b81094
F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08
F src/insert.c 076dc5876e261a9908603d54cfc5344cd680166c
F src/insert.c 6dadbb671c2cc035ddbbf11a0b0209185d5bfe2c
F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d
F src/legacy.c ba1863ea58c4c840335a84ec276fc2b25e22bc4e
F src/lempar.c 92bafa308607dd985ca389a788cd9e0a2b608712
F src/loadext.c dfcee8c7c032cd0fd55af3e0fc1fcfb01e426df2
F src/main.c e17fcffae4306a9b8334faf3bac80d7396850b54
F src/malloc.c 021012e28a81ffdabf4c30ec3df6ce1f6cc93f1d
F src/lempar.c d344a95d60c24e2f490ee59db9784b1b17439012
F src/loadext.c 18586e45a215325f15096821e9c082035d4fb810
F src/main.c fec97668771438033a7559883401067b139729e1
F src/malloc.c 0a2e42b835c980ba91c17866e9b6a9810ff54d75
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
F src/mem1.c abe6ee469b6c5a35c7f22bfeb9c9bac664a1c987
F src/mem1.c 52485a88f22649c3b3b4f3eb15760505d49ccf71
F src/mem2.c f1940d9e91948dd6a908fbb9ce3835c36b5d83c3
F src/mem3.c 61c9d47b792908c532ca3a62b999cf21795c6534
F src/mem5.c 61eeb90134f9a5be6c2e68d8daae7628b25953fb
F src/mem3.c 8768ac94694f31ffaf8b4d0ea5dc08af7010a35a
F src/mem5.c c1ab1153bd6443bdf6f71e4213c6fb31221b9eb7
F src/memjournal.c 3eb2c0b51adbd869cb6a44780323f05fa904dc85
F src/msvc.h d9ba56c6851227ab44b3f228a35f3f5772296495
F src/mutex.c 529e95739f815300a33c73fd8a7d6bdf0c24bd18
F src/mutex.c 8e45800ee78e0cd1f1f3fe8e398853307f4a085c
F src/mutex.h 779d588e3b7756ec3ecf7d78cde1d84aba414f85
F src/mutex_noop.c 9d4309c075ba9cc7249e19412d3d62f7f94839c4
F src/mutex_unix.c b0d280089df0f49545f1318f45d61d07d2f674a8
F src/mutex_w32.c b601f9e3073f7bd2c1f42a8c0ce59e42d6a08f85
F src/mutex_unix.c a94b46f3f7beba307dde1b298b0f99f9c3677a93
F src/mutex_w32.c 5e6fe1c298fb5a8a15aaed4161d5759311431c17
F src/notify.c 9711a7575036f0d3040ba61bc6e217f13a9888e7
F src/os.c 8fd25588eeba74068d41102d26810e216999b6c8
F src/os.h 3e57a24e2794a94d3cf2342c6d9a884888cd96bf
F src/os_common.h abdb9a191a367793268fe553d25bab894e986a0e
F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa
F src/os_unix.c 76f493ed71c4154338049dee1bf6e47f69c74a55
F src/os_win.c 40b3af7a47eb1107d0d69e592bec345a3b7b798a
F src/os_unix.c fc93d55f96bb978f0b0168c6ea7d6fc60b0e172c
F src/os_win.c 1716291e5ec2dbfc5a1fe0b32182030f1f7d8acf
F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca
F src/pager.c 4784012f80b2197c61ff6eaf4f5c7026d93253fd
F src/pager.h 6d435f563b3f7fcae4b84433b76a6ac2730036e2
F src/pager.c 2fbeeba28f4e6d08a15bc106f36c43346a81f09e
F src/pager.h ac213f8143ebfee6a8bfb91cf4ca02c9a83343c5
F src/parse.y f599aa5e871a493330d567ced93de696f61f48f7
F src/pcache.c 24be750c79272e0ca7b6e007bc94999700f3e5ef
F src/pcache.h 9968603796240cdf83da7e7bef76edf90619cea9
F src/pcache1.c bf2afe64a3dedb8643c8dcbd94a145cc80ab2a67
F src/pragma.c d71b813e67bf03f3116b9dd5164fbfd81ec673a2
F src/pcache1.c 902e1bc7bdaa81b40f8543407c5e2ac8ef4dc035
F src/pragma.c dcfe3a35d2de935feeaba1455528b4a5c4f1208c
F src/pragma.h 631a91c8b0e6ca8f051a1d8a4a0da4150e04620a
F src/prepare.c 82e5db1013846a819f198336fed72c44c974e7b1
F src/printf.c 0c4bcdd1c2e2521024f0a69cb5eb334f86b3652a
F src/random.c ba2679f80ec82c4190062d756f22d0c358180696
F src/resolve.c 47c00ca0ab24d4b8113c6c05aa07bc6cf6eac9af
F src/resolve.c 1954a0f01bf65d78d7d559aea3d5c67f33376d91
F src/rowset.c eccf6af6d620aaa4579bd3b72c1b6395d9e9fa1e
F src/select.c c17613385bc6b095c421b1f30548814f5fd8a9b2
F src/shell.c 6332ef06db1390ef812cfdff1fc97b4fd76cdd42
F src/sqlite.h.in 378bebc8fe6a88bade25e5f23b7e6123fdc64b00
F src/select.c dbf1fb82317043304da334a33206add211487f96
F src/shell.c d25df04168d6ba5a4fa05bdbf859df667f9eb621
F src/sqlite.h.in 839c818e16ea68703d90d17bd2bb3607191debce
F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad
F src/sqlite3ext.h f700e6a9dd1fdcccc9951ab022b366fb66b9e413
F src/sqliteInt.h e7e92112a71aeb214c66ebdea1366560535614d1
F src/sqlite3ext.h 4b66e3e3435da4b4c8c83696d0349f0c503b3924
F src/sqliteInt.h 1ad779ee62efee60494af0a75d8d45592f9f53c3
F src/sqliteLimit.h 216557999cb45f2e3578ed53ebefe228d779cb46
F src/status.c f266ad8a2892d659b74f0f50cb6a88b6e7c12179
F src/status.c 7005932757445183b0439cd0343ce7391a23b6df
F src/table.c 51b46b2a62d1b3a959633d593b89bab5e2c9155e
F src/tclsqlite.c d9439b6a910985b7fff43ba6756bcef00de22649
F src/test1.c c96508c835979bf15dc0e3146e2c7a51a2333d3c
F src/test1.c 8fff9c5aa63d6490f516d018b70c12a9cb9a4d8a
F src/test2.c 577961fe48961b2f2e5c8b56ee50c3f459d3359d
F src/test3.c 64d2afdd68feac1bb5e2ffb8226c8c639f798622
F src/test4.c d168f83cc78d02e8d35567bb5630e40dcd85ac1e
@@ -363,11 +362,11 @@ F src/test_autoext.c dea8a01a7153b9adc97bd26161e4226329546e12
F src/test_backup.c 2e6e6a081870150f20c526a2e9d0d29cda47d803
F src/test_blob.c e5a7a81d61a780da79101aeb1e60d300af169e07
F src/test_btree.c 2e9978eca99a9a4bfa8cae949efb00886860a64f
F src/test_config.c fb2e5d354d9a077f5fbb261652eff4787deb104f
F src/test_config.c ada6f38b0acb6722fb7f0ed8c54fd66df41085b9
F src/test_demovfs.c 0de72c2c89551629f58486fde5734b7d90758852
F src/test_devsym.c e7498904e72ba7491d142d5c83b476c4e76993bc
F src/test_fs.c ced436e3d4b8e4681328409b8081051ce614e28f
F src/test_func.c f1ac201465472e76a73e2f3695c3553c63e7322a
F src/test_func.c 0d9c25956152adefee8881c6fadc8354793764d0
F src/test_hexio.c abfdecb6fa58c354623978efceb088ca18e379cd
F src/test_init.c 66b33120ffe9cd853b5a905ec850d51151337b32
F src/test_intarray.c 870124b95ec4c645d4eb84f15efb7133528fb1a5
@@ -394,32 +393,32 @@ F src/test_thread.c af391ec03d23486dffbcc250b7e58e073f172af9
F src/test_vfs.c 3b65d42e18b262805716bd96178c81da8f2d9283
F src/test_vfstrace.c bab9594adc976cbe696ff3970728830b4c5ed698
F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9
F src/threads.c 6bbcc9fe50c917864d48287b4792d46d6e873481
F src/tokenize.c 57cb3720f53f84d811def2069c2b169b6be539a5
F src/treeview.c 46036cbbceada0836833531b2d963edbca3d9cfa
F src/threads.c bbfb74450643cb5372a43ad4f6cffd7e9dfcecb0
F src/tokenize.c 338bc8f7c9dd103188952cda7964696bacac6d22
F src/treeview.c 154f0acc622fa3514de8777dcedf4c8a8802b4ce
F src/trigger.c 322f23aad694e8f31d384dcfa386d52a48d3c52f
F src/update.c 3c5bc9570df3bfafa0db36828406a8a14e4c426e
F src/update.c aa10336a2719bd1b9f89004f3d7ba6d566623a49
F src/utf.c fc6b889ba0779b7722634cdeaa25f1930d93820c
F src/util.c fc612367108b74573c5fd13a85d0a23027f438bd
F src/vacuum.c 2ddd5cad2a7b9cef7f9e431b8c7771634c6b1701
F src/vdbe.c 6d85be995bd2308a5aa2a68c7b564c5d4cc1a6fb
F src/vdbe.c ca0bbae502784e57a3d7a22f58aeb69ecf22b75b
F src/vdbe.h 4bc88bd0e06f8046ee6ab7487c0015e85ad949ad
F src/vdbeInt.h 8b54e01ad0463590e7cffabce0bc36da9ee4f816
F src/vdbeapi.c bda74ef4b5103d7b4a4be36f936d3cf2b56a7d6f
F src/vdbeaux.c fd00b489ab3f44f2dca1e4344faf289b7bfcf649
F src/vdbeblob.c 1d7b97115e7bbac4c318db416d2ca83fc779544a
F src/vdbemem.c ae38a0d35ae71cf604381a887c170466ba518090
F src/vdbesort.c f5009e7a35e3065635d8918b9a31f498a499976b
F src/vdbeInt.h 777dd76d513347acb1a71d94df2be00516add637
F src/vdbeapi.c 020681b943e77766b32ae1cddf86d7831b7374ca
F src/vdbeaux.c 906bc74ea90707b57a23e4264727fff7b48d0cb5
F src/vdbeblob.c 565fabd302f5fca3bdf3d56cac330483616a39b6
F src/vdbemem.c fdd1578e47bea61390d472de53c565781d81e045
F src/vdbesort.c 8b23930a1289526f6d2a3a9f2e965bcc963e4a68
F src/vdbetrace.c 8befe829faff6d9e6f6e4dee5a7d3f85cc85f1a0
F src/vtab.c 2ecfe020c10e0a0c7b078203fdba2fae844744bc
F src/vtab.c 2a8b44aa372c33f6154208e7a7f6c44254549806
F src/vxworks.h c18586c8edc1bddbc15c004fa16aeb1e1342b4fb
F src/wal.c 8cd07f1f99e1a81346db1c9da879bef6c6f97cf6
F src/wal.c 18b0ed49830cf04fe2d68224b41838a73ac6cd24
F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4
F src/walker.c 2e14d17f592d176b6dc879c33fbdec4fbccaa2ba
F src/where.c e6efbb9e5f0c20943cd03909b3894ad5b105dedf
F src/whereInt.h 292d3ac90da4eab1e03ac8452f1add746bcafaa1
F src/wherecode.c 6ac8599523f4840d9efac335329f627ebf3f79fd
F src/whereexpr.c 2473e4350e30f9b55d1c6a8f66ca23c689f23f1d
F src/where.c 4c4646675e794ac71e701289edefd7cd81bac844
F src/whereInt.h 7892bb54cf9ca0ae5c7e6094491b94c9286dc647
F src/wherecode.c b924b78acd9e623fb69bfa2cb65cd7d542166dd3
F src/whereexpr.c e63244ca06c503e5f3c5b7f3c9aea0db826089ed
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
@@ -530,7 +529,7 @@ F test/conflict2.test 0d3af4fb534fa1bd020c79960bb56e4d52655f09
F test/conflict3.test dec0634c0f31dec9a4b01c63063e939f0cd21b6b
F test/contrib01.test 2a1cbc0f2f48955d7d073f725765da6fbceda6b4
F test/corrupt.test 141c39ea650c1365e85a49e402fa05cb9617fb97
F test/corrupt2.test 08cec1e5ffa68a3610306d6068f112d08bc9f090
F test/corrupt2.test cb787825d761b0f869764d6990531382840de872
F test/corrupt3.test 4b548d0bbe2933bc81d3f54099a05fc4d28aff18
F test/corrupt4.test b99652079d542b21f4965f6248703b983e40fe80
F test/corrupt5.test 8ead52af76006f3286e9396cb41898018ccea107
@@ -540,7 +539,7 @@ F test/corrupt8.test 2399dfe40d2c0c63af86706e30f3e6302a8d0516
F test/corrupt9.test 730a3db08d4ab9aa43392ea30d9c2b4879cbff85
F test/corruptA.test 53e56dafd180addcdadb402244b8cb9771d2ba26
F test/corruptB.test 73a8d6c0b9833697ecf16b63e3c5c05c945b5dec
F test/corruptC.test 3fcc0f73d2cf2d69befe2d96332b942426a6aae2
F test/corruptC.test 0c46574f8d4f27ecc799b1b5c4cbf9b1817bce9a
F test/corruptD.test b3c205fac7952b1de645ce44bb02335cd9e3e040
F test/corruptE.test be8e5088c369fc7979c662cd644efdaafc0f7f6d
F test/corruptF.test be9fde98e4c93648f1ba52b74e5318edc8f59fe4
@@ -568,9 +567,10 @@ F test/date.test 42973251b9429f2c41b77eb98a7b0b0ba2d3b2c0
F test/dbstatus.test 8de104bb5606f19537d23cd553b41349b5ab1204
F test/dbstatus2.test 10418e62b3db5dca070f0c3eef3ea13946f339c2
F test/default.test 0cb49b1c315a0d81c81d775e407f66906a2a604d
F test/delete.test a065b05d2ebf60fd16639c579a4adfb7c381c701
F test/delete.test e1bcdf8926234e27aac24b346ad83d3329ec8b6f
F test/delete2.test 3a03f2cca1f9a67ec469915cb8babd6485db43fa
F test/delete3.test 555e84a00a99230b7d049d477a324a631126a6ab
F test/delete4.test 3ac0b8d23689ba764c2e8b78c1b56b8f1b942fa2
F test/descidx1.test 6d03b44c8538fe0eb4924e19fba10cdd8f3c9240
F test/descidx2.test 9f1a0c83fd57f8667c82310ca21b30a350888b5d
F test/descidx3.test 09ddbe3f5295f482d2f8b687cf6db8bad7acd9a2
@@ -582,20 +582,20 @@ F test/e_blobclose.test df756753f571bc30e42e3a6cba2807576e49e716
F test/e_blobopen.test 234f960d90235a9b51ec3ca1e062e8541dd558d8
F test/e_blobwrite.test 615b405f29feb2cfb5a1f03dab7933258294fa26
F test/e_changes.test fd66105385153dbf21fdb35eb8ef6c3e1eade579
F test/e_createtable.test c7e67b49e6cf92473c8fb30ab26143e9e2128cf7
F test/e_delete.test d5186e2f5478b659f16a2c8b66c09892823e542a
F test/e_createtable.test d4c6059d44dcd4b636de9aae322766062b471844
F test/e_delete.test ab39084f26ae1f033c940b70ebdbbd523dc4962e
F test/e_droptrigger.test 3cd080807622c13e5bbb61fc9a57bd7754da2412
F test/e_dropview.test 0c9f7f60989164a70a67a9d9c26d1083bc808306
F test/e_expr.test 8f5fdd7261e2d746813b0c6a1c0e34824ad3c5ad
F test/e_expr.test 03a84a6fa9bd3472112d6bd4599f5269f5f74803
F test/e_fkey.test a1783fe1f759e1990e6a11adfcf0702dac4d0707
F test/e_fts3.test 5c02288842e4f941896fd44afdef564dd5fc1459
F test/e_insert.test 0e63edc037afe738bb81a626a676811ed7862c90
F test/e_reindex.test 57d439f6c644befc8274ac93cf2f5449cf2736c1
F test/e_resolve.test dcce9308fb13b934ce29591105d031d3e14fbba6
F test/e_insert.test 3de217e95094d3d165992a6de1164bbc4bd92dc7
F test/e_reindex.test 2bebf7b393e519198b7c654407221cf171a439b8
F test/e_resolve.test a61751c368b109db73df0f20fc75fb47e166b1d8
F test/e_select.test 52692ff3849541e828ad4661fe3773a9b8711763
F test/e_select2.test aceb80ab927d46fba5ce7586ebabf23e2bb0604f
F test/e_totalchanges.test b12ee5809d3e63aeb83238dd501a7bca7fd72c10
F test/e_update.test 312cb8f5ccfe41515a6bb092f8ea562a9bd54d52
F test/e_update.test f46c2554d915c9197548681e8d8c33a267e84528
F test/e_uri.test 5ae33760fb2039c61aa2d90886f1664664173585
F test/e_vacuum.test 5bfbdc21b65c0abf24398d0ba31dc88d93ca77a9
F test/e_wal.test ae9a593207a77d711443ee69ffe081fda9243625
@@ -619,11 +619,11 @@ F test/extraquick.test cb254400bd42bfb777ff675356aabf3287978f79
F test/fallocate.test 3e979af17dfa7e5e9dda5eba1a696c04fa9d47f7
F test/filectrl.test 7c13f96457435238da99aff7343ad6a3a4885787
F test/filefmt.test cb34663f126cbc2d358af552dcaf5c72769b0146
F test/fkey1.test de5b287f6a480b36bd51e8debcf48168e26e4ed2
F test/fkey1.test 13e3d48236a2b9f5c5ebd232eef9b3ab682a8a2c
F test/fkey2.test f3d27ecba480a348c328965d154214719bb158a9
F test/fkey3.test 76d475c80b84ee7a5d062e56ccb6ea68882e2b49
F test/fkey4.test 86446017011273aad8f9a99c1a65019e7bd9ca9d
F test/fkey5.test 56bcb5a6e8b725b17febc267fb041a6695e86853
F test/fkey5.test 5a373303f201ac03c22ba1ef17a733d3f56e611a
F test/fkey6.test abb59f866c1b44926fd02d1fdd217d831fe04f48
F test/fkey7.test 72e915890ee4a005daaf3002cb208e8fe973ac13
F test/fkey8.test 8f08203458321e6c19a263829de4cfc936274ab0
@@ -688,7 +688,7 @@ F test/fts3aux2.test 7ae2b2c13aefdf4169279a27a5f51780ce57f6ba
F test/fts3b.test e93bbb653e52afde110ad53bbd793f14fe7a8984
F test/fts3c.test fc723a9cf10b397fdfc2b32e73c53c8b1ec02958
F test/fts3comp1.test a0f5b16a2df44dd0b15751787130af2183167c0c
F test/fts3conf.test ee8500c86dd58ec075e8831a1e216a79989436de
F test/fts3conf.test ff90127b2462c788348c0dd7f6f8c573ef9cb5d9
F test/fts3corrupt.test 2710b77983cc7789295ddbffea52c1d3b7506dbb
F test/fts3corrupt2.test 6d96efae2f8a6af3eeaf283aba437e6d0e5447ba
F test/fts3cov.test e0fb00d8b715ddae4a94c305992dfc3ef70353d7
@@ -700,7 +700,7 @@ F test/fts3drop.test 1b906e293d6773812587b3dc458cb9e8f3f0c297
F test/fts3e.test 1f6c6ac9cc8b772ca256e6b22aaeed50c9350851
F test/fts3expr.test 3401d47b229c4504424caf362cc4ff704cad4162
F test/fts3expr2.test 18da930352e5693eaa163a3eacf96233b7290d1a
F test/fts3expr3.test 9e91b8edbcb197bf2e92161aa7696446d96dce5f
F test/fts3expr3.test c4d4a7d6327418428c96e0a3a1137c251b8dfbf8
F test/fts3expr4.test e1be1248566f43c252d4404d52914f1fc4bfa065
F test/fts3expr5.test f9abfffbf5e53d48a33e12a1e8f8ba2c551c9b49
F test/fts3fault.test da49627b280b210ebc6657f76344c7851f10ce66
@@ -734,6 +734,7 @@ F test/fts4merge2.test 5faa558d1b672f82b847d2a337465fa745e46891
F test/fts4merge3.test aab02a09f50fe6baaddc2e159c3eabc116d45fc7
F test/fts4merge4.test d895b1057a7798b67e03455d0fa50e9ea836c47b
F test/fts4noti.test 524807f0c36d49deea7920cdd4cd687408b58849
F test/fts4onepass.test bfca61f69c6ca74cd71e6dca12a0cdd47192fc24
F test/fts4unicode.test 27378af76394542cf490cf001d8d1505fe55f6a9
F test/full.test 6b3c8fb43c6beab6b95438c1675374b95fab245d
F test/func.test ae97561957aba6ca9e3a7b8a13aac41830d701ef
@@ -747,10 +748,11 @@ F test/fuzz2.test 76dc35b32b6d6f965259508508abce75a6c4d7e1
F test/fuzz3.test 53fabcd5f0f430f8b221282f6c12c4d0903c21eb
F test/fuzz_common.tcl a87dfbb88c2a6b08a38e9a070dabd129e617b45b
F test/fuzz_malloc.test 328f70aaca63adf29b4c6f06505ed0cf57ca7c26
F test/fuzzcheck.c 79980bbc00e19ad44c3ba6699e643348572757a2
F test/fuzzcheck.c c84086021a514360268190a1bc6ae8ed78d7c94f
F test/fuzzdata1.db 7ee3227bad0e7ccdeb08a9e6822916777073c664
F test/fuzzdata2.db f03a420d3b822cc82e4f894ca957618fbe9c4973
F test/fuzzdata3.db 1d6044c33a114007f02b6e6846f1fa232f607bfd
F test/fuzzdata3.db c6586d3e3cef0fbc18108f9bb649aa77bfc38aba
F test/fuzzdata4.db 1882f0055fb63214d8407ddc7aca9b0b1c59af21
F test/fuzzer1.test d4c52aaf3ef923da293a2653cfab33d02f718a36
F test/fuzzerfault.test 8792cd77fd5bce765b05d0c8e01b9edcf8af8536
F test/genesis.tcl 1e2e2e8e5cc4058549a154ff1892fe5c9de19f98
@@ -781,8 +783,8 @@ F test/index4.test ab92e736d5946840236cd61ac3191f91a7856bf6
F test/index5.test 8621491915800ec274609e42e02a97d67e9b13e7
F test/index6.test 7102ec371414c42dfb1d5ca37eb4519aa9edc23a
F test/index7.test 9c6765a74fc3fcde7aebc5b3bd40d98df14a527c
F test/indexedby.test 5f527a78bae74c61b8046ae3037f9dfb0bf0c353
F test/indexexpr1.test 3c5033412f851f225e3a37d6795709df71bea638
F test/indexedby.test 9c4cd331224e57f79fbf411ae245e6272d415985
F test/indexexpr1.test bbb52b5d5717d9f23853826963b0af5110009366
F test/indexfault.test 31d4ab9a7d2f6e9616933eb079722362a883eb1d
F test/init.test 15c823093fdabbf7b531fe22cf037134d09587a7
F test/insert.test 38742b5e9601c8f8d76e9b7555f7270288c2d371
@@ -813,7 +815,8 @@ F test/journal3.test ff8af941f9e06161d3db1b46bb9f965ff0e7f307
F test/jrnlmode.test 7864d59cf7f6e552b9b99ba0f38acd167edc10fa
F test/jrnlmode2.test 81610545a4e6ed239ea8fa661891893385e23a1d
F test/jrnlmode3.test 556b447a05be0e0963f4311e95ab1632b11c9eaa
F test/json101.test 11535d8986184500f4c30cc2f0b154b4ab05cc4e
F test/json101.test f0178422b3a2418f423fd0d3caf3571c8d1b9863
F test/json102.test bf3fe7a706d30936a76a0f7a0375e1e8e73aff5a
F test/keyword1.test 37ef6bba5d2ed5b07ecdd6810571de2956599dff
F test/lastinsert.test 42e948fd6442f07d60acbd15d33fb86473e0ef63
F test/laststmtchanges.test ae613f53819206b3222771828d024154d51db200
@@ -893,6 +896,7 @@ F test/notify3.test 10ff25cde502e72a92053a2f215d64bece4ef934
F test/notnull.test f8fcf58669ddba79274daa2770d61dfad8274f62
F test/null.test 0dcce4f04284ec66108c503327ad6d224c0752b3
F test/numcast.test 5d126f7f581432e86a90d1e35cac625164aec4a1
F test/offset1.test f06b83657bcf26f9ce805e67450e189e282143b2
F test/openv2.test 0d3040974bf402e19b7df4b783e447289d7ab394
F test/orderby1.test 870e150450437d3980badbde3d0166b81d9e33f6
F test/orderby2.test bc11009f7cd99d96b1b11e57b199b00633eb5b04
@@ -902,7 +906,7 @@ F test/orderby5.test 8f08a54836d21fb7c70245360751aedd1c2286fb
F test/orderby6.test 8b38138ab0972588240b3fca0985d2e400432859
F test/orderby7.test 3d1383d52ade5b9eb3a173b3147fdd296f0202da
F test/orderby8.test 23ef1a5d72bd3adcc2f65561c654295d1b8047bd
F test/orderby9.test 88a330ea5fc7bed7e407b28beb0d2b79485ae2cc
F test/orderby9.test 87fb9548debcc2cd141c5299002dd94672fa76a3
F test/oserror.test 14fec2796c2b6fe431c7823750e8a18a761176d7
F test/ovfl.test 4f7ca651cba5c059a12d8c67dddd49bec5747799
F test/pager1.test 1acbdb14c5952a72dd43129cabdbf69aaa3ed1fa
@@ -919,8 +923,8 @@ F test/pcache.test c8acbedd3b6fd0f9a7ca887a83b11d24a007972b
F test/pcache2.test af7f3deb1a819f77a6d0d81534e97d1cf62cd442
F test/percentile.test 4243af26b8f3f4555abe166f723715a1f74c77ff
F test/permutations.test ac3b00c299250cc087d4a527b5c75a0f8aef4e54
F test/pragma.test be7195f0aa72bdb8a512133e9640ac40f15b57a2
F test/pragma2.test 8e72df3a16c0fda748ad52abf79cb8256b04a6fe
F test/pragma.test a44253f911e7d50127d4a08f927f47c861a4c772
F test/pragma2.test b5e2ce4c892afceb308c6ae6163a9099b2a0d8d7
F test/pragma3.test 6f849ccffeee7e496d2f2b5e74152306c0b8757c
F test/printf.test b3ff34e73d59124140eaf89f7672e21bc2ca5fcc
F test/printf2.test 0b61566dd1c0f0b802f59dffa228c5dc5aa6b054
@@ -938,7 +942,7 @@ F test/rbu.test 168573d353cd0fd10196b87b0caa322c144ef736
F test/rdonly.test 64e2696c322e3538df0b1ed624e21f9a23ed9ff8
F test/regexp1.test 497ea812f264d12b6198d6e50a76be4a1973a9d8
F test/reindex.test 44edd3966b474468b823d481eafef0c305022254
F test/releasetest.tcl cd2de2749aab7f45b2fe91b4a05431fc08e1692a
F test/releasetest.tcl 67a82199e6ddee609211488bc04ed3f9ea3aa28a
F test/resolver01.test f4022acafda7f4d40eca94dbf16bc5fc4ac30ceb
F test/rollback.test 458fe73eb3ffdfdf9f6ba3e9b7350a6220414dea
F test/rollback2.test fc14cf6d1a2b250d2735ef16124b971bce152f14
@@ -1024,9 +1028,9 @@ F test/speed4p.explain 6b5f104ebeb34a038b2f714150f51d01143e59aa
F test/speed4p.test 0e51908951677de5a969b723e03a27a1c45db38b
F test/speedtest1.c 857439869d1cb4db35e1c720ee9c2756eb9ea2a0
F test/spellfix.test 0597065ff57042df1f138e6a2611ae19c2698135
F test/spellfix2.test e5f2bc1dae046dbdd8008f2a84ed7749ff9b325e
F test/spellfix2.test dfc8f519a3fc204cb2dfa8b4f29821ae90f6f8c3
F test/sqldiff1.test 8f6bc7c6a5b3585d350d779c6078869ba402f8f5
F test/sqllimits1.test e05786eaed7950ff6a2d00031d001d8a26131e68
F test/sqllimits1.test 89b3d5aad05b99f707ee3786bdd4416dccf83304
F test/stat.test 8de91498c99f5298b303f70f1d1f3b9557af91bf
F test/statfault.test f525a7bf633e50afd027700e9a486090684b1ac1
F test/stmt.test 25d64e3dbf9a3ce89558667d7f39d966fe2a71b9
@@ -1034,12 +1038,13 @@ F test/subquery.test d7268d193dd33d5505df965399d3a594e76ae13f
F test/subquery2.test 438f8a7da1457277b22e4176510f7659b286995f
F test/subselect.test d24fd8757daf97dafd2e889c73ea4c4272dcf4e4
F test/substr.test 18f57c4ca8a598805c4d64e304c418734d843c1a
F test/subtype1.test 7fe09496352f97053af1437150751be2d0a0cae8
F test/superlock.test 1cde669f68d2dd37d6c9bd35eee1d95491ae3fc2
F test/sync.test a34cd43e98b7fb84eabbf38f7ed8f7349b3f3d85
F test/syscall.test d2fdaad713f103ac611fe7ef9b724c7b69f8149c
F test/sysfault.test fa776e60bf46bdd3ae69f0b73e46ee3977a58ae6
F test/tabfunc01.test a12eba3f48a03a6626f985734ecc28132381fa9b
F test/table.test 33bf0d1fd07f304582695184b8e6feb017303816
F test/tabfunc01.test 03c4ad422c6ab596cff6dcaf86dd061a9f039525
F test/table.test b708f3e5fa2542fa51dfab21fc07b36ea445cb2f
F test/tableapi.test 2674633fa95d80da917571ebdd759a14d9819126
F test/tableopts.test dba698ba97251017b7c80d738c198d39ab747930
F test/tclsqlite.test 7fb866443c7deceed22b63948ccd6f76b52ad054
@@ -1230,11 +1235,11 @@ F test/types.test bf816ce73c7dfcfe26b700c19f97ef4050d194ff
F test/types2.test 3555aacf8ed8dc883356e59efc314707e6247a84
F test/types3.test 99e009491a54f4dc02c06bdbc0c5eea56ae3e25a
F test/unique.test 93f8b2ef5ea51b9495f8d6493429b1fd0f465264
F test/unique2.test 41e7f83c6827605991160a31380148a9fc5f1339
F test/unique2.test 3674e9f2a3f1fbbfd4772ac74b7a97090d0f77d2
F test/unixexcl.test cd6c765f75e50e8e2c2ba763149e5d340ea19825
F test/unordered.test ca7adce0419e4ca0c50f039885e76ed2c531eda8
F test/update.test 6c68446b8a0a33d522a7c72b320934596a2d7d32
F test/uri.test 23662b7b61958b0f0e47082de7d06341ccf85d5b
F test/uri.test 6630ecbdea2aac10df3c89dbae2243f4c2c353e4
F test/userauth01.test e740a2697a7b40d7c5003a7d7edaee16acd349a9
F test/utf16align.test 54cd35a27c005a9b6e7815d887718780b6a462ae
F test/vacuum.test ce91c39f7f91a4273bf620efad21086b5aa6ef1d
@@ -1243,7 +1248,7 @@ F test/vacuum3.test 77ecdd54592b45a0bcb133339f99f1ae0ae94d0d
F test/vacuum4.test d3f8ecff345f166911568f397d2432c16d2867d9
F test/varint.test ab7b110089a08b9926ed7390e7e97bdefeb74102
F test/veryquick.test 57ab846bacf7b90cf4e9a672721ea5c5b669b661
F test/view.test 3930ae94042d702ab15a6a0ef692cfa5c9f9b68b
F test/view.test f6c3a39e0c819891265e1d0754e99960d81ef6c9
F test/vtab1.test 6210e076997f176bedc300a87ad6404651b601dd
F test/vtab2.test f8cd1bb9aba7143eba97812d9617880a36d247ad
F test/vtab3.test b45f47d20f225ccc9c28dc915d92740c2dee311e
@@ -1264,7 +1269,7 @@ F test/vtab_err.test 0d4d8eb4def1d053ac7c5050df3024fd47a3fbd8
F test/vtab_shared.test ea8778d5b0df200adef2ca7c00c3c37d4375f772
F test/wal.test dbfc482e10c7263298833bb1fc60b3ac9d6340a1
F test/wal2.test 1f841d2048080d32f552942e333fd99ce541dada
F test/wal3.test 2b5445e5da44780b9b44712f5a38523f7aeb0941
F test/wal3.test 2ab8e490afe0164bfc89b185c8b2572e0d821f23
F test/wal4.test 4744e155cd6299c6bd99d3eab1c82f77db9cdb3c
F test/wal5.test 88b5d9a6a3d1532497ee9f4296f010d66f07e33c
F test/wal6.test 4421cd5a2fa99d29cc91ef12fb23bed171ed3a4c
@@ -1323,49 +1328,52 @@ F test/without_rowid2.test af260339f79d13cb220288b67cd287fbcf81ad99
F test/without_rowid3.test aad4f9d383e199349b6c7e508a778f7dff5dff79
F test/without_rowid4.test 4e08bcbaee0399f35d58b5581881e7a6243d458a
F test/without_rowid5.test 61256715b686359df48ca1742db50cc7e3e7b862
F test/without_rowid6.test db0dbf03c49030aa3c1ba5f618620334bd2baf5f
F test/without_rowid6.test 1f99644e6508447fb050f73697350c7ceca3392e
F test/wordcount.c 9915e06cb33d8ca8109b8700791afe80d305afda
F test/zeroblob.test 3857870fe681b8185654414a9bccfde80b62a0fa
F test/zerodamage.test cf6748bad89553cc1632be51a6f54e487e4039ac
F tool/build-all-msvc.bat 761d8c82a1a529261291812732a853a1b4256d85 x
F tool/GetFile.cs a15e08acb5dd7539b75ba23501581d7c2b462cb5
F tool/GetTclKit.bat 8606413d3035c05373a0d7fae82ebf59ae9e16c3
F tool/addopcodes.tcl 7cc82ecca456a6b3148abf492b0419b83140881a
F tool/build-all-msvc.bat 2b1703b322da121e56b955cb58de091107f777c3 x
F tool/build-shell.sh 950f47c6174f1eea171319438b93ba67ff5bf367
F tool/checkSpacing.c 810e51703529a204fc4e1eb060e9ab663e3c06d2
F tool/diffdb.c 7524b1b5df217c20cd0431f6789851a4e0cb191b
F tool/extract.c 054069d81b095fbdc189a6f5d4466e40380505e2
F tool/fast_vacuum.c 5ba0d6f5963a0a63bdc42840f678bad75b2ebce1
F tool/fragck.tcl 5265a95126abcf6ab357f7efa544787e5963f439
F tool/fuzzershell.c f2fc86dd22df654b28851b85019d3bd007361751
F tool/fuzzershell.c b36096cdbcb4af985a2d6c20093d61e55b49bfe1
F tool/genfkey.README cf68fddd4643bbe3ff8e31b8b6d8b0a1b85e20f4
F tool/genfkey.test 4196a8928b78f51d54ef58e99e99401ab2f0a7e5
F tool/getlock.c f4c39b651370156cae979501a7b156bdba50e7ce
F tool/lemon.c b9109f59b57e7b6f101c4fe644c8361ba6dee969
F tool/lempar.c 01ca97f87610d1dac6d8cd96ab109ab1130e76dc
F tool/lemon.c 039f813b520b9395740c52f9cbf36c90b5d8df03
F tool/lempar.c 3617143ddb9b176c3605defe6a9c798793280120
F tool/loadfts.c c3c64e4d5e90e8ba41159232c2189dba4be7b862
F tool/logest.c eef612f8adf4d0993dafed0416064cf50d5d33c6
F tool/mkautoconfamal.sh d1a2da0e15b2ed33d60af35c7e9d483f13a8eb9f
F tool/mkkeywordhash.c dfff09dbbfaf950e89af294f48f902181b144670
F tool/mkopcodec.tcl edde8adc42621b5e598127f8cdc6d52cfe21f52b
F tool/mkopcodeh.tcl e04177031532b7aa9379ded50e820231ac4abd6e
F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e
F tool/mkpragmatab.tcl 84af2b180484323a2ea22a2279e8bd9e3e1e492e
F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97
F tool/mksqlite3c-noext.tcl 87240b09c20042999b41d5fabe091b7111287835
F tool/mksqlite3c.tcl 421ecbd437d8cd7123e67430ee8146218396680d
F tool/mksqlite3h.tcl 44730d586c9031638cdd2eb443b801c0d2dbd9f8
F tool/mksqlite3c.tcl b66b4170f693602cd6985aed15d9509fe2f18c84
F tool/mksqlite3h.tcl 1d41ab59bffb025121f75b76e183125ce41b3ec8
F tool/mksqlite3internalh.tcl eb994013e833359137eb53a55acdad0b5ae1049b
F tool/mkvsix.tcl bbe57cd9ae11c6cc70319241101ef8d2b8c3765b
F tool/offsets.c fe4262fdfa378e8f5499a42136d17bf3b98f6091
F tool/omittest.tcl 34d7ac01fe4fd18e3637f64abe12c40eca0f6b97
F tool/opcodeDoc.awk b3a2a3d5d3075b8bd90b7afe24283efdd586659c
F tool/pagesig.c ff0ca355fd3c2398e933da5e22439bbff89b803b
F tool/replace.tcl 7727c60a04299b65a92f5e1590896fea0f25b9e0
F tool/restore_jrnl.tcl 6957a34f8f1f0f8285e07536225ec3b292a9024a
F tool/rollback-test.c 9fc98427d1e23e84429d7e6d07d9094fbdec65a5
F tool/showdb.c b1e16174385d5bd0815823a7fda1ecc82ed6088b
F tool/showjournal.c 053eb1cc774710c6890b7dd6293300cc297b16a5
F tool/showjournal.c 5bad7ae8784a43d2b270d953060423b8bd480818
F tool/showlocks.c 9920bcc64f58378ff1118caead34147201f48c68
F tool/showstat4.c 9515faa8ec176599d4a8288293ba8ec61f7b728a
F tool/showwal.c 85cb36d4fe3e93e2fbd63e786e0d1ce42d0c4fad
F tool/soak1.tcl 8d407956e1a45b485a8e072470a3e629a27037fe
F tool/space_used.tcl f714c41a59e326b8b9042f415b628b561bafa06b
F tool/spaceanal.tcl 63a415385a66fdbf736bfd204a31c6d851ed8da6
F tool/spaceanal.tcl 93c1fdc9733c525b17a2024c7df193daa002e037
F tool/speedtest.tcl 06c76698485ccf597b9e7dbb1ac70706eb873355
F tool/speedtest16.c c8a9c793df96db7e4933f0852abb7a03d48f2e81
F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
@@ -1376,14 +1384,17 @@ F tool/sqldiff.c b318efc2eaf7a7fac4d281a0ce736193cb2506df
F tool/stack_usage.tcl f8e71b92cdb099a147dad572375595eae55eca43
F tool/symbols-mingw.sh 4dbcea7e74768305384c9fd2ed2b41bbf9f0414d
F tool/symbols.sh fec58532668296d7c7dc48be9c87f75ccdb5814f
F tool/tostr.awk 11760e1b94a5d3dcd42378f3cc18544c06cfa576
F tool/tostr.tcl 96022f35ada2194f6f8ccf6fd95809e90ed277c4
F tool/varint.c 5d94cb5003db9dbbcbcc5df08d66f16071aee003
F tool/vdbe-compress.tcl 5926c71f9c12d2ab73ef35c29376e756eb68361c
F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1
F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
P 1ab10cbf27245961b40eda1ce70f35646f0a9966 3d3df79bfaf9dbc7aa711c08a19d2f6dbe744b32
R 46fafd1e16150312779d43bb23b81793
U drh
Z 1a60e3fe37bc43a63ce49e32494691dc
P 0a903ec26bfbbe9bfd18bc34934e689ffdb01ce5
R 6c382e4c78016ecd57806c65884973bc
T *branch * noWarn
T *sym-noWarn *
T -sym-trunk *
U mistachkin
Z ca4478407fbab500452d21bb1a48b6b7
+1 -1
View File
@@ -1 +1 @@
5ff855293865c244ac632c630e8e7e8d7c05a5f6
12e869bbac4308f859baf6c6cbf051128b7308ec
-50
View File
@@ -1,50 +0,0 @@
#!/usr/bin/awk -f
#
# This AWK script scans the opcodes.h file (which is itself generated by
# another awk script) and uses the information gleaned to create the
# opcodes.c source file.
#
# Opcodes.c contains strings which are the symbolic names for the various
# opcodes used by the VDBE. These strings are used when disassembling a
# VDBE program during tracing or as a result of the EXPLAIN keyword.
#
BEGIN {
print "/* Automatically generated. Do not edit */"
print "/* See the mkopcodec.awk script for details. */"
printf "#if !defined(SQLITE_OMIT_EXPLAIN)"
printf " || defined(VDBE_PROFILE)"
print " || defined(SQLITE_DEBUG)"
print "#if defined(SQLITE_ENABLE_EXPLAIN_COMMENTS) || defined(SQLITE_DEBUG)"
print "# define OpHelp(X) \"\\0\" X"
print "#else"
print "# define OpHelp(X)"
print "#endif"
print "const char *sqlite3OpcodeName(int i){"
print " static const char *const azName[] = { \"?\","
mx = 0
}
/^.define OP_/ {
sub("OP_","",$2)
i = $3+0
label[i] = $2
if( mx<i ) mx = i
for(j=5; j<NF; j++) if( $j=="synopsis:" ) break
if( j<NF ){
j++
x = $j
for(j=j+1; j<NF; j++) x = x " " $j
synopsis[i] = x
}else{
synopsis[i] = ""
}
}
END {
for(i=1; i<=mx; i++){
printf " /* %3d */ %-18s OpHelp(\"%s\"),\n", i, \
"\"" label[i] "\"", synopsis[i]
}
print " };"
print " return azName[i];"
print "}"
print "#endif"
}
-228
View File
@@ -1,228 +0,0 @@
#!/usr/bin/awk -f
#
# Generate the file opcodes.h.
#
# This AWK script scans a concatenation of the parse.h output file from the
# parser and the vdbe.c source file in order to generate the opcodes numbers
# for all opcodes.
#
# The lines of the vdbe.c that we are interested in are of the form:
#
# case OP_aaaa: /* same as TK_bbbbb */
#
# The TK_ comment is optional. If it is present, then the value assigned to
# the OP_ is the same as the TK_ value. If missing, the OP_ value is assigned
# a small integer that is different from every other OP_ value.
#
# We go to the trouble of making some OP_ values the same as TK_ values
# as an optimization. During parsing, things like expression operators
# are coded with TK_ values such as TK_ADD, TK_DIVIDE, and so forth. Later
# during code generation, we need to generate corresponding opcodes like
# OP_Add and OP_Divide. By making TK_ADD==OP_Add and TK_DIVIDE==OP_Divide,
# code to translate from one to the other is avoided. This makes the
# code generator run (infinitesimally) faster and more importantly it makes
# the library footprint smaller.
#
# This script also scans for lines of the form:
#
# case OP_aaaa: /* jump, in1, in2, in3, out2-prerelease, out3 */
#
# When such comments are found on an opcode, it means that certain
# properties apply to that opcode. Set corresponding flags using the
# OPFLG_INITIALIZER macro.
#
# Remember the TK_ values from the parse.h file
/^#define TK_/ {
tk[$2] = 0+$3 # tk[x] holds the numeric value for TK symbol X
}
# Find "/* Opcode: " lines in the vdbe.c file. Each one introduces
# a new opcode. Remember which parameters are used.
/^.. Opcode: / {
currentOp = "OP_" $3
m = 0
for(i=4; i<=NF; i++){
x = $i
if( x=="P1" ) m += 1
if( x=="P2" ) m += 2
if( x=="P3" ) m += 4
if( x=="P4" ) m += 8
if( x=="P5" ) m += 16
}
paramused[currentOp] = m
}
# Find "** Synopsis: " lines that follow Opcode:
/^.. Synopsis: / {
if( currentOp ){
x = $3
for(i=4; i<=NF; i++){
x = x " " $i
}
synopsis[currentOp] = x
}
}
# Scan for "case OP_aaaa:" lines in the vdbe.c file
/^case OP_/ {
name = $2
sub(/:/,"",name)
sub("\r","",name)
op[name] = -1 # op[x] holds the numeric value for OP symbol x
jump[name] = 0
in1[name] = 0
in2[name] = 0
in3[name] = 0
out2[name] = 0
out3[name] = 0
for(i=3; i<NF; i++){
if($i=="same" && $(i+1)=="as"){
sym = $(i+2)
sub(/,/,"",sym)
val = tk[sym]
op[name] = val
used[val] = 1
sameas[val] = sym
def[val] = name
}
x = $i
sub(",","",x)
if(x=="jump"){
jump[name] = 1
}else if(x=="in1"){
in1[name] = 1
}else if(x=="in2"){
in2[name] = 1
}else if(x=="in3"){
in3[name] = 1
}else if(x=="out2"){
out2[name] = 1
}else if(x=="out3"){
out3[name] = 1
}
}
order[n_op++] = name;
}
# Assign numbers to all opcodes and output the result.
END {
cnt = 0
max = 0
print "/* Automatically generated. Do not edit */"
print "/* See the mkopcodeh.awk script for details */"
op["OP_Noop"] = -1;
order[n_op++] = "OP_Noop";
op["OP_Explain"] = -1;
order[n_op++] = "OP_Explain";
# Assign small values to opcodes that are processed by resolveP2Values()
# to make code generation for the switch() statement smaller and faster.
for(i=0; i<n_op; i++){
name = order[i];
if( op[name]>=0 ) continue;
if( name=="OP_Transaction" \
|| name=="OP_AutoCommit" \
|| name=="OP_Savepoint" \
|| name=="OP_Checkpoint" \
|| name=="OP_Vacuum" \
|| name=="OP_JournalMode" \
|| name=="OP_VUpdate" \
|| name=="OP_VFilter" \
|| name=="OP_Next" \
|| name=="OP_NextIfOpen" \
|| name=="OP_SorterNext" \
|| name=="OP_Prev" \
|| name=="OP_PrevIfOpen" \
){
cnt++
while( used[cnt] ) cnt++
op[name] = cnt
used[cnt] = 1
def[cnt] = name
}
}
# Generate the numeric values for opcodes
for(i=0; i<n_op; i++){
name = order[i];
if( op[name]<0 ){
cnt++
while( used[cnt] ) cnt++
op[name] = cnt
used[cnt] = 1
def[cnt] = name
}
}
max = cnt
for(i=1; i<=max; i++){
if( !used[i] ){
def[i] = "OP_NotUsed_" i
}
printf "#define %-16s %3d", def[i], i
com = ""
if( sameas[i] ){
com = "same as " sameas[i]
}
x = synopsis[def[i]]
if( x ){
if( com=="" ){
com = "synopsis: " x
} else {
com = com ", synopsis: " x
}
}
if( com!="" ){
printf " /* %-42s */", com
}
printf "\n"
}
# Generate the bitvectors:
#
# bit 0: jump
# bit 1: pushes a result onto stack
# bit 2: output to p1. release p1 before opcode runs
#
for(i=0; i<=max; i++){
name = def[i]
a0 = a1 = a2 = a3 = a4 = a5 = a6 = a7 = 0
if( jump[name] ) a0 = 1;
if( in1[name] ) a2 = 2;
if( in2[name] ) a3 = 4;
if( in3[name] ) a4 = 8;
if( out2[name] ) a5 = 16;
if( out3[name] ) a6 = 32;
bv[i] = a0+a1+a2+a3+a4+a5+a6;
}
print "\n"
print "/* Properties such as \"out2\" or \"jump\" that are specified in"
print "** comments following the \"case\" for each opcode in the vdbe.c"
print "** are encoded into bitvectors as follows:"
print "*/"
print "#define OPFLG_JUMP 0x0001 /* jump: P2 holds jmp target */"
print "#define OPFLG_IN1 0x0002 /* in1: P1 is an input */"
print "#define OPFLG_IN2 0x0004 /* in2: P2 is an input */"
print "#define OPFLG_IN3 0x0008 /* in3: P3 is an input */"
print "#define OPFLG_OUT2 0x0010 /* out2: P2 is an output */"
print "#define OPFLG_OUT3 0x0020 /* out3: P3 is an output */"
print "#define OPFLG_INITIALIZER {\\"
for(i=0; i<=max; i++){
if( i%8==0 ) printf("/* %3d */",i)
printf " 0x%02x,", bv[i]
if( i%8==7 ) printf("\\\n");
}
print "}"
if( 0 ){
print "\n/* Bitmask to indicate which fields (P1..P5) of each opcode are"
print "** actually used.\n*/"
print "#define OP_PARAM_USED_INITIALIZER {\\"
for(i=0; i<=max; i++){
if( i%8==0 ) printf("/* %3d */",i)
printf " 0x%02x,", paramused[def[i]]
if( i%8==7 ) printf("\\\n");
}
print "}"
}
}
+3 -3
View File
@@ -602,14 +602,14 @@ void sqlite3MinimumFileFormat(Parse *pParse, int iDb, int minFormat){
if( ALWAYS(v) ){
int r1 = sqlite3GetTempReg(pParse);
int r2 = sqlite3GetTempReg(pParse);
int j1;
int addr1;
sqlite3VdbeAddOp3(v, OP_ReadCookie, iDb, r1, BTREE_FILE_FORMAT);
sqlite3VdbeUsesBtree(v, iDb);
sqlite3VdbeAddOp2(v, OP_Integer, minFormat, r2);
j1 = sqlite3VdbeAddOp3(v, OP_Ge, r2, 0, r1);
addr1 = sqlite3VdbeAddOp3(v, OP_Ge, r2, 0, r1);
sqlite3VdbeChangeP5(v, SQLITE_NOTNULL); VdbeCoverage(v);
sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_FILE_FORMAT, r2);
sqlite3VdbeJumpHere(v, j1);
sqlite3VdbeJumpHere(v, addr1);
sqlite3ReleaseTempReg(pParse, r1);
sqlite3ReleaseTempReg(pParse, r2);
}
+4
View File
@@ -769,6 +769,10 @@ int sqlite3BtreeCopyFile(Btree *pTo, Btree *pFrom){
b.pDest = pTo;
b.iNext = 1;
#ifdef SQLITE_HAS_CODEC
sqlite3PagerAlignReserve(sqlite3BtreePager(pTo), sqlite3BtreePager(pFrom));
#endif
/* 0x7FFFFFFF is the hard limit for the number of pages in a database
** file. By passing this as the number of pages to copy to
** sqlite3_backup_step(), we can guarantee that the copy finishes
+112 -35
View File
@@ -591,6 +591,49 @@ static void btreeReleaseAllCursorPages(BtCursor *pCur){
pCur->iPage = -1;
}
/*
** The cursor passed as the only argument must point to a valid entry
** when this function is called (i.e. have eState==CURSOR_VALID). This
** function saves the current cursor key in variables pCur->nKey and
** pCur->pKey. SQLITE_OK is returned if successful or an SQLite error
** code otherwise.
**
** If the cursor is open on an intkey table, then the integer key
** (the rowid) is stored in pCur->nKey and pCur->pKey is left set to
** NULL. If the cursor is open on a non-intkey table, then pCur->pKey is
** set to point to a malloced buffer pCur->nKey bytes in size containing
** the key.
*/
static int saveCursorKey(BtCursor *pCur){
int rc;
assert( CURSOR_VALID==pCur->eState );
assert( 0==pCur->pKey );
assert( cursorHoldsMutex(pCur) );
rc = sqlite3BtreeKeySize(pCur, &pCur->nKey);
assert( rc==SQLITE_OK ); /* KeySize() cannot fail */
/* If this is an intKey table, then the above call to BtreeKeySize()
** stores the integer key in pCur->nKey. In this case this value is
** all that is required. Otherwise, if pCur is not open on an intKey
** table, then malloc space for and store the pCur->nKey bytes of key
** data. */
if( 0==pCur->curIntKey ){
void *pKey = sqlite3Malloc( pCur->nKey );
if( pKey ){
rc = sqlite3BtreeKey(pCur, 0, (int)pCur->nKey, pKey);
if( rc==SQLITE_OK ){
pCur->pKey = pKey;
}else{
sqlite3_free(pKey);
}
}else{
rc = SQLITE_NOMEM;
}
}
assert( !pCur->curIntKey || !pCur->pKey );
return rc;
}
/*
** Save the current cursor position in the variables BtCursor.nKey
@@ -611,36 +654,14 @@ static int saveCursorPosition(BtCursor *pCur){
}else{
pCur->skipNext = 0;
}
rc = sqlite3BtreeKeySize(pCur, &pCur->nKey);
assert( rc==SQLITE_OK ); /* KeySize() cannot fail */
/* If this is an intKey table, then the above call to BtreeKeySize()
** stores the integer key in pCur->nKey. In this case this value is
** all that is required. Otherwise, if pCur is not open on an intKey
** table, then malloc space for and store the pCur->nKey bytes of key
** data.
*/
if( 0==pCur->curIntKey ){
void *pKey = sqlite3Malloc( pCur->nKey );
if( pKey ){
rc = sqlite3BtreeKey(pCur, 0, (int)pCur->nKey, pKey);
if( rc==SQLITE_OK ){
pCur->pKey = pKey;
}else{
sqlite3_free(pKey);
}
}else{
rc = SQLITE_NOMEM;
}
}
assert( !pCur->curIntKey || !pCur->pKey );
rc = saveCursorKey(pCur);
if( rc==SQLITE_OK ){
btreeReleaseAllCursorPages(pCur);
pCur->eState = CURSOR_REQUIRESEEK;
}
invalidateOverflowCache(pCur);
pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl|BTCF_AtLast);
return rc;
}
@@ -4478,7 +4499,9 @@ static int accessPayload(
/* If required, populate the overflow page-list cache. */
if( (pCur->curFlags & BTCF_ValidOvfl)!=0 ){
assert(!pCur->aOverflow[iIdx] || pCur->aOverflow[iIdx]==nextPage);
assert( pCur->aOverflow[iIdx]==0
|| pCur->aOverflow[iIdx]==nextPage
|| CORRUPT_DB );
pCur->aOverflow[iIdx] = nextPage;
}
@@ -6478,7 +6501,13 @@ static int pageInsertArray(
if( pData<pBegin ) return 1;
pSlot = pData;
}
memcpy(pSlot, pCArray->apCell[i], sz);
/* pSlot and pCArray->apCell[i] will never overlap on a well-formed
** database. But they might for a corrupt database. Hence use memmove()
** since memcpy() sends SIGABORT with overlapping buffers on OpenBSD */
assert( (pSlot+sz)<=pCArray->apCell[i]
|| pSlot>=(pCArray->apCell[i]+sz)
|| CORRUPT_DB );
memmove(pSlot, pCArray->apCell[i], sz);
put2byte(pCellptr, (pSlot - aData));
pCellptr += 2;
}
@@ -7603,7 +7632,7 @@ static int balance_nonroot(
** by smaller than the child due to the database header, and so all the
** free space needs to be up front.
*/
assert( nNew==1 );
assert( nNew==1 || CORRUPT_DB );
rc = defragmentPage(apNew[0]);
testcase( rc!=SQLITE_OK );
assert( apNew[0]->nFree ==
@@ -8026,10 +8055,15 @@ end_insert:
}
/*
** Delete the entry that the cursor is pointing to. The cursor
** is left pointing at an arbitrary location.
** Delete the entry that the cursor is pointing to.
**
** If the second parameter is zero, then the cursor is left pointing at an
** arbitrary location after the delete. If it is non-zero, then the cursor
** is left in a state such that the next call to BtreeNext() or BtreePrev()
** moves it to the same row as it would if the call to BtreeDelete() had
** been omitted.
*/
int sqlite3BtreeDelete(BtCursor *pCur){
int sqlite3BtreeDelete(BtCursor *pCur, int bPreserve){
Btree *p = pCur->pBtree;
BtShared *pBt = p->pBt;
int rc; /* Return code */
@@ -8038,6 +8072,7 @@ int sqlite3BtreeDelete(BtCursor *pCur){
int iCellIdx; /* Index of cell to delete */
int iCellDepth; /* Depth of node containing pCell */
u16 szCell; /* Size of the cell being deleted */
int bSkipnext = 0; /* Leaf cursor in SKIPNEXT state */
assert( cursorHoldsMutex(pCur) );
assert( pBt->inTransaction==TRANS_WRITE );
@@ -8067,10 +8102,7 @@ int sqlite3BtreeDelete(BtCursor *pCur){
}
/* Save the positions of any other cursors open on this table before
** making any modifications. Make the page containing the entry to be
** deleted writable. Then free any overflow pages associated with the
** entry and finally remove the cell itself from within the page.
*/
** making any modifications. */
if( pCur->curFlags & BTCF_Multiple ){
rc = saveAllCursors(pBt, pCur->pgnoRoot, pCur);
if( rc ) return rc;
@@ -8082,6 +8114,31 @@ int sqlite3BtreeDelete(BtCursor *pCur){
invalidateIncrblobCursors(p, pCur->info.nKey, 0);
}
/* If the bPreserve flag is set to true, then the cursor position must
** be preserved following this delete operation. If the current delete
** will cause a b-tree rebalance, then this is done by saving the cursor
** key and leaving the cursor in CURSOR_REQUIRESEEK state before
** returning.
**
** Or, if the current delete will not cause a rebalance, then the cursor
** will be left in CURSOR_SKIPNEXT state pointing to the entry immediately
** before or after the deleted entry. In this case set bSkipnext to true. */
if( bPreserve ){
if( !pPage->leaf
|| (pPage->nFree+cellSizePtr(pPage,pCell)+2)>(int)(pBt->usableSize*2/3)
){
/* A b-tree rebalance will be required after deleting this entry.
** Save the cursor key. */
rc = saveCursorKey(pCur);
if( rc ) return rc;
}else{
bSkipnext = 1;
}
}
/* Make the page containing the entry to be deleted writable. Then free any
** overflow pages associated with the entry and finally remove the cell
** itself from within the page. */
rc = sqlite3PagerWrite(pPage->pDbPage);
if( rc ) return rc;
rc = clearCell(pPage, pCell, &szCell);
@@ -8135,7 +8192,23 @@ int sqlite3BtreeDelete(BtCursor *pCur){
}
if( rc==SQLITE_OK ){
moveToRoot(pCur);
if( bSkipnext ){
assert( bPreserve && pCur->iPage==iCellDepth );
assert( pPage==pCur->apPage[pCur->iPage] );
assert( (pPage->nCell>0 || CORRUPT_DB) && iCellIdx<=pPage->nCell );
pCur->eState = CURSOR_SKIPNEXT;
if( iCellIdx>=pPage->nCell ){
pCur->skipNext = -1;
pCur->aiIdx[iCellDepth] = pPage->nCell-1;
}else{
pCur->skipNext = 1;
}
}else{
rc = moveToRoot(pCur);
if( bPreserve ){
pCur->eState = CURSOR_REQUIRESEEK;
}
}
}
return rc;
}
@@ -8857,6 +8930,10 @@ static void checkList(
#endif
iPage = get4byte(pOvflData);
sqlite3PagerUnref(pOvflPage);
if( isFreeList && N<(iPage!=0) ){
checkAppendMsg(pCheck, "free-page count in header is too small");
}
}
}
#endif /* SQLITE_OMIT_INTEGRITY_CHECK */
+1 -1
View File
@@ -185,7 +185,7 @@ int sqlite3BtreeMovetoUnpacked(
);
int sqlite3BtreeCursorHasMoved(BtCursor*);
int sqlite3BtreeCursorRestore(BtCursor*, int*);
int sqlite3BtreeDelete(BtCursor*);
int sqlite3BtreeDelete(BtCursor*, int);
int sqlite3BtreeInsert(BtCursor*, const void *pKey, i64 nKey,
const void *pData, int nData,
int nZero, int bias, int seekResult);
+22 -17
View File
@@ -192,6 +192,8 @@ void sqlite3FinishCoding(Parse *pParse){
db->aDb[iDb].pSchema->iGeneration /* P4 */
);
if( db->init.busy==0 ) sqlite3VdbeChangeP5(v, 1);
VdbeComment((v,
"usesStmtJournal=%d", pParse->mayAbort && pParse->isMultiWrite));
}
#ifndef SQLITE_OMIT_VIRTUALTABLE
for(i=0; i<pParse->nVtabLock; i++){
@@ -357,12 +359,14 @@ Table *sqlite3LocateTable(
if( p==0 ){
const char *zMsg = isView ? "no such view" : "no such table";
#ifndef SQLITE_OMIT_VIRTUALTABLE
/* If zName is the not the name of a table in the schema created using
** CREATE, then check to see if it is the name of an virtual table that
** can be an eponymous virtual table. */
Module *pMod = (Module*)sqlite3HashFind(&pParse->db->aModule, zName);
if( pMod && sqlite3VtabEponymousTableInit(pParse, pMod) ){
return pMod->pEpoTab;
if( sqlite3FindDbName(pParse->db, zDbase)<1 ){
/* If zName is the not the name of a table in the schema created using
** CREATE, then check to see if it is the name of an virtual table that
** can be an eponymous virtual table. */
Module *pMod = (Module*)sqlite3HashFind(&pParse->db->aModule, zName);
if( pMod && sqlite3VtabEponymousTableInit(pParse, pMod) ){
return pMod->pEpoTab;
}
}
#endif
if( zDbase ){
@@ -372,7 +376,7 @@ Table *sqlite3LocateTable(
}
pParse->checkSchema = 1;
}
#if SQLITE_USER_AUTHENICATION
#if SQLITE_USER_AUTHENTICATION
else if( pParse->db->auth.authLevel<UAUTH_User ){
sqlite3ErrorMsg(pParse, "user not authenticated");
p = 0;
@@ -981,9 +985,11 @@ void sqlite3StartTable(
** now.
*/
if( !db->init.busy && (v = sqlite3GetVdbe(pParse))!=0 ){
int j1;
int addr1;
int fileFormat;
int reg1, reg2, reg3;
/* nullRow[] is an OP_Record encoding of a row containing 5 NULLs */
static const char nullRow[] = { 6, 0, 0, 0, 0, 0 };
sqlite3BeginWriteOperation(pParse, 1, iDb);
#ifndef SQLITE_OMIT_VIRTUALTABLE
@@ -1000,14 +1006,14 @@ void sqlite3StartTable(
reg3 = ++pParse->nMem;
sqlite3VdbeAddOp3(v, OP_ReadCookie, iDb, reg3, BTREE_FILE_FORMAT);
sqlite3VdbeUsesBtree(v, iDb);
j1 = sqlite3VdbeAddOp1(v, OP_If, reg3); VdbeCoverage(v);
addr1 = sqlite3VdbeAddOp1(v, OP_If, reg3); VdbeCoverage(v);
fileFormat = (db->flags & SQLITE_LegacyFileFmt)!=0 ?
1 : SQLITE_MAX_FILE_FORMAT;
sqlite3VdbeAddOp2(v, OP_Integer, fileFormat, reg3);
sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_FILE_FORMAT, reg3);
sqlite3VdbeAddOp2(v, OP_Integer, ENC(db), reg3);
sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_TEXT_ENCODING, reg3);
sqlite3VdbeJumpHere(v, j1);
sqlite3VdbeJumpHere(v, addr1);
/* This just creates a place-holder record in the sqlite_master table.
** The record created does not contain anything yet. It will be replaced
@@ -1028,7 +1034,7 @@ void sqlite3StartTable(
}
sqlite3OpenMasterTable(pParse, iDb);
sqlite3VdbeAddOp2(v, OP_NewRowid, 0, reg1);
sqlite3VdbeAddOp2(v, OP_Null, 0, reg3);
sqlite3VdbeAddOp4(v, OP_Blob, 6, reg3, 0, nullRow, P4_STATIC);
sqlite3VdbeAddOp3(v, OP_Insert, 0, reg3, reg1);
sqlite3VdbeChangeP5(v, OPFLAG_APPEND);
sqlite3VdbeAddOp0(v, OP_Close);
@@ -2078,8 +2084,7 @@ void sqlite3CreateView(
if( pParse->nVar>0 ){
sqlite3ErrorMsg(pParse, "parameters are not allowed in views");
sqlite3SelectDelete(db, pSelect);
return;
goto create_view_fail;
}
sqlite3StartTable(pParse, pName1, pName2, isTemp, 1, 0, noErr);
p = pParse->pNewTable;
@@ -3131,7 +3136,7 @@ Index *sqlite3CreateIndex(
/* Analyze the list of expressions that form the terms of the index and
** report any errors. In the common case where the expression is exactly
** a table column, store that column in aiColumn[]. For general expressions,
** populate pIndex->aColExpr and store -2 in aiColumn[].
** populate pIndex->aColExpr and store XN_EXPR (-2) in aiColumn[].
**
** TODO: Issue a warning if two or more columns of the index are identical.
** TODO: Issue a warning if the table primary key is used as part of the
@@ -3160,8 +3165,8 @@ Index *sqlite3CreateIndex(
pListItem = &pCopy->a[i];
}
}
j = -2;
pIndex->aiColumn[i] = -2;
j = XN_EXPR;
pIndex->aiColumn[i] = XN_EXPR;
pIndex->uniqNotNull = 0;
}else{
j = pCExpr->iColumn;
@@ -3214,7 +3219,7 @@ Index *sqlite3CreateIndex(
}
assert( i==pIndex->nColumn );
}else{
pIndex->aiColumn[i] = -1;
pIndex->aiColumn[i] = XN_ROWID;
pIndex->azColl[i] = "BINARY";
}
sqlite3DefaultRowEst(pIndex);
+6
View File
@@ -96,12 +96,18 @@ static const char * const azCompileOpt[] = {
#if SQLITE_ENABLE_FTS4
"ENABLE_FTS4",
#endif
#if SQLITE_ENABLE_FTS5
"ENABLE_FTS5",
#endif
#if SQLITE_ENABLE_ICU
"ENABLE_ICU",
#endif
#if SQLITE_ENABLE_IOTRACE
"ENABLE_IOTRACE",
#endif
#if SQLITE_ENABLE_JSON1
"ENABLE_JSON1",
#endif
#if SQLITE_ENABLE_LOAD_EXTENSION
"ENABLE_LOAD_EXTENSION",
#endif
+77 -28
View File
@@ -16,6 +16,9 @@
** information from an SQLite database in order to implement the
** "sqlite3_analyzer" utility. See the ../tool/spaceanal.tcl script
** for an example implementation.
**
** Additional information is available on the "dbstat.html" page of the
** official SQLite documentation.
*/
#include "sqliteInt.h" /* Requires access to internal data structures */
@@ -64,7 +67,8 @@
" unused INTEGER, /* Bytes of unused space on this page */" \
" mx_payload INTEGER, /* Largest payload size of all cells */" \
" pgoffset INTEGER, /* Offset of page in file */" \
" pgsize INTEGER /* Size of the page */" \
" pgsize INTEGER, /* Size of the page */" \
" schema TEXT HIDDEN /* Database schema being analyzed */" \
");"
@@ -102,6 +106,7 @@ struct StatCursor {
sqlite3_vtab_cursor base;
sqlite3_stmt *pStmt; /* Iterates through set of root pages */
int isEof; /* After pStmt has returned SQLITE_DONE */
int iDb; /* Schema used for this query */
StatPage aPage[32];
int iPage; /* Current entry in aPage[] */
@@ -179,9 +184,32 @@ static int statDisconnect(sqlite3_vtab *pVtab){
/*
** There is no "best-index". This virtual table always does a linear
** scan of the binary VFS log file.
** scan. However, a schema=? constraint should cause this table to
** operate on a different database schema, so check for it.
**
** idxNum is normally 0, but will be 1 if a schema=? constraint exists.
*/
static int statBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
int i;
pIdxInfo->estimatedCost = 1.0e6; /* Initial cost estimate */
/* Look for a valid schema=? constraint. If found, change the idxNum to
** 1 and request the value of that constraint be sent to xFilter. And
** lower the cost estimate to encourage the constrained version to be
** used.
*/
for(i=0; i<pIdxInfo->nConstraint; i++){
if( pIdxInfo->aConstraint[i].usable==0 ) continue;
if( pIdxInfo->aConstraint[i].op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue;
if( pIdxInfo->aConstraint[i].iColumn!=10 ) continue;
pIdxInfo->idxNum = 1;
pIdxInfo->estimatedCost = 1.0;
pIdxInfo->aConstraintUsage[i].argvIndex = 1;
pIdxInfo->aConstraintUsage[i].omit = 1;
break;
}
/* Records are always returned in ascending order of (name, path).
** If this will satisfy the client, set the orderByConsumed flag so that
@@ -201,7 +229,6 @@ static int statBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
pIdxInfo->orderByConsumed = 1;
}
pIdxInfo->estimatedCost = 10.0;
return SQLITE_OK;
}
@@ -211,36 +238,18 @@ static int statBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
static int statOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){
StatTable *pTab = (StatTable *)pVTab;
StatCursor *pCsr;
int rc;
pCsr = (StatCursor *)sqlite3_malloc64(sizeof(StatCursor));
if( pCsr==0 ){
rc = SQLITE_NOMEM;
return SQLITE_NOMEM;
}else{
char *zSql;
memset(pCsr, 0, sizeof(StatCursor));
pCsr->base.pVtab = pVTab;
zSql = sqlite3_mprintf(
"SELECT 'sqlite_master' AS name, 1 AS rootpage, 'table' AS type"
" UNION ALL "
"SELECT name, rootpage, type"
" FROM \"%w\".sqlite_master WHERE rootpage!=0"
" ORDER BY name", pTab->db->aDb[pTab->iDb].zName);
if( zSql==0 ){
rc = SQLITE_NOMEM;
}else{
rc = sqlite3_prepare_v2(pTab->db, zSql, -1, &pCsr->pStmt, 0);
sqlite3_free(zSql);
}
if( rc!=SQLITE_OK ){
sqlite3_free(pCsr);
pCsr = 0;
}
pCsr->iDb = pTab->iDb;
}
*ppCursor = (sqlite3_vtab_cursor *)pCsr;
return rc;
return SQLITE_OK;
}
static void statClearPage(StatPage *p){
@@ -265,6 +274,7 @@ static void statResetCsr(StatCursor *pCsr){
pCsr->iPage = 0;
sqlite3_free(pCsr->zPath);
pCsr->zPath = 0;
pCsr->isEof = 0;
}
/*
@@ -427,7 +437,7 @@ static int statNext(sqlite3_vtab_cursor *pCursor){
char *z;
StatCursor *pCsr = (StatCursor *)pCursor;
StatTable *pTab = (StatTable *)pCursor->pVtab;
Btree *pBt = pTab->db->aDb[pTab->iDb].pBt;
Btree *pBt = pTab->db->aDb[pCsr->iDb].pBt;
Pager *pPager = sqlite3BtreePager(pBt);
sqlite3_free(pCsr->zPath);
@@ -565,9 +575,43 @@ static int statFilter(
int argc, sqlite3_value **argv
){
StatCursor *pCsr = (StatCursor *)pCursor;
StatTable *pTab = (StatTable*)(pCursor->pVtab);
char *zSql;
int rc = SQLITE_OK;
char *zMaster;
if( idxNum==1 ){
const char *zDbase = (const char*)sqlite3_value_text(argv[0]);
pCsr->iDb = sqlite3FindDbName(pTab->db, zDbase);
if( pCsr->iDb<0 ){
sqlite3_free(pCursor->pVtab->zErrMsg);
pCursor->pVtab->zErrMsg = sqlite3_mprintf("no such schema: %s", zDbase);
return pCursor->pVtab->zErrMsg ? SQLITE_ERROR : SQLITE_NOMEM;
}
}else{
pCsr->iDb = pTab->iDb;
}
statResetCsr(pCsr);
return statNext(pCursor);
sqlite3_finalize(pCsr->pStmt);
pCsr->pStmt = 0;
zMaster = pCsr->iDb==1 ? "sqlite_temp_master" : "sqlite_master";
zSql = sqlite3_mprintf(
"SELECT 'sqlite_master' AS name, 1 AS rootpage, 'table' AS type"
" UNION ALL "
"SELECT name, rootpage, type"
" FROM \"%w\".%s WHERE rootpage!=0"
" ORDER BY name", pTab->db->aDb[pCsr->iDb].zName, zMaster);
if( zSql==0 ){
return SQLITE_NOMEM;
}else{
rc = sqlite3_prepare_v2(pTab->db, zSql, -1, &pCsr->pStmt, 0);
sqlite3_free(zSql);
}
if( rc==SQLITE_OK ){
rc = statNext(pCursor);
}
return rc;
}
static int statColumn(
@@ -604,10 +648,15 @@ static int statColumn(
case 8: /* pgoffset */
sqlite3_result_int64(ctx, pCsr->iOffset);
break;
default: /* pgsize */
assert( i==9 );
case 9: /* pgsize */
sqlite3_result_int(ctx, pCsr->szPage);
break;
default: { /* schema */
sqlite3 *db = sqlite3_context_db_handle(ctx);
int iDb = pCsr->iDb;
sqlite3_result_text(ctx, db->aDb[iDb].zName, -1, SQLITE_STATIC);
break;
}
}
return SQLITE_OK;
}
+92 -44
View File
@@ -235,7 +235,7 @@ void sqlite3DeleteFrom(
int iDb; /* Database number */
int memCnt = -1; /* Memory cell used for change counting */
int rcauth; /* Value returned by authorization callback */
int okOnePass; /* True for one-pass algorithm without the FIFO */
int eOnePass; /* ONEPASS_OFF or _SINGLE or _MULTI */
int aiCurOnePass[2]; /* The write cursors opened by WHERE_ONEPASS */
u8 *aToOpen = 0; /* Open cursor iTabCur+j if aToOpen[j] is true */
Index *pPk; /* The PRIMARY KEY index on the table */
@@ -247,12 +247,12 @@ void sqlite3DeleteFrom(
int iRowSet = 0; /* Register for rowset of rows to delete */
int addrBypass = 0; /* Address of jump over the delete logic */
int addrLoop = 0; /* Top of the delete loop */
int addrDelete = 0; /* Jump directly to the delete logic */
int addrEphOpen = 0; /* Instruction to open the Ephemeral table */
#ifndef SQLITE_OMIT_TRIGGER
int isView; /* True if attempting to delete from a view */
Trigger *pTrigger; /* List of table triggers, if required */
int bComplex; /* True if there are either triggers or FKs */
#endif
memset(&sContext, 0, sizeof(sContext));
@@ -276,9 +276,11 @@ void sqlite3DeleteFrom(
#ifndef SQLITE_OMIT_TRIGGER
pTrigger = sqlite3TriggersExist(pParse, pTab, TK_DELETE, 0, 0);
isView = pTab->pSelect!=0;
bComplex = pTrigger || sqlite3FkRequired(pParse, pTab, 0, 0);
#else
# define pTrigger 0
# define isView 0
# define bComplex 0
#endif
#ifdef SQLITE_OMIT_VIEW
# undef isView
@@ -359,8 +361,10 @@ void sqlite3DeleteFrom(
** It is easier just to erase the whole table. Prior to version 3.6.5,
** this optimization caused the row change count (the value returned by
** API function sqlite3_count_changes) to be set incorrectly. */
if( rcauth==SQLITE_OK && pWhere==0 && !pTrigger && !IsVirtual(pTab)
&& 0==sqlite3FkRequired(pParse, pTab, 0, 0)
if( rcauth==SQLITE_OK
&& pWhere==0
&& !bComplex
&& !IsVirtual(pTab)
){
assert( !isView );
sqlite3TableLock(pParse, iDb, pTab->tnum, 1, pTab->zName);
@@ -375,6 +379,8 @@ void sqlite3DeleteFrom(
}else
#endif /* SQLITE_OMIT_TRUNCATE_OPTIMIZATION */
{
u16 wcf = WHERE_ONEPASS_DESIRED|WHERE_DUPLICATES_OK;
wcf |= (bComplex ? 0 : WHERE_ONEPASS_MULTIROW);
if( HasRowid(pTab) ){
/* For a rowid table, initialize the RowSet to an empty set */
pPk = 0;
@@ -395,13 +401,18 @@ void sqlite3DeleteFrom(
}
/* Construct a query to find the rowid or primary key for every row
** to be deleted, based on the WHERE clause.
** to be deleted, based on the WHERE clause. Set variable eOnePass
** to indicate the strategy used to implement this delete:
**
** ONEPASS_OFF: Two-pass approach - use a FIFO for rowids/PK values.
** ONEPASS_SINGLE: One-pass approach - at most one row deleted.
** ONEPASS_MULTI: One-pass approach - any number of rows may be deleted.
*/
pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0, 0,
WHERE_ONEPASS_DESIRED|WHERE_DUPLICATES_OK,
iTabCur+1);
pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0, 0, wcf, iTabCur+1);
if( pWInfo==0 ) goto delete_from_cleanup;
okOnePass = sqlite3WhereOkOnePass(pWInfo, aiCurOnePass);
eOnePass = sqlite3WhereOkOnePass(pWInfo, aiCurOnePass);
assert( IsVirtual(pTab)==0 || eOnePass!=ONEPASS_MULTI );
assert( IsVirtual(pTab) || bComplex || eOnePass!=ONEPASS_OFF );
/* Keep track of the number of rows to be deleted */
if( db->flags & SQLITE_CountRows ){
@@ -411,7 +422,7 @@ void sqlite3DeleteFrom(
/* Extract the rowid or primary key for the current row */
if( pPk ){
for(i=0; i<nPk; i++){
assert( pPk->aiColumn[i]>=(-1) );
assert( pPk->aiColumn[i]>=0 );
sqlite3ExprCodeGetColumnOfTable(v, pTab, iTabCur,
pPk->aiColumn[i], iPk+i);
}
@@ -422,11 +433,10 @@ void sqlite3DeleteFrom(
if( iKey>pParse->nMem ) pParse->nMem = iKey;
}
if( okOnePass ){
/* For ONEPASS, no need to store the rowid/primary-key. There is only
if( eOnePass!=ONEPASS_OFF ){
/* For ONEPASS, no need to store the rowid/primary-key. There is only
** one, so just keep it in its register(s) and fall through to the
** delete code.
*/
** delete code. */
nKey = nPk; /* OP_Found will use an unpacked key */
aToOpen = sqlite3DbMallocRaw(db, nIdx+2);
if( aToOpen==0 ){
@@ -438,27 +448,27 @@ void sqlite3DeleteFrom(
if( aiCurOnePass[0]>=0 ) aToOpen[aiCurOnePass[0]-iTabCur] = 0;
if( aiCurOnePass[1]>=0 ) aToOpen[aiCurOnePass[1]-iTabCur] = 0;
if( addrEphOpen ) sqlite3VdbeChangeToNoop(v, addrEphOpen);
addrDelete = sqlite3VdbeAddOp0(v, OP_Goto); /* Jump to DELETE logic */
}else if( pPk ){
/* Construct a composite key for the row to be deleted and remember it */
iKey = ++pParse->nMem;
nKey = 0; /* Zero tells OP_Found to use a composite key */
sqlite3VdbeAddOp4(v, OP_MakeRecord, iPk, nPk, iKey,
sqlite3IndexAffinityStr(pParse->db, pPk), nPk);
sqlite3VdbeAddOp2(v, OP_IdxInsert, iEphCur, iKey);
}else{
/* Get the rowid of the row to be deleted and remember it in the RowSet */
nKey = 1; /* OP_Seek always uses a single rowid */
sqlite3VdbeAddOp2(v, OP_RowSetAdd, iRowSet, iKey);
if( pPk ){
/* Add the PK key for this row to the temporary table */
iKey = ++pParse->nMem;
nKey = 0; /* Zero tells OP_Found to use a composite key */
sqlite3VdbeAddOp4(v, OP_MakeRecord, iPk, nPk, iKey,
sqlite3IndexAffinityStr(pParse->db, pPk), nPk);
sqlite3VdbeAddOp2(v, OP_IdxInsert, iEphCur, iKey);
}else{
/* Add the rowid of the row to be deleted to the RowSet */
nKey = 1; /* OP_Seek always uses a single rowid */
sqlite3VdbeAddOp2(v, OP_RowSetAdd, iRowSet, iKey);
}
}
/* End of the WHERE loop */
sqlite3WhereEnd(pWInfo);
if( okOnePass ){
/* Bypass the delete logic below if the WHERE loop found zero rows */
/* If this DELETE cannot use the ONEPASS strategy, this is the
** end of the WHERE loop */
if( eOnePass!=ONEPASS_OFF ){
addrBypass = sqlite3VdbeMakeLabel(v);
sqlite3VdbeGoto(v, addrBypass);
sqlite3VdbeJumpHere(v, addrDelete);
}else{
sqlite3WhereEnd(pWInfo);
}
/* Unless this is a view, open cursors for the table we are
@@ -467,21 +477,24 @@ void sqlite3DeleteFrom(
** triggers.
*/
if( !isView ){
int iAddrOnce = 0;
if( eOnePass==ONEPASS_MULTI ){
iAddrOnce = sqlite3CodeOnce(pParse); VdbeCoverage(v);
}
testcase( IsVirtual(pTab) );
sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenWrite, iTabCur, aToOpen,
&iDataCur, &iIdxCur);
assert( pPk || IsVirtual(pTab) || iDataCur==iTabCur );
assert( pPk || IsVirtual(pTab) || iIdxCur==iDataCur+1 );
if( eOnePass==ONEPASS_MULTI ) sqlite3VdbeJumpHere(v, iAddrOnce);
}
/* Set up a loop over the rowids/primary-keys that were found in the
** where-clause loop above.
*/
if( okOnePass ){
/* Just one row. Hence the top-of-loop is a no-op */
if( eOnePass!=ONEPASS_OFF ){
assert( nKey==nPk ); /* OP_Found will use an unpacked key */
assert( !IsVirtual(pTab) );
if( aToOpen[iDataCur-iTabCur] ){
if( !IsVirtual(pTab) && aToOpen[iDataCur-iTabCur] ){
assert( pPk!=0 || pTab->pSelect!=0 );
sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, addrBypass, iKey, nKey);
VdbeCoverage(v);
@@ -503,18 +516,27 @@ void sqlite3DeleteFrom(
sqlite3VtabMakeWritable(pParse, pTab);
sqlite3VdbeAddOp4(v, OP_VUpdate, 0, 1, iKey, pVTab, P4_VTAB);
sqlite3VdbeChangeP5(v, OE_Abort);
assert( eOnePass==ONEPASS_OFF || eOnePass==ONEPASS_SINGLE );
sqlite3MayAbort(pParse);
if( eOnePass==ONEPASS_SINGLE && sqlite3IsToplevel(pParse) ){
pParse->isMultiWrite = 0;
}
}else
#endif
{
int count = (pParse->nested==0); /* True to count changes */
int iIdxNoSeek = -1;
if( bComplex==0 && aiCurOnePass[1]!=iDataCur ){
iIdxNoSeek = aiCurOnePass[1];
}
sqlite3GenerateRowDelete(pParse, pTab, pTrigger, iDataCur, iIdxCur,
iKey, nKey, count, OE_Default, okOnePass);
iKey, nKey, count, OE_Default, eOnePass, iIdxNoSeek);
}
/* End of the loop over all rowids/primary-keys. */
if( okOnePass ){
if( eOnePass!=ONEPASS_OFF ){
sqlite3VdbeResolveLabel(v, addrBypass);
sqlite3WhereEnd(pWInfo);
}else if( pPk ){
sqlite3VdbeAddOp2(v, OP_Next, iEphCur, addrLoop+1); VdbeCoverage(v);
sqlite3VdbeJumpHere(v, addrLoop);
@@ -586,6 +608,25 @@ delete_from_cleanup:
** sequence of nPk memory cells starting at iPk. If nPk==0 that means
** that a search record formed from OP_MakeRecord is contained in the
** single memory location iPk.
**
** eMode:
** Parameter eMode may be passed either ONEPASS_OFF (0), ONEPASS_SINGLE, or
** ONEPASS_MULTI. If eMode is not ONEPASS_OFF, then the cursor
** iDataCur already points to the row to delete. If eMode is ONEPASS_OFF
** then this function must seek iDataCur to the entry identified by iPk
** and nPk before reading from it.
**
** If eMode is ONEPASS_MULTI, then this call is being made as part
** of a ONEPASS delete that affects multiple rows. In this case, if
** iIdxNoSeek is a valid cursor number (>=0), then its position should
** be preserved following the delete operation. Or, if iIdxNoSeek is not
** a valid cursor number, the position of iDataCur should be preserved
** instead.
**
** iIdxNoSeek:
** If iIdxNoSeek is a valid cursor number (>=0), then it identifies an
** index cursor (from within array of cursors starting at iIdxCur) that
** already points to the index entry to be deleted.
*/
void sqlite3GenerateRowDelete(
Parse *pParse, /* Parsing context */
@@ -597,7 +638,8 @@ void sqlite3GenerateRowDelete(
i16 nPk, /* Number of PRIMARY KEY memory cells */
u8 count, /* If non-zero, increment the row change counter */
u8 onconf, /* Default ON CONFLICT policy for triggers */
u8 bNoSeek /* iDataCur is already pointing to the row to delete */
u8 eMode, /* ONEPASS_OFF, _SINGLE, or _MULTI. See above */
int iIdxNoSeek /* Cursor number of cursor that does not need seeking */
){
Vdbe *v = pParse->pVdbe; /* Vdbe */
int iOld = 0; /* First register in OLD.* array */
@@ -614,7 +656,7 @@ void sqlite3GenerateRowDelete(
** not attempt to delete it or fire any DELETE triggers. */
iLabel = sqlite3VdbeMakeLabel(v);
opSeek = HasRowid(pTab) ? OP_NotExists : OP_NotFound;
if( !bNoSeek ){
if( eMode==ONEPASS_OFF ){
sqlite3VdbeAddOp4Int(v, opSeek, iDataCur, iLabel, iPk, nPk);
VdbeCoverageIf(v, opSeek==OP_NotExists);
VdbeCoverageIf(v, opSeek==OP_NotFound);
@@ -674,11 +716,15 @@ void sqlite3GenerateRowDelete(
** a view (in which case the only effect of the DELETE statement is to
** fire the INSTEAD OF triggers). */
if( pTab->pSelect==0 ){
sqlite3GenerateRowIndexDelete(pParse, pTab, iDataCur, iIdxCur, 0);
sqlite3GenerateRowIndexDelete(pParse, pTab, iDataCur, iIdxCur,0,iIdxNoSeek);
sqlite3VdbeAddOp2(v, OP_Delete, iDataCur, (count?OPFLAG_NCHANGE:0));
if( count ){
sqlite3VdbeChangeP4(v, -1, pTab->zName, P4_TRANSIENT);
}
if( iIdxNoSeek>=0 ){
sqlite3VdbeAddOp1(v, OP_Delete, iIdxNoSeek);
}
sqlite3VdbeChangeP5(v, eMode==ONEPASS_MULTI);
}
/* Do any ON CASCADE, SET NULL or SET DEFAULT operations required to
@@ -721,7 +767,8 @@ void sqlite3GenerateRowIndexDelete(
Table *pTab, /* Table containing the row to be deleted */
int iDataCur, /* Cursor of table holding data. */
int iIdxCur, /* First index cursor */
int *aRegIdx /* Only delete if aRegIdx!=0 && aRegIdx[i]>0 */
int *aRegIdx, /* Only delete if aRegIdx!=0 && aRegIdx[i]>0 */
int iIdxNoSeek /* Do not delete from this cursor */
){
int i; /* Index loop counter */
int r1 = -1; /* Register holding an index key */
@@ -737,11 +784,12 @@ void sqlite3GenerateRowIndexDelete(
assert( iIdxCur+i!=iDataCur || pPk==pIdx );
if( aRegIdx!=0 && aRegIdx[i]==0 ) continue;
if( pIdx==pPk ) continue;
if( iIdxCur+i==iIdxNoSeek ) continue;
VdbeModuleComment((v, "GenRowIdxDel for %s", pIdx->zName));
r1 = sqlite3GenerateIndexKey(pParse, pIdx, iDataCur, 0, 1,
&iPartIdxLabel, pPrior, r1);
&iPartIdxLabel, pPrior, r1);
sqlite3VdbeAddOp3(v, OP_IdxDelete, iIdxCur+i, r1,
pIdx->uniqNotNull ? pIdx->nKeyCol : pIdx->nColumn);
pIdx->uniqNotNull ? pIdx->nKeyCol : pIdx->nColumn);
sqlite3ResolvePartIdxLabel(pParse, iPartIdxLabel);
pPrior = pIdx;
}
@@ -810,7 +858,7 @@ int sqlite3GenerateIndexKey(
for(j=0; j<nCol; j++){
if( pPrior
&& pPrior->aiColumn[j]==pIdx->aiColumn[j]
&& pPrior->aiColumn[j]>=(-1)
&& pPrior->aiColumn[j]!=XN_EXPR
){
/* This column was already computed by the previous index */
continue;
+36 -22
View File
@@ -91,7 +91,7 @@ Expr *sqlite3ExprAddCollateString(Parse *pParse, Expr *pExpr, const char *zC){
}
/*
** Skip over any TK_COLLATE or TK_AS operators and any unlikely()
** Skip over any TK_COLLATE operators and any unlikely()
** or likelihood() function at the root of an expression.
*/
Expr *sqlite3ExprSkipCollate(Expr *pExpr){
@@ -102,7 +102,7 @@ Expr *sqlite3ExprSkipCollate(Expr *pExpr){
assert( pExpr->op==TK_FUNCTION );
pExpr = pExpr->x.pList->a[0].pExpr;
}else{
assert( pExpr->op==TK_COLLATE || pExpr->op==TK_AS );
assert( pExpr->op==TK_COLLATE );
pExpr = pExpr->pLeft;
}
}
@@ -1595,13 +1595,13 @@ int sqlite3CodeOnce(Parse *pParse){
** to be set to NULL if iCur contains one or more NULL values.
*/
static void sqlite3SetHasNullFlag(Vdbe *v, int iCur, int regHasNull){
int j1;
int addr1;
sqlite3VdbeAddOp2(v, OP_Integer, 0, regHasNull);
j1 = sqlite3VdbeAddOp1(v, OP_Rewind, iCur); VdbeCoverage(v);
addr1 = sqlite3VdbeAddOp1(v, OP_Rewind, iCur); VdbeCoverage(v);
sqlite3VdbeAddOp3(v, OP_Column, iCur, 0, regHasNull);
sqlite3VdbeChangeP5(v, OPFLAG_TYPEOFARG);
VdbeComment((v, "first_entry_in(%d)", iCur));
sqlite3VdbeJumpHere(v, j1);
sqlite3VdbeJumpHere(v, addr1);
}
@@ -2201,7 +2201,7 @@ static void sqlite3ExprCodeIN(
** the presence of a NULL on the RHS makes a difference in the
** outcome.
*/
int j1;
int addr1;
/* First check to see if the LHS is contained in the RHS. If so,
** then the answer is TRUE the presence of NULLs in the RHS does
@@ -2209,12 +2209,12 @@ static void sqlite3ExprCodeIN(
** answer is NULL if the RHS contains NULLs and the answer is
** FALSE if the RHS is NULL-free.
*/
j1 = sqlite3VdbeAddOp4Int(v, OP_Found, pExpr->iTable, 0, r1, 1);
addr1 = sqlite3VdbeAddOp4Int(v, OP_Found, pExpr->iTable, 0, r1, 1);
VdbeCoverage(v);
sqlite3VdbeAddOp2(v, OP_IsNull, rRhsHasNull, destIfNull);
VdbeCoverage(v);
sqlite3VdbeGoto(v, destIfFalse);
sqlite3VdbeJumpHere(v, j1);
sqlite3VdbeJumpHere(v, addr1);
}
}
}
@@ -2443,15 +2443,15 @@ void sqlite3ExprCodeLoadIndexColumn(
int regOut /* Store the index column value in this register */
){
i16 iTabCol = pIdx->aiColumn[iIdxCol];
if( iTabCol>=(-1) ){
if( iTabCol==XN_EXPR ){
assert( pIdx->aColExpr );
assert( pIdx->aColExpr->nExpr>iIdxCol );
pParse->iSelfTab = iTabCur;
sqlite3ExprCode(pParse, pIdx->aColExpr->a[iIdxCol].pExpr, regOut);
}else{
sqlite3ExprCodeGetColumnOfTable(pParse->pVdbe, pIdx->pTable, iTabCur,
iTabCol, regOut);
return;
}
assert( pIdx->aColExpr );
assert( pIdx->aColExpr->nExpr>iIdxCol );
pParse->iSelfTab = iTabCur;
sqlite3ExprCode(pParse, pIdx->aColExpr->a[iIdxCol].pExpr, regOut);
}
/*
@@ -2481,9 +2481,12 @@ void sqlite3ExprCodeGetColumnOfTable(
/*
** Generate code that will extract the iColumn-th column from
** table pTab and store the column value in a register. An effort
** is made to store the column value in register iReg, but this is
** not guaranteed. The location of the column value is returned.
** table pTab and store the column value in a register.
**
** An effort is made to store the column value in register iReg. This
** is not garanteeed for GetColumn() - the result can be stored in
** any register. But the result is guaranteed to land in register iReg
** for GetColumnToReg().
**
** There must be an open cursor to pTab in iTable when this routine
** is called. If iColumn<0 then code is generated that extracts the rowid.
@@ -2494,7 +2497,7 @@ int sqlite3ExprCodeGetColumn(
int iColumn, /* Index of the table column */
int iTable, /* The cursor pointing to the table */
int iReg, /* Store results here */
u8 p5 /* P5 value for OP_Column */
u8 p5 /* P5 value for OP_Column + FLAGS */
){
Vdbe *v = pParse->pVdbe;
int i;
@@ -2516,6 +2519,17 @@ int sqlite3ExprCodeGetColumn(
}
return iReg;
}
void sqlite3ExprCodeGetColumnToReg(
Parse *pParse, /* Parsing and code generating context */
Table *pTab, /* Description of the table we are reading from */
int iColumn, /* Index of the table column */
int iTable, /* The cursor pointing to the table */
int iReg /* Store results here */
){
int r1 = sqlite3ExprCodeGetColumn(pParse, pTab, iColumn, iTable, iReg, 0);
if( r1!=iReg ) sqlite3VdbeAddOp2(pParse->pVdbe, OP_SCopy, r1, iReg);
}
/*
** Clear all column cache entries.
@@ -2701,10 +2715,6 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){
inReg = pExpr->iTable;
break;
}
case TK_AS: {
inReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft, target);
break;
}
#ifndef SQLITE_OMIT_CAST
case TK_CAST: {
/* Expressions of the form: CAST(pLeft AS token) */
@@ -3346,6 +3356,10 @@ void sqlite3ExprCodeAndCache(Parse *pParse, Expr *pExpr, int target){
**
** The SQLITE_ECEL_FACTOR argument allows constant arguments to be
** factored out into initialization code.
**
** The SQLITE_ECEL_REF flag means that expressions in the list with
** ExprList.a[].u.x.iOrderByCol>0 have already been evaluated and stored
** in registers at srcReg, and so the value can be copied from there.
*/
int sqlite3ExprCodeExprList(
Parse *pParse, /* Parsing context */
+10 -1
View File
@@ -252,6 +252,8 @@ int sqlite3FkLocateIndex(
char *zDfltColl; /* Def. collation for column */
char *zIdxCol; /* Name of indexed column */
if( iCol<0 ) break; /* No foreign keys against expression indexes */
/* If the index uses a collation sequence that is different from
** the default collation sequence for the column, this index is
** unusable. Bail out early in this case. */
@@ -404,6 +406,7 @@ static void fkLookupParent(
for(i=0; i<nCol; i++){
int iChild = aiCol[i]+1+regData;
int iParent = pIdx->aiColumn[i]+1+regData;
assert( pIdx->aiColumn[i]>=0 );
assert( aiCol[i]!=pTab->iPKey );
if( pIdx->aiColumn[i]==pTab->iPKey ){
/* The parent key is a composite key that includes the IPK column */
@@ -612,6 +615,7 @@ static void fkScanChildren(
assert( pIdx!=0 );
for(i=0; i<pPk->nKeyCol; i++){
i16 iCol = pIdx->aiColumn[i];
assert( iCol>=0 );
pLeft = exprTableRegister(pParse, pTab, regData, iCol);
pRight = exprTableColumn(db, pTab, pSrc->a[0].iCursor, iCol);
pEq = sqlite3PExpr(pParse, TK_EQ, pLeft, pRight, 0);
@@ -931,6 +935,7 @@ void sqlite3FkCheck(
if( aiCol[i]==pTab->iPKey ){
aiCol[i] = -1;
}
assert( pIdx==0 || pIdx->aiColumn[i]>=0 );
#ifndef SQLITE_OMIT_AUTHORIZATION
/* Request permission to read the parent key columns. If the
** authorization callback returns SQLITE_IGNORE, behave as if any
@@ -1062,7 +1067,10 @@ u32 sqlite3FkOldmask(
Index *pIdx = 0;
sqlite3FkLocateIndex(pParse, pTab, p, &pIdx, 0);
if( pIdx ){
for(i=0; i<pIdx->nKeyCol; i++) mask |= COLUMN_MASK(pIdx->aiColumn[i]);
for(i=0; i<pIdx->nKeyCol; i++){
assert( pIdx->aiColumn[i]>=0 );
mask |= COLUMN_MASK(pIdx->aiColumn[i]);
}
}
}
}
@@ -1185,6 +1193,7 @@ static Trigger *fkActionTrigger(
iFromCol = aiCol ? aiCol[i] : pFKey->aCol[0].iFrom;
assert( iFromCol>=0 );
assert( pIdx!=0 || (pTab->iPKey>=0 && pTab->iPKey<pTab->nCol) );
assert( pIdx==0 || pIdx->aiColumn[i]>=0 );
tToCol.z = pTab->aCol[pIdx ? pIdx->aiColumn[i] : pTab->iPKey].zName;
tFromCol.z = pFKey->pFrom->aCol[iFromCol].zName;
+33 -26
View File
@@ -90,11 +90,11 @@ const char *sqlite3IndexAffinityStr(sqlite3 *db, Index *pIdx){
i16 x = pIdx->aiColumn[n];
if( x>=0 ){
pIdx->zColAff[n] = pTab->aCol[x].affinity;
}else if( x==(-1) ){
}else if( x==XN_ROWID ){
pIdx->zColAff[n] = SQLITE_AFF_INTEGER;
}else{
char aff;
assert( x==(-2) );
assert( x==XN_EXPR );
assert( pIdx->aColExpr!=0 );
aff = sqlite3ExprAffinity(pIdx->aColExpr->a[n].pExpr);
if( aff==0 ) aff = SQLITE_AFF_BLOB;
@@ -260,7 +260,7 @@ void sqlite3AutoincrementBegin(Parse *pParse){
/* This routine is never called during trigger-generation. It is
** only called from the top-level */
assert( pParse->pTriggerTab==0 );
assert( pParse==sqlite3ParseToplevel(pParse) );
assert( sqlite3IsToplevel(pParse) );
assert( v ); /* We failed long ago if this is not so */
for(p = pParse->pAinc; p; p = p->pNext){
@@ -313,16 +313,16 @@ void sqlite3AutoincrementEnd(Parse *pParse){
assert( v );
for(p = pParse->pAinc; p; p = p->pNext){
Db *pDb = &db->aDb[p->iDb];
int j1;
int addr1;
int iRec;
int memId = p->regCtr;
iRec = sqlite3GetTempReg(pParse);
assert( sqlite3SchemaMutexHeld(db, 0, pDb->pSchema) );
sqlite3OpenTable(pParse, 0, p->iDb, pDb->pSchema->pSeqTab, OP_OpenWrite);
j1 = sqlite3VdbeAddOp1(v, OP_NotNull, memId+1); VdbeCoverage(v);
addr1 = sqlite3VdbeAddOp1(v, OP_NotNull, memId+1); VdbeCoverage(v);
sqlite3VdbeAddOp2(v, OP_NewRowid, 0, memId+1);
sqlite3VdbeJumpHere(v, j1);
sqlite3VdbeJumpHere(v, addr1);
sqlite3VdbeAddOp3(v, OP_MakeRecord, memId-1, 2, iRec);
sqlite3VdbeAddOp3(v, OP_Insert, 0, iRec, memId+1);
sqlite3VdbeChangeP5(v, OPFLAG_APPEND);
@@ -814,7 +814,7 @@ void sqlite3Insert(
if( ipkColumn<0 ){
sqlite3VdbeAddOp2(v, OP_Integer, -1, regCols);
}else{
int j1;
int addr1;
assert( !withoutRowid );
if( useTempTable ){
sqlite3VdbeAddOp3(v, OP_Column, srcTab, ipkColumn, regCols);
@@ -822,9 +822,9 @@ void sqlite3Insert(
assert( pSelect==0 ); /* Otherwise useTempTable is true */
sqlite3ExprCode(pParse, pList->a[ipkColumn].pExpr, regCols);
}
j1 = sqlite3VdbeAddOp1(v, OP_NotNull, regCols); VdbeCoverage(v);
addr1 = sqlite3VdbeAddOp1(v, OP_NotNull, regCols); VdbeCoverage(v);
sqlite3VdbeAddOp2(v, OP_Integer, -1, regCols);
sqlite3VdbeJumpHere(v, j1);
sqlite3VdbeJumpHere(v, addr1);
sqlite3VdbeAddOp1(v, OP_MustBeInt, regCols); VdbeCoverage(v);
}
@@ -898,14 +898,14 @@ void sqlite3Insert(
** to generate a unique primary key value.
*/
if( !appendFlag ){
int j1;
int addr1;
if( !IsVirtual(pTab) ){
j1 = sqlite3VdbeAddOp1(v, OP_NotNull, regRowid); VdbeCoverage(v);
addr1 = sqlite3VdbeAddOp1(v, OP_NotNull, regRowid); VdbeCoverage(v);
sqlite3VdbeAddOp3(v, OP_NewRowid, iDataCur, regRowid, regAutoinc);
sqlite3VdbeJumpHere(v, j1);
sqlite3VdbeJumpHere(v, addr1);
}else{
j1 = sqlite3VdbeCurrentAddr(v);
sqlite3VdbeAddOp2(v, OP_IsNull, regRowid, j1+2); VdbeCoverage(v);
addr1 = sqlite3VdbeCurrentAddr(v);
sqlite3VdbeAddOp2(v, OP_IsNull, regRowid, addr1+2); VdbeCoverage(v);
}
sqlite3VdbeAddOp1(v, OP_MustBeInt, regRowid); VdbeCoverage(v);
}
@@ -1159,7 +1159,7 @@ void sqlite3GenerateConstraintChecks(
int ix; /* Index loop counter */
int nCol; /* Number of columns */
int onError; /* Conflict resolution strategy */
int j1; /* Address of jump instruction */
int addr1; /* Address of jump instruction */
int seenReplace = 0; /* True if REPLACE is used to resolve INT PK conflict */
int nPkField; /* Number of fields in PRIMARY KEY. 1 for ROWID tables */
int ipkTop = 0; /* Top of the rowid change constraint check */
@@ -1230,9 +1230,10 @@ void sqlite3GenerateConstraintChecks(
}
default: {
assert( onError==OE_Replace );
j1 = sqlite3VdbeAddOp1(v, OP_NotNull, regNewData+1+i); VdbeCoverage(v);
addr1 = sqlite3VdbeAddOp1(v, OP_NotNull, regNewData+1+i);
VdbeCoverage(v);
sqlite3ExprCode(pParse, pTab->aCol[i].pDflt, regNewData+1+i);
sqlite3VdbeJumpHere(v, j1);
sqlite3VdbeJumpHere(v, addr1);
break;
}
}
@@ -1347,10 +1348,13 @@ void sqlite3GenerateConstraintChecks(
if( pTrigger || sqlite3FkRequired(pParse, pTab, 0, 0) ){
sqlite3MultiWrite(pParse);
sqlite3GenerateRowDelete(pParse, pTab, pTrigger, iDataCur, iIdxCur,
regNewData, 1, 0, OE_Replace, 1);
}else if( pTab->pIndex ){
sqlite3MultiWrite(pParse);
sqlite3GenerateRowIndexDelete(pParse, pTab, iDataCur, iIdxCur, 0);
regNewData, 1, 0, OE_Replace,
ONEPASS_SINGLE, -1);
}else{
if( pTab->pIndex ){
sqlite3MultiWrite(pParse);
sqlite3GenerateRowIndexDelete(pParse, pTab, iDataCur, iIdxCur,0,-1);
}
}
seenReplace = 1;
break;
@@ -1405,20 +1409,20 @@ void sqlite3GenerateConstraintChecks(
for(i=0; i<pIdx->nColumn; i++){
int iField = pIdx->aiColumn[i];
int x;
if( iField==(-2) ){
if( iField==XN_EXPR ){
pParse->ckBase = regNewData+1;
sqlite3ExprCode(pParse, pIdx->aColExpr->a[i].pExpr, regIdx+i);
pParse->ckBase = 0;
VdbeComment((v, "%s column %d", pIdx->zName, i));
}else{
if( iField==(-1) || iField==pTab->iPKey ){
if( iField==XN_ROWID || iField==pTab->iPKey ){
if( regRowid==regIdx+i ) continue; /* ROWID already in regIdx+i */
x = regNewData;
regRowid = pIdx->pPartIdxWhere ? -1 : regIdx+i;
}else{
x = iField + regNewData + 1;
}
sqlite3VdbeAddOp2(v, OP_SCopy, x, regIdx+i);
sqlite3VdbeAddOp2(v, iField<0 ? OP_IntCopy : OP_SCopy, x, regIdx+i);
VdbeComment((v, "%s", iField<0 ? "rowid" : pTab->aCol[iField].zName));
}
}
@@ -1470,6 +1474,7 @@ void sqlite3GenerateConstraintChecks(
** store it in registers regR..regR+nPk-1 */
if( pIdx!=pPk ){
for(i=0; i<pPk->nKeyCol; i++){
assert( pPk->aiColumn[i]>=0 );
x = sqlite3ColumnOfIndex(pIdx, pPk->aiColumn[i]);
sqlite3VdbeAddOp3(v, OP_Column, iThisCur, x, regR+i);
VdbeComment((v, "%s.%s", pTab->zName,
@@ -1491,6 +1496,7 @@ void sqlite3GenerateConstraintChecks(
for(i=0; i<pPk->nKeyCol; i++){
char *p4 = (char*)sqlite3LocateCollSeq(pParse, pPk->azColl[i]);
x = pPk->aiColumn[i];
assert( x>=0 );
if( i==(pPk->nKeyCol-1) ){
addrJump = addrUniqueOk;
op = OP_Eq;
@@ -1528,7 +1534,8 @@ void sqlite3GenerateConstraintChecks(
pTrigger = sqlite3TriggersExist(pParse, pTab, TK_DELETE, 0, 0);
}
sqlite3GenerateRowDelete(pParse, pTab, pTrigger, iDataCur, iIdxCur,
regR, nPkField, 0, OE_Replace, pIdx==pPk);
regR, nPkField, 0, OE_Replace,
(pIdx==pPk ? ONEPASS_SINGLE : ONEPASS_OFF), -1);
seenReplace = 1;
break;
}
@@ -1741,7 +1748,7 @@ static int xferCompatibleIndex(Index *pDest, Index *pSrc){
if( pSrc->aiColumn[i]!=pDest->aiColumn[i] ){
return 0; /* Different columns indexed */
}
if( pSrc->aiColumn[i]==(-2) ){
if( pSrc->aiColumn[i]==XN_EXPR ){
assert( pSrc->aColExpr!=0 && pDest->aColExpr!=0 );
if( sqlite3ExprCompare(pSrc->aColExpr->a[i].pExpr,
pDest->aColExpr->a[i].pExpr, -1)!=0 ){
+70 -39
View File
@@ -56,15 +56,19 @@
** ParseARG_PDECL A parameter declaration for the %extra_argument
** ParseARG_STORE Code to store %extra_argument into yypParser
** ParseARG_FETCH Code to extract %extra_argument from yypParser
** YYNSTATE the combined number of states.
** YYNRULE the number of rules in the grammar
** YYERRORSYMBOL is the code number of the error symbol. If not
** defined, then do no error processing.
** YYNSTATE the combined number of states.
** YYNRULE the number of rules in the grammar
** YY_MAX_SHIFT Maximum value for shift actions
** YY_MIN_SHIFTREDUCE Minimum value for shift-reduce actions
** YY_MAX_SHIFTREDUCE Maximum value for shift-reduce actions
** YY_MIN_REDUCE Maximum value for reduce actions
** YY_ERROR_ACTION The yy_action[] code for syntax error
** YY_ACCEPT_ACTION The yy_action[] code for accept
** YY_NO_ACTION The yy_action[] code for no-op
*/
%%
#define YY_NO_ACTION (YYNSTATE+YYNRULE+2)
#define YY_ACCEPT_ACTION (YYNSTATE+YYNRULE+1)
#define YY_ERROR_ACTION (YYNSTATE+YYNRULE)
/* The yyzerominor constant is used to initialize instances of
** YYMINORTYPE objects to zero. */
@@ -91,16 +95,20 @@ static const YYMINORTYPE yyzerominor = { 0 };
** Suppose the action integer is N. Then the action is determined as
** follows
**
** 0 <= N < YYNSTATE Shift N. That is, push the lookahead
** 0 <= N <= YY_MAX_SHIFT Shift N. That is, push the lookahead
** token onto the stack and goto state N.
**
** YYNSTATE <= N < YYNSTATE+YYNRULE Reduce by rule N-YYNSTATE.
** N between YY_MIN_SHIFTREDUCE Shift to an arbitrary state then
** and YY_MAX_SHIFTREDUCE reduce by rule N-YY_MIN_SHIFTREDUCE.
**
** N == YYNSTATE+YYNRULE A syntax error has occurred.
** N between YY_MIN_REDUCE Reduce by rule N-YY_MIN_REDUCE
** and YY_MAX_REDUCE
** N == YY_ERROR_ACTION A syntax error has occurred.
**
** N == YYNSTATE+YYNRULE+1 The parser accepts its input.
** N == YY_ACCEPT_ACTION The parser accepts its input.
**
** N == YYNSTATE+YYNRULE+2 No such action. Denotes unused
** N == YY_NO_ACTION No such action. Denotes unused
** slots in the yy_action[] table.
**
** The action table is constructed as a single large table named yy_action[].
@@ -159,9 +167,13 @@ static const YYCODETYPE yyFallback[] = {
** + The semantic value stored at this level of the stack. This is
** the information used by the action routines in the grammar.
** It is sometimes called the "minor" token.
**
** After the "shift" half of a SHIFTREDUCE action, the stateno field
** actually contains the reduce action for the second half of the
** SHIFTREDUCE.
*/
struct yyStackEntry {
YYACTIONTYPE stateno; /* The state-number */
YYACTIONTYPE stateno; /* The state-number, or reduce action in SHIFTREDUCE */
YYCODETYPE major; /* The major token value. This is the code
** number for the token at this stack level */
YYMINORTYPE minor; /* The user-supplied minor token value. This
@@ -395,10 +407,10 @@ static int yy_find_shift_action(
int i;
int stateno = pParser->yystack[pParser->yyidx].stateno;
if( stateno>YY_SHIFT_COUNT
|| (i = yy_shift_ofst[stateno])==YY_SHIFT_USE_DFLT ){
return yy_default[stateno];
}
if( stateno>=YY_MIN_REDUCE ) return stateno;
assert( stateno <= YY_SHIFT_COUNT );
i = yy_shift_ofst[stateno];
if( i==YY_SHIFT_USE_DFLT ) return yy_default[stateno];
assert( iLookAhead!=YYNOCODE );
i += iLookAhead;
if( i<0 || i>=YY_ACTTAB_COUNT || yy_lookahead[i]!=iLookAhead ){
@@ -499,7 +511,29 @@ static void yyStackOverflow(yyParser *yypParser, YYMINORTYPE *yypMinor){
}
/*
** Perform a shift action.
** Print tracing information for a SHIFT action
*/
#ifndef NDEBUG
static void yyTraceShift(yyParser *yypParser, int yyNewState){
if( yyTraceFILE ){
int i;
if( yyNewState<YYNSTATE ){
fprintf(yyTraceFILE,"%sShift %d\n",yyTracePrompt,yyNewState);
fprintf(yyTraceFILE,"%sStack:",yyTracePrompt);
for(i=1; i<=yypParser->yyidx; i++)
fprintf(yyTraceFILE," %s",yyTokenName[yypParser->yystack[i].major]);
fprintf(yyTraceFILE,"\n");
}else{
fprintf(yyTraceFILE,"%sShift *\n",yyTracePrompt);
}
}
}
#else
# define yyTraceShift(X,Y)
#endif
/*
** Perform a shift action. Return the number of errors.
*/
static void yy_shift(
yyParser *yypParser, /* The parser to be shifted */
@@ -532,16 +566,7 @@ static void yy_shift(
yytos->stateno = (YYACTIONTYPE)yyNewState;
yytos->major = (YYCODETYPE)yyMajor;
yytos->minor = *yypMinor;
#ifndef NDEBUG
if( yyTraceFILE && yypParser->yyidx>0 ){
int i;
fprintf(yyTraceFILE,"%sShift %d\n",yyTracePrompt,yyNewState);
fprintf(yyTraceFILE,"%sStack:",yyTracePrompt);
for(i=1; i<=yypParser->yyidx; i++)
fprintf(yyTraceFILE," %s",yyTokenName[yypParser->yystack[i].major]);
fprintf(yyTraceFILE,"\n");
}
#endif
yyTraceShift(yypParser, yyNewState);
}
/* The following table contains information about every rule that
@@ -574,8 +599,9 @@ static void yy_reduce(
#ifndef NDEBUG
if( yyTraceFILE && yyruleno>=0
&& yyruleno<(int)(sizeof(yyRuleName)/sizeof(yyRuleName[0])) ){
fprintf(yyTraceFILE, "%sReduce [%s].\n", yyTracePrompt,
yyRuleName[yyruleno]);
yysize = yyRuleInfo[yyruleno].nrhs;
fprintf(yyTraceFILE, "%sReduce [%s] -> state %d.\n", yyTracePrompt,
yyRuleName[yyruleno], yymsp[-yysize].stateno);
}
#endif /* NDEBUG */
@@ -613,9 +639,9 @@ static void yy_reduce(
yysize = yyRuleInfo[yyruleno].nrhs;
yypParser->yyidx -= yysize;
yyact = yy_find_reduce_action(yymsp[-yysize].stateno,(YYCODETYPE)yygoto);
if( yyact < YYNSTATE ){
#ifdef NDEBUG
/* If we are not debugging and the reduce action popped at least
if( yyact <= YY_MAX_SHIFTREDUCE ){
if( yyact>YY_MAX_SHIFT ) yyact += YY_MIN_REDUCE - YY_MIN_SHIFTREDUCE;
/* If the reduce action popped at least
** one element off the stack, then we can push the new element back
** onto the stack here, and skip the stack overflow test in yy_shift().
** That gives a significant speed improvement. */
@@ -625,13 +651,12 @@ static void yy_reduce(
yymsp->stateno = (YYACTIONTYPE)yyact;
yymsp->major = (YYCODETYPE)yygoto;
yymsp->minor = yygotominor;
}else
#endif
{
yyTraceShift(yypParser, yyact);
}else{
yy_shift(yypParser,yyact,yygoto,&yygotominor);
}
}else{
assert( yyact == YYNSTATE + YYNRULE + 1 );
assert( yyact == YY_ACCEPT_ACTION );
yy_accept(yypParser);
}
}
@@ -755,12 +780,13 @@ void Parse(
do{
yyact = yy_find_shift_action(yypParser,(YYCODETYPE)yymajor);
if( yyact<YYNSTATE ){
if( yyact <= YY_MAX_SHIFTREDUCE ){
if( yyact > YY_MAX_SHIFT ) yyact += YY_MIN_REDUCE - YY_MIN_SHIFTREDUCE;
yy_shift(yypParser,yyact,yymajor,&yyminorunion);
yypParser->yyerrcnt--;
yymajor = YYNOCODE;
}else if( yyact < YYNSTATE + YYNRULE ){
yy_reduce(yypParser,yyact-YYNSTATE);
}else if( yyact <= YY_MAX_REDUCE ){
yy_reduce(yypParser,yyact-YY_MIN_REDUCE);
}else{
assert( yyact == YY_ERROR_ACTION );
#ifdef YYERRORSYMBOL
@@ -810,7 +836,7 @@ void Parse(
yymx != YYERRORSYMBOL &&
(yyact = yy_find_reduce_action(
yypParser->yystack[yypParser->yyidx].stateno,
YYERRORSYMBOL)) >= YYNSTATE
YYERRORSYMBOL)) >= YY_MIN_REDUCE
){
yy_pop_parser_stack(yypParser);
}
@@ -860,5 +886,10 @@ void Parse(
#endif
}
}while( yymajor!=YYNOCODE && yypParser->yyidx>=0 );
#ifndef NDEBUG
if( yyTraceFILE ){
fprintf(yyTraceFILE,"%sReturn\n",yyTracePrompt);
}
#endif
return;
}
+4 -1
View File
@@ -407,7 +407,10 @@ static const sqlite3_api_routines sqlite3Apis = {
(sqlite3_value*(*)(const sqlite3_value*))sqlite3_value_dup,
sqlite3_value_free,
sqlite3_result_zeroblob64,
sqlite3_bind_zeroblob64
sqlite3_bind_zeroblob64,
/* Version 3.9.0 and later */
sqlite3_value_subtype,
sqlite3_result_subtype
};
/*
+19 -1
View File
@@ -25,6 +25,12 @@
#ifdef SQLITE_ENABLE_ICU
# include "sqliteicu.h"
#endif
#ifdef SQLITE_ENABLE_JSON1
int sqlite3Json1Init(sqlite3*);
#endif
#ifdef SQLITE_ENABLE_FTS5
int sqlite3Fts5Init(sqlite3*);
#endif
#ifndef SQLITE_AMALGAMATION
/* IMPLEMENTATION-OF: R-46656-45156 The sqlite3_version[] string constant
@@ -2872,12 +2878,18 @@ static int openDatabase(
}
#endif
#ifdef SQLITE_ENABLE_FTS3
#ifdef SQLITE_ENABLE_FTS3 /* automatically defined by SQLITE_ENABLE_FTS4 */
if( !db->mallocFailed && rc==SQLITE_OK ){
rc = sqlite3Fts3Init(db);
}
#endif
#ifdef SQLITE_ENABLE_FTS5
if( !db->mallocFailed && rc==SQLITE_OK ){
rc = sqlite3Fts5Init(db);
}
#endif
#ifdef SQLITE_ENABLE_ICU
if( !db->mallocFailed && rc==SQLITE_OK ){
rc = sqlite3IcuInit(db);
@@ -2896,6 +2908,12 @@ static int openDatabase(
}
#endif
#ifdef SQLITE_ENABLE_JSON1
if( !db->mallocFailed && rc==SQLITE_OK){
rc = sqlite3Json1Init(db);
}
#endif
/* -DSQLITE_DEFAULT_LOCKING_MODE=1 makes EXCLUSIVE the default locking
** mode. -DSQLITE_DEFAULT_LOCKING_MODE=0 make NORMAL the default locking
** mode. Doing nothing at all also makes NORMAL the default.
+51 -68
View File
@@ -45,7 +45,7 @@ typedef struct ScratchFreeslot {
*/
static SQLITE_WSD struct Mem0Global {
sqlite3_mutex *mutex; /* Mutex to serialize access */
sqlite3_int64 alarmThreshold; /* The soft heap limit */
sqlite3_int64 alarmThreshold; /* The soft heap limit */
/*
** Pointers to the end of sqlite3GlobalConfig.pScratch memory
@@ -73,59 +73,20 @@ sqlite3_mutex *sqlite3MallocMutex(void){
return mem0.mutex;
}
/*
** Return the amount of memory currently in use.
*/
static sqlite3_int64 memInUse(void){
assert( sqlite3_mutex_held(mem0.mutex) );
return sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED);
}
/*
** Called when the soft heap limit is exceeded for an allocation
** of nBytes.
*/
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
static void sqlite3HeapLimitExceeded(int nByte){
sqlite3_int64 excess = memInUse() + nByte - mem0.alarmThreshold;
sqlite3_mutex_leave(mem0.mutex);
sqlite3_release_memory((int)(excess & 0x7fffffff));
sqlite3_mutex_enter(mem0.mutex);
}
#else
# define sqlite3HeapLimitExceeded(X) /* no-op */
#endif
/*
** Check to see if increasing the total memory usage by nNew bytes
** will exceed the soft heap limit.
**
** If the soft heap limit is exceeded, set the mem0.nearlyFull flag
** and invoke sqlite3HeapLimitExceeded() to try to free up some
** memory.
*/
static void sqlite3CheckSoftHeapLimit(int nNew){
assert( sqlite3_mutex_held(mem0.mutex) );
if( mem0.alarmThreshold>0 ){
if( mem0.alarmThreshold-nNew >= memInUse() ){
mem0.nearlyFull = 1;
sqlite3HeapLimitExceeded(nNew);
}else{
mem0.nearlyFull = 0;
}
}
}
#ifndef SQLITE_OMIT_DEPRECATED
/*
** Deprecated external interface. First deprecated 2007-11-05. Changed
** into a no-op on 2015-09-02.
** Deprecated external interface. It used to set an alarm callback
** that was invoked when memory usage grew too large. Now it is a
** no-op.
*/
int sqlite3_memory_alarm(
void(*xCallback)(void *pArg, sqlite3_int64 used,int N),
void *pArg,
sqlite3_int64 iThreshold
){
(void)xCallback;
(void)pArg;
(void)iThreshold;
return SQLITE_OK;
}
#endif
@@ -136,20 +97,24 @@ int sqlite3_memory_alarm(
*/
sqlite3_int64 sqlite3_soft_heap_limit64(sqlite3_int64 n){
sqlite3_int64 priorLimit;
sqlite3_int64 excess;
sqlite3_int64 nUsed;
#ifndef SQLITE_OMIT_AUTOINIT
int rc = sqlite3_initialize();
if( rc ) return -1;
#endif
sqlite3_mutex_enter(mem0.mutex);
priorLimit = mem0.alarmThreshold;
if( n>0 ){
mem0.alarmThreshold = n;
sqlite3CheckSoftHeapLimit(0);
}else if( n==0 ){
mem0.alarmThreshold = 0;
mem0.nearlyFull = 0;
if( n<0 ){
sqlite3_mutex_leave(mem0.mutex);
return priorLimit;
}
mem0.alarmThreshold = n;
nUsed = sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED);
mem0.nearlyFull = (n>0 && n<=nUsed);
sqlite3_mutex_leave(mem0.mutex);
excess = sqlite3_memory_used() - n;
if( excess>0 ) sqlite3_release_memory((int)(excess & 0x7fffffff));
return priorLimit;
}
void sqlite3_soft_heap_limit(int n){
@@ -166,9 +131,7 @@ int sqlite3MallocInit(void){
sqlite3MemSetDefault();
}
memset(&mem0, 0, sizeof(mem0));
if( sqlite3GlobalConfig.bCoreMutex ){
mem0.mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MEM);
}
mem0.mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MEM);
if( sqlite3GlobalConfig.pScratch && sqlite3GlobalConfig.szScratch>=100
&& sqlite3GlobalConfig.nScratch>0 ){
int i, n, sz;
@@ -240,6 +203,16 @@ sqlite3_int64 sqlite3_memory_highwater(int resetFlag){
return mx;
}
/*
** Trigger the alarm
*/
static void sqlite3MallocAlarm(int nByte){
if( mem0.alarmThreshold<=0 ) return;
sqlite3_mutex_leave(mem0.mutex);
sqlite3_release_memory(nByte);
sqlite3_mutex_enter(mem0.mutex);
}
/*
** Do a memory allocation with statistics and alarms. Assume the
** lock is already held.
@@ -249,12 +222,20 @@ static int mallocWithAlarm(int n, void **pp){
void *p;
assert( sqlite3_mutex_held(mem0.mutex) );
nFull = sqlite3GlobalConfig.m.xRoundup(n);
sqlite3StatusSet(SQLITE_STATUS_MALLOC_SIZE, n);
sqlite3CheckSoftHeapLimit(nFull);
sqlite3StatusHighwater(SQLITE_STATUS_MALLOC_SIZE, n);
if( mem0.alarmThreshold>0 ){
sqlite3_int64 nUsed = sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED);
if( nUsed >= mem0.alarmThreshold - nFull ){
mem0.nearlyFull = 1;
sqlite3MallocAlarm(nFull);
}else{
mem0.nearlyFull = 0;
}
}
p = sqlite3GlobalConfig.m.xMalloc(nFull);
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
if( p==0 && mem0.alarmThreshold ){
sqlite3HeapLimitExceeded(nFull);
if( p==0 && mem0.alarmThreshold>0 ){
sqlite3MallocAlarm(nFull);
p = sqlite3GlobalConfig.m.xMalloc(nFull);
}
#endif
@@ -333,7 +314,7 @@ void *sqlite3ScratchMalloc(int n){
assert( n>0 );
sqlite3_mutex_enter(mem0.mutex);
sqlite3StatusSet(SQLITE_STATUS_SCRATCH_SIZE, n);
sqlite3StatusHighwater(SQLITE_STATUS_SCRATCH_SIZE, n);
if( mem0.nScratchFree && sqlite3GlobalConfig.szScratch>=n ){
p = mem0.pScratchFree;
mem0.pScratchFree = mem0.pScratchFree->pNext;
@@ -428,6 +409,7 @@ int sqlite3MallocSize(void *p){
return sqlite3GlobalConfig.m.xSize(p);
}
int sqlite3DbMallocSize(sqlite3 *db, void *p){
assert( p!=0 );
if( db==0 || !isLookaside(db,p) ){
#if SQLITE_DEBUG
if( db==0 ){
@@ -447,7 +429,7 @@ int sqlite3DbMallocSize(sqlite3 *db, void *p){
sqlite3_uint64 sqlite3_msize(void *p){
assert( sqlite3MemdebugNoType(p, (u8)~MEMTYPE_HEAP) );
assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) );
return (sqlite3_uint64)sqlite3GlobalConfig.m.xSize(p);
return p ? sqlite3GlobalConfig.m.xSize(p) : 0;
}
/*
@@ -473,7 +455,7 @@ void sqlite3_free(void *p){
** *db->pnBytesFreed.
*/
static SQLITE_NOINLINE void measureAllocationSize(sqlite3 *db, void *p){
*db->pnBytesFreed += sqlite3DbMallocSize(db,p);
if( p ) *db->pnBytesFreed += sqlite3DbMallocSize(db,p);
}
/*
@@ -535,16 +517,17 @@ void *sqlite3Realloc(void *pOld, u64 nBytes){
pNew = pOld;
}else if( sqlite3GlobalConfig.bMemstat ){
sqlite3_mutex_enter(mem0.mutex);
sqlite3StatusSet(SQLITE_STATUS_MALLOC_SIZE, (int)nBytes);
sqlite3StatusHighwater(SQLITE_STATUS_MALLOC_SIZE, (int)nBytes);
nDiff = nNew - nOld;
sqlite3CheckSoftHeapLimit(nDiff);
if( sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED) >=
mem0.alarmThreshold-nDiff ){
sqlite3MallocAlarm(nDiff);
}
pNew = sqlite3GlobalConfig.m.xRealloc(pOld, nNew);
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
if( pNew==0 && mem0.alarmThreshold ){
sqlite3HeapLimitExceeded((int)nBytes);
if( pNew==0 && mem0.alarmThreshold>0 ){
sqlite3MallocAlarm((int)nBytes);
pNew = sqlite3GlobalConfig.m.xRealloc(pOld, nNew);
}
#endif
if( pNew ){
nNew = sqlite3MallocSize(pNew);
sqlite3StatusUp(SQLITE_STATUS_MEMORY_USED, nNew-nOld);
+2 -2
View File
@@ -171,11 +171,11 @@ static void sqlite3MemFree(void *pPrior){
** or xRealloc().
*/
static int sqlite3MemSize(void *pPrior){
assert( pPrior!=0 );
#ifdef SQLITE_MALLOCSIZE
return pPrior ? (int)SQLITE_MALLOCSIZE(pPrior) : 0;
return (int)SQLITE_MALLOCSIZE(pPrior);
#else
sqlite3_int64 *p;
if( pPrior==0 ) return 0;
p = (sqlite3_int64*)pPrior;
p--;
return (int)p[0];
+1 -1
View File
@@ -476,7 +476,7 @@ static void memsys3FreeUnsafe(void *pOld){
*/
static int memsys3Size(void *p){
Mem3Block *pBlock;
if( p==0 ) return 0;
assert( p!=0 );
pBlock = (Mem3Block*)p;
assert( (pBlock[-1].u.hdr.size4x&1)!=0 );
return (pBlock[-1].u.hdr.size4x&~3)*2 - 4;
+5 -6
View File
@@ -200,12 +200,11 @@ static void memsys5Leave(void){
** works for chunks that are currently checked out.
*/
static int memsys5Size(void *p){
int iSize = 0;
if( p ){
int i = (int)(((u8 *)p-mem5.zPool)/mem5.szAtom);
assert( i>=0 && i<mem5.nBlock );
iSize = mem5.szAtom * (1 << (mem5.aCtrl[i]&CTRL_LOGSIZE));
}
int iSize, i;
assert( p!=0 );
i = (int)(((u8 *)p-mem5.zPool)/mem5.szAtom);
assert( i>=0 && i<mem5.nBlock );
iSize = mem5.szAtom * (1 << (mem5.aCtrl[i]&CTRL_LOGSIZE));
return iSize;
}
+11 -1
View File
@@ -22,7 +22,7 @@
** allocate a mutex while the system is uninitialized.
*/
static SQLITE_WSD int mutexIsInit = 0;
#endif /* SQLITE_DEBUG */
#endif /* SQLITE_DEBUG && !defined(SQLITE_MUTEX_OMIT) */
#ifndef SQLITE_MUTEX_OMIT
@@ -53,8 +53,10 @@ int sqlite3MutexInit(void){
pTo->xMutexLeave = pFrom->xMutexLeave;
pTo->xMutexHeld = pFrom->xMutexHeld;
pTo->xMutexNotheld = pFrom->xMutexNotheld;
sqlite3MemoryBarrier();
pTo->xMutexAlloc = pFrom->xMutexAlloc;
}
assert( sqlite3GlobalConfig.mutex.xMutexInit );
rc = sqlite3GlobalConfig.mutex.xMutexInit();
#ifdef SQLITE_DEBUG
@@ -89,6 +91,7 @@ sqlite3_mutex *sqlite3_mutex_alloc(int id){
if( id<=SQLITE_MUTEX_RECURSIVE && sqlite3_initialize() ) return 0;
if( id>SQLITE_MUTEX_RECURSIVE && sqlite3MutexInit() ) return 0;
#endif
assert( sqlite3GlobalConfig.mutex.xMutexAlloc );
return sqlite3GlobalConfig.mutex.xMutexAlloc(id);
}
@@ -97,6 +100,7 @@ sqlite3_mutex *sqlite3MutexAlloc(int id){
return 0;
}
assert( GLOBAL(int, mutexIsInit) );
assert( sqlite3GlobalConfig.mutex.xMutexAlloc );
return sqlite3GlobalConfig.mutex.xMutexAlloc(id);
}
@@ -105,6 +109,7 @@ sqlite3_mutex *sqlite3MutexAlloc(int id){
*/
void sqlite3_mutex_free(sqlite3_mutex *p){
if( p ){
assert( sqlite3GlobalConfig.mutex.xMutexFree );
sqlite3GlobalConfig.mutex.xMutexFree(p);
}
}
@@ -115,6 +120,7 @@ void sqlite3_mutex_free(sqlite3_mutex *p){
*/
void sqlite3_mutex_enter(sqlite3_mutex *p){
if( p ){
assert( sqlite3GlobalConfig.mutex.xMutexEnter );
sqlite3GlobalConfig.mutex.xMutexEnter(p);
}
}
@@ -126,6 +132,7 @@ void sqlite3_mutex_enter(sqlite3_mutex *p){
int sqlite3_mutex_try(sqlite3_mutex *p){
int rc = SQLITE_OK;
if( p ){
assert( sqlite3GlobalConfig.mutex.xMutexTry );
return sqlite3GlobalConfig.mutex.xMutexTry(p);
}
return rc;
@@ -139,6 +146,7 @@ int sqlite3_mutex_try(sqlite3_mutex *p){
*/
void sqlite3_mutex_leave(sqlite3_mutex *p){
if( p ){
assert( sqlite3GlobalConfig.mutex.xMutexLeave );
sqlite3GlobalConfig.mutex.xMutexLeave(p);
}
}
@@ -149,9 +157,11 @@ void sqlite3_mutex_leave(sqlite3_mutex *p){
** intended for use inside assert() statements.
*/
int sqlite3_mutex_held(sqlite3_mutex *p){
assert( p==0 || sqlite3GlobalConfig.mutex.xMutexHeld );
return p==0 || sqlite3GlobalConfig.mutex.xMutexHeld(p);
}
int sqlite3_mutex_notheld(sqlite3_mutex *p){
assert( p==0 || sqlite3GlobalConfig.mutex.xMutexNotheld );
return p==0 || sqlite3GlobalConfig.mutex.xMutexNotheld(p);
}
#endif
+13
View File
@@ -80,6 +80,19 @@ static int pthreadMutexNotheld(sqlite3_mutex *p){
}
#endif
/*
** Try to provide a memory barrier operation, needed for initialization
** and also for the implementation of xShmBarrier in the VFS in cases
** where SQLite is compiled without mutexes.
*/
void sqlite3MemoryBarrier(void){
#if defined(SQLITE_MEMORY_BARRIER)
SQLITE_MEMORY_BARRIER;
#elif defined(__GNUC__) && GCC_VERSION>=4001000
__sync_synchronize();
#endif
}
/*
** Initialize and deinitialize the mutex subsystem.
*/
+18
View File
@@ -77,6 +77,24 @@ static int winMutexNotheld(sqlite3_mutex *p){
}
#endif
/*
** Try to provide a memory barrier operation, needed for initialization
** and also for the xShmBarrier method of the VFS in cases when SQLite is
** compiled without mutexes (SQLITE_THREADSAFE=0).
*/
void sqlite3MemoryBarrier(void){
#if defined(SQLITE_MEMORY_BARRIER)
SQLITE_MEMORY_BARRIER;
#elif defined(__GNUC__)
__sync_synchronize();
#elif !defined(SQLITE_DISABLE_INTRINSIC) && \
defined(_MSC_VER) && _MSC_VER>=1300
_ReadWriteBarrier();
#elif defined(MemoryBarrier)
MemoryBarrier();
#endif
}
/*
** Initialize and deinitialize the mutex subsystem.
*/
+2 -1
View File
@@ -4660,7 +4660,8 @@ static void unixShmBarrier(
sqlite3_file *fd /* Database file holding the shared memory */
){
UNUSED_PARAMETER(fd);
unixEnterMutex();
sqlite3MemoryBarrier(); /* compiler-defined memory barrier */
unixEnterMutex(); /* Also mutex, for redundancy */
unixLeaveMutex();
}
+2 -2
View File
@@ -3850,8 +3850,8 @@ static void winShmBarrier(
sqlite3_file *fd /* Database holding the shared memory */
){
UNUSED_PARAMETER(fd);
/* MemoryBarrier(); // does not work -- do not know why not */
winShmEnterMutex();
sqlite3MemoryBarrier(); /* compiler-defined memory barrier */
winShmEnterMutex(); /* Also mutex, for redundancy */
winShmLeaveMutex();
}
+14
View File
@@ -2116,6 +2116,20 @@ static void pagerReportSize(Pager *pPager){
# define pagerReportSize(X) /* No-op if we do not support a codec */
#endif
#ifdef SQLITE_HAS_CODEC
/*
** Make sure the number of reserved bits is the same in the destination
** pager as it is in the source. This comes up when a VACUUM changes the
** number of reserved bits to the "optimal" amount.
*/
void sqlite3PagerAlignReserve(Pager *pDest, Pager *pSrc){
if( pDest->nReserve!=pSrc->nReserve ){
pDest->nReserve = pSrc->nReserve;
pagerReportSize(pDest);
}
}
#endif
/*
** Read a single page from either the journal file (if isMainJrnl==1) or
** from the sub-journal (if isMainJrnl==0) and playback that page.
+3
View File
@@ -118,6 +118,9 @@ int sqlite3PagerReadFileheader(Pager*, int, unsigned char*);
/* Functions used to configure a Pager object. */
void sqlite3PagerSetBusyhandler(Pager*, int(*)(void *), void *);
int sqlite3PagerSetPagesize(Pager*, u32*, int);
#ifdef SQLITE_HAS_CODEC
void sqlite3PagerAlignReserve(Pager*,Pager*);
#endif
int sqlite3PagerMaxPageCount(Pager*, int);
void sqlite3PagerSetCachesize(Pager*, int);
void sqlite3PagerSetMmapLimit(Pager *, sqlite3_int64);
+7 -6
View File
@@ -320,7 +320,7 @@ static void *pcache1Alloc(int nByte){
pcache1.nFreeSlot--;
pcache1.bUnderPressure = pcache1.nFreeSlot<pcache1.nReserve;
assert( pcache1.nFreeSlot>=0 );
sqlite3StatusSet(SQLITE_STATUS_PAGECACHE_SIZE, nByte);
sqlite3StatusHighwater(SQLITE_STATUS_PAGECACHE_SIZE, nByte);
sqlite3StatusUp(SQLITE_STATUS_PAGECACHE_USED, 1);
}
sqlite3_mutex_leave(pcache1.mutex);
@@ -334,7 +334,7 @@ static void *pcache1Alloc(int nByte){
if( p ){
int sz = sqlite3MallocSize(p);
sqlite3_mutex_enter(pcache1.mutex);
sqlite3StatusSet(SQLITE_STATUS_PAGECACHE_SIZE, nByte);
sqlite3StatusHighwater(SQLITE_STATUS_PAGECACHE_SIZE, nByte);
sqlite3StatusUp(SQLITE_STATUS_PAGECACHE_OVERFLOW, sz);
sqlite3_mutex_leave(pcache1.mutex);
}
@@ -413,7 +413,7 @@ static PgHdr1 *pcache1AllocPage(PCache1 *pCache, int benignMalloc){
assert( pCache->pGroup==&pcache1.grp );
pcache1LeaveMutex(pCache->pGroup);
#endif
if( benignMalloc ) sqlite3BeginBenignMalloc();
if( benignMalloc ){ sqlite3BeginBenignMalloc(); }
#ifdef SQLITE_PCACHE_SEPARATE_HEADER
pPg = pcache1Alloc(pCache->szPage);
p = sqlite3Malloc(sizeof(PgHdr1) + pCache->szExtra);
@@ -426,7 +426,7 @@ static PgHdr1 *pcache1AllocPage(PCache1 *pCache, int benignMalloc){
pPg = pcache1Alloc(pCache->szAlloc);
p = (PgHdr1 *)&((u8 *)pPg)[pCache->szPage];
#endif
if( benignMalloc ) sqlite3EndBenignMalloc();
if( benignMalloc ){ sqlite3EndBenignMalloc(); }
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
pcache1EnterMutex(pCache->pGroup);
#endif
@@ -1193,7 +1193,8 @@ int sqlite3PcacheReleaseMemory(int nReq){
PgHdr1 *p;
pcache1EnterMutex(&pcache1.grp);
while( (nReq<0 || nFree<nReq)
&& (p=pcache1.grp.lru.pLruPrev)->isAnchor==0
&& (p=pcache1.grp.lru.pLruPrev)!=0
&& p->isAnchor==0
){
nFree += pcache1MemSize(p->page.pBuf);
#ifdef SQLITE_PCACHE_SEPARATE_HEADER
@@ -1222,7 +1223,7 @@ void sqlite3PcacheStats(
){
PgHdr1 *p;
int nRecyclable = 0;
for(p=pcache1.grp.lru.pLruNext; !p->isAnchor; p=p->pLruNext){
for(p=pcache1.grp.lru.pLruNext; p && !p->isAnchor; p=p->pLruNext){
assert( p->isPinned==0 );
nRecyclable++;
}
+8 -7
View File
@@ -1361,8 +1361,9 @@ void sqlite3Pragma(
*/
static const int iLn = VDBE_OFFSET_LINENO(2);
static const VdbeOpList endCode[] = {
{ OP_IfNeg, 1, 0, 0}, /* 0 */
{ OP_String8, 0, 3, 0}, /* 1 */
{ OP_AddImm, 1, 0, 0}, /* 0 */
{ OP_If, 1, 0, 0}, /* 1 */
{ OP_String8, 0, 3, 0}, /* 2 */
{ OP_ResultRow, 3, 1, 0},
};
@@ -1524,8 +1525,8 @@ void sqlite3Pragma(
int kk;
for(kk=0; kk<pIdx->nKeyCol; kk++){
int iCol = pIdx->aiColumn[kk];
assert( iCol>=0 && iCol<pTab->nCol );
if( pTab->aCol[iCol].notNull ) continue;
assert( iCol!=XN_ROWID && iCol<pTab->nCol );
if( iCol>=0 && pTab->aCol[iCol].notNull ) continue;
sqlite3VdbeAddOp2(v, OP_IsNull, r1+kk, uniqOk);
VdbeCoverage(v);
}
@@ -1563,9 +1564,9 @@ void sqlite3Pragma(
}
}
addr = sqlite3VdbeAddOpList(v, ArraySize(endCode), endCode, iLn);
sqlite3VdbeChangeP3(v, addr, -mxErr);
sqlite3VdbeJumpHere(v, addr);
sqlite3VdbeChangeP4(v, addr+1, "ok", P4_STATIC);
sqlite3VdbeChangeP2(v, addr, -mxErr);
sqlite3VdbeJumpHere(v, addr+1);
sqlite3VdbeChangeP4(v, addr+2, "ok", P4_STATIC);
}
break;
#endif /* SQLITE_OMIT_INTEGRITY_CHECK */
+10 -37
View File
@@ -45,30 +45,6 @@ static void incrAggFunctionDepth(Expr *pExpr, int N){
** Turn the pExpr expression into an alias for the iCol-th column of the
** result set in pEList.
**
** If the result set column is a simple column reference, then this routine
** makes an exact copy. But for any other kind of expression, this
** routine make a copy of the result set column as the argument to the
** TK_AS operator. The TK_AS operator causes the expression to be
** evaluated just once and then reused for each alias.
**
** The reason for suppressing the TK_AS term when the expression is a simple
** column reference is so that the column reference will be recognized as
** usable by indices within the WHERE clause processing logic.
**
** The TK_AS operator is inhibited if zType[0]=='G'. This means
** that in a GROUP BY clause, the expression is evaluated twice. Hence:
**
** SELECT random()%5 AS x, count(*) FROM tab GROUP BY x
**
** Is equivalent to:
**
** SELECT random()%5 AS x, count(*) FROM tab GROUP BY random()%5
**
** The result of random()%5 in the GROUP BY clause is probably different
** from the result in the result-set. On the other hand Standard SQL does
** not allow the GROUP BY clause to contain references to result-set columns.
** So this should never come up in well-formed queries.
**
** If the reference is followed by a COLLATE operator, then make sure
** the COLLATE operator is preserved. For example:
**
@@ -102,19 +78,11 @@ static void resolveAlias(
db = pParse->db;
pDup = sqlite3ExprDup(db, pOrig, 0);
if( pDup==0 ) return;
if( pOrig->op!=TK_COLUMN && zType[0]!='G' ){
incrAggFunctionDepth(pDup, nSubquery);
pDup = sqlite3PExpr(pParse, TK_AS, pDup, 0, 0);
if( pDup==0 ) return;
ExprSetProperty(pDup, EP_Skip);
if( pEList->a[iCol].u.x.iAlias==0 ){
pEList->a[iCol].u.x.iAlias = (u16)(++pParse->nAlias);
}
pDup->iTable = pEList->a[iCol].u.x.iAlias;
}
if( zType[0]!='G' ) incrAggFunctionDepth(pDup, nSubquery);
if( pExpr->op==TK_COLLATE ){
pDup = sqlite3ExprAddCollateString(pParse, pDup, pExpr->u.zToken);
}
ExprSetProperty(pDup, EP_Alias);
/* Before calling sqlite3ExprDelete(), set the EP_Static flag. This
** prevents ExprDelete() from deleting the Expr structure itself,
@@ -387,8 +355,13 @@ static int lookupName(
/*
** Perhaps the name is a reference to the ROWID
*/
if( cnt==0 && cntTab==1 && pMatch && sqlite3IsRowid(zCol)
&& VisibleRowid(pMatch->pTab) ){
if( cnt==0
&& cntTab==1
&& pMatch
&& (pNC->ncFlags & NC_IdxExpr)==0
&& sqlite3IsRowid(zCol)
&& VisibleRowid(pMatch->pTab)
){
cnt = 1;
pExpr->iColumn = -1; /* IMP: R-44911-55124 */
pExpr->affinity = SQLITE_AFF_INTEGER;
@@ -506,7 +479,7 @@ static int lookupName(
lookupname_end:
if( cnt==1 ){
assert( pNC!=0 );
if( pExpr->op!=TK_AS ){
if( !ExprHasProperty(pExpr, EP_Alias) ){
sqlite3AuthRead(pParse, pExpr, pSchema, pNC->pSrcList);
}
/* Increment the nRef value on all name contexts from TopNC up to
+83 -90
View File
@@ -579,7 +579,7 @@ static void pushOntoSorter(
}else{
iLimit = pSelect->iLimit;
}
addr = sqlite3VdbeAddOp3(v, OP_IfNotZero, iLimit, 0, -1); VdbeCoverage(v);
addr = sqlite3VdbeAddOp3(v, OP_IfNotZero, iLimit, 0, 1); VdbeCoverage(v);
sqlite3VdbeAddOp1(v, OP_Last, pSort->iECursor);
sqlite3VdbeAddOp1(v, OP_Delete, pSort->iECursor);
sqlite3VdbeJumpHere(v, addr);
@@ -595,11 +595,8 @@ static void codeOffset(
int iContinue /* Jump here to skip the current record */
){
if( iOffset>0 ){
int addr;
addr = sqlite3VdbeAddOp3(v, OP_IfNeg, iOffset, 0, -1); VdbeCoverage(v);
sqlite3VdbeGoto(v, iContinue);
VdbeComment((v, "skip OFFSET records"));
sqlite3VdbeJumpHere(v, addr);
sqlite3VdbeAddOp3(v, OP_IfPos, iOffset, iContinue, 1); VdbeCoverage(v);
VdbeComment((v, "OFFSET"));
}
}
@@ -1815,7 +1812,7 @@ static void computeLimitRegisters(Parse *pParse, Select *p, int iBreak){
Vdbe *v = 0;
int iLimit = 0;
int iOffset;
int addr1, n;
int n;
if( p->iLimit ) return;
/*
@@ -1850,14 +1847,10 @@ static void computeLimitRegisters(Parse *pParse, Select *p, int iBreak){
sqlite3ExprCode(pParse, p->pOffset, iOffset);
sqlite3VdbeAddOp1(v, OP_MustBeInt, iOffset); VdbeCoverage(v);
VdbeComment((v, "OFFSET counter"));
addr1 = sqlite3VdbeAddOp1(v, OP_IfPos, iOffset); VdbeCoverage(v);
sqlite3VdbeAddOp2(v, OP_Integer, 0, iOffset);
sqlite3VdbeJumpHere(v, addr1);
sqlite3VdbeAddOp3(v, OP_SetIfNotPos, iOffset, iOffset, 0);
sqlite3VdbeAddOp3(v, OP_Add, iLimit, iOffset, iOffset+1);
VdbeComment((v, "LIMIT+OFFSET"));
addr1 = sqlite3VdbeAddOp1(v, OP_IfPos, iLimit); VdbeCoverage(v);
sqlite3VdbeAddOp2(v, OP_Integer, -1, iOffset+1);
sqlite3VdbeJumpHere(v, addr1);
sqlite3VdbeAddOp3(v, OP_SetIfNotPos, iLimit, iOffset+1, -1);
}
}
}
@@ -2273,6 +2266,11 @@ static int multiSelect(
if( p->iLimit ){
addr = sqlite3VdbeAddOp1(v, OP_IfNot, p->iLimit); VdbeCoverage(v);
VdbeComment((v, "Jump ahead if LIMIT reached"));
if( p->iOffset ){
sqlite3VdbeAddOp3(v, OP_SetIfNotPos, p->iOffset, p->iOffset, 0);
sqlite3VdbeAddOp3(v, OP_Add, p->iLimit, p->iOffset, p->iOffset+1);
sqlite3VdbeAddOp3(v, OP_SetIfNotPos, p->iLimit, p->iOffset+1, -1);
}
}
explainSetInteger(iSub2, pParse->iNextSelectId);
rc = sqlite3Select(pParse, p, &dest);
@@ -2580,12 +2578,12 @@ static int generateOutputSubroutine(
/* Suppress duplicates for UNION, EXCEPT, and INTERSECT
*/
if( regPrev ){
int j1, j2;
j1 = sqlite3VdbeAddOp1(v, OP_IfNot, regPrev); VdbeCoverage(v);
j2 = sqlite3VdbeAddOp4(v, OP_Compare, pIn->iSdst, regPrev+1, pIn->nSdst,
int addr1, addr2;
addr1 = sqlite3VdbeAddOp1(v, OP_IfNot, regPrev); VdbeCoverage(v);
addr2 = sqlite3VdbeAddOp4(v, OP_Compare, pIn->iSdst, regPrev+1, pIn->nSdst,
(char*)sqlite3KeyInfoRef(pKeyInfo), P4_KEYINFO);
sqlite3VdbeAddOp3(v, OP_Jump, j2+2, iContinue, j2+2); VdbeCoverage(v);
sqlite3VdbeJumpHere(v, j1);
sqlite3VdbeAddOp3(v, OP_Jump, addr2+2, iContinue, addr2+2); VdbeCoverage(v);
sqlite3VdbeJumpHere(v, addr1);
sqlite3VdbeAddOp3(v, OP_Copy, pIn->iSdst, regPrev+1, pIn->nSdst-1);
sqlite3VdbeAddOp2(v, OP_Integer, 1, regPrev);
}
@@ -2802,7 +2800,7 @@ static int multiSelectOrderBy(
int savedOffset; /* Saved value of p->iOffset */
int labelCmpr; /* Label for the start of the merge algorithm */
int labelEnd; /* Label for the end of the overall SELECT stmt */
int j1; /* Jump instructions that get retargetted */
int addr1; /* Jump instructions that get retargetted */
int op; /* One of TK_ALL, TK_UNION, TK_EXCEPT, TK_INTERSECT */
KeyInfo *pKeyDup = 0; /* Comparison information for duplicate removal */
KeyInfo *pKeyMerge; /* Comparison information for merging rows */
@@ -2938,19 +2936,19 @@ static int multiSelectOrderBy(
** left of the compound operator - the "A" select.
*/
addrSelectA = sqlite3VdbeCurrentAddr(v) + 1;
j1 = sqlite3VdbeAddOp3(v, OP_InitCoroutine, regAddrA, 0, addrSelectA);
addr1 = sqlite3VdbeAddOp3(v, OP_InitCoroutine, regAddrA, 0, addrSelectA);
VdbeComment((v, "left SELECT"));
pPrior->iLimit = regLimitA;
explainSetInteger(iSub1, pParse->iNextSelectId);
sqlite3Select(pParse, pPrior, &destA);
sqlite3VdbeAddOp1(v, OP_EndCoroutine, regAddrA);
sqlite3VdbeJumpHere(v, j1);
sqlite3VdbeJumpHere(v, addr1);
/* Generate a coroutine to evaluate the SELECT statement on
** the right - the "B" select
*/
addrSelectB = sqlite3VdbeCurrentAddr(v) + 1;
j1 = sqlite3VdbeAddOp3(v, OP_InitCoroutine, regAddrB, 0, addrSelectB);
addr1 = sqlite3VdbeAddOp3(v, OP_InitCoroutine, regAddrB, 0, addrSelectB);
VdbeComment((v, "right SELECT"));
savedLimit = p->iLimit;
savedOffset = p->iOffset;
@@ -3041,7 +3039,7 @@ static int multiSelectOrderBy(
/* This code runs once to initialize everything.
*/
sqlite3VdbeJumpHere(v, j1);
sqlite3VdbeJumpHere(v, addr1);
sqlite3VdbeAddOp2(v, OP_Yield, regAddrA, addrEofA_noB); VdbeCoverage(v);
sqlite3VdbeAddOp2(v, OP_Yield, regAddrB, addrEofB); VdbeCoverage(v);
@@ -3084,7 +3082,7 @@ static int multiSelectOrderBy(
#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW)
/* Forward Declarations */
static void substExprList(sqlite3*, ExprList*, int, ExprList*);
static void substSelect(sqlite3*, Select *, int, ExprList *);
static void substSelect(sqlite3*, Select *, int, ExprList*, int);
/*
** Scan through the expression pExpr. Replace every reference to
@@ -3121,7 +3119,7 @@ static Expr *substExpr(
pExpr->pLeft = substExpr(db, pExpr->pLeft, iTable, pEList);
pExpr->pRight = substExpr(db, pExpr->pRight, iTable, pEList);
if( ExprHasProperty(pExpr, EP_xIsSelect) ){
substSelect(db, pExpr->x.pSelect, iTable, pEList);
substSelect(db, pExpr->x.pSelect, iTable, pEList, 1);
}else{
substExprList(db, pExpr->x.pList, iTable, pEList);
}
@@ -3144,25 +3142,28 @@ static void substSelect(
sqlite3 *db, /* Report malloc errors here */
Select *p, /* SELECT statement in which to make substitutions */
int iTable, /* Table to be replaced */
ExprList *pEList /* Substitute values */
ExprList *pEList, /* Substitute values */
int doPrior /* Do substitutes on p->pPrior too */
){
SrcList *pSrc;
struct SrcList_item *pItem;
int i;
if( !p ) return;
substExprList(db, p->pEList, iTable, pEList);
substExprList(db, p->pGroupBy, iTable, pEList);
substExprList(db, p->pOrderBy, iTable, pEList);
p->pHaving = substExpr(db, p->pHaving, iTable, pEList);
p->pWhere = substExpr(db, p->pWhere, iTable, pEList);
substSelect(db, p->pPrior, iTable, pEList);
pSrc = p->pSrc;
assert( pSrc ); /* Even for (SELECT 1) we have: pSrc!=0 but pSrc->nSrc==0 */
if( ALWAYS(pSrc) ){
do{
substExprList(db, p->pEList, iTable, pEList);
substExprList(db, p->pGroupBy, iTable, pEList);
substExprList(db, p->pOrderBy, iTable, pEList);
p->pHaving = substExpr(db, p->pHaving, iTable, pEList);
p->pWhere = substExpr(db, p->pWhere, iTable, pEList);
pSrc = p->pSrc;
assert( pSrc!=0 );
for(i=pSrc->nSrc, pItem=pSrc->a; i>0; i--, pItem++){
substSelect(db, pItem->pSelect, iTable, pEList);
substSelect(db, pItem->pSelect, iTable, pEList, 1);
if( pItem->fg.isTabFunc ){
substExprList(db, pItem->u1.pFuncArg, iTable, pEList);
}
}
}
}while( doPrior && (p = p->pPrior)!=0 );
}
#endif /* !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) */
@@ -3314,7 +3315,7 @@ static int flattenSubquery(
int subqueryIsAgg /* True if the subquery uses aggregate functions */
){
const char *zSavedAuthContext = pParse->zAuthContext;
Select *pParent;
Select *pParent; /* Current UNION ALL term of the other query */
Select *pSub; /* The inner query or "subquery" */
Select *pSub1; /* Pointer to the rightmost select in sub-query */
SrcList *pSrc; /* The FROM clause of the outer query */
@@ -3609,9 +3610,9 @@ static int flattenSubquery(
**
** The outer query has 3 slots in its FROM clause. One slot of the
** outer query (the middle slot) is used by the subquery. The next
** block of code will expand the out query to 4 slots. The middle
** slot is expanded to two slots in order to make space for the
** two elements in the FROM clause of the subquery.
** block of code will expand the outer query FROM clause to 4 slots.
** The middle slot is expanded to two slots in order to make space
** for the two elements in the FROM clause of the subquery.
*/
if( nSubSrc>1 ){
pParent->pSrc = pSrc = sqlite3SrcListEnlarge(db, pSrc, nSubSrc-1,iFrom+1);
@@ -3650,11 +3651,6 @@ static int flattenSubquery(
pList->a[i].zName = zName;
}
}
substExprList(db, pParent->pEList, iParent, pSub->pEList);
if( isAgg ){
substExprList(db, pParent->pGroupBy, iParent, pSub->pEList);
pParent->pHaving = substExpr(db, pParent->pHaving, iParent, pSub->pEList);
}
if( pSub->pOrderBy ){
/* At this point, any non-zero iOrderByCol values indicate that the
** ORDER BY column expression is identical to the iOrderByCol'th
@@ -3674,27 +3670,20 @@ static int flattenSubquery(
assert( pSub->pPrior==0 );
pParent->pOrderBy = pOrderBy;
pSub->pOrderBy = 0;
}else if( pParent->pOrderBy ){
substExprList(db, pParent->pOrderBy, iParent, pSub->pEList);
}
if( pSub->pWhere ){
pWhere = sqlite3ExprDup(db, pSub->pWhere, 0);
}else{
pWhere = 0;
}
pWhere = sqlite3ExprDup(db, pSub->pWhere, 0);
if( subqueryIsAgg ){
assert( pParent->pHaving==0 );
pParent->pHaving = pParent->pWhere;
pParent->pWhere = pWhere;
pParent->pHaving = substExpr(db, pParent->pHaving, iParent, pSub->pEList);
pParent->pHaving = sqlite3ExprAnd(db, pParent->pHaving,
sqlite3ExprDup(db, pSub->pHaving, 0));
assert( pParent->pGroupBy==0 );
pParent->pGroupBy = sqlite3ExprListDup(db, pSub->pGroupBy, 0);
}else{
pParent->pWhere = substExpr(db, pParent->pWhere, iParent, pSub->pEList);
pParent->pWhere = sqlite3ExprAnd(db, pParent->pWhere, pWhere);
}
substSelect(db, pParent, iParent, pSub->pEList, 0);
/* The flattened query is distinct if either the inner or the
** outer query is distinct.
@@ -4221,17 +4210,9 @@ static int selectExpander(Walker *pWalker, Select *p){
*/
for(i=0, pFrom=pTabList->a; i<pTabList->nSrc; i++, pFrom++){
Table *pTab;
assert( pFrom->fg.isRecursive==0 || pFrom->pTab );
assert( pFrom->fg.isRecursive==0 || pFrom->pTab!=0 );
if( pFrom->fg.isRecursive ) continue;
if( pFrom->pTab!=0 ){
/* This statement has already been prepared. There is no need
** to go further. */
assert( i==0 );
#ifndef SQLITE_OMIT_CTE
selectPopWith(pWalker, p);
#endif
return WRC_Prune;
}
assert( pFrom->pTab==0 );
#ifndef SQLITE_OMIT_CTE
if( withExpand(pWalker, pFrom) ) return WRC_Abort;
if( pFrom->pTab ) {} else
@@ -4267,12 +4248,19 @@ static int selectExpander(Walker *pWalker, Select *p){
pTab->nRef++;
#if !defined(SQLITE_OMIT_VIEW) || !defined (SQLITE_OMIT_VIRTUALTABLE)
if( pTab->pSelect || IsVirtual(pTab) ){
/* We reach here if the named table is a really a view */
i16 nCol;
if( sqlite3ViewGetColumnNames(pParse, pTab) ) return WRC_Abort;
assert( pFrom->pSelect==0 );
if( pFrom->fg.isTabFunc && !IsVirtual(pTab) ){
sqlite3ErrorMsg(pParse, "'%s' is not a function", pTab->zName);
return WRC_Abort;
}
pFrom->pSelect = sqlite3SelectDup(db, pTab->pSelect, 0);
sqlite3SelectSetName(pFrom->pSelect, pTab->zName);
nCol = pTab->nCol;
pTab->nCol = -1;
sqlite3WalkSelect(pWalker, pFrom->pSelect);
pTab->nCol = nCol;
}
#endif
}
@@ -4520,19 +4508,19 @@ static void selectAddSubqueryTypeInfo(Walker *pWalker, Select *p){
struct SrcList_item *pFrom;
assert( p->selFlags & SF_Resolved );
if( (p->selFlags & SF_HasTypeInfo)==0 ){
p->selFlags |= SF_HasTypeInfo;
pParse = pWalker->pParse;
pTabList = p->pSrc;
for(i=0, pFrom=pTabList->a; i<pTabList->nSrc; i++, pFrom++){
Table *pTab = pFrom->pTab;
if( ALWAYS(pTab!=0) && (pTab->tabFlags & TF_Ephemeral)!=0 ){
/* A sub-query in the FROM clause of a SELECT */
Select *pSel = pFrom->pSelect;
if( pSel ){
while( pSel->pPrior ) pSel = pSel->pPrior;
selectAddColumnTypeAndCollation(pParse, pTab, pSel);
}
assert( (p->selFlags & SF_HasTypeInfo)==0 );
p->selFlags |= SF_HasTypeInfo;
pParse = pWalker->pParse;
pTabList = p->pSrc;
for(i=0, pFrom=pTabList->a; i<pTabList->nSrc; i++, pFrom++){
Table *pTab = pFrom->pTab;
assert( pTab!=0 );
if( (pTab->tabFlags & TF_Ephemeral)!=0 ){
/* A sub-query in the FROM clause of a SELECT */
Select *pSel = pFrom->pSelect;
if( pSel ){
while( pSel->pPrior ) pSel = pSel->pPrior;
selectAddColumnTypeAndCollation(pParse, pTab, pSel);
}
}
}
@@ -4858,7 +4846,17 @@ int sqlite3Select(
struct SrcList_item *pItem = &pTabList->a[i];
Select *pSub = pItem->pSelect;
int isAggSub;
Table *pTab = pItem->pTab;
if( pSub==0 ) continue;
/* Catch mismatch in the declared columns of a view and the number of
** columns in the SELECT on the RHS */
if( pTab->nCol!=pSub->pEList->nExpr ){
sqlite3ErrorMsg(pParse, "expected %d columns for '%s' but got %d",
pTab->nCol, pTab->zName, pSub->pEList->nExpr);
goto select_end;
}
isAggSub = (pSub->selFlags & SF_Aggregate)!=0;
if( flattenSubquery(pParse, p, i, isAgg, isAggSub) ){
/* This subquery can be absorbed into its parent. */
@@ -5210,7 +5208,7 @@ int sqlite3Select(
*/
if( pGroupBy ){
KeyInfo *pKeyInfo; /* Keying information for the group by clause */
int j1; /* A-vs-B comparision jump */
int addr1; /* A-vs-B comparision jump */
int addrOutputRow; /* Start of subroutine that outputs a result row */
int regOutputRow; /* Return address register for output subroutine */
int addrSetAbort; /* Set the abort flag and return */
@@ -5297,13 +5295,8 @@ int sqlite3Select(
struct AggInfo_col *pCol = &sAggInfo.aCol[i];
if( pCol->iSorterColumn>=j ){
int r1 = j + regBase;
int r2;
r2 = sqlite3ExprCodeGetColumn(pParse,
pCol->pTab, pCol->iColumn, pCol->iTable, r1, 0);
if( r1!=r2 ){
sqlite3VdbeAddOp2(v, OP_SCopy, r2, r1);
}
sqlite3ExprCodeGetColumnToReg(pParse,
pCol->pTab, pCol->iColumn, pCol->iTable, r1);
j++;
}
}
@@ -5358,8 +5351,8 @@ int sqlite3Select(
}
sqlite3VdbeAddOp4(v, OP_Compare, iAMem, iBMem, pGroupBy->nExpr,
(char*)sqlite3KeyInfoRef(pKeyInfo), P4_KEYINFO);
j1 = sqlite3VdbeCurrentAddr(v);
sqlite3VdbeAddOp3(v, OP_Jump, j1+1, 0, j1+1); VdbeCoverage(v);
addr1 = sqlite3VdbeCurrentAddr(v);
sqlite3VdbeAddOp3(v, OP_Jump, addr1+1, 0, addr1+1); VdbeCoverage(v);
/* Generate code that runs whenever the GROUP BY changes.
** Changes in the GROUP BY are detected by the previous code
@@ -5381,7 +5374,7 @@ int sqlite3Select(
/* Update the aggregate accumulators based on the content of
** the current row
*/
sqlite3VdbeJumpHere(v, j1);
sqlite3VdbeJumpHere(v, addr1);
updateAccumulator(pParse, &sAggInfo);
sqlite3VdbeAddOp2(v, OP_Integer, 1, iUseFlag);
VdbeComment((v, "indicate data in accumulator"));
+45 -17
View File
@@ -2612,6 +2612,22 @@ static int shell_dbinfo_command(ShellState *p, int nArg, char **azArg){
return 0;
}
/*
** Print the current sqlite3_errmsg() value to stderr and return 1.
*/
static int shellDatabaseError(sqlite3 *db){
const char *zErr = sqlite3_errmsg(db);
fprintf(stderr, "Error: %s\n", zErr);
return 1;
}
/*
** Print an out-of-memory message to stderr and return 1.
*/
static int shellNomemError(void){
fprintf(stderr, "Error: out of memory\n");
return 1;
}
/*
** If an input line begins with "." then invoke this routine to
@@ -3713,13 +3729,17 @@ static int do_meta_command(char *zLine, ShellState *p){
int ii;
open_db(p, 0);
rc = sqlite3_prepare_v2(p->db, "PRAGMA database_list", -1, &pStmt, 0);
if( rc ) return rc;
if( rc ) return shellDatabaseError(p->db);
/* Create an SQL statement to query for the list of tables in the
** main and all attached databases where the table name matches the
** LIKE pattern bound to variable "?1". */
zSql = sqlite3_mprintf(
"SELECT name FROM sqlite_master"
" WHERE type IN ('table','view')"
" AND name NOT LIKE 'sqlite_%%'"
" AND name LIKE ?1");
while( sqlite3_step(pStmt)==SQLITE_ROW ){
while( zSql && sqlite3_step(pStmt)==SQLITE_ROW ){
const char *zDbName = (const char*)sqlite3_column_text(pStmt, 1);
if( zDbName==0 || strcmp(zDbName,"main")==0 ) continue;
if( strcmp(zDbName,"temp")==0 ){
@@ -3738,11 +3758,17 @@ static int do_meta_command(char *zLine, ShellState *p){
" AND name LIKE ?1", zSql, zDbName, zDbName);
}
}
sqlite3_finalize(pStmt);
zSql = sqlite3_mprintf("%z ORDER BY 1", zSql);
rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
rc = sqlite3_finalize(pStmt);
if( zSql && rc==SQLITE_OK ){
zSql = sqlite3_mprintf("%z ORDER BY 1", zSql);
if( zSql ) rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
}
sqlite3_free(zSql);
if( rc ) return rc;
if( !zSql ) return shellNomemError();
if( rc ) return shellDatabaseError(p->db);
/* Run the SQL statement prepared by the above block. Store the results
** as an array of nul-terminated strings in azResult[]. */
nRow = nAlloc = 0;
azResult = 0;
if( nArg>1 ){
@@ -3756,17 +3782,25 @@ static int do_meta_command(char *zLine, ShellState *p){
int n2 = nAlloc*2 + 10;
azNew = sqlite3_realloc64(azResult, sizeof(azResult[0])*n2);
if( azNew==0 ){
fprintf(stderr, "Error: out of memory\n");
rc = shellNomemError();
break;
}
nAlloc = n2;
azResult = azNew;
}
azResult[nRow] = sqlite3_mprintf("%s", sqlite3_column_text(pStmt, 0));
if( azResult[nRow] ) nRow++;
if( 0==azResult[nRow] ){
rc = shellNomemError();
break;
}
nRow++;
}
sqlite3_finalize(pStmt);
if( nRow>0 ){
if( sqlite3_finalize(pStmt)!=SQLITE_OK ){
rc = shellDatabaseError(p->db);
}
/* Pretty-print the contents of array azResult[] to the output */
if( rc==0 && nRow>0 ){
int len, maxlen = 0;
int i, j;
int nPrintCol, nPrintRow;
@@ -3785,6 +3819,7 @@ static int do_meta_command(char *zLine, ShellState *p){
fprintf(p->out, "\n");
}
}
for(ii=0; ii<nRow; ii++) sqlite3_free(azResult[ii]);
sqlite3_free(azResult);
}else
@@ -4619,13 +4654,6 @@ int SQLITE_CDECL main(int argc, char **argv){
}
data.out = stdout;
#ifdef SQLITE_ENABLE_JSON1
{
extern int sqlite3_json_init(sqlite3*);
sqlite3_auto_extension((void(*)(void))sqlite3_json_init);
}
#endif
/* Go ahead and open the database file if it already exists. If the
** file does not exist, delay opening it. This prevents empty database
** files from being created if a user mistypes the database name argument
+70 -8
View File
@@ -124,7 +124,7 @@ extern "C" {
** but are associated with the library instead of the header file. ^(Cautious
** programmers might include assert() statements in their application to
** verify that values returned by these interfaces match the macros in
** the header, and thus insure that the application is
** the header, and thus ensure that the application is
** compiled with matching library and header files.
**
** <blockquote><pre>
@@ -374,7 +374,7 @@ typedef int (*sqlite3_callback)(void*,int,char**, char**);
** Restrictions:
**
** <ul>
** <li> The application must insure that the 1st parameter to sqlite3_exec()
** <li> The application must ensure that the 1st parameter to sqlite3_exec()
** is a valid and open [database connection].
** <li> The application must not close the [database connection] specified by
** the 1st parameter to sqlite3_exec() while sqlite3_exec() is running.
@@ -1367,9 +1367,11 @@ int sqlite3_os_end(void);
** applications and so this routine is usually not necessary. It is
** provided to support rare applications with unusual needs.
**
** The sqlite3_config() interface is not threadsafe. The application
** must insure that no other SQLite interfaces are invoked by other
** threads while sqlite3_config() is running. Furthermore, sqlite3_config()
** <b>The sqlite3_config() interface is not threadsafe. The application
** must ensure that no other SQLite interfaces are invoked by other
** threads while sqlite3_config() is running.</b>
**
** The sqlite3_config() interface
** may only be invoked prior to library initialization using
** [sqlite3_initialize()] or after shutdown by [sqlite3_shutdown()].
** ^If sqlite3_config() is called after [sqlite3_initialize()] and before
@@ -3628,7 +3630,7 @@ const char *sqlite3_bind_parameter_name(sqlite3_stmt*, int);
**
** See also: [sqlite3_bind_blob|sqlite3_bind()],
** [sqlite3_bind_parameter_count()], and
** [sqlite3_bind_parameter_index()].
** [sqlite3_bind_parameter_name()].
*/
int sqlite3_bind_parameter_index(sqlite3_stmt*, const char *zName);
@@ -4357,6 +4359,22 @@ const void *sqlite3_value_text16be(sqlite3_value*);
int sqlite3_value_type(sqlite3_value*);
int sqlite3_value_numeric_type(sqlite3_value*);
/*
** CAPI3REF: Finding The Subtype Of SQL Values
** METHOD: sqlite3_value
**
** The sqlite3_value_subtype(V) function returns the subtype for
** an [application-defined SQL function] argument V. The subtype
** information can be used to pass a limited amount of context from
** one SQL function to another. Use the [sqlite3_result_subtype()]
** routine to set the subtype for the return value of an SQL function.
**
** SQLite makes no use of subtype itself. It merely passes the subtype
** from the result of one [application-defined SQL function] into the
** input of another.
*/
unsigned int sqlite3_value_subtype(sqlite3_value*);
/*
** CAPI3REF: Copy And Free SQL Values
** METHOD: sqlite3_value
@@ -4656,6 +4674,21 @@ void sqlite3_result_value(sqlite3_context*, sqlite3_value*);
void sqlite3_result_zeroblob(sqlite3_context*, int n);
int sqlite3_result_zeroblob64(sqlite3_context*, sqlite3_uint64 n);
/*
** CAPI3REF: Setting The Subtype Of An SQL Function
** METHOD: sqlite3_context
**
** The sqlite3_result_subtype(C,T) function causes the subtype of
** the result from the [application-defined SQL function] with
** [sqlite3_context] C to be the value T. Only the lower 8 bits
** of the subtype T are preserved in current versions of SQLite;
** higher order bits are discarded.
** The number of subtype bytes preserved by SQLite might increase
** in future releases of SQLite.
*/
void sqlite3_result_subtype(sqlite3_context*,unsigned int);
/*
** CAPI3REF: Define New Collating Sequences
** METHOD: sqlite3
@@ -5601,13 +5634,31 @@ struct sqlite3_module {
** ^The estimatedRows value is an estimate of the number of rows that
** will be returned by the strategy.
**
** The xBestIndex method may optionally populate the idxFlags field with a
** mask of SQLITE_INDEX_SCAN_* flags. Currently there is only one such flag -
** SQLITE_INDEX_SCAN_UNIQUE. If the xBestIndex method sets this flag, SQLite
** assumes that the strategy may visit at most one row.
**
** Additionally, if xBestIndex sets the SQLITE_INDEX_SCAN_UNIQUE flag, then
** SQLite also assumes that if a call to the xUpdate() method is made as
** part of the same statement to delete or update a virtual table row and the
** implementation returns SQLITE_CONSTRAINT, then there is no need to rollback
** any database changes. In other words, if the xUpdate() returns
** SQLITE_CONSTRAINT, the database contents must be exactly as they were
** before xUpdate was called. By contrast, if SQLITE_INDEX_SCAN_UNIQUE is not
** set and xUpdate returns SQLITE_CONSTRAINT, any database changes made by
** the xUpdate method are automatically rolled back by SQLite.
**
** IMPORTANT: The estimatedRows field was added to the sqlite3_index_info
** structure for SQLite version 3.8.2. If a virtual table extension is
** used with an SQLite version earlier than 3.8.2, the results of attempting
** to read or write the estimatedRows field are undefined (but are likely
** to included crashing the application). The estimatedRows field should
** therefore only be used if [sqlite3_libversion_number()] returns a
** value greater than or equal to 3008002.
** value greater than or equal to 3008002. Similarly, the idxFlags field
** was added for version 3.9.0. It may therefore only be used if
** sqlite3_libversion_number() returns a value greater than or equal to
** 3009000.
*/
struct sqlite3_index_info {
/* Inputs */
@@ -5635,8 +5686,15 @@ struct sqlite3_index_info {
double estimatedCost; /* Estimated cost of using this index */
/* Fields below are only available in SQLite 3.8.2 and later */
sqlite3_int64 estimatedRows; /* Estimated number of rows returned */
/* Fields below are only available in SQLite 3.9.0 and later */
int idxFlags; /* Mask of SQLITE_INDEX_SCAN_* flags */
};
/*
** CAPI3REF: Virtual Table Scan Flags
*/
#define SQLITE_INDEX_SCAN_UNIQUE 1 /* Scan visits at most 1 row */
/*
** CAPI3REF: Virtual Table Constraint Operator Codes
**
@@ -6094,6 +6152,9 @@ int sqlite3_vfs_unregister(sqlite3_vfs*);
** <li> SQLITE_MUTEX_STATIC_APP1
** <li> SQLITE_MUTEX_STATIC_APP2
** <li> SQLITE_MUTEX_STATIC_APP3
** <li> SQLITE_MUTEX_STATIC_VFS1
** <li> SQLITE_MUTEX_STATIC_VFS2
** <li> SQLITE_MUTEX_STATIC_VFS3
** </ul>
**
** ^The first two constants (SQLITE_MUTEX_FAST and SQLITE_MUTEX_RECURSIVE)
@@ -6511,7 +6572,8 @@ int sqlite3_status64(
** The value written into the *pCurrent parameter is undefined.</dd>)^
**
** [[SQLITE_STATUS_PARSER_STACK]] ^(<dt>SQLITE_STATUS_PARSER_STACK</dt>
** <dd>This parameter records the deepest parser stack. It is only
** <dd>The *pHighwater parameter records the deepest parser stack.
** The *pCurrent value is undefined. The *pHighwater value is only
** meaningful if SQLite is compiled with [YYTRACKMAXSTACKDEPTH].</dd>)^
** </dl>
**
+9 -3
View File
@@ -272,6 +272,9 @@ struct sqlite3_api_routines {
void (*value_free)(sqlite3_value*);
int (*result_zeroblob64)(sqlite3_context*,sqlite3_uint64);
int (*bind_zeroblob64)(sqlite3_stmt*, int, sqlite3_uint64);
/* Version 3.9.0 and later */
unsigned int (*value_subtype)(sqlite3_value*);
void (*result_subtype)(sqlite3_context*,unsigned int);
};
/*
@@ -285,7 +288,7 @@ struct sqlite3_api_routines {
** the API. So the redefinition macros are only valid if the
** SQLITE_CORE macros is undefined.
*/
#ifndef SQLITE_CORE
#if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
#define sqlite3_aggregate_context sqlite3_api->aggregate_context
#ifndef SQLITE_OMIT_DEPRECATED
#define sqlite3_aggregate_count sqlite3_api->aggregate_count
@@ -508,9 +511,12 @@ struct sqlite3_api_routines {
#define sqlite3_value_free sqlite3_api->value_free
#define sqlite3_result_zeroblob64 sqlite3_api->result_zeroblob64
#define sqlite3_bind_zeroblob64 sqlite3_api->bind_zeroblob64
#endif /* SQLITE_CORE */
/* Version 3.9.0 and later */
#define sqlite3_value_subtype sqlite3_api->value_subtype
#define sqlite3_result_subtype sqlite3_api->result_subtype
#endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */
#ifndef SQLITE_CORE
#if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
/* This case when the file really is being compiled as a loadable
** extension */
# define SQLITE_EXTENSION_INIT1 const sqlite3_api_routines *sqlite3_api=0;
+24 -3
View File
@@ -196,6 +196,7 @@
# include <intrin.h>
# pragma intrinsic(_byteswap_ushort)
# pragma intrinsic(_byteswap_ulong)
# pragma intrinsic(_ReadWriteBarrier)
# else
# include <cmnintrin.h>
# endif
@@ -1917,6 +1918,12 @@ struct Index {
/* Return true if index X is a UNIQUE index */
#define IsUniqueIndex(X) ((X)->onError!=OE_None)
/* The Index.aiColumn[] values are normally positive integer. But
** there are some negative values that have special meaning:
*/
#define XN_ROWID (-1) /* Indexed column is the rowid */
#define XN_EXPR (-2) /* Indexed column is an expression */
/*
** Each sample stored in the sqlite_stat3 table is represented in memory
** using a structure of this type. See documentation at the top of the
@@ -2135,6 +2142,7 @@ struct Expr {
#define EP_ConstFunc 0x080000 /* A SQLITE_FUNC_CONSTANT or _SLOCHNG function */
#define EP_CanBeNull 0x100000 /* Can be null despite NOT NULL constraint */
#define EP_Subquery 0x200000 /* Tree contains a TK_SELECT operator */
#define EP_Alias 0x400000 /* Is an alias for a result set column */
/*
** Combinations of two or more EP_* flags
@@ -2351,6 +2359,7 @@ struct SrcList {
#define WHERE_WANT_DISTINCT 0x0400 /* All output needs to be distinct */
#define WHERE_SORTBYGROUP 0x0800 /* Support sqlite3WhereIsSorted() */
#define WHERE_REOPEN_IDX 0x1000 /* Try to use OP_ReopenIdx */
#define WHERE_ONEPASS_MULTIROW 0x2000 /* ONEPASS is ok with multiple rows */
/* Allowed return values from sqlite3WhereIsDistinct()
*/
@@ -3191,11 +3200,16 @@ const sqlite3_mem_methods *sqlite3MemGetMemsys5(void);
int sqlite3MutexInit(void);
int sqlite3MutexEnd(void);
#endif
#if !defined(SQLITE_MUTEX_OMIT) && !defined(SQLITE_MUTEX_NOOP)
void sqlite3MemoryBarrier(void);
#else
# define sqlite3MemoryBarrier()
#endif
sqlite3_int64 sqlite3StatusValue(int);
void sqlite3StatusUp(int, int);
void sqlite3StatusDown(int, int);
void sqlite3StatusSet(int, int);
void sqlite3StatusHighwater(int, int);
/* Access to mutexes used by sqlite3_status() */
sqlite3_mutex *sqlite3Pcache1Mutex(void);
@@ -3374,8 +3388,12 @@ int sqlite3WhereIsSorted(WhereInfo*);
int sqlite3WhereContinueLabel(WhereInfo*);
int sqlite3WhereBreakLabel(WhereInfo*);
int sqlite3WhereOkOnePass(WhereInfo*, int*);
#define ONEPASS_OFF 0 /* Use of ONEPASS not allowed */
#define ONEPASS_SINGLE 1 /* ONEPASS valid for a single row update */
#define ONEPASS_MULTI 2 /* ONEPASS is valid for multiple rows */
void sqlite3ExprCodeLoadIndexColumn(Parse*, Index*, int, int, int);
int sqlite3ExprCodeGetColumn(Parse*, Table*, int, int, int, u8);
void sqlite3ExprCodeGetColumnToReg(Parse*, Table*, int, int, int);
void sqlite3ExprCodeGetColumnOfTable(Vdbe*, Table*, int, int, int);
void sqlite3ExprCodeMove(Parse*, int, int, int);
void sqlite3ExprCacheStore(Parse*, int, int, int);
@@ -3434,8 +3452,9 @@ int sqlite3ExprIsInteger(Expr*, int*);
int sqlite3ExprCanBeNull(const Expr*);
int sqlite3ExprNeedsNoAffinityChange(const Expr*, char);
int sqlite3IsRowid(const char*);
void sqlite3GenerateRowDelete(Parse*,Table*,Trigger*,int,int,int,i16,u8,u8,u8);
void sqlite3GenerateRowIndexDelete(Parse*, Table*, int, int, int*);
void sqlite3GenerateRowDelete(
Parse*,Table*,Trigger*,int,int,int,i16,u8,u8,u8,int);
void sqlite3GenerateRowIndexDelete(Parse*, Table*, int, int, int*, int);
int sqlite3GenerateIndexKey(Parse*, Index*, int, int, int, int*,Index*,int);
void sqlite3ResolvePartIdxLabel(Parse*,int);
void sqlite3GenerateConstraintChecks(Parse*,Table*,int*,int,int,int,int,
@@ -3493,6 +3512,7 @@ void sqlite3MaterializeView(Parse*, Table*, Expr*, int);
void sqlite3UnlinkAndDeleteTrigger(sqlite3*,int,const char*);
u32 sqlite3TriggerColmask(Parse*,Trigger*,ExprList*,int,int,Table*,int);
# define sqlite3ParseToplevel(p) ((p)->pToplevel ? (p)->pToplevel : (p))
# define sqlite3IsToplevel(p) ((p)->pToplevel==0)
#else
# define sqlite3TriggersExist(B,C,D,E,F) 0
# define sqlite3DeleteTrigger(A,B)
@@ -3502,6 +3522,7 @@ void sqlite3MaterializeView(Parse*, Table*, Expr*, int);
# define sqlite3CodeRowTriggerDirect(A,B,C,D,E,F)
# define sqlite3TriggerList(X, Y) 0
# define sqlite3ParseToplevel(p) p
# define sqlite3IsToplevel(p) 1
# define sqlite3TriggerColmask(A,B,C,D,E,F,G) 0
#endif
+18 -10
View File
@@ -108,18 +108,26 @@ void sqlite3StatusDown(int op, int N){
}
/*
** Set the value of a status to X. The highwater mark is adjusted if
** necessary. The caller must hold the appropriate mutex.
** Adjust the highwater mark if necessary.
** The caller must hold the appropriate mutex.
*/
void sqlite3StatusSet(int op, int X){
void sqlite3StatusHighwater(int op, int X){
#if SQLITE_PTRSIZE>4
sqlite3_int64 newValue = (sqlite3_int64)X;
#else
u32 newValue = (u32)X;
#endif
wsdStatInit;
assert( op>=0 && op<ArraySize(wsdStat.nowValue) );
assert( op>=0 && op<ArraySize(statMutex) );
assert( sqlite3_mutex_held(statMutex[op] ? sqlite3Pcache1Mutex()
: sqlite3MallocMutex()) );
wsdStat.nowValue[op] = X;
if( wsdStat.nowValue[op]>wsdStat.mxValue[op] ){
wsdStat.mxValue[op] = wsdStat.nowValue[op];
assert( op==SQLITE_STATUS_MALLOC_SIZE
|| op==SQLITE_STATUS_PAGECACHE_SIZE
|| op==SQLITE_STATUS_SCRATCH_SIZE
|| op==SQLITE_STATUS_PARSER_STACK );
if( newValue>wsdStat.mxValue[op] ){
wsdStat.mxValue[op] = newValue;
}
}
@@ -252,10 +260,10 @@ int sqlite3_db_status(
+ pSchema->idxHash.count
+ pSchema->fkeyHash.count
);
nByte += sqlite3MallocSize(pSchema->tblHash.ht);
nByte += sqlite3MallocSize(pSchema->trigHash.ht);
nByte += sqlite3MallocSize(pSchema->idxHash.ht);
nByte += sqlite3MallocSize(pSchema->fkeyHash.ht);
nByte += sqlite3_msize(pSchema->tblHash.ht);
nByte += sqlite3_msize(pSchema->trigHash.ht);
nByte += sqlite3_msize(pSchema->idxHash.ht);
nByte += sqlite3_msize(pSchema->fkeyHash.ht);
for(p=sqliteHashFirst(&pSchema->trigHash); p; p=sqliteHashNext(p)){
sqlite3DeleteTrigger(db, (Trigger*)sqliteHashData(p));
+5 -7
View File
@@ -6377,7 +6377,6 @@ static int tclLoadStaticExtensionCmd(
extern int sqlite3_fileio_init(sqlite3*,char**,const sqlite3_api_routines*);
extern int sqlite3_fuzzer_init(sqlite3*,char**,const sqlite3_api_routines*);
extern int sqlite3_ieee_init(sqlite3*,char**,const sqlite3_api_routines*);
extern int sqlite3_json_init(sqlite3*,char**,const sqlite3_api_routines*);
extern int sqlite3_nextchar_init(sqlite3*,char**,const sqlite3_api_routines*);
extern int sqlite3_percentile_init(sqlite3*,char**,const sqlite3_api_routines*);
extern int sqlite3_regexp_init(sqlite3*,char**,const sqlite3_api_routines*);
@@ -6385,7 +6384,6 @@ static int tclLoadStaticExtensionCmd(
extern int sqlite3_spellfix_init(sqlite3*,char**,const sqlite3_api_routines*);
extern int sqlite3_totype_init(sqlite3*,char**,const sqlite3_api_routines*);
extern int sqlite3_wholenumber_init(sqlite3*,char**,const sqlite3_api_routines*);
extern int sqlite3_fts5_init(sqlite3*,char**,const sqlite3_api_routines*);
static const struct {
const char *zExtName;
int (*pInit)(sqlite3*,char**,const sqlite3_api_routines*);
@@ -6393,13 +6391,9 @@ static int tclLoadStaticExtensionCmd(
{ "amatch", sqlite3_amatch_init },
{ "closure", sqlite3_closure_init },
{ "eval", sqlite3_eval_init },
#ifdef SQLITE_ENABLE_FTS5
{ "fts5", sqlite3_fts5_init },
#endif
{ "fileio", sqlite3_fileio_init },
{ "fuzzer", sqlite3_fuzzer_init },
{ "ieee754", sqlite3_ieee_init },
{ "json", sqlite3_json_init },
{ "nextchar", sqlite3_nextchar_init },
{ "percentile", sqlite3_percentile_init },
{ "regexp", sqlite3_regexp_init },
@@ -6426,7 +6420,11 @@ static int tclLoadStaticExtensionCmd(
Tcl_AppendResult(interp, "no such extension: ", zName, (char*)0);
return TCL_ERROR;
}
rc = aExtension[i].pInit(db, &zErrMsg, 0);
if( aExtension[i].pInit ){
rc = aExtension[i].pInit(db, &zErrMsg, 0);
}else{
rc = SQLITE_OK;
}
if( rc!=SQLITE_OK || zErrMsg ){
Tcl_AppendResult(interp, "initialization of ", zName, " failed: ", zErrMsg,
(char*)0);
+6
View File
@@ -167,6 +167,12 @@ static void set_options(Tcl_Interp *interp){
Tcl_SetVar2(interp, "sqlite_options", "atomicwrite", "0", TCL_GLOBAL_ONLY);
#endif
#ifdef SQLITE_ENABLE_JSON1
Tcl_SetVar2(interp, "sqlite_options", "json1", "1", TCL_GLOBAL_ONLY);
#else
Tcl_SetVar2(interp, "sqlite_options", "json1", "0", TCL_GLOBAL_ONLY);
#endif
#ifdef SQLITE_OMIT_ATTACH
Tcl_SetVar2(interp, "sqlite_options", "attach", "0", TCL_GLOBAL_ONLY);
#else
+31 -2
View File
@@ -462,7 +462,7 @@ static void real2hex(
}
/*
** tclcmd: test_extract(record, field)
** test_extract(record, field)
**
** This function implements an SQL user-function that accepts a blob
** containing a formatted database record as the first argument. The
@@ -509,7 +509,7 @@ static void test_extract(
}
/*
** tclcmd: test_decode(record)
** test_decode(record)
**
** This function implements an SQL user-function that accepts a blob
** containing a formatted database record as its only argument. It returns
@@ -601,6 +601,8 @@ static void test_decode(
}
/*
** test_zeroblob(N)
**
** The implementation of scalar SQL function "test_zeroblob()". This is
** similar to the built-in zeroblob() function, except that it does not
** check that the integer parameter is within range before passing it
@@ -615,6 +617,31 @@ static void test_zeroblob(
sqlite3_result_zeroblob(context, nZero);
}
/* test_getsubtype(V)
**
** Return the subtype for value V.
*/
static void test_getsubtype(
sqlite3_context *context,
int argc,
sqlite3_value **argv
){
sqlite3_result_int(context, (int)sqlite3_value_subtype(argv[0]));
}
/* test_setsubtype(V, T)
**
** Return the value V with its subtype changed to T
*/
static void test_setsubtype(
sqlite3_context *context,
int argc,
sqlite3_value **argv
){
sqlite3_result_value(context, argv[0]);
sqlite3_result_subtype(context, (unsigned int)sqlite3_value_int(argv[1]));
}
static int registerTestFunctions(sqlite3 *db){
static const struct {
char *zName;
@@ -641,6 +668,8 @@ static int registerTestFunctions(sqlite3 *db){
{ "test_decode", 1, SQLITE_UTF8, test_decode},
{ "test_extract", 2, SQLITE_UTF8, test_extract},
{ "test_zeroblob", 1, SQLITE_UTF8|SQLITE_DETERMINISTIC, test_zeroblob},
{ "test_getsubtype", 1, SQLITE_UTF8, test_getsubtype},
{ "test_setsubtype", 2, SQLITE_UTF8, test_setsubtype},
};
int i;
+11 -2
View File
@@ -67,6 +67,10 @@ int sqlite3ThreadCreate(
memset(p, 0, sizeof(*p));
p->xTask = xTask;
p->pIn = pIn;
/* If the SQLITE_TESTCTRL_FAULT_INSTALL callback is registered to a
** function that returns SQLITE_ERROR when passed the argument 200, that
** forces worker threads to run sequentially and deterministically
** for testing purposes. */
if( sqlite3FaultSim(200) ){
rc = 1;
}else{
@@ -151,7 +155,12 @@ int sqlite3ThreadCreate(
*ppThread = 0;
p = sqlite3Malloc(sizeof(*p));
if( p==0 ) return SQLITE_NOMEM;
if( sqlite3GlobalConfig.bCoreMutex==0 ){
/* If the SQLITE_TESTCTRL_FAULT_INSTALL callback is registered to a
** function that returns SQLITE_ERROR when passed the argument 200, that
** forces worker threads to run sequentially and deterministically
** (via the sqlite3FaultSim() term of the conditional) for testing
** purposes. */
if( sqlite3GlobalConfig.bCoreMutex==0 || sqlite3FaultSim(200) ){
memset(p, 0, sizeof(*p));
}else{
p->xTask = xTask;
@@ -179,7 +188,7 @@ int sqlite3ThreadJoin(SQLiteThread *p, void **ppOut){
assert( ppOut!=0 );
if( NEVER(p==0) ) return SQLITE_NOMEM;
if( p->xTask==0 ){
assert( p->id==GetCurrentThreadId() );
/* assert( p->id==GetCurrentThreadId() ); */
rc = WAIT_OBJECT_0;
assert( p->tid==0 );
}else{
+2 -1
View File
@@ -403,6 +403,7 @@ int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzErrMsg){
pParse->zTail = zSql;
i = 0;
assert( pzErrMsg!=0 );
/* sqlite3ParserTrace(stdout, "parser: "); */
pEngine = sqlite3ParserAlloc(sqlite3Malloc);
if( pEngine==0 ){
db->mallocFailed = 1;
@@ -466,7 +467,7 @@ abort_parse:
}
#ifdef YYTRACKMAXSTACKDEPTH
sqlite3_mutex_enter(sqlite3MallocMutex());
sqlite3StatusSet(SQLITE_STATUS_PARSER_STACK,
sqlite3StatusHighwater(SQLITE_STATUS_PARSER_STACK,
sqlite3ParserStackPeak(pEngine)
);
sqlite3_mutex_leave(sqlite3MallocMutex());
-5
View File
@@ -253,11 +253,6 @@ void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 moreToFollow){
sqlite3TreeViewLine(pView,"REGISTER(%d)", pExpr->iTable);
break;
}
case TK_AS: {
sqlite3TreeViewLine(pView,"AS %Q", pExpr->u.zToken);
sqlite3TreeViewExpr(pView, pExpr->pLeft, 0);
break;
}
case TK_ID: {
sqlite3TreeViewLine(pView,"ID \"%w\"", pExpr->u.zToken);
break;

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