Compare commits

..

104 Commits

Author SHA1 Message Date
dan bc76063cd2 Add a test to ensure os_unix.c works with 64KiB OS pages.
FossilOrigin-Name: e3d2be3ba47cdaafd26347620ae3bc2813203f16
2014-03-20 09:42:09 +00:00
dan 781e34cde3 Add an experimental fix to avoid attempting to mmap memory from an offset that is not a multiple of the system page size on systems with page sizes larger than 32KB.
FossilOrigin-Name: 6f3a5c24d254fc6faf607b505bdef4a7aafc21af
2014-03-20 08:59:47 +00:00
dan 344510e62b Avoid some unnecessary calls to sqlite3VdbeRecordUnpack() that were being made when merging data from two or more temp files together in vdbesort.c
FossilOrigin-Name: 707ea170b3e26965b7e3982f7554d122d130b9a6
2014-03-19 20:01:25 +00:00
drh 0e682099a1 Clean up some obsolete "register" declarations in printf.c.
FossilOrigin-Name: ecd9d3f9453be0bb8e312d8027fd1a9e55882f36
2014-03-17 15:06:57 +00:00
drh a70a073b3f Performance enhancements and size reduction for sqlite3VXPrintf()
FossilOrigin-Name: eb071eb58cf675bd6cd9dd46aed9d57fbb7a77e8
2014-03-17 14:24:27 +00:00
drh 18c7e40ca3 Fix a harmless compiler warning that crops up with SQLITE_MAX_MMAP_SIZE=0.
FossilOrigin-Name: 1277932b7e8bb36c7070ffafbf110a8e128c267b
2014-03-14 11:46:10 +00:00
dan d88e521f59 Fix an obscure bug causing sqlite3_close() to fail if there are virtual tables on the disconnect list when it is called.
FossilOrigin-Name: 6504aa47a8ebb13827be017c4cb4b2dc3c4c55f4
2014-03-12 19:38:38 +00:00
dan 82d25da5b0 Changes to FTS to ensure that it does not access the database from within the xConnect method.
FossilOrigin-Name: c67a52c356416cc200f51f9168d942e78db11d34
2014-03-12 19:20:36 +00:00
dan 87af14a639 Prevent the rtree module from reading sqlite_stat1 data from the wrong database.
FossilOrigin-Name: 7ce03c1b5552d830300575c5b41a874db7a2ec77
2014-03-12 12:44:46 +00:00
drh 468108628c Version 3.8.4.1
FossilOrigin-Name: 018d317b1257ce68a92908b05c9c7cf1494050d0
2014-03-11 15:27:36 +00:00
drh 8073c70b33 Update version number to 3.8.4.1
FossilOrigin-Name: 33f5694fa42d9a521ca081de4ddd1e9dc8952b16
2014-03-11 15:25:43 +00:00
dan 3afca7d18c Add a test to see what happens if an rtree constructor encounters an SQLITE_BUSY error. No changes to code.
FossilOrigin-Name: 5527e23636eee192030f6a3c41628030b6c50bb8
2014-03-11 09:19:26 +00:00
drh 89212fb9f9 Adjustments to the cost computation for the skip-scan query plan, to take
into account the fact that a seek has to occur on each skip.

FossilOrigin-Name: 0769eebd028ce31375cf93509a1d3687f7b117eb
2014-03-10 20:12:31 +00:00
drh b06a4ec1f0 Attempt to work around MSVC's treatment of __LINE__ as a non-constant value
in "Edit and Continue" mode by avoiding the use of __LINE__ when
SQLITE_VDBE_COVERAGE is not defined.

FossilOrigin-Name: 0a5318bc272b844e937cb1df3a07224034bc3450
2014-03-10 18:03:09 +00:00
drh 55aeee4b48 Version 3.8.4
FossilOrigin-Name: 530a1ee7dc2435f80960ce4710a3c2d2bfaaccc5
2014-03-10 12:20:37 +00:00
dan b72cad14d0 Fix a bug causing "SELECT char()" to return SQLITE_NOMEM.
FossilOrigin-Name: ba39df9d4f7ffc6475ae0dc794f7d3f58c486de8
2014-03-08 19:07:03 +00:00
drh f3ccc38a69 Improved comment on the pager.c PERSIST rollback journal delete logic
inside of hasHotJournal().  No changes to code.

FossilOrigin-Name: e5b17a9d07a35c9b44ff977ba81b93d745d26a11
2014-03-07 14:57:07 +00:00
mistachkin eb443925ef Revise change from the previous check-in to clarify the situation when handling open journal files, regardless of journal mode.
FossilOrigin-Name: 1c318ef3b76e9a9a5ff2f156a9acddfc1bda0949
2014-03-07 03:31:35 +00:00
mistachkin 8879481868 Avoid calling sqlite3OsDelete() on a file that is open, since this causes Windows to run *very* slowly. Comes up on error recovery in journal_mode=PERSIST.
FossilOrigin-Name: fdc651e2ec7a0babee669e24fd56632e7cd5f0e9
2014-03-07 02:29:56 +00:00
dan f0ec2a5ea7 Do not run corruptH.test in mmap mode.
FossilOrigin-Name: c0d54b4e41cba84dc5934e0fcd03fe422fe5c92b
2014-03-06 18:16:45 +00:00
drh fe70510aa7 Improved EXPLAIN indentation of a loop in the ANALYZE logic for STAT4.
Mark the not-found jump of a seek operation in that loop as never taken.

FossilOrigin-Name: 0a4200f95cf46ad620b9fd91f4444114a0c74730
2014-03-06 13:38:37 +00:00
dan 0df163a9f0 Remove a branch that is never taken from where.c.
FossilOrigin-Name: 4a4997221f3d61c1411a993053b40c787beea736
2014-03-06 12:36:26 +00:00
mistachkin 378d01aa94 Cosmetic change to the shell in-memory database warning to skip coloring the trailing period.
FossilOrigin-Name: c87d8e07ec596d5f0ef3003cfeb226d4b7c49549
2014-03-06 02:15:42 +00:00
drh b6e8fd105c Fix some incorrect comments and typos in comments. Add testcase() macros
to some of the new record comparison code.

FossilOrigin-Name: b83cfe899d84fe9d61540e9984321ca30401638c
2014-03-06 01:56:33 +00:00
mistachkin 62117159d0 Better loadable extension handling in the Win32 VFS when compiled for Cygwin.
FossilOrigin-Name: 29b0a4f158785449b6f3da6fcceeb63442c9711c
2014-03-06 00:30:27 +00:00
mistachkin 0d71d121ae Better support for MinGW 4.x.
FossilOrigin-Name: 170e0585202eec6882e9513eba05e6d5767bfc5b
2014-03-06 00:28:57 +00:00
drh dc90d3d8af Always include the ctype.h header in the spellfix.c extension.
FossilOrigin-Name: bfd75f471a607b442d8cd8a7070491a158e8fb1a
2014-03-05 19:36:52 +00:00
dan a6eaa635cc Avoid running a couple of test cases that use realloc() extensively if SQLITE_MEMDEBUG is defined.
FossilOrigin-Name: e406d4bb786a34cdd5dd23ed39f35dfce3e1cabd
2014-03-05 19:13:32 +00:00
drh fc5717cc99 Fix a harmless compiler warning on MSVC.
FossilOrigin-Name: 0723effc9ccae7c660fb847b36ce9324e0cb5042
2014-03-05 19:04:46 +00:00
dan 03af2168db Add SQLITE_OMIT_CTE to the list of compile options that might be returned by "PRAGMA compile_options".
FossilOrigin-Name: f33f2b3f924347e3da26741d153749330cb645ec
2014-03-05 17:29:34 +00:00
dan 13ef14afc1 Add tests to join.test to verify that it is not possible to use more than 64 tables in a join.
FossilOrigin-Name: ef1a998625e1fc051732228844388d6c59665382
2014-03-05 16:15:07 +00:00
drh 6d1626eb7c Count the number of elements in a SrcList object using an "int" rather than
a "u8", to avoid overflows and to work around an issue in the C compiler on
AIX.

FossilOrigin-Name: eee2a13f2caa48b7b8a693680edc2bbc9275292c
2014-03-05 15:52:43 +00:00
dan 1496566560 Add a test case for the problem fixed by [1d134ba2ed].
FossilOrigin-Name: d4fbc05df9501a09623d420fcd5b2bce3a57201b
2014-03-05 15:04:36 +00:00
drh 817492630a When converting a result type from TEXT to BLOB using the
sqlite3_value_blob() interface, continue to report SQLITE_TEXT as
the true type from sqlite3_value_text() as long as that text is still
valid.  The maintains legacy behavior from before the noMemType change.

FossilOrigin-Name: 1d134ba2edbdb8c0cf9e99590a69cd17e0b874a9
2014-03-05 14:40:22 +00:00
drh b1a1c29a07 Separate the column NULL value constant into a separate routine for greater
commonality with the sessions branch.

FossilOrigin-Name: 12cbebb997705e37769460e00a4aaa52c12f305e
2014-03-05 12:47:55 +00:00
dan ef4668bc05 Remove the redundant memType field from struct Mem.
FossilOrigin-Name: 9e8528578966e4f1a16d63333de648fd8cdaf0f2
2014-03-05 11:48:35 +00:00
dan d520041bc0 Do not run corruptI.test with the mmap permutation.
FossilOrigin-Name: 378b290da85cadc1acba081322d1f0e8d7694e17
2014-03-05 11:22:33 +00:00
mistachkin afc14f72ef Experimental simplification of memory flags/type handling.
FossilOrigin-Name: bac2820e13a79d91d0f8938c643134a9d6900327
2014-03-05 01:29:18 +00:00
drh 19c6d96aec Avoid indexing off the front end of an array when creating a view with
two or more blank column names in the SELECT statement that defines the view.

FossilOrigin-Name: 554501f158534f9c27fd51900589c2ab7cf300d8
2014-03-04 21:19:51 +00:00
dan 052c6784ee Fix a problem with "DEFAULT (-(-9223372036854775808))" clauses in ALTER TABLE ... ADD COLUMN commands.
FossilOrigin-Name: e072cb3ee2a03d786c08230cecc6e970de2cec5b
2014-03-04 21:00:20 +00:00
drh d1053a4314 Fix a potential memory use-after-free problem following an OOM error.
FossilOrigin-Name: 767ccb1fa11b3e7b895fb8c2e91f79e3b4202907
2014-03-04 18:06:04 +00:00
drh ed79b45cf7 Fix an assert() so that it takes OOM errors into account.
FossilOrigin-Name: 53f6ec792f5f62fcdbf25e0fce5545dd1c3048a4
2014-03-04 16:21:18 +00:00
dan a4660bd695 Ensure that BtreeMovetoUnpacked() does not try to invoke xRecordCompare when it is set to NULL.
FossilOrigin-Name: 2879234b7c373be422af3fe180cae9840943e29a
2014-03-04 16:05:25 +00:00
drh 5f1d536b53 Improve clarity of presentation in the sqlite3VdbeMemFromBtree() routine.
FossilOrigin-Name: 9830c343bc954b828f6ca752f8ae63e2c0a980c1
2014-03-04 13:18:23 +00:00
mistachkin b64fa0adf7 Fix comment in test.
FossilOrigin-Name: 1e57f67b20a1c01ede36d684be628e9270bf109a
2014-03-04 12:07:24 +00:00
mistachkin ad4b262545 Fix minor typos in the new test file.
FossilOrigin-Name: 3cbb9b1b4f8c5c2735799e84dc80614586222cd2
2014-03-04 11:54:35 +00:00
dan 5810d0315b Add tests to verify the fix for bug [4ef7e3cfca].
FossilOrigin-Name: 62410bb8a7b33efcd13bce8fd75b83523922adb8
2014-03-04 11:35:20 +00:00
mistachkin 9d42cc994c Fix name resolution problem in sub-selects within triggers, ticket [4ef7e3cfca].
FossilOrigin-Name: 5bcd0b1ca5d73ffbe7978ee9d73fe5e769e3d3a2
2014-03-04 11:29:42 +00:00
mistachkin ffe6bc2b93 Fix harmless compiler warning.
FossilOrigin-Name: 8d18a803bdeab290a6e9ff26911897f5f8683876
2014-03-04 11:16:20 +00:00
drh d34ab07507 Refactor the sqlite3VdbeRecordCompare() routine used to compare btree records.
Create fast-track special case routines to handle the common cases more
quickly.  This gives a significant performance boost.

FossilOrigin-Name: 3325ad5bdc2f81f63b556d6f4d0589d89b142b2b
2014-03-04 04:12:56 +00:00
drh f926d1ea47 Fix more instances of assuming 'char' is signed. And, make sure to never shift
a signed integer.

FossilOrigin-Name: f10130ede433a19b3945753f23962871c8d2dcf3
2014-03-04 04:04:33 +00:00
drh a9e0aeb552 Do not assume that 'char' is signed. Make it explicit.
FossilOrigin-Name: 979da752e6f8767a61a8efed824ffad9605d0f4c
2014-03-04 00:15:16 +00:00
drh f2c135fabd Refactor the sqlite3VdbeRecordCompare() routine used to compare btree records.
Create a couple of fast-track routines to handle the common cases of a string
with BINARY collation or integer values as the left-most column.  This gives
a significant performance boost in common use.

FossilOrigin-Name: aec5473a750e412eb1e11e17bbafd760db086c86
2014-03-03 21:59:33 +00:00
drh 13a747e5e4 Fix a couple of harmless compiler warnings.
FossilOrigin-Name: fcf480cc630976b619aabd5f7fb7b09601a178fb
2014-03-03 21:46:55 +00:00
dan 9b8afef260 Avoid a buffer overread in vdbeCompareRecordInt() that might occur if the database is corrupt.
FossilOrigin-Name: 7c0b4381f0e6f33cb13299a915851d9431bf3850
2014-03-03 20:48:50 +00:00
drh 5668969a69 Fix a typo in a comment. No changes to code.
FossilOrigin-Name: 1f4991ab1676bf85599fc32068ceeddeb05f648c
2014-03-03 19:29:28 +00:00
drh 295aedf097 Fix compiler warnings.
FossilOrigin-Name: ba8993727e5752cbc92c7d78437e9e0510c899f7
2014-03-03 18:25:24 +00:00
dan 80b2f97234 Merge latest trunk changes.
FossilOrigin-Name: 1d60356462f111ed147aa865dd17a13511db6ab7
2014-03-03 17:48:03 +00:00
drh 6295524e3d Change an OP_SCopy into an OP_Copy in a case where the destination might be
used after the source has changed.

FossilOrigin-Name: c0fa0c0e2de50d7eda19ab8862496b18eff93538
2014-03-03 17:36:39 +00:00
dan dea63f24e1 Change the "explain_i" tcl test command so that xterm color codes are only added if the output is actually a terminal.
FossilOrigin-Name: 559835e54e0715f2b4d207d056199a8268af739e
2014-03-03 16:48:47 +00:00
drh fcb44a89f2 Fix a harmless compiler warning.
FossilOrigin-Name: d7f6837e6997a4d5c0fd2d08b52887d691dd6f97
2014-03-03 15:13:27 +00:00
dan 900defa07a Merge latest trunk changes.
FossilOrigin-Name: e00ed717fbe456010ec6c746490d7c3e9d94ec5a
2014-03-03 14:45:06 +00:00
dan fbf0f0e1f6 Fix a segfault that can occur following an OOM error.
FossilOrigin-Name: 7fdd378d54754a3ffdc01c6c0a66cf6d5899a495
2014-03-03 14:20:30 +00:00
drh f21fa489b1 Change the MEM_Dyn flag so that it means that Mem.xDel exists and must
be used to free the string or blob. Add tighter invariant checks on Mem.

FossilOrigin-Name: e3f6c61e0333d4d237dcd2ba2e404f0a91ee5069
2014-03-03 00:12:39 +00:00
dan 7e065fcf7d Merge trunk changes.
FossilOrigin-Name: 9c1747b5ded995e77fdab2fa9d334ec3c17c7c14
2014-03-01 19:45:23 +00:00
dan 3833e934d3 Remove the vdbeRecordCompareLargeHeader function. Fix some other details.
FossilOrigin-Name: 3861e853105cb8da344c7eebd2e455622b26395e
2014-03-01 19:44:56 +00:00
drh c91b2fd310 Change the MEM_Dyn flag so that it means that Mem.xDel exists and must be
used to free the string or blob.  Add tighter invariant checks on Mem.

FossilOrigin-Name: 44e1c33767cae3bf2cbd2238831fe67197009b43
2014-03-01 18:13:23 +00:00
drh 75fd054201 Factor the Mem invariant checker into a separate procedure (rather than a
macro) so that it can be more easily extended.

FossilOrigin-Name: 354699d50e7d251504a7b3d6fbec9e5bcf99557f
2014-03-01 16:24:44 +00:00
drh defbd9dade Add extra assert() statements trying to catch a Mem object in an inconsistent
state.

FossilOrigin-Name: 4aeb3ae435c78070232fef21a147fde4e1c5cd31
2014-03-01 14:45:18 +00:00
drh efbf3b1a10 In the command-line shell add the (undocumented and unsupported) ".eqp"
command and -eqp command-line option, to cause EXPLAIN QUERY PLAN to be
run on each SQL statement as it is evaluated.  Intended use is for analysis
of the query planner.

FossilOrigin-Name: e6ecf7337658624d664e1e71ba3fc527fd6578c1
2014-02-28 20:47:24 +00:00
drh 07901eb8c3 Provide an #ifdef in shell.c to work around issues when cross-compiling
from Ubuntu to windows.

FossilOrigin-Name: 0a3579d9b9d2a60bb85a9811bc7936edb88debae
2014-02-28 19:37:45 +00:00
dan 597515d70c Update some test cases that deal with corrupt databases.
FossilOrigin-Name: 3a09f5605ac7c6e503eb10acfdc607010414d917
2014-02-28 18:39:51 +00:00
dan 063d4a041a Minor tweak to vdbeRecordCompareInt().
FossilOrigin-Name: 284bde0ee20261737446eb8f5b6b36ad9bc3f355
2014-02-28 09:48:30 +00:00
dan a6efad8a97 Merge in latest trunk changes.
FossilOrigin-Name: 8f30b09518d23c3f6cecd244a66ef918fdb55323
2014-02-27 20:52:26 +00:00
dan 3b9330f83c Further changes to sqlite3VdbeRecordCompare().
FossilOrigin-Name: 570893740067a7caa952f259fa078cdf67017d71
2014-02-27 20:44:18 +00:00
drh 69b30abd59 A better way of handling the USE_SYSTEM_SQLITE #define in shell.c.
FossilOrigin-Name: 51ce713c6ee91bdf0126155334dcc800b3daa509
2014-02-27 15:11:52 +00:00
drh c718190768 Add #defines to the command-line shell source code (shell.c) so that it
can be imported directly into other projects (ex: Fossil) and used without 
editing.

FossilOrigin-Name: a6690400235705ecc0d1a60dacff6ad5fb1f944a
2014-02-27 15:04:13 +00:00
drh 7e4efaecad More efficient removal of duplicates in recursive queries using the UNION
compound operator.

FossilOrigin-Name: 06c2db875e6cabd81c2a153b2fa4aba03eaed268
2014-02-26 21:35:31 +00:00
drh 3852b68edd In the command-line shell for CSV import, if the lines are \r\n terminated
and the last field is blank, make sure an empty string and not a "\r" string
is imported.

FossilOrigin-Name: 9c2e7612cd137895e13ee872e668ce1216719d85
2014-02-26 13:53:34 +00:00
drh 434a93147c Improved handling of constants and especially constant functions in the
ORDER BY clause of a query.  Do not optimize out "ORDER BY random()".
Fix for ticket [65bdeb9739605cc2296].

FossilOrigin-Name: dca1945aeb3fb005263f9be00ee8e72b966ae303
2014-02-26 02:26:09 +00:00
drh 0baa035a1e Do not allow temporary registers to be in use across an OP_Yield within a
co-routine.  Fix for ticket [8c63ff0eca81a9132d8].

FossilOrigin-Name: 97a8c9733cba97c78e979dfd5c66610c23e90288
2014-02-25 21:55:16 +00:00
dan 1fed5dab0d Attempt to speed up sqlite3VdbeRecordCompare() by various means. This code is in an interim state.
FossilOrigin-Name: 85206e0bbac29adab52bef795f6d1479f2ae2c0e
2014-02-25 21:01:25 +00:00
drh e8c1eba9a9 Also adjust the order of files in the amalgamation to ensure that
_FILE_OFFSET_BITS is defined before any #include, for QNX.

FossilOrigin-Name: 23001a85cd334090cf6c70d4d7e722a01f4f6899
2014-02-25 18:12:58 +00:00
drh 5e990bea51 QNX requires that _FILE_OFFSET_BITS be set prior to any system #include.
FossilOrigin-Name: 953cdd6adadfd46b51ad61d7939cecca154a02cb
2014-02-25 14:52:01 +00:00
mistachkin 151d05cd39 Fix several small style/consistency issues with the previous check-in.
FossilOrigin-Name: 2477b3a294beb35f806a38f3ebc008942ba01617
2014-02-24 21:42:33 +00:00
mistachkin edb4ece65e Merge updates from trunk.
FossilOrigin-Name: 854d410ad3a2bb3af5465d933ac9535fe3f22bfe
2014-02-24 21:23:07 +00:00
mistachkin 1925a2e6f8 Enhance testing support for the Win32 VFS dynamic extension loading facilities.
FossilOrigin-Name: 53081e7202fb55f792a78e73627466eb0200f11c
2014-02-24 21:20:25 +00:00
dan 98c91905c9 Close some stray connections in walro.test.
FossilOrigin-Name: d6746cabaa22429644c956a4b5fd91896376de2d
2014-02-24 19:49:36 +00:00
drh 9d41bc105d In memsys5, initialize new allocations to non-zero bytes. Change the content
of freed allocations to prevent use after free.  These changes in SQLITE_DEBUG
only.

FossilOrigin-Name: ba5f0a5599dece6d8f3dfe652800c28875c74a24
2014-02-24 19:07:51 +00:00
drh 15ab9418d9 Remove an unused variable from the VDBE_PROFILE compile-time option. Keep the
opcode count in an u32 instead of an int.

FossilOrigin-Name: 4df0ac9023d9261145a4425a508ba009a10276fc
2014-02-24 14:24:01 +00:00
mistachkin 5b4627e957 Better loadable extension handling in the Win32 VFS when compiled for Cygwin.
FossilOrigin-Name: 6676475c47558a52cb2632e92a541e13d143b2dc
2014-02-21 05:44:18 +00:00
drh 4d87aaed56 Fix the text of a comment used to generate VDBE opcode documentation so that
it omits symbols that can be mistaken for a hyperlink by the parser.

FossilOrigin-Name: b46d4e8923e6e367412bba7aeac07039bbcbabd1
2014-02-20 19:42:00 +00:00
drh 06280ee582 Fix a harmless shadowed-variable warning.
FossilOrigin-Name: 824029090d1c4c4c608f67dd197961eba29c039d
2014-02-20 19:32:38 +00:00
drh 4300c1ae3b Make sure that the difference between two string pointers is passed into
sqlite3_mprintf() as type "int".

FossilOrigin-Name: d5d973fedcf5a2eea219f10e11ba3dacdd0593f0
2014-02-20 19:23:15 +00:00
drh 5655c549aa Add the VdbeCoverageNeverTaken() macro, and comments that better describe how
the VDBE branch coverage measurement works.  Add some tags to provide 100%
VDBE branch coverage.

FossilOrigin-Name: c1e94169dd8eb80b4d18c73be9f81585330d11ad
2014-02-19 19:14:34 +00:00
drh 3d77dee935 Add the SQLITE_NOTNULL P5 code for comparison operations - really a composite
of SQLITE_NULLEQ and SQLITE_JUMPIFNULL.  This flag indicates that NULL operands
are not possible and raises and assert() if NULL operands are seen.
Also omit an unnecessary scan of the sqlite_sequence table when writing
into an AUTOINCREMENT table.

FossilOrigin-Name: d2c047f304848e49864ed8c216b48fd671fa3916
2014-02-19 14:20:49 +00:00
drh c0bf493ea5 Make sure a multi-row VALUES clause works correctly in a compound SELECT.
FossilOrigin-Name: 85b355cfb40e8dbeb171980204ffad897184063f
2014-02-19 01:31:02 +00:00
drh 49d9ba6354 Tweaks in support of VDBE branch test coverage.
FossilOrigin-Name: b97825646996792d0a67b83f135658027c8569ca
2014-02-19 00:53:46 +00:00
drh f4345e40a0 Fix VDBE branch accounting on comparison operators.
FossilOrigin-Name: b287520c9226f7a9fab98142f5c207bfe959cd7e
2014-02-18 11:31:59 +00:00
drh 7d1761059b Add VdbeCoverage() and VdbeCoverageIf() macros for improved VDBE coverage
testing.

FossilOrigin-Name: b92d31a97d5fe4606d9ae1393c7f3e052f46bf5a
2014-02-18 03:07:12 +00:00
drh 552fd45441 Improvements to "NOT IN (SELECT ...)" processing. Only test for NULL values
on the RHS on the first iteration, then remember the result.  There has been
logic to do this for year, but it didn't work right and ended up repeating
the NULL test on every iteration.  This inefficiency was found using the
VDBE coverage testing tools.

FossilOrigin-Name: 915f6f1c7aab54583729e60bdc1565f25ecc6f74
2014-02-18 01:07:38 +00:00
drh bb13813ed1 Merge in performance enhancements for INSERT operations, especially INSERTs
on tables that have no affinity columns or that have many indices or INSERTs
with content coming from a SELECT.  Add the SQLITE_TESTCTRL_VDBE_COVERAGE
test control and the SQLITE_VDBE_COVERAGE compile-time option used for measure
coverage of branches in VDBE programs.

FossilOrigin-Name: a72687699ba2af2e7383be7371d4121750c7e34f
2014-02-17 23:52:13 +00:00
mistachkin 65acf373c9 Use the modern MinGW major version macro, not the deprecated one.
FossilOrigin-Name: 057c16ee9786efcad6372a29b02d743ff3d628ff
2014-02-16 19:20:00 +00:00
mistachkin a7b3b63524 Better support for MinGW 4.x.
FossilOrigin-Name: e147230767383ed9f64085b613fd18508f74be21
2014-02-14 23:35:49 +00:00
78 changed files with 2394 additions and 815 deletions
+11
View File
@@ -1319,6 +1319,9 @@ testfixture.exe: $(TESTFIXTURE_SRC) $(LIBRESOBJS) $(HDR)
$(TESTFIXTURE_SRC) \
/link $(LTLINKOPTS) $(LTLIBPATHS) $(LIBRESOBJS) $(LTLIBS) $(TLIBS)
extensiontest: testfixture.exe testloadext.dll
.\testfixture.exe $(TOP)\test\loadext.test
fulltest: testfixture.exe sqlite3.exe
.\testfixture.exe $(TOP)\test\all.test
@@ -1345,6 +1348,12 @@ sqlite3_analyzer.exe: sqlite3_analyzer.c $(LIBRESOBJS)
$(LTLINK) -DBUILD_sqlite -DTCLSH=2 -I$(TCLINCDIR) sqlite3_analyzer.c \
/link $(LTLINKOPTS) $(LTLIBPATHS) $(LIBRESOBJS) $(LTLIBS) $(TLIBS)
testloadext.lo: $(TOP)\src\test_loadext.c
$(LTCOMPILE) -c $(TOP)\src\test_loadext.c
testloadext.dll: testloadext.lo
$(LD) $(LDFLAGS) $(LTLINKOPTS) $(LTLIBPATHS) /DLL /OUT:$@ testloadext.lo
showdb.exe: $(TOP)\tool\showdb.c $(SQLITE3C)
$(LTLINK) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -Fe$@ \
$(TOP)\tool\showdb.c $(SQLITE3C)
@@ -1363,6 +1372,7 @@ clean:
del /Q sqlite3.h opcodes.c opcodes.h
del /Q lemon.exe lempar.c parse.*
del /Q mkkeywordhash.exe keywordhash.h
del /Q notasharedlib.*
-rmdir /Q/S .deps
-rmdir /Q/S .libs
-rmdir /Q/S quota2a
@@ -1371,6 +1381,7 @@ clean:
-rmdir /Q/S tsrc
del /Q .target_source
del /Q tclsqlite3.exe tclsqlite3.exp
del /Q testloadext.dll testloadext.exp
del /Q testfixture.exe testfixture.exp test.db
del /Q sqlite3.dll sqlite3.lib sqlite3.exp sqlite3.def
del /Q sqlite3.c sqlite3-*.c
+1 -1
View File
@@ -1 +1 @@
3.8.4
3.8.4.1
Vendored
+9 -9
View File
@@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.62 for sqlite 3.8.4.
# Generated by GNU Autoconf 2.62 for sqlite 3.8.4.1.
#
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
# 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
@@ -743,8 +743,8 @@ SHELL=${CONFIG_SHELL-/bin/sh}
# Identity of this package.
PACKAGE_NAME='sqlite'
PACKAGE_TARNAME='sqlite'
PACKAGE_VERSION='3.8.4'
PACKAGE_STRING='sqlite 3.8.4'
PACKAGE_VERSION='3.8.4.1'
PACKAGE_STRING='sqlite 3.8.4.1'
PACKAGE_BUGREPORT=''
# Factoring default headers for most tests.
@@ -1483,7 +1483,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.4 to adapt to many kinds of systems.
\`configure' configures sqlite 3.8.4.1 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1548,7 +1548,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
short | recursive ) echo "Configuration of sqlite 3.8.4:";;
short | recursive ) echo "Configuration of sqlite 3.8.4.1:";;
esac
cat <<\_ACEOF
@@ -1664,7 +1664,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
sqlite configure 3.8.4
sqlite configure 3.8.4.1
generated by GNU Autoconf 2.62
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
@@ -1678,7 +1678,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.4, which was
It was created by sqlite $as_me 3.8.4.1, which was
generated by GNU Autoconf 2.62. Invocation command line was
$ $0 $@
@@ -14021,7 +14021,7 @@ exec 6>&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.4, which was
This file was extended by sqlite $as_me 3.8.4.1, which was
generated by GNU Autoconf 2.62. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -14074,7 +14074,7 @@ Report bugs to <bug-autoconf@gnu.org>."
_ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_version="\\
sqlite config.status 3.8.4
sqlite config.status 3.8.4.1
configured by $0, generated by GNU Autoconf 2.62,
with options \\"`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"
+37 -7
View File
@@ -1410,10 +1410,7 @@ static int fts3InitVtab(
** addition of a %_stat table so that it can use incremental merge.
*/
if( !isFts4 && !isCreate ){
int rc2 = SQLITE_OK;
fts3DbExec(&rc2, db, "SELECT 1 FROM %Q.'%q_stat' WHERE id=2",
p->zDb, p->zName);
if( rc2==SQLITE_OK ) p->bHasStat = 1;
p->bHasStat = 2;
}
/* Figure out the page-size for the database. This is required in order to
@@ -3320,7 +3317,34 @@ static int fts3SyncMethod(sqlite3_vtab *pVtab){
}
/*
** Implementation of xBegin() method. This is a no-op.
** If it is currently unknown whether or not the FTS table has an %_stat
** table (if p->bHasStat==2), attempt to determine this (set p->bHasStat
** to 0 or 1). Return SQLITE_OK if successful, or an SQLite error code
** if an error occurs.
*/
static int fts3SetHasStat(Fts3Table *p){
int rc = SQLITE_OK;
if( p->bHasStat==2 ){
const char *zFmt ="SELECT 1 FROM %Q.sqlite_master WHERE tbl_name='%q_stat'";
char *zSql = sqlite3_mprintf(zFmt, p->zDb, p->zName);
if( zSql ){
sqlite3_stmt *pStmt = 0;
rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
if( rc==SQLITE_OK ){
int bHasStat = (sqlite3_step(pStmt)==SQLITE_ROW);
rc = sqlite3_finalize(pStmt);
if( rc==SQLITE_OK ) p->bHasStat = bHasStat;
}
sqlite3_free(zSql);
}else{
rc = SQLITE_NOMEM;
}
}
return rc;
}
/*
** Implementation of xBegin() method.
*/
static int fts3BeginMethod(sqlite3_vtab *pVtab){
Fts3Table *p = (Fts3Table*)pVtab;
@@ -3331,7 +3355,7 @@ static int fts3BeginMethod(sqlite3_vtab *pVtab){
TESTONLY( p->inTransaction = 1 );
TESTONLY( p->mxSavepoint = -1; );
p->nLeafAdd = 0;
return SQLITE_OK;
return fts3SetHasStat(p);
}
/*
@@ -3580,6 +3604,10 @@ static int fts3RenameMethod(
sqlite3 *db = p->db; /* Database connection */
int rc; /* Return Code */
/* At this point it must be known if the %_stat table exists or not.
** So bHasStat may not be 2. */
rc = fts3SetHasStat(p);
/* As it happens, the pending terms table is always empty here. This is
** because an "ALTER TABLE RENAME TABLE" statement inside a transaction
** always opens a savepoint transaction. And the xSavepoint() method
@@ -3587,7 +3615,9 @@ static int fts3RenameMethod(
** PendingTermsFlush() in in case that changes.
*/
assert( p->nPendingData==0 );
rc = sqlite3Fts3PendingTermsFlush(p);
if( rc==SQLITE_OK ){
rc = sqlite3Fts3PendingTermsFlush(p);
}
if( p->zContentTbl==0 ){
fts3DbExec(&rc, db,
+1 -1
View File
@@ -223,7 +223,7 @@ struct Fts3Table {
int nNodeSize; /* Soft limit for node size */
u8 bFts4; /* True for FTS4, false for FTS3 */
u8 bHasStat; /* True if %_stat table exists */
u8 bHasStat; /* True if %_stat table exists (2==unknown) */
u8 bHasDocsize; /* True if %_docsize table exists */
u8 bDescIdx; /* True if doclists are in reverse order */
u8 bIgnoreSavepoint; /* True to ignore xSavepoint invocations */
+4
View File
@@ -5271,6 +5271,10 @@ int sqlite3Fts3UpdateMethod(
int nChng = 0; /* Net change in number of documents */
int bInsertDone = 0;
/* At this point it must be known if the %_stat table exists or not.
** So bHasStat may not be 2. */
assert( p->bHasStat==0 || p->bHasStat==1 );
assert( p->pSegments==0 );
assert(
nArg==1 /* DELETE operations */
+1 -1
View File
@@ -26,8 +26,8 @@ SQLITE_EXTENSION_INIT1
# define NEVER(X) 0
typedef unsigned char u8;
typedef unsigned short u16;
# include <ctype.h>
#endif
#include <ctype.h>
#ifndef SQLITE_OMIT_VIRTUALTABLE
+23 -15
View File
@@ -2947,26 +2947,32 @@ static int rtreeRename(sqlite3_vtab *pVtab, const char *zNewName){
** on sqlite_stat1 data. Otherwise, use RTREE_DEFAULT_ROWEST.
*/
static int rtreeQueryStat1(sqlite3 *db, Rtree *pRtree){
const char *zSql = "SELECT stat FROM sqlite_stat1 WHERE tbl= ? || '_rowid'";
const char *zFmt = "SELECT stat FROM %Q.sqlite_stat1 WHERE tbl = '%q_rowid'";
char *zSql;
sqlite3_stmt *p;
int rc;
i64 nRow = 0;
rc = sqlite3_prepare_v2(db, zSql, -1, &p, 0);
if( rc==SQLITE_OK ){
sqlite3_bind_text(p, 1, pRtree->zName, -1, SQLITE_STATIC);
if( sqlite3_step(p)==SQLITE_ROW ) nRow = sqlite3_column_int64(p, 0);
rc = sqlite3_finalize(p);
}else if( rc!=SQLITE_NOMEM ){
rc = SQLITE_OK;
}
if( rc==SQLITE_OK ){
if( nRow==0 ){
pRtree->nRowEst = RTREE_DEFAULT_ROWEST;
}else{
pRtree->nRowEst = MAX(nRow, RTREE_MIN_ROWEST);
zSql = sqlite3_mprintf(zFmt, pRtree->zDb, pRtree->zName);
if( zSql==0 ){
rc = SQLITE_NOMEM;
}else{
rc = sqlite3_prepare_v2(db, zSql, -1, &p, 0);
if( rc==SQLITE_OK ){
if( sqlite3_step(p)==SQLITE_ROW ) nRow = sqlite3_column_int64(p, 0);
rc = sqlite3_finalize(p);
}else if( rc!=SQLITE_NOMEM ){
rc = SQLITE_OK;
}
if( rc==SQLITE_OK ){
if( nRow==0 ){
pRtree->nRowEst = RTREE_DEFAULT_ROWEST;
}else{
pRtree->nRowEst = MAX(nRow, RTREE_MIN_ROWEST);
}
}
sqlite3_free(zSql);
}
return rc;
@@ -3235,6 +3241,8 @@ static int rtreeInit(
if( rc==SQLITE_OK ){
*ppVtab = (sqlite3_vtab *)pRtree;
}else{
assert( *ppVtab==0 );
assert( pRtree->nBusy==1 );
rtreeRelease(pRtree);
}
return rc;
+112
View File
@@ -158,5 +158,117 @@ do_execsql_test 4.3 {
SELECT b, a FROM t2 LEFT JOIN t1 ON (+a = +b);
} {1 1 3 {}}
#--------------------------------------------------------------------
# Test that the sqlite_stat1 data is used correctly.
#
reset_db
do_execsql_test 5.1 {
CREATE TABLE t1(x PRIMARY KEY, y);
CREATE VIRTUAL TABLE rt USING rtree(id, x1, x2);
INSERT INTO t1(x) VALUES(1);
INSERT INTO t1(x) SELECT x+1 FROM t1; -- 2
INSERT INTO t1(x) SELECT x+2 FROM t1; -- 4
INSERT INTO t1(x) SELECT x+4 FROM t1; -- 8
INSERT INTO t1(x) SELECT x+8 FROM t1; -- 16
INSERT INTO t1(x) SELECT x+16 FROM t1; -- 32
INSERT INTO t1(x) SELECT x+32 FROM t1; -- 64
INSERT INTO t1(x) SELECT x+64 FROM t1; -- 128
INSERT INTO t1(x) SELECT x+128 FROM t1; -- 256
INSERT INTO t1(x) SELECT x+256 FROM t1; -- 512
INSERT INTO t1(x) SELECT x+512 FROM t1; --1024
INSERT INTO rt SELECT x, x, x+1 FROM t1 WHERE x<=5;
}
# First test a query with no ANALYZE data at all. The outer loop is
# real table "t1".
#
do_eqp_test 5.2 {
SELECT * FROM t1, rt WHERE x==id;
} {
0 0 0 {SCAN TABLE t1}
0 1 1 {SCAN TABLE rt VIRTUAL TABLE INDEX 1:}
}
# Now create enough ANALYZE data to tell SQLite that virtual table "rt"
# contains very few rows. This causes it to move "rt" to the outer loop.
#
do_execsql_test 5.3 {
ANALYZE;
DELETE FROM sqlite_stat1 WHERE tbl='t1';
}
db close
sqlite3 db test.db
do_eqp_test 5.4 {
SELECT * FROM t1, rt WHERE x==id;
} {
0 0 1 {SCAN TABLE rt VIRTUAL TABLE INDEX 2:}
0 1 0 {SEARCH TABLE t1 USING INDEX sqlite_autoindex_t1_1 (x=?)}
}
# Delete the ANALYZE data. "t1" should be the outer loop again.
#
do_execsql_test 5.5 { DROP TABLE sqlite_stat1; }
db close
sqlite3 db test.db
do_eqp_test 5.6 {
SELECT * FROM t1, rt WHERE x==id;
} {
0 0 0 {SCAN TABLE t1}
0 1 1 {SCAN TABLE rt VIRTUAL TABLE INDEX 1:}
}
# This time create and attach a database that contains ANALYZE data for
# tables of the same names as those used internally by virtual table
# "rt". Check that the rtree module is not fooled into using this data.
# Table "t1" should remain the outer loop.
#
do_test 5.7 {
db backup test.db2
sqlite3 db2 test.db2
db2 eval {
ANALYZE;
DELETE FROM sqlite_stat1 WHERE tbl='t1';
}
db2 close
db close
sqlite3 db test.db
execsql { ATTACH 'test.db2' AS aux; }
} {}
do_eqp_test 5.8 {
SELECT * FROM t1, rt WHERE x==id;
} {
0 0 0 {SCAN TABLE t1}
0 1 1 {SCAN TABLE rt VIRTUAL TABLE INDEX 1:}
}
#--------------------------------------------------------------------
# Test that having a second connection drop the sqlite_stat1 table
# before it is required by rtreeConnect() does not cause problems.
#
ifcapable rtree {
reset_db
do_execsql_test 6.1 {
CREATE TABLE t1(x);
CREATE VIRTUAL TABLE rt USING rtree(id, x1, x2);
INSERT INTO t1 VALUES(1);
INSERT INTO rt VALUES(1,2,3);
ANALYZE;
}
db close
sqlite3 db test.db
do_execsql_test 6.2 { SELECT * FROM t1 } {1}
do_test 6.3 {
sqlite3 db2 test.db
db2 eval { DROP TABLE sqlite_stat1 }
db2 close
execsql { SELECT * FROM rt }
} {1 2.0 3.0}
db close
}
finish_test
+57
View File
@@ -0,0 +1,57 @@
# 2014 March 11
#
# 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.
#
#***********************************************************************
#
# Miscellaneous tests for errors in the rtree constructor.
#
if {![info exists testdir]} {
set testdir [file join [file dirname [info script]] .. .. test]
}
source [file join [file dirname [info script]] rtree_util.tcl]
source $testdir/tester.tcl
source $testdir/lock_common.tcl
ifcapable !rtree {
finish_test
return
}
set testprefix rtreeD
#-------------------------------------------------------------------------
# Test that if an SQLITE_BUSY is encountered within the vtable
# constructor, a relevant error message is returned.
#
do_multiclient_test tn {
do_test 1.$tn.1 {
sql1 {
CREATE TABLE t1(a, b);
INSERT INTO t1 VALUES(1,2);
CREATE VIRTUAL TABLE rt USING rtree(id, minx, maxx, miny, maxy);
INSERT INTO rt VALUES(1,2,3,4,5);
}
} {}
do_test 1.$tn.2 {
sql2 { SELECT * FROM t1; }
} {1 2}
do_test 1.$tn.3 {
sql1 { BEGIN EXCLUSIVE; INSERT INTO t1 VALUES(3, 4); }
} {}
do_test 1.$tn.4 {
list [catch { sql2 { SELECT * FROM rt } } msg] $msg
} {1 {database is locked}}
}
finish_test
+82 -76
View File
@@ -1,12 +1,12 @@
C Add\slogic\sto\sdo\stest\scoverage\smeasurements\son\sthe\sVDBE\scode.
D 2014-02-17T22:40:43.958
C Add\sa\stest\sto\sensure\sos_unix.c\sworks\swith\s64KiB\sOS\spages.
D 2014-03-20T09:42:09.744
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
F Makefile.msc 371a17ef9cd011b103cfa1964119a8528f5427c9
F Makefile.msc fdacba6fb574868c71fde6db6b77789a383a4c19
F Makefile.vxworks db21ed42a01d5740e656b16f92cb5d8d5e5dd315
F README.md 64f270c43c38c46de749e419c22f0ae2f4499fe8
F VERSION 0dc30ad5cf90736d5fd9e540c9f05c542658abe7
F VERSION c3b0d47c3c5cf25c5bd4ff9e6f3af2f9d7934ea6
F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50
F addopcodes.awk 9eb448a552d5c0185cf62c463f9c173cedae3811
F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2
@@ -38,7 +38,7 @@ F autoconf/tea/win/rules.vc c511f222b80064096b705dbeb97060ee1d6b6d63
F config.guess 226d9a188c6196f3033ffc651cbc9dcee1a42977
F config.h.in 0921066a13130082764ab4ab6456f7b5bebe56de
F config.sub 9ebe4c3b3dab6431ece34f16828b594fb420da55
F configure e12e1a4f031354f9af735bcb377941a72dc2cca5 x
F configure 6a7a482649dd20b7ee31424bf6553c6f20ca7936 x
F configure.ac 4cf9f60785143fa141b10962ccc885d973792e9a
F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad
F doc/lemon.html 334dbf6621b8fb8790297ec1abf3cfa4621709d1
@@ -78,9 +78,9 @@ 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 3fe91e36a0304ad4b35020f0e22ff37e95873166
F ext/fts3/fts3.c 41b1920b9a8657963f09cb93b208c2671c5568db
F ext/fts3/fts3.h 3a10a0af180d502cecc50df77b1b22df142817fe
F ext/fts3/fts3Int.h eb5f8029589f3d8f1dc7fd50c773326a640388b1
F ext/fts3/fts3Int.h bdeb9015405e8facffb8fc7e09174521a2a780f4
F ext/fts3/fts3_aux.c 5c211e17a64885faeb16b9ba7772f9d5445c2365
F ext/fts3/fts3_expr.c 5165c365cb5a035f5be8bb296f7aa3211d43e4ac
F ext/fts3/fts3_hash.c 29b986e43f4e9dd40110eafa377dc0d63c422c60
@@ -96,7 +96,7 @@ F ext/fts3/fts3_tokenizer.h 64c6ef6c5272c51ebe60fc607a896e84288fcbc3
F ext/fts3/fts3_tokenizer1.c 5c98225a53705e5ee34824087478cf477bdb7004
F ext/fts3/fts3_unicode.c 92391b4b4fb043564c6539ea9b8661e3bcba47b9
F ext/fts3/fts3_unicode2.c 0113d3acf13429e6dc38e0647d1bc71211c31a4d
F ext/fts3/fts3_write.c cdebe72171a217b1465032dec103f8d17f7dad4d
F ext/fts3/fts3_write.c 74c00329006c3ed6325ba4e5ab7c9b5fc99c8934
F ext/fts3/fts3speed.tcl b54caf6a18d38174f1a6e84219950d85e98bb1e9
F ext/fts3/mkfts3amal.tcl 252ecb7fe6467854f2aa237bf2c390b74e71f100
F ext/fts3/tool/fts3view.c 6cfc5b67a5f0e09c0d698f9fd012c784bfaa9197
@@ -114,13 +114,13 @@ F ext/misc/nextchar.c 35c8b8baacb96d92abbb34a83a997b797075b342
F ext/misc/percentile.c bcbee3c061b884eccb80e21651daaae8e1e43c63
F ext/misc/regexp.c af92cdaa5058fcec1451e49becc7ba44dba023dc
F ext/misc/rot13.c 1ac6f95f99b575907b9b09c81a349114cf9be45a
F ext/misc/spellfix.c 3548c433f473c2054e080b6382771636fcaa2c4c
F ext/misc/spellfix.c 93f3961074cebe63c31fcefe62ca2a032ee8dfed
F ext/misc/totype.c 4a167594e791abeed95e0a8db028822b5e8fe512
F ext/misc/vfslog.c fe40fab5c077a40477f7e5eba994309ecac6cc95
F ext/misc/vtshim.c babb0dc2bf116029e3e7c9a618b8a1377045303e
F ext/misc/wholenumber.c 784b12543d60702ebdd47da936e278aa03076212
F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761
F ext/rtree/rtree.c a4e18b2c150adad20aecbeb3408cd235a0a57441
F ext/rtree/rtree.c 2d9f95da404d850474e628c720c5ce15d29b47de
F ext/rtree/rtree.h 834dbcb82dc85b2481cde6a07cdadfddc99e9b9e
F ext/rtree/rtree1.test cf679265ecafff494a768ac9c2f43a70915a6290
F ext/rtree/rtree2.test acbb3a4ce0f4fbc2c304d2b4b784cfa161856bba
@@ -133,7 +133,8 @@ F ext/rtree/rtree8.test db79c812f9e4a11f9b1f3f9934007884610a713a
F ext/rtree/rtree9.test d86ebf08ff6328895613ed577dd8a2a37c472c34
F ext/rtree/rtreeA.test ace05e729a36e342d40cf94e9efc7b4723d9dcdf
F ext/rtree/rtreeB.test 983e567b49b5dca165940f66b87e161aa30e82b2
F ext/rtree/rtreeC.test 03975565f40a0bee165f613143e4dec716dd5a59
F ext/rtree/rtreeC.test 16d7aa86ecb6a876d2a38cf590a1471a41b3a46d
F ext/rtree/rtreeD.test 636630357638f5983701550b37f0f5867130d2ca
F ext/rtree/rtree_perf.tcl 6c18c1f23cd48e0f948930c98dfdd37dfccb5195
F ext/rtree/rtree_util.tcl 06aab2ed5b826545bf215fff90ecb9255a8647ea
F ext/rtree/sqlite3rtree.h c34c1e41d1ab80bb8ad09aae402c9c956871a765
@@ -156,42 +157,42 @@ F spec.template 86a4a43b99ebb3e75e6b9a735d5fd293a24e90ca
F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b
F sqlite3.1 3d8b83c91651f53472ca17599dae3457b8b89494
F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a
F src/alter.c 829d67a359b7c5d37120be994af2c0eac730070c
F src/analyze.c 69761e1677142d180a9f55250dee2952f45e4793
F src/alter.c 5d99edbac5bc416032772b723ee30182ee6e5de0
F src/analyze.c 663e0b291d27eb03c9fd6b421e2d61ba348a2389
F src/attach.c 3801129015ef59d76bf23c95ef9b0069d18a0c52
F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34
F src/backup.c a729e63cf5cd1829507cb7b8e89f99b95141bb53
F src/bitvec.c 19a4ba637bd85f8f63fc8c9bae5ade9fb05ec1cb
F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7
F src/btree.c b945df4f0114b4cc71006acc2fbb1333fb33a200
F src/btree.h 9e0f97c01b972f779eb7655cfb4f8727fd6dc26f
F src/btree.c 2a0e73f26c329f49e426237e71a879ffd205d778
F src/btree.h da1b69b441ecee21f8b34ba73f0ae339540c4025
F src/btreeInt.h 0be66063468a520e4d66b80c7a1dc26d04ee6ea4
F src/build.c 00ce613bc2256e525c9195cb10d0df7bcc48d1f0
F src/build.c 0d50ef95aad63f4c4fc47f3fa2670d4557c45db0
F src/callback.c 174e3c8656bc29f91d710ab61550d16eea34be98
F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac
F src/ctime.c 77779efbe78dd678d84bfb4fc2e87b6b6ad8dccd
F src/ctime.c 0231df905e2c4abba4483ee18ffc05adc321df2a
F src/date.c 593c744b2623971e45affd0bde347631bdfa4625
F src/delete.c a00bf893bd39868c51020eba1fc5182eb36bfeb7
F src/expr.c d1a8ccbf7e4dac6198674d33853e8ed01072eca4
F src/delete.c cdd57149543bb28304d8f717c243f2a86b1fc280
F src/expr.c 014b8087a15c4c314bdd798cb1cb0b32693f8b40
F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
F src/fkey.c 3cd6ce998404fb1b7203d886d6fdff71cf3c8846
F src/func.c f4499b39d66b71825514334ce67b32ff14bd19f5
F src/fkey.c 5269ef07b100763134f71b889327c333bd0989cf
F src/func.c 2945bb2c4cdc0ac43733046285a4434310be1811
F src/global.c 1d7bb7ea8254ae6a68ed9bfaf65fcb3d1690b486
F src/hash.c d139319967164f139c8d1bb8a11b14db9c4ba3cd
F src/hash.h 8890a25af81fb85a9ad7790d32eedab4b994da22
F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08
F src/insert.c 5d5e1d78f74804739b424c92346bdc26c146dfa4
F src/insert.c d8bb30535c8c0785876025a4a07f9074640a15d1
F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d
F src/legacy.c 0df0b1550b9cc1f58229644735e317ac89131f12
F src/lempar.c cdf0a000315332fc9b50b62f3b5e22e080a0952b
F src/loadext.c 867c7b330b740c6c917af9956b13b81d0a048303
F src/main.c e054917b1beb3081b0f23e8bdd3d6c0e12933dd3
F src/main.c 691b25754bef596108fe60ff1bcbe8445369c9db
F src/malloc.c 0203ebce9152c6a0e5de520140b8ba65187350be
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
F src/mem1.c c0c990fcaddff810ea277b4fb5d9138603dd5d4b
F src/mem2.c dce31758da87ec2cfa52ba4c5df1aed6e07d8e8f
F src/mem3.c 61c9d47b792908c532ca3a62b999cf21795c6534
F src/mem5.c 19d9271cb936742707b6118ed44d779657c7c511
F src/mem5.c aeb019f271ea53de83d651ec526877e6ba863450
F src/memjournal.c 0683aac6cab6ec2b5374c0db37c0deb2436a3785
F src/mutex.c d3b66a569368015e0fcb1ac15f81c119f504d3bc
F src/mutex.h 5bc526e19dccc412b7ff04642f6fdad3fdfdabea
@@ -202,26 +203,26 @@ F src/notify.c 976dd0f6171d4588e89e874fcc765e92914b6d30
F src/os.c 1b147e4cf7cc39e618115c14a086aed44bc91ace
F src/os.h 4a46270a64e9193af4a0aaa3bc2c66dc07c29b3f
F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04
F src/os_unix.c 18f7f95dc6bcb9cf4d4a238d8e2de96611bc2ae5
F src/os_win.c d4284f003445054a26689f1264b1b9bf7261bd1b
F src/pager.c 0ffa313a30ed6d061d9c6601b7b175cc50a1cab7
F src/os_unix.c ae4b5240af4619d711301d7992396e182585269f
F src/os_win.c e71678ac927d0a0fb11d993db20a9748eabf808e
F src/pager.c 97a8908bf4e6e7c3adea09d3597cfa48ae33ab4e
F src/pager.h ffd5607f7b3e4590b415b007a4382f693334d428
F src/parse.y cce844ccb80b5f969b04c25100c8d94338488efb
F src/parse.y 2613ca5d609c2f3d71dd297351f010bcec16e1e0
F src/pcache.c d8eafac28290d4bb80332005435db44991d07fc2
F src/pcache.h a5e4f5d9f5d592051d91212c5949517971ae6222
F src/pcache1.c 102e6f5a2fbc646154463eb856d1fd716867b64c
F src/pragma.c 2635d6bf8b54003ebefd773df2f50258cece2bec
F src/pragma.c e78b4bf2a267de2c17ee09f90b6807cf8d40e6a3
F src/prepare.c 677521ab7132615a8a26107a1d1c3132f44ae337
F src/printf.c 85d07756e45d7496d19439dcae3e6e9e0090f269
F src/printf.c e5a0005f8b3de21f85da6a709d2fbee76775bf4b
F src/random.c d10c1f85b6709ca97278428fd5db5bbb9c74eece
F src/resolve.c ca8b99d894164435f5c55cb304c1b8121705c51e
F src/resolve.c 273d5f47c4e2c05b2d3d2bffeda939551ab59e66
F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0
F src/select.c 618b53bd4553bd7a9ef95069396f12a8f28489e7
F src/shell.c 3dd86bf73ccd079f0e32ef5069600586085e8239
F src/select.c 0adf172d33cc610ff5ffe26edfd2ba67c3551655
F src/shell.c bab4de12b441369491812ecc93212ff4deda68fa
F src/sqlite.h.in a2ef671f92747a5a1c8a47bad5c585a8dd9eca80
F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e
F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc
F src/sqliteInt.h 004bd50575a05eefba7228c2d0fee432a53200de
F src/sqliteInt.h fa7161b3de18a9c355d4148233f3563c92311fcc
F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d
F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158
F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e
@@ -230,7 +231,7 @@ F src/test1.c 2401eee14a4309a7cfe2aeb2f30ad517a1d9c299
F src/test2.c 7355101c085304b90024f2261e056cdff13c6c35
F src/test3.c 1c0e5d6f080b8e33c1ce8b3078e7013fdbcd560c
F src/test4.c 9b32d22f5f150abe23c1830e2057c4037c45b3df
F src/test5.c 41e6e732f14a54c7b47f753e364700760f6521b0
F src/test5.c 5a34feec76d9b3a86aab30fd4f6cc9c48cbab4c1
F src/test6.c 41cacf3b0dd180823919bf9e1fbab287c9266723
F src/test7.c 72b732baa5642f795655ba1126ea032af46ecfd2
F src/test8.c 54ccd7b1df5062f0ecbf50a8f7b618f8b1f13b20
@@ -243,13 +244,13 @@ F src/test_config.c 0336e0bdbe541b4af89d7e3dd0656e8e6b51e585
F src/test_demovfs.c 69b2085076654ebc18014cbc6386f04409c959a9
F src/test_devsym.c e7498904e72ba7491d142d5c83b476c4e76993bc
F src/test_fs.c ced436e3d4b8e4681328409b8081051ce614e28f
F src/test_func.c f8235719dff4bf9ffee04c55a190af8782ce9ab5
F src/test_func.c d3013ce36f19ac72a99c73864930fd1fa41832f8
F src/test_hexio.c abfdecb6fa58c354623978efceb088ca18e379cd
F src/test_init.c 66b33120ffe9cd853b5a905ec850d51151337b32
F src/test_intarray.c 87847c71c3c36889c0bcc9c4baf9d31881665d61
F src/test_intarray.h 2ece66438cfd177b78d1bfda7a4180cd3a10844d
F src/test_journal.c f5c0a05b7b3d5930db769b5ee6c3766dc2221a64
F src/test_loadext.c df586c27176e3c2cb2e099c78da67bf14379a56e
F src/test_loadext.c a5251f956ab6af21e138dc1f9c0399394a510cb4
F src/test_malloc.c 1ff5b1243d96124c9a180f3b89424820a1f337f3
F src/test_multiplex.c 9f304bf04170c91c0318238d512df2da039eb1c8
F src/test_multiplex.h 110a8c4d356e0aa464ca8730375608a9a0b61ae1
@@ -265,32 +266,32 @@ F src/test_server.c a2615049954cbb9cfb4a62e18e2f0616e4dc38fe
F src/test_sqllog.c c1c1bbedbcaf82b93d83e4f9dd990e62476a680e
F src/test_stat.c 9898687a6c2beca733b0dd6fe19163d987826d31
F src/test_superlock.c 2b97936ca127d13962c3605dbc9a4ef269c424cd
F src/test_syscall.c 16dbe79fb320fadb5acd7a0a59f49e52ab2d2091
F src/test_syscall.c 2e21ca7f7dc54a028f1967b63f1e76155c356f9b
F src/test_tclvar.c f4dc67d5f780707210d6bb0eb6016a431c04c7fa
F src/test_thread.c 1e133a40b50e9c035b00174035b846e7eef481cb
F src/test_vfs.c e72f555ef7a59080f898fcf1a233deb9eb704ea9
F src/test_vfstrace.c 3a0ab304682fecbceb689e7d9b904211fde11d78
F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9
F src/tokenize.c 6da2de6e12218ccb0aea5184b56727d011f4bee7
F src/trigger.c a80036fcbd992729adc7cd34a875d59a71fa10cc
F src/update.c 16d6555a32298da18ce6e2a00637c462d9e3ac97
F src/utf.c 6fc6c88d50448c469c5c196acf21617a24f90269
F src/trigger.c 66f3470b03b52b395e839155786966e3e037fddb
F src/update.c 5b3e74a03b3811e586b4f2b4cbd7c49f01c93115
F src/utf.c 6dc9ec9f1b3db43ae8ba0365377f11df1ee4c01c
F src/util.c c46c90459ef9bdc0c6c73803cf4c55425b4771cf
F src/vacuum.c 3728d74919d4fb1356f9e9a13e27773db60b7179
F src/vdbe.c 392f03b25152eb44565a78b8b809743c97e5852b
F src/vdbe.h f429f5e5e14b02acbdffb2b2e8ba6e865e66e320
F src/vdbeInt.h 5286af9067cabdb8ba57b87c0c988a931be6c6c8
F src/vdbeapi.c 5bc41aaea448a7fc250902c418f1795859be3820
F src/vdbeaux.c 0e01d6fda149c689039caadb8c89b20abb58e21d
F src/vdbeblob.c d939997de046b8fcc607cfee4248f3d33dbcca50
F src/vdbemem.c 06603e8e9d2f3247b68c6bbe4bd37fb6721b5bda
F src/vdbesort.c 9d83601f9d6243fe70dd0169a2820c5ddfd48147
F src/vdbe.c 5f0fffa9bf49a90c05dc3d46d8217603fd0ee00e
F src/vdbe.h fb2c48c198300a7c632f09fc940011d2ad2fc2ae
F src/vdbeInt.h e54fc4f289fce48e81b3371128446033d097733b
F src/vdbeapi.c 0ed6053f947edd0b30f64ce5aeb811872a3450a4
F src/vdbeaux.c e45e3f9daf38c5be3fd39e9aacc1c9066af57a06
F src/vdbeblob.c 15377abfb59251bccedd5a9c7d014a895f0c04aa
F src/vdbemem.c 6fc77594c60f6155404f3f8d71bf36d1fdeb4447
F src/vdbesort.c 0a9e5e63d7ce196651610d1a264eeb0b2152d3ba
F src/vdbetrace.c 6f52bc0c51e144b7efdcfb2a8f771167a8816767
F src/vtab.c 21b932841e51ebd7d075e2d0ad1415dce8d2d5fd
F src/wal.c 76e7fc6de229bea8b30bb2539110f03a494dc3a8
F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4
F src/walker.c 11edb74d587bc87b33ca96a5173e3ec1b8389e45
F src/where.c 7825dce3f92d7c7de9329505deefe176cbd5ba43
F src/where.c bb50b5aed4f9b2284eb92c944253e60df2fb8259
F src/whereInt.h 921f935af8b684ffb49705610bda7284db1db138
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
@@ -300,7 +301,7 @@ F test/all.test 6ff7b43c2b4b905c74dc4a813d201d0fa64c5783
F test/alter.test e88dfa77e020c2b48e52a8020c70171ab828e079
F test/alter2.test 7ea05c7d92ac99349a802ef7ada17294dd647060
F test/alter3.test 49c9d9fba2b8fcdce2dedeca97bbf1f369cc548d
F test/alter4.test 8e93bf7a7e6919b14b0c9a6c1e4908bcf21b0165
F test/alter4.test d6c011fa0d6227abba762498cafbb607c9609e93
F test/altermalloc.test e81ac9657ed25c6c5bb09bebfa5a047cd8e4acfc
F test/amatch1.test b5ae7065f042b7f4c1c922933f4700add50cdb9f
F test/analyze.test 1772936d66471c65221e437b6d1999c3a03166c4
@@ -310,7 +311,7 @@ F test/analyze5.test 765c4e284aa69ca172772aa940946f55629bc8c4
F test/analyze6.test d31defa011a561b938b4608d3538c1b4e0b5e92c
F test/analyze7.test bb1409afc9e8629e414387ef048b8e0e3e0bdc4f
F test/analyze8.test 093d15c1c888eed5034304a98c992f7360130b88
F test/analyze9.test 339e87723cd4dc158dc5e9095acd8df9e87faf79
F test/analyze9.test e072a5172d55afcba98d6ca6a219ce8878c2f5c9
F test/analyzeA.test 1a5c40079894847976d983ca39c707aaa44b6944
F test/analyzeB.test 8bf35ee0a548aea831bf56762cb8e7fdb1db083d
F test/async.test 1d0e056ba1bb9729283a0f22718d3a25e82c277b
@@ -361,7 +362,7 @@ F test/btreefault.test c2bcb542685eea44621275cfedbd8a13f65201e3
F test/busy.test 76b4887f8b9160ba903c1ac22e8ff406ad6ae2f0
F test/cache.test 13bc046b26210471ca6f2889aceb1ea52dc717de
F test/capi2.test 011c16da245fdc0106a2785035de6b242c05e738
F test/capi3.test 6cdd49656bd62a296924f4d2fcfd05cd2a298369
F test/capi3.test 71bcf2fbd36a9732f617766dfd752552c8e491b5
F test/capi3b.test efb2b9cfd127efa84433cd7a2d72ce0454ae0dc4
F test/capi3c.test a21869e4d50d5dbb7e566e328fc0bc7c2efa6a32
F test/capi3d.test 6d0fc0a86d73f42dd19a7d8b7761ab9bc02277d0
@@ -402,8 +403,9 @@ F test/corruptC.test 02405cf7ed0c1e989060e1aab6d02ffbc3906fbb
F test/corruptD.test b3c205fac7952b1de645ce44bb02335cd9e3e040
F test/corruptE.test 193b4ca4e927e77c1d5f4f56203ddc998432a7ee
F test/corruptF.test be9fde98e4c93648f1ba52b74e5318edc8f59fe4
F test/corruptG.test c150f156dace653c00a121ad0f5772a0568c41ba
F test/corruptH.test 9d8186f6f8751efdfd445d8546fd98f073499039
F test/corruptG.test 58ec333a01997fe655e34e5bea52b7a2a6b9704d
F test/corruptH.test 88ed71a086e13591c917aac6de32750e7c7281cb
F test/corruptI.test 88886ec9cd1bdba835263566bbf60ee009c6ea09
F test/count.test 42a251178e32f617eda33f76236a7f79825a50b5
F test/coveridxscan.test cdb47d01acc4a634a34fd25abe85189e0d0f1e62
F test/crash.test fb9dc4a02dcba30d4aa5c2c226f98b220b2b959f
@@ -521,7 +523,7 @@ F test/fts3ak.test bd14deafe9d1586e8e9bf032411026ac4f8c925d
F test/fts3al.test 07d64326e79bbdbab20ee87fc3328fbf01641c9f
F test/fts3am.test 218aa6ba0dfc50c7c16b2022aac5c6be593d08d8
F test/fts3an.test a49ccadc07a2f7d646ec1b81bc09da2d85a85b18
F test/fts3ao.test 71b0675e3df5c512a5a03daaa95ee1916de23dda
F test/fts3ao.test 3e4e3d5e75c076520341d0bdf4eb17c00e8cbde2
F test/fts3atoken.test fca30fd86db9241d571c637751e9a8a2f50f1451
F test/fts3auto.test b981fea19b132b4e6878f50d7c1f369b28f68eb9
F test/fts3aux1.test f8f287a4a73f381f8fa15b6a70f36245f903d221
@@ -533,7 +535,7 @@ F test/fts3conf.test ee8500c86dd58ec075e8831a1e216a79989436de
F test/fts3corrupt.test 2710b77983cc7789295ddbffea52c1d3b7506dbb
F test/fts3corrupt2.test 6d96efae2f8a6af3eeaf283aba437e6d0e5447ba
F test/fts3cov.test e0fb00d8b715ddae4a94c305992dfc3ef70353d7
F test/fts3d.test c8a193513a269ec4c205ca09645e26e0bc71b860
F test/fts3d.test 597b0b76e41f0d672e2731c4d7b631d628efd13f
F test/fts3defer.test 0be4440b73a2e651fc1e472066686d6ada4b9963
F test/fts3defer2.test a3b6cbeabaf28c9398652a4d101ea224d9358479
F test/fts3defer3.test dd53fc13223c6d8264a98244e9b19abd35ed71cd
@@ -572,7 +574,7 @@ F test/fts4merge4.test c19c85ca1faa7b6d536832b49c12e1867235f584
F test/fts4noti.test aed33ba44808852dcb24bf70fa132e7bf530f057
F test/fts4unicode.test 01ec3fe2a7c3cfff3b4c0581b83caa11b33efa36
F test/full.test 6b3c8fb43c6beab6b95438c1675374b95fab245d
F test/func.test 00667bbeac044d007f6f021af1b9f6150f0c7ff8
F test/func.test a21814945d32137412b553d98ad2107f9b2173a9
F test/func2.test 772d66227e4e6684b86053302e2d74a2500e1e0f
F test/func3.test dbccee9133cfef1473c59ec07b5f0262b9d72f9a
F test/func4.test 6beacdfcb0e18c358e6c2dcacf1b65d1fa80955f
@@ -629,7 +631,7 @@ F test/ioerr3.test d3cec5e1a11ad6d27527d0d38573fbff14c71bdd
F test/ioerr4.test f130fe9e71008577b342b8874d52984bd04ede2c
F test/ioerr5.test 2edfa4fb0f896f733071303b42224df8bedd9da4
F test/ioerr6.test a395a6ab144b26a9e3e21059a1ab6a7149cca65b
F test/join.test 8d63cc4d230a7affafa4b6ab0b97c49b8ccb365c
F test/join.test 559b81eb56ae350246f9c25986aa52c81c725c7e
F test/join2.test f2171c265e57ee298a27e57e7051d22962f9f324
F test/join3.test 6f0c774ff1ba0489e6c88a3e77b9d3528fb4fda0
F test/join4.test 1a352e4e267114444c29266ce79e941af5885916
@@ -647,7 +649,7 @@ F test/laststmtchanges.test ae613f53819206b3222771828d024154d51db200
F test/like.test e191e536d0fcd722a6b965e7cd1ee0bfd12a5991
F test/like2.test 3b2ee13149ba4a8a60b59756f4e5d345573852da
F test/limit.test cc0ab63385239b63c72452b0e93700bf5e8f0b99
F test/loadext.test 92e6dfefd1229c3ef4aaabd87419efd8fa57a7a5
F test/loadext.test 648cb95f324d1775c54a55c12271b2d1156b633b
F test/loadext2.test 0408380b57adca04004247179837a18e866a74f7
F test/lock.test 87af515b0c4cf928576d0f89946d67d7c265dfb4
F test/lock2.test 5242d8ac4e2d59c403aebff606af449b455aceff
@@ -735,7 +737,7 @@ F test/pcache.test b09104b03160aca0d968d99e8cd2c5b1921a993d
F test/pcache2.test a83efe2dec0d392f814bfc998def1d1833942025
F test/percentile.test b98fc868d71eb5619d42a1702e9ab91718cbed54
F test/permutations.test 40add071ba71aefe1c04f5845308cf46f7de8d04
F test/pragma.test e882183ecd21d064cec5c7aaea174fbd36293429
F test/pragma.test adb21a90875bc54a880fa939c4d7c46598905aa0
F test/pragma2.test aea7b3d82c76034a2df2b38a13745172ddc0bc13
F test/printf.test ec9870c4dce8686a37818e0bf1aba6e6a1863552
F test/printf2.test bed79b4c3e5da08ba88ad637c0bf62586843cfb1
@@ -777,7 +779,7 @@ F test/securedel2.test 2d54c28e46eb1fd6902089958b20b1b056c6f1c5
F test/select1.test fc2a61f226a649393664ad54bc5376631801517c
F test/select2.test 352480e0e9c66eda9c3044e412abdf5be0215b56
F test/select3.test 2ce595f8fb8e2ac10071d3b4e424cadd4634a054
F test/select4.test 00179be44e531fe04c1c3f15df216439dff2519d
F test/select4.test 8c5a60d439e2df824aed56223566877a883c5c84
F test/select5.test e758b8ef94f69b111df4cb819008856655dcd535
F test/select6.test e76bd10a56988f15726c097a5d5a7966fe82d3b2
F test/select7.test 7fd2ef598cfabb6b9ff6ac13973b91d0527df49d
@@ -788,6 +790,7 @@ F test/selectB.test 954e4e49cf1f896d61794e440669e03a27ceea25
F test/selectC.test 871fb55d884d3de5943c4057ebd22c2459e71977
F test/selectD.test b0f02a04ef7737decb24e08be2c39b9664b43394
F test/selectE.test fc02a1eb04c8eb537091482644b7d778ae8759b7
F test/selectF.test 21c94e6438f76537b72532fa9fd4710cdd455fc3
F test/server1.test 46803bd3fe8b99b30dbc5ff38ffc756f5c13a118
F test/shared.test 1da9dbad400cee0d93f252ccf76e1ae007a63746
F test/shared2.test 03eb4a8d372e290107d34b6ce1809919a698e879
@@ -804,11 +807,11 @@ F test/shell1.test f2a1d471e5cd2b42f7a65b166dc1ace2b8d11583
F test/shell2.test c57da3a381c099b02c813ba156298d5c2f5c93a3
F test/shell3.test 5e8545ec72c4413a0e8d4c6be56496e3c257ca29
F test/shell4.test aa4eef8118b412d1a01477a53426ece169ea86a9
F test/shell5.test cee83b4385f842fec1f2a0bec9ea811f35386edf
F test/shell5.test bb755ea9144b8078a752fc56223582627070b5f1
F test/shortread1.test bb591ef20f0fd9ed26d0d12e80eee6d7ac8897a3
F test/shrink.test 8c70f62b6e8eb4d54533de6d65bd06b1b9a17868
F test/sidedelete.test f0ad71abe6233e3b153100f3b8d679b19a488329
F test/skipscan1.test 8c777ffd9dad6ee6d2568160cb2158f0b5cd9dd2
F test/skipscan1.test bed8cbe9d554c8c27afb6c88500f704c86a9196f
F test/skipscan2.test 5a4db0799c338ddbacb154aaa5589c0254b36a8d
F test/soak.test 0b5b6375c9f4110c828070b826b3b4b0bb65cd5f
F test/softheap1.test 40562fe6cac6d9827b7b42b86d45aedf12c15e24
@@ -832,7 +835,7 @@ F test/subselect.test d24fd8757daf97dafd2e889c73ea4c4272dcf4e4
F test/substr.test 18f57c4ca8a598805c4d64e304c418734d843c1a
F test/superlock.test 1cde669f68d2dd37d6c9bd35eee1d95491ae3fc2
F test/sync.test a34cd43e98b7fb84eabbf38f7ed8f7349b3f3d85
F test/syscall.test a653783d985108c4912cc64d341ffbbb55ad2806
F test/syscall.test d2fdaad713f103ac611fe7ef9b724c7b69f8149c
F test/sysfault.test fa776e60bf46bdd3ae69f0b73e46ee3977a58ae6
F test/table.test 580d23530187026d4502fae74a490f0408cf2cc7
F test/tableapi.test 2674633fa95d80da917571ebdd759a14d9819126
@@ -841,7 +844,7 @@ F test/tclsqlite.test 37a61c2da7e3bfe3b8c1a2867199f6b860df5d43
F test/tempdb.test 19d0f66e2e3eeffd68661a11c83ba5e6ace9128c
F test/temptable.test d2c9b87a54147161bcd1822e30c1d1cd891e5b30
F test/temptrigger.test 8ec228b0db5d7ebc4ee9b458fc28cb9e7873f5e1
F test/tester.tcl 9bd04481b8b0ef1f2049ad01f28e175ee9a14f7b
F test/tester.tcl f31bea1483ea1d39620f982130026e76f872d744
F test/thread001.test 9f22fd3525a307ff42a326b6bc7b0465be1745a5
F test/thread002.test e630504f8a06c00bf8bbe68528774dd96aeb2e58
F test/thread003.test ee4c9efc3b86a6a2767516a37bd64251272560a7
@@ -868,6 +871,7 @@ F test/tkt-3fe897352e.test 27e26eb0f1811aeba4d65aba43a4c52e99da5e70
F test/tkt-4a03edc4c8.test 91c0e135888cdc3d4eea82406a44b05c8c1648d0
F test/tkt-4c86b126f2.test cbcc611becd0396890169ab23102dd70048bbc9a
F test/tkt-4dd95f6943.test 3d0ce415d2ee15d3d564121960016b9c7be79407
F test/tkt-4ef7e3cfca.test 3965ae11cc9cf6e334f9d7d3c1e20bf8d56254b1
F test/tkt-54844eea3f.test a12b851128f46a695e4e378cca67409b9b8f5894
F test/tkt-5d863f876e.test c9f36ca503fa154a3655f92a69d2c30da1747bfa
F test/tkt-5e10420e8d.test 904d1687b3c06d43e5b3555bbcf6802e7c0ffd84
@@ -881,6 +885,7 @@ F test/tkt-80ba201079.test 105a721e6aad0ae3c5946d7615d1e4d03f6145b8
F test/tkt-80e031a00f.test 9a154173461a4dbe2de49cda73963e04842d52f7
F test/tkt-8454a207b9.test c583a9f814a82a2b5ba95207f55001c9f0cd816c
F test/tkt-868145d012.test a5f941107ece6a64410ca4755c6329b7eb57a356
F test/tkt-8c63ff0ec.test 258b7fc8d7e4e1cb5362c7d65c143528b9c4cbed
F test/tkt-91e2e8ba6f.test 08c4f94ae07696b05c9b822da0b4e5337a2f54c5
F test/tkt-94c04eaadb.test f738c57c7f68ab8be1c054415af7774617cb6223
F test/tkt-9d68c883.test 458f7d82a523d7644b54b497c986378a7d8c8b67
@@ -1016,7 +1021,7 @@ F test/unique.test 93f8b2ef5ea51b9495f8d6493429b1fd0f465264
F test/unixexcl.test cd6c765f75e50e8e2c2ba763149e5d340ea19825
F test/unordered.test ef85ac8f2f3c93ed2b9e811b684de73175fc464c
F test/update.test 1b6c488a8f993d090b7ee9ad0e234faa161b3aeb
F test/uri.test 63e03df051620a18f794b4f4adcdefb3c23b6751
F test/uri.test 23662b7b61958b0f0e47082de7d06341ccf85d5b
F test/utf16align.test 54cd35a27c005a9b6e7815d887718780b6a462ae
F test/vacuum.test ce91c39f7f91a4273bf620efad21086b5aa6ef1d
F test/vacuum2.test af432e6e3bfc0ea20a80cb86a03c7d9876d38324
@@ -1024,7 +1029,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 4057630287bfa5955628fe90a13d4c225d1c7352
F test/view.test f311691d696a5cc27e3c1b875cec1b0866b4ccd9
F test/vtab1.test b631d147b198cfd7903ab5fed028eb2a3d321dc6
F test/vtab2.test 7bcffc050da5c68f4f312e49e443063e2d391c0d
F test/vtab3.test baad99fd27217f5d6db10660522e0b7192446de1
@@ -1042,13 +1047,14 @@ F test/vtabE.test 7c4693638d7797ce2eda17af74292b97e705cc61
F test/vtabF.test fd5ad376f5a34fe0891df1f3cddb4fe7c3eb077e
F test/vtab_alter.test 9e374885248f69e251bdaacf480b04a197f125e5
F test/vtab_err.test 0d4d8eb4def1d053ac7c5050df3024fd47a3fbd8
F test/vtab_shared.test 6acafaae7126c9f49be72c2f57eb8bef3024f1cb
F test/vtab_shared.test ea8778d5b0df200adef2ca7c00c3c37d4375f772
F test/wal.test 40073e54359d43354925b2b700b7eebd5e207285
F test/wal2.test a8e3963abf6b232cf0b852b09b53665ef34007af
F test/wal3.test b22eb662bcbc148c5f6d956eaf94b047f7afe9c0
F test/wal4.test 4744e155cd6299c6bd99d3eab1c82f77db9cdb3c
F test/wal5.test 8f888b50f66b78821e61ed0e233ded5de378224b
F test/wal6.test 527581f5527bf9c24394991e2be83000aace5f9e
F test/wal64k.test 63828c2161ad76ddd4109dee0a096b6ef6895698
F test/wal7.test 2ae8f427d240099cc4b2dfef63cff44e2a68a1bd
F test/wal8.test 75c42e1bc4545c277fed212f8fc9b7723cd02216
F test/wal9.test 378e76a9ad09cd9bee06c172ad3547b0129a6750
@@ -1064,12 +1070,12 @@ F test/walhook.test ed00a40ba7255da22d6b66433ab61fab16a63483
F test/walmode.test 4022fe03ae6e830583672caa101f046438a0473c
F test/walnoshm.test 84ca10c544632a756467336b7c3b864d493ee496
F test/walpersist.test 8c6b7e3ec1ba91b5e4dc4e0921d6d3f87cd356a6
F test/walro.test 6cc247a0cc9b36aeea2057dd28a922a1cdfbd630
F test/walro.test 34422d1d95aaff0388f0791ec20edb34e2a3ed57
F test/walshared.test 0befc811dcf0b287efae21612304d15576e35417
F test/walslow.test e7be6d9888f83aa5d3d3c7c08aa9b5c28b93609a
F test/walthread.test de8dbaf6d9e41481c460ba31ca61e163d7348f8e
F test/where.test 28b64e93428961b07b0d486778d63fd672948f6b
F test/where2.test ed6baa9420a109d8be683dbef5d153d186f3690b
F test/where2.test 455a2eb2666e66c1e84e2cb5815173a85e6237db
F test/where3.test d28c51f257e60be30f74308fa385ceeddfb54a6e
F test/where4.test d8420ceeb8323a41ceff1f1841fc528e824e1ecf
F test/where5.test fdf66f96d29a064b63eb543e28da4dfdccd81ad2
@@ -1120,7 +1126,7 @@ F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e
F tool/mkpragmatab.tcl 78a77b2c554d534c6f2dc903130186ed15715460
F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97
F tool/mksqlite3c-noext.tcl 8bce31074e4cbe631bb7676526a048335f4c9f02
F tool/mksqlite3c.tcl e2ba20d3f690990079d17f3e5a7417dfb7ada543
F tool/mksqlite3c.tcl ed5b4e9ca8bf209ff401059a16362f37710fd8b8
F tool/mksqlite3h.tcl ba24038056f51fde07c0079c41885ab85e2cff12
F tool/mksqlite3internalh.tcl 3dca7bb5374cee003379b8cbac73714f610ef795
F tool/mkvsix.tcl 6477fb9dab838b7eea1eed50658ff1cda04850b5
@@ -1151,7 +1157,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01
F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff
P f29d194e03d6bcc78bf883b77e591dbccada02f0
R 3842d7f2fc20472907a26e6db9a0b24a
U drh
Z 8a746710251048df8d65813e18590ec6
P 6f3a5c24d254fc6faf607b505bdef4a7aafc21af
R 20782a7f4b1e1e0590156d829fb7cb71
U dan
Z 523769a43e90bd1d8c3037ea221853f3
+1 -1
View File
@@ -1 +1 @@
ce184c7bb16988641d37c908d9b3042456d4be3d
e3d2be3ba47cdaafd26347620ae3bc2813203f16
+7 -6
View File
@@ -77,8 +77,8 @@ static void renameTableFunc(
assert( len>0 );
} while( token!=TK_LP && token!=TK_USING );
zRet = sqlite3MPrintf(db, "%.*s\"%w\"%s", ((u8*)tname.z) - zSql, zSql,
zTableName, tname.z+tname.n);
zRet = sqlite3MPrintf(db, "%.*s\"%w\"%s", (int)(((u8*)tname.z) - zSql),
zSql, zTableName, tname.z+tname.n);
sqlite3_result_text(context, zRet, -1, SQLITE_DYNAMIC);
}
}
@@ -130,7 +130,7 @@ static void renameParentFunc(
sqlite3Dequote(zParent);
if( 0==sqlite3StrICmp((const char *)zOld, zParent) ){
char *zOut = sqlite3MPrintf(db, "%s%.*s\"%w\"",
(zOutput?zOutput:""), z-zInput, zInput, (const char *)zNew
(zOutput?zOutput:""), (int)(z-zInput), zInput, (const char *)zNew
);
sqlite3DbFree(db, zOutput);
zOutput = zOut;
@@ -216,8 +216,8 @@ static void renameTriggerFunc(
/* Variable tname now contains the token that is the old table-name
** in the CREATE TRIGGER statement.
*/
zRet = sqlite3MPrintf(db, "%.*s\"%w\"%s", ((u8*)tname.z) - zSql, zSql,
zTableName, tname.z+tname.n);
zRet = sqlite3MPrintf(db, "%.*s\"%w\"%s", (int)(((u8*)tname.z) - zSql),
zSql, zTableName, tname.z+tname.n);
sqlite3_result_text(context, zRet, -1, SQLITE_DYNAMIC);
}
}
@@ -604,7 +604,8 @@ void sqlite3MinimumFileFormat(Parse *pParse, int iDb, int minFormat){
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); VdbeCoverage(v);
j1 = 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);
sqlite3ReleaseTempReg(pParse, r1);
+5 -2
View File
@@ -1178,7 +1178,10 @@ static void analyzeOneTable(
callStatGet(v, regStat4, STAT_GET_NLT, regLt);
callStatGet(v, regStat4, STAT_GET_NDLT, regDLt);
sqlite3VdbeAddOp4Int(v, seekOp, iTabCur, addrNext, regSampleRowid, 0);
VdbeCoverage(v);
/* We know that the regSampleRowid row exists because it was read by
** the previous loop. Thus the not-found jump of seekOp will never
** be taken */
VdbeCoverageNeverTaken(v);
#ifdef SQLITE_ENABLE_STAT3
sqlite3ExprCodeGetColumnOfTable(v, pTab, iTabCur,
pIdx->aiColumn[0], regSample);
@@ -1192,7 +1195,7 @@ static void analyzeOneTable(
sqlite3VdbeAddOp3(v, OP_MakeRecord, regTabname, 6, regTemp);
sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur+1, regNewRowid);
sqlite3VdbeAddOp3(v, OP_Insert, iStatCur+1, regTemp, regNewRowid);
sqlite3VdbeAddOp2(v, OP_Goto, 0, addrNext);
sqlite3VdbeAddOp2(v, OP_Goto, 1, addrNext); /* P1==1 for end-of-loop */
sqlite3VdbeJumpHere(v, addrIsNull);
}
#endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */
+17 -4
View File
@@ -2161,6 +2161,7 @@ int sqlite3BtreeSetCacheSize(Btree *p, int mxPage){
return SQLITE_OK;
}
#if SQLITE_MAX_MMAP_SIZE>0
/*
** Change the limit on the amount of the database file that may be
** memory mapped.
@@ -2173,6 +2174,7 @@ int sqlite3BtreeSetMmapLimit(Btree *p, sqlite3_int64 szMmap){
sqlite3BtreeLeave(p);
return SQLITE_OK;
}
#endif /* SQLITE_MAX_MMAP_SIZE>0 */
/*
** Change the way data is synced to disk in order to increase or decrease
@@ -4547,6 +4549,7 @@ int sqlite3BtreeMovetoUnpacked(
int *pRes /* Write search results here */
){
int rc;
RecordCompare xRecordCompare;
assert( cursorHoldsMutex(pCur) );
assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) );
@@ -4568,6 +4571,16 @@ int sqlite3BtreeMovetoUnpacked(
}
}
if( pIdxKey ){
xRecordCompare = sqlite3VdbeFindCompare(pIdxKey);
assert( pIdxKey->default_rc==1
|| pIdxKey->default_rc==0
|| pIdxKey->default_rc==-1
);
}else{
xRecordCompare = 0; /* All keys are integers */
}
rc = moveToRoot(pCur);
if( rc ){
return rc;
@@ -4600,7 +4613,7 @@ int sqlite3BtreeMovetoUnpacked(
assert( biasRight==0 || biasRight==1 );
idx = upr>>(1-biasRight); /* idx = biasRight ? upr : (lwr+upr)/2; */
pCur->aiIdx[pCur->iPage] = (u16)idx;
if( pPage->intKey ){
if( xRecordCompare==0 ){
for(;;){
i64 nCellKey;
pCell = findCell(pPage, idx) + pPage->childPtrSize;
@@ -4652,14 +4665,14 @@ int sqlite3BtreeMovetoUnpacked(
** single byte varint and the record fits entirely on the main
** b-tree page. */
testcase( pCell+nCell+1==pPage->aDataEnd );
c = sqlite3VdbeRecordCompare(nCell, (void*)&pCell[1], pIdxKey);
c = xRecordCompare(nCell, (void*)&pCell[1], pIdxKey, 0);
}else if( !(pCell[1] & 0x80)
&& (nCell = ((nCell&0x7f)<<7) + pCell[1])<=pPage->maxLocal
){
/* The record-size field is a 2 byte varint and the record
** fits entirely on the main b-tree page. */
testcase( pCell+nCell+2==pPage->aDataEnd );
c = sqlite3VdbeRecordCompare(nCell, (void*)&pCell[2], pIdxKey);
c = xRecordCompare(nCell, (void*)&pCell[2], pIdxKey, 0);
}else{
/* The record flows over onto one or more overflow pages. In
** this case the whole cell needs to be parsed, a buffer allocated
@@ -4680,7 +4693,7 @@ int sqlite3BtreeMovetoUnpacked(
sqlite3_free(pCellKey);
goto moveto_finish;
}
c = sqlite3VdbeRecordCompare(nCell, pCellKey, pIdxKey);
c = xRecordCompare(nCell, pCellKey, pIdxKey, 0);
sqlite3_free(pCellKey);
}
if( c<0 ){
+3 -1
View File
@@ -63,7 +63,9 @@ int sqlite3BtreeOpen(
int sqlite3BtreeClose(Btree*);
int sqlite3BtreeSetCacheSize(Btree*,int);
int sqlite3BtreeSetMmapLimit(Btree*,sqlite3_int64);
#if SQLITE_MAX_MMAP_SIZE>0
int sqlite3BtreeSetMmapLimit(Btree*,sqlite3_int64);
#endif
int sqlite3BtreeSetPagerFlags(Btree*,unsigned);
int sqlite3BtreeSyncDisabled(Btree*);
int sqlite3BtreeSetPageSize(Btree *p, int nPagesize, int nReserve, int eFix);
+3 -3
View File
@@ -3473,7 +3473,7 @@ SrcList *sqlite3SrcListEnlarge(
assert( iStart<=pSrc->nSrc );
/* Allocate additional space if needed */
if( pSrc->nSrc+nExtra>pSrc->nAlloc ){
if( (u32)pSrc->nSrc+nExtra>pSrc->nAlloc ){
SrcList *pNew;
int nAlloc = pSrc->nSrc+nExtra;
int nGot;
@@ -3485,7 +3485,7 @@ SrcList *sqlite3SrcListEnlarge(
}
pSrc = pNew;
nGot = (sqlite3DbMallocSize(db, pNew) - sizeof(*pSrc))/sizeof(pSrc->a[0])+1;
pSrc->nAlloc = (u8)nGot;
pSrc->nAlloc = nGot;
}
/* Move existing slots that come after the newly inserted slots
@@ -3493,7 +3493,7 @@ SrcList *sqlite3SrcListEnlarge(
for(i=pSrc->nSrc-1; i>=iStart; i--){
pSrc->a[i+nExtra] = pSrc->a[i];
}
pSrc->nSrc += (i8)nExtra;
pSrc->nSrc += nExtra;
/* Zero the newly allocated slots */
memset(&pSrc->a[iStart], 0, sizeof(pSrc->a[0])*nExtra);
+3
View File
@@ -215,6 +215,9 @@ static const char * const azCompileOpt[] = {
#ifdef SQLITE_OMIT_COMPOUND_SELECT
"OMIT_COMPOUND_SELECT",
#endif
#ifdef SQLITE_OMIT_CTE
"OMIT_CTE",
#endif
#ifdef SQLITE_OMIT_DATETIME_FUNCS
"OMIT_DATETIME_FUNCS",
#endif
+4 -2
View File
@@ -613,7 +613,8 @@ void sqlite3GenerateRowDelete(
opSeek = HasRowid(pTab) ? OP_NotExists : OP_NotFound;
if( !bNoSeek ){
sqlite3VdbeAddOp4Int(v, opSeek, iDataCur, iLabel, iPk, nPk);
VdbeCoverage(v);
VdbeCoverageIf(v, opSeek==OP_NotExists);
VdbeCoverageIf(v, opSeek==OP_NotFound);
}
/* If there are any triggers to fire, allocate a range of registers to
@@ -656,7 +657,8 @@ void sqlite3GenerateRowDelete(
*/
if( addrStart<sqlite3VdbeCurrentAddr(v) ){
sqlite3VdbeAddOp4Int(v, opSeek, iDataCur, iLabel, iPk, nPk);
VdbeCoverage(v);
VdbeCoverageIf(v, opSeek==OP_NotExists);
VdbeCoverageIf(v, opSeek==OP_NotFound);
}
/* Do FK processing. This call checks that any FK constraints that
+70 -116
View File
@@ -1369,24 +1369,6 @@ int sqlite3ExprCanBeNull(const Expr *p){
}
}
/*
** Generate an OP_IsNull instruction that tests register iReg and jumps
** to location iDest if the value in iReg is NULL. The value in iReg
** was computed by pExpr. If we can look at pExpr at compile-time and
** determine that it can never generate a NULL, then the OP_IsNull operation
** can be omitted.
*/
void sqlite3ExprCodeIsNullJump(
Vdbe *v, /* The VDBE under construction */
const Expr *pExpr, /* Only generate OP_IsNull if this expr can be NULL */
int iReg, /* Test the value in this register for NULL */
int iDest /* Jump here if the value is null */
){
if( sqlite3ExprCanBeNull(pExpr) ){
sqlite3VdbeAddOp2(v, OP_IsNull, iReg, iDest); VdbeCoverage(v);
}
}
/*
** Return TRUE if the given expression is a constant which would be
** unchanged by OP_Affinity with the affinity given in the second
@@ -1486,9 +1468,7 @@ static int isCandidateForInOpt(Select *p){
*/
int sqlite3CodeOnce(Parse *pParse){
Vdbe *v = sqlite3GetVdbe(pParse); /* Virtual machine being coded */
int addr = sqlite3VdbeAddOp1(v, OP_Once, pParse->nOnce++);
VdbeCoverage(v);
return addr;
return sqlite3VdbeAddOp1(v, OP_Once, pParse->nOnce++);
}
/*
@@ -1596,9 +1576,8 @@ int sqlite3FindInIndex(Parse *pParse, Expr *pX, int *prNotFound){
*/
assert(v);
if( iCol<0 ){
int iAddr;
iAddr = sqlite3CodeOnce(pParse);
int iAddr = sqlite3CodeOnce(pParse);
VdbeCoverage(v);
sqlite3OpenTable(pParse, iTab, iDb, pTab, OP_OpenRead);
eType = IN_INDEX_ROWID;
@@ -1623,18 +1602,18 @@ int sqlite3FindInIndex(Parse *pParse, Expr *pX, int *prNotFound){
&& sqlite3FindCollSeq(db, ENC(db), pIdx->azColl[0], 0)==pReq
&& (!mustBeUnique || (pIdx->nKeyCol==1 && pIdx->onError!=OE_None))
){
int iAddr = sqlite3CodeOnce(pParse);
int iAddr = sqlite3CodeOnce(pParse); VdbeCoverage(v);
sqlite3VdbeAddOp3(v, OP_OpenRead, iTab, pIdx->tnum, iDb);
sqlite3VdbeSetP4KeyInfo(pParse, pIdx);
VdbeComment((v, "%s", pIdx->zName));
assert( IN_INDEX_INDEX_DESC == IN_INDEX_INDEX_ASC+1 );
eType = IN_INDEX_INDEX_ASC + pIdx->aSortOrder[0];
sqlite3VdbeJumpHere(v, iAddr);
if( prNotFound && !pTab->aCol[iCol].notNull ){
*prNotFound = ++pParse->nMem;
sqlite3VdbeAddOp2(v, OP_Null, 0, *prNotFound);
}
sqlite3VdbeJumpHere(v, iAddr);
}
}
}
@@ -1723,7 +1702,7 @@ int sqlite3CodeSubselect(
** save the results, and reuse the same result on subsequent invocations.
*/
if( !ExprHasProperty(pExpr, EP_VarSelect) ){
testAddr = sqlite3CodeOnce(pParse);
testAddr = sqlite3CodeOnce(pParse); VdbeCoverage(v);
}
#ifndef SQLITE_OMIT_EXPLAIN
@@ -2004,7 +1983,7 @@ static void sqlite3ExprCodeIN(
** the presence of a NULL on the RHS makes a difference in the
** outcome.
*/
int j1, j2, j3;
int j1, j2;
/* First check to see if the LHS is contained in the RHS. If so,
** then the presence of NULLs in the RHS does not matter, so jump
@@ -2019,19 +1998,15 @@ static void sqlite3ExprCodeIN(
** jump to destIfNull. If there are no NULLs in the RHS then
** jump to destIfFalse.
*/
j2 = sqlite3VdbeAddOp1(v, OP_NotNull, rRhsHasNull); VdbeCoverage(v);
j3 = sqlite3VdbeAddOp4Int(v, OP_Found, pExpr->iTable, 0, rRhsHasNull, 1);
VdbeCoverage(v);
sqlite3VdbeAddOp2(v, OP_Integer, -1, rRhsHasNull);
sqlite3VdbeJumpHere(v, j3);
sqlite3VdbeAddOp2(v, OP_AddImm, rRhsHasNull, 1);
sqlite3VdbeJumpHere(v, j2);
/* Jump to the appropriate target depending on whether or not
** the RHS contains a NULL
*/
sqlite3VdbeAddOp2(v, OP_If, rRhsHasNull, destIfNull); VdbeCoverage(v);
sqlite3VdbeAddOp2(v, OP_IfNot, rRhsHasNull, destIfFalse); VdbeCoverage(v);
j2 = sqlite3VdbeAddOp4Int(v, OP_Found, pExpr->iTable, 0, rRhsHasNull, 1);
VdbeCoverage(v);
sqlite3VdbeAddOp2(v, OP_Integer, 0, rRhsHasNull);
sqlite3VdbeAddOp2(v, OP_Goto, 0, destIfFalse);
sqlite3VdbeJumpHere(v, j2);
sqlite3VdbeAddOp2(v, OP_Integer, 1, rRhsHasNull);
sqlite3VdbeAddOp2(v, OP_Goto, 0, destIfNull);
/* The OP_Found at the top of this branch jumps here when true,
** causing the overall IN expression evaluation to fall through.
@@ -2552,22 +2527,16 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){
case TK_GE:
case TK_NE:
case TK_EQ: {
assert( TK_LT==OP_Lt );
assert( TK_LE==OP_Le );
assert( TK_GT==OP_Gt );
assert( TK_GE==OP_Ge );
assert( TK_EQ==OP_Eq );
assert( TK_NE==OP_Ne );
testcase( op==TK_LT );
testcase( op==TK_LE );
testcase( op==TK_GT );
testcase( op==TK_GE );
testcase( op==TK_EQ );
testcase( op==TK_NE );
r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, &regFree1);
r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, &regFree2);
codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op,
r1, r2, inReg, SQLITE_STOREP2); VdbeCoverage(v);
r1, r2, inReg, SQLITE_STOREP2);
assert(TK_LT==OP_Lt); testcase(op==OP_Lt); VdbeCoverageIf(v,op==OP_Lt);
assert(TK_LE==OP_Le); testcase(op==OP_Le); VdbeCoverageIf(v,op==OP_Le);
assert(TK_GT==OP_Gt); testcase(op==OP_Gt); VdbeCoverageIf(v,op==OP_Gt);
assert(TK_GE==OP_Ge); testcase(op==OP_Ge); VdbeCoverageIf(v,op==OP_Ge);
assert(TK_EQ==OP_Eq); testcase(op==OP_Eq); VdbeCoverageIf(v,op==OP_Eq);
assert(TK_NE==OP_Ne); testcase(op==OP_Ne); VdbeCoverageIf(v,op==OP_Ne);
testcase( regFree1==0 );
testcase( regFree2==0 );
break;
@@ -2581,7 +2550,8 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){
op = (op==TK_IS) ? TK_EQ : TK_NE;
codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op,
r1, r2, inReg, SQLITE_STOREP2 | SQLITE_NULLEQ);
VdbeCoverage(v);
VdbeCoverageIf(v, op==TK_EQ);
VdbeCoverageIf(v, op==TK_NE);
testcase( regFree1==0 );
testcase( regFree2==0 );
break;
@@ -2598,28 +2568,17 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){
case TK_LSHIFT:
case TK_RSHIFT:
case TK_CONCAT: {
assert( TK_AND==OP_And );
assert( TK_OR==OP_Or );
assert( TK_PLUS==OP_Add );
assert( TK_MINUS==OP_Subtract );
assert( TK_REM==OP_Remainder );
assert( TK_BITAND==OP_BitAnd );
assert( TK_BITOR==OP_BitOr );
assert( TK_SLASH==OP_Divide );
assert( TK_LSHIFT==OP_ShiftLeft );
assert( TK_RSHIFT==OP_ShiftRight );
assert( TK_CONCAT==OP_Concat );
testcase( op==TK_AND );
testcase( op==TK_OR );
testcase( op==TK_PLUS );
testcase( op==TK_MINUS );
testcase( op==TK_REM );
testcase( op==TK_BITAND );
testcase( op==TK_BITOR );
testcase( op==TK_SLASH );
testcase( op==TK_LSHIFT );
testcase( op==TK_RSHIFT );
testcase( op==TK_CONCAT );
assert( TK_AND==OP_And ); testcase( op==TK_AND );
assert( TK_OR==OP_Or ); testcase( op==TK_OR );
assert( TK_PLUS==OP_Add ); testcase( op==TK_PLUS );
assert( TK_MINUS==OP_Subtract ); testcase( op==TK_MINUS );
assert( TK_REM==OP_Remainder ); testcase( op==TK_REM );
assert( TK_BITAND==OP_BitAnd ); testcase( op==TK_BITAND );
assert( TK_BITOR==OP_BitOr ); testcase( op==TK_BITOR );
assert( TK_SLASH==OP_Divide ); testcase( op==TK_SLASH );
assert( TK_LSHIFT==OP_ShiftLeft ); testcase( op==TK_LSHIFT );
assert( TK_RSHIFT==OP_ShiftRight ); testcase( op==TK_RSHIFT );
assert( TK_CONCAT==OP_Concat ); testcase( op==TK_CONCAT );
r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, &regFree1);
r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, &regFree2);
sqlite3VdbeAddOp3(v, op, r2, r1, target);
@@ -2651,10 +2610,8 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){
}
case TK_BITNOT:
case TK_NOT: {
assert( TK_BITNOT==OP_BitNot );
assert( TK_NOT==OP_Not );
testcase( op==TK_BITNOT );
testcase( op==TK_NOT );
assert( TK_BITNOT==OP_BitNot ); testcase( op==TK_BITNOT );
assert( TK_NOT==OP_Not ); testcase( op==TK_NOT );
r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, &regFree1);
testcase( regFree1==0 );
inReg = target;
@@ -2664,14 +2621,14 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){
case TK_ISNULL:
case TK_NOTNULL: {
int addr;
assert( TK_ISNULL==OP_IsNull );
assert( TK_NOTNULL==OP_NotNull );
testcase( op==TK_ISNULL );
testcase( op==TK_NOTNULL );
assert( TK_ISNULL==OP_IsNull ); testcase( op==TK_ISNULL );
assert( TK_NOTNULL==OP_NotNull ); testcase( op==TK_NOTNULL );
sqlite3VdbeAddOp2(v, OP_Integer, 1, target);
r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, &regFree1);
testcase( regFree1==0 );
addr = sqlite3VdbeAddOp1(v, op, r1); VdbeCoverage(v);
addr = sqlite3VdbeAddOp1(v, op, r1);
VdbeCoverageIf(v, op==TK_ISNULL);
VdbeCoverageIf(v, op==TK_NOTNULL);
sqlite3VdbeAddOp2(v, OP_AddImm, target, -1);
sqlite3VdbeJumpHere(v, addr);
break;
@@ -2861,8 +2818,7 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){
r3 = sqlite3GetTempReg(pParse);
r4 = sqlite3GetTempReg(pParse);
codeCompare(pParse, pLeft, pRight, OP_Ge,
r1, r2, r3, SQLITE_STOREP2);
VdbeCoverage(v);
r1, r2, r3, SQLITE_STOREP2); VdbeCoverage(v);
pLItem++;
pRight = pLItem->pExpr;
sqlite3ReleaseTempReg(pParse, regFree2);
@@ -3609,23 +3565,17 @@ void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){
case TK_GE:
case TK_NE:
case TK_EQ: {
assert( TK_LT==OP_Lt );
assert( TK_LE==OP_Le );
assert( TK_GT==OP_Gt );
assert( TK_GE==OP_Ge );
assert( TK_EQ==OP_Eq );
assert( TK_NE==OP_Ne );
testcase( op==TK_LT );
testcase( op==TK_LE );
testcase( op==TK_GT );
testcase( op==TK_GE );
testcase( op==TK_EQ );
testcase( op==TK_NE );
testcase( jumpIfNull==0 );
r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, &regFree1);
r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, &regFree2);
codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op,
r1, r2, dest, jumpIfNull); VdbeCoverage(v);
r1, r2, dest, jumpIfNull);
assert(TK_LT==OP_Lt); testcase(op==OP_Lt); VdbeCoverageIf(v,op==OP_Lt);
assert(TK_LE==OP_Le); testcase(op==OP_Le); VdbeCoverageIf(v,op==OP_Le);
assert(TK_GT==OP_Gt); testcase(op==OP_Gt); VdbeCoverageIf(v,op==OP_Gt);
assert(TK_GE==OP_Ge); testcase(op==OP_Ge); VdbeCoverageIf(v,op==OP_Ge);
assert(TK_EQ==OP_Eq); testcase(op==OP_Eq); VdbeCoverageIf(v,op==OP_Eq);
assert(TK_NE==OP_Ne); testcase(op==OP_Ne); VdbeCoverageIf(v,op==OP_Ne);
testcase( regFree1==0 );
testcase( regFree2==0 );
break;
@@ -3638,19 +3588,21 @@ void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){
r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, &regFree2);
op = (op==TK_IS) ? TK_EQ : TK_NE;
codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op,
r1, r2, dest, SQLITE_NULLEQ); VdbeCoverage(v);
r1, r2, dest, SQLITE_NULLEQ);
VdbeCoverageIf(v, op==TK_EQ);
VdbeCoverageIf(v, op==TK_NE);
testcase( regFree1==0 );
testcase( regFree2==0 );
break;
}
case TK_ISNULL:
case TK_NOTNULL: {
assert( TK_ISNULL==OP_IsNull );
assert( TK_NOTNULL==OP_NotNull );
testcase( op==TK_ISNULL );
testcase( op==TK_NOTNULL );
assert( TK_ISNULL==OP_IsNull ); testcase( op==TK_ISNULL );
assert( TK_NOTNULL==OP_NotNull ); testcase( op==TK_NOTNULL );
r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, &regFree1);
sqlite3VdbeAddOp2(v, op, r1, dest); VdbeCoverage(v);
sqlite3VdbeAddOp2(v, op, r1, dest);
VdbeCoverageIf(v, op==TK_ISNULL);
VdbeCoverageIf(v, op==TK_NOTNULL);
testcase( regFree1==0 );
break;
}
@@ -3769,17 +3721,17 @@ void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){
case TK_GE:
case TK_NE:
case TK_EQ: {
testcase( op==TK_LT );
testcase( op==TK_LE );
testcase( op==TK_GT );
testcase( op==TK_GE );
testcase( op==TK_EQ );
testcase( op==TK_NE );
testcase( jumpIfNull==0 );
r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, &regFree1);
r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, &regFree2);
codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op,
r1, r2, dest, jumpIfNull); VdbeCoverage(v);
r1, r2, dest, jumpIfNull);
assert(TK_LT==OP_Lt); testcase(op==OP_Lt); VdbeCoverageIf(v,op==OP_Lt);
assert(TK_LE==OP_Le); testcase(op==OP_Le); VdbeCoverageIf(v,op==OP_Le);
assert(TK_GT==OP_Gt); testcase(op==OP_Gt); VdbeCoverageIf(v,op==OP_Gt);
assert(TK_GE==OP_Ge); testcase(op==OP_Ge); VdbeCoverageIf(v,op==OP_Ge);
assert(TK_EQ==OP_Eq); testcase(op==OP_Eq); VdbeCoverageIf(v,op==OP_Eq);
assert(TK_NE==OP_Ne); testcase(op==OP_Ne); VdbeCoverageIf(v,op==OP_Ne);
testcase( regFree1==0 );
testcase( regFree2==0 );
break;
@@ -3792,17 +3744,19 @@ void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){
r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, &regFree2);
op = (pExpr->op==TK_IS) ? TK_NE : TK_EQ;
codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op,
r1, r2, dest, SQLITE_NULLEQ); VdbeCoverage(v);
r1, r2, dest, SQLITE_NULLEQ);
VdbeCoverageIf(v, op==TK_EQ);
VdbeCoverageIf(v, op==TK_NE);
testcase( regFree1==0 );
testcase( regFree2==0 );
break;
}
case TK_ISNULL:
case TK_NOTNULL: {
testcase( op==TK_ISNULL );
testcase( op==TK_NOTNULL );
r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, &regFree1);
sqlite3VdbeAddOp2(v, op, r1, dest); VdbeCoverage(v);
sqlite3VdbeAddOp2(v, op, r1, dest);
testcase( op==TK_ISNULL ); VdbeCoverageIf(v, op==TK_ISNULL);
testcase( op==TK_NOTNULL ); VdbeCoverageIf(v, op==TK_NOTNULL);
testcase( regFree1==0 );
break;
}
+1
View File
@@ -369,6 +369,7 @@ static void fkLookupParent(
** increment the constraint-counter. */
if( pTab==pFKey->pFrom && nIncr==1 ){
sqlite3VdbeAddOp3(v, OP_Eq, regData, iOk, regTemp); VdbeCoverage(v);
sqlite3VdbeChangeP5(v, SQLITE_NOTNULL);
}
sqlite3OpenTable(pParse, iCur, iDb, pTab, OP_OpenRead);
+1 -1
View File
@@ -1017,7 +1017,7 @@ static void charFunc(
){
unsigned char *z, *zOut;
int i;
zOut = z = sqlite3_malloc( argc*4 );
zOut = z = sqlite3_malloc( argc*4+1 );
if( z==0 ){
sqlite3_result_error_nomem(context);
return;
+15 -20
View File
@@ -101,13 +101,13 @@ const char *sqlite3IndexAffinityStr(Vdbe *v, Index *pIdx){
** Compute the affinity string for table pTab, if it has not already been
** computed. As an optimization, omit trailing SQLITE_AFF_NONE affinities.
**
** If the affinity exists (if it is no entirely SQLITE_AFF_NONE values and
** If the affinity exists (if it is no entirely SQLITE_AFF_NONE values) and
** if iReg>0 then code an OP_Affinity opcode that will set the affinities
** for register iReg and following. Or if affinities exists and iReg==0,
** then just set the P4 operand of the previous opcode (which should be
** an OP_MakeRecord) to the affinity string.
**
** A column affinity string has one character column:
** A column affinity string has one character per column:
**
** Character Column affinity
** ------------------------------
@@ -148,10 +148,9 @@ void sqlite3TableAffinity(Vdbe *v, Table *pTab, int iReg){
/*
** Return non-zero if the table pTab in database iDb or any of its indices
** have been opened at any point in the VDBE program beginning at location
** iStartAddr throught the end of the program. This is used to see if
** have been opened at any point in the VDBE program. This is used to see if
** a statement of the form "INSERT INTO <iDb, pTab> SELECT ..." can
** run without using temporary table for the results of the SELECT.
** run without using a temporary table for the results of the SELECT.
*/
static int readsTable(Parse *p, int iDb, Table *pTab){
Vdbe *v = sqlite3GetVdbe(p);
@@ -304,7 +303,7 @@ void sqlite3AutoincrementEnd(Parse *pParse){
assert( v );
for(p = pParse->pAinc; p; p = p->pNext){
Db *pDb = &db->aDb[p->iDb];
int j1, j2, j3, j4, j5;
int j1;
int iRec;
int memId = p->regCtr;
@@ -312,17 +311,8 @@ void sqlite3AutoincrementEnd(Parse *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);
j2 = sqlite3VdbeAddOp0(v, OP_Rewind); VdbeCoverage(v);
j3 = sqlite3VdbeAddOp3(v, OP_Column, 0, 0, iRec);
j4 = sqlite3VdbeAddOp3(v, OP_Eq, memId-1, 0, iRec); VdbeCoverage(v);
sqlite3VdbeAddOp2(v, OP_Next, 0, j3); VdbeCoverage(v);
sqlite3VdbeJumpHere(v, j2);
sqlite3VdbeAddOp2(v, OP_NewRowid, 0, memId+1);
j5 = sqlite3VdbeAddOp0(v, OP_Goto);
sqlite3VdbeJumpHere(v, j4);
sqlite3VdbeAddOp2(v, OP_Rowid, 0, memId+1);
sqlite3VdbeJumpHere(v, j1);
sqlite3VdbeJumpHere(v, j5);
sqlite3VdbeAddOp3(v, OP_MakeRecord, memId-1, 2, iRec);
sqlite3VdbeAddOp3(v, OP_Insert, 0, iRec, memId+1);
sqlite3VdbeChangeP5(v, OPFLAG_APPEND);
@@ -686,18 +676,18 @@ void sqlite3Insert(
*/
int regRec; /* Register to hold packed record */
int regTempRowid; /* Register to hold temp table ROWID */
int addrTop; /* Label "L" */
int addrL; /* Label "L" */
srcTab = pParse->nTab++;
regRec = sqlite3GetTempReg(pParse);
regTempRowid = sqlite3GetTempReg(pParse);
sqlite3VdbeAddOp2(v, OP_OpenEphemeral, srcTab, nColumn);
addrTop = sqlite3VdbeAddOp1(v, OP_Yield, dest.iSDParm); VdbeCoverage(v);
addrL = sqlite3VdbeAddOp1(v, OP_Yield, dest.iSDParm); VdbeCoverage(v);
sqlite3VdbeAddOp3(v, OP_MakeRecord, regFromSelect, nColumn, regRec);
sqlite3VdbeAddOp2(v, OP_NewRowid, srcTab, regTempRowid);
sqlite3VdbeAddOp3(v, OP_Insert, srcTab, regRec, regTempRowid);
sqlite3VdbeAddOp2(v, OP_Goto, 0, addrTop);
sqlite3VdbeJumpHere(v, addrTop);
sqlite3VdbeAddOp2(v, OP_Goto, 0, addrL);
sqlite3VdbeJumpHere(v, addrL);
sqlite3ReleaseTempReg(pParse, regRec);
sqlite3ReleaseTempReg(pParse, regTempRowid);
}
@@ -1275,6 +1265,7 @@ void sqlite3GenerateConstraintChecks(
** it might have changed. Skip the conflict logic below if the rowid
** is unchanged. */
sqlite3VdbeAddOp3(v, OP_Eq, regNewData, addrRowidOk, regOldData);
sqlite3VdbeChangeP5(v, SQLITE_NOTNULL);
VdbeCoverage(v);
}
@@ -1446,6 +1437,7 @@ void sqlite3GenerateConstraintChecks(
** is different from old-rowid */
if( isUpdate ){
sqlite3VdbeAddOp3(v, OP_Eq, regR, addrUniqueOk, regOldData);
sqlite3VdbeChangeP5(v, SQLITE_NOTNULL);
VdbeCoverage(v);
}
}else{
@@ -1481,7 +1473,10 @@ void sqlite3GenerateConstraintChecks(
}
sqlite3VdbeAddOp4(v, op,
regOldData+1+x, addrJump, regCmp+i, p4, P4_COLLSEQ
); VdbeCoverage(v);
);
sqlite3VdbeChangeP5(v, SQLITE_NOTNULL);
VdbeCoverageIf(v, op==OP_Eq);
VdbeCoverageIf(v, op==OP_Ne);
}
}
}
+1
View File
@@ -800,6 +800,7 @@ static void disconnectAllVtab(sqlite3 *db){
}
}
}
sqlite3VtabUnlockList(db);
sqlite3BtreeLeaveAll(db);
#else
UNUSED_PARAMETER(db);
+13
View File
@@ -275,6 +275,12 @@ static void *memsys5MallocUnsafe(int nByte){
if( mem5.maxCount<mem5.currentCount ) mem5.maxCount = mem5.currentCount;
if( mem5.maxOut<mem5.currentOut ) mem5.maxOut = mem5.currentOut;
#ifdef SQLITE_DEBUG
/* Make sure the allocated memory does not assume that it is set to zero
** or retains a value from a previous allocation */
memset(&mem5.zPool[i*mem5.szAtom], 0xAA, iFullSz);
#endif
/* Return a pointer to the allocated memory. */
return (void*)&mem5.zPool[i*mem5.szAtom];
}
@@ -332,6 +338,13 @@ static void memsys5FreeUnsafe(void *pOld){
}
size *= 2;
}
#ifdef SQLITE_DEBUG
/* Overwrite freed memory with the 0x55 bit pattern to verify that it is
** not used after being freed */
memset(&mem5.zPool[iBlock*mem5.szAtom], 0x55, size);
#endif
memsys5Link(iBlock, iLogsize);
}
+59 -23
View File
@@ -323,6 +323,7 @@ static int posixFchown(int fd, uid_t uid, gid_t gid){
/* Forward reference */
static int openDirectory(const char*, int*);
static int unixGetpagesize(void);
/*
** Many system calls are accessed through pointer-to-functions so that
@@ -446,6 +447,9 @@ static struct unix_syscall {
#define osMremap ((void*(*)(void*,size_t,size_t,int,...))aSyscall[23].pCurrent)
#endif
{ "getpagesize", (sqlite3_syscall_ptr)unixGetpagesize, 0 },
#define osGetpagesize ((int(*)(void))aSyscall[24].pCurrent)
}; /* End of the overrideable system calls */
/*
@@ -4105,6 +4109,36 @@ static int unixShmSystemLock(
return rc;
}
/*
** Return the system page size.
**
** This function should not be called directly by other code in this file.
** Instead, it should be called via macro osGetpagesize().
*/
static int unixGetpagesize(void){
#if defined(_BSD_SOURCE)
return getpagesize();
#else
return (int)sysconf(_SC_PAGESIZE);
#endif
}
/*
** Return the minimum number of 32KB shm regions that should be mapped at
** a time, assuming that each mapping must be an integer multiple of the
** current system page-size.
**
** Usually, this is 1. The exception seems to be systems that are configured
** to use 64KB pages - in this case each mapping must cover at least two
** shm regions.
*/
static int unixShmRegionPerMap(void){
int shmsz = 32*1024; /* SHM region size */
int pgsz = osGetpagesize(); /* System page size */
assert( ((pgsz-1)&pgsz)==0 ); /* Page size must be a power of 2 */
if( pgsz<shmsz ) return 1;
return pgsz/shmsz;
}
/*
** Purge the unixShmNodeList list of all entries with unixShmNode.nRef==0.
@@ -4116,10 +4150,11 @@ static void unixShmPurge(unixFile *pFd){
unixShmNode *p = pFd->pInode->pShmNode;
assert( unixMutexHeld() );
if( p && p->nRef==0 ){
int nShmPerMap = unixShmRegionPerMap();
int i;
assert( p->pInode==pFd->pInode );
sqlite3_mutex_free(p->mutex);
for(i=0; i<p->nRegion; i++){
for(i=0; i<p->nRegion; i+=nShmPerMap){
if( p->h>=0 ){
osMunmap(p->apRegion[i], p->szRegion);
}else{
@@ -4326,6 +4361,8 @@ static int unixShmMap(
unixShm *p;
unixShmNode *pShmNode;
int rc = SQLITE_OK;
int nShmPerMap = unixShmRegionPerMap();
int nReqRegion;
/* If the shared-memory file has not yet been opened, open it now. */
if( pDbFd->pShm==0 ){
@@ -4341,9 +4378,12 @@ static int unixShmMap(
assert( pShmNode->h>=0 || pDbFd->pInode->bProcessLock==1 );
assert( pShmNode->h<0 || pDbFd->pInode->bProcessLock==0 );
if( pShmNode->nRegion<=iRegion ){
/* Minimum number of regions required to be mapped. */
nReqRegion = ((iRegion+nShmPerMap) / nShmPerMap) * nShmPerMap;
if( pShmNode->nRegion<nReqRegion ){
char **apNew; /* New apRegion[] array */
int nByte = (iRegion+1)*szRegion; /* Minimum required file size */
int nByte = nReqRegion*szRegion; /* Minimum required file size */
struct stat sStat; /* Used by fstat() */
pShmNode->szRegion = szRegion;
@@ -4392,17 +4432,19 @@ static int unixShmMap(
/* Map the requested memory region into this processes address space. */
apNew = (char **)sqlite3_realloc(
pShmNode->apRegion, (iRegion+1)*sizeof(char *)
pShmNode->apRegion, nReqRegion*sizeof(char *)
);
if( !apNew ){
rc = SQLITE_IOERR_NOMEM;
goto shmpage_out;
}
pShmNode->apRegion = apNew;
while(pShmNode->nRegion<=iRegion){
while( pShmNode->nRegion<nReqRegion ){
int nMap = szRegion*nShmPerMap;
int i;
void *pMem;
if( pShmNode->h>=0 ){
pMem = osMmap(0, szRegion,
pMem = osMmap(0, nMap,
pShmNode->isReadonly ? PROT_READ : PROT_READ|PROT_WRITE,
MAP_SHARED, pShmNode->h, szRegion*(i64)pShmNode->nRegion
);
@@ -4418,8 +4460,11 @@ static int unixShmMap(
}
memset(pMem, 0, szRegion);
}
pShmNode->apRegion[pShmNode->nRegion] = pMem;
pShmNode->nRegion++;
for(i=0; i<nShmPerMap; i++){
pShmNode->apRegion[pShmNode->nRegion+i] = &((char*)pMem)[szRegion*i];
}
pShmNode->nRegion += nShmPerMap;
}
}
@@ -4633,19 +4678,6 @@ static void unixUnmapfile(unixFile *pFd){
}
}
/*
** Return the system page size.
*/
static int unixGetPagesize(void){
#if HAVE_MREMAP
return 512;
#elif defined(_BSD_SOURCE)
return getpagesize();
#else
return (int)sysconf(_SC_PAGESIZE);
#endif
}
/*
** Attempt to set the size of the memory mapping maintained by file
** descriptor pFd to nNew bytes. Any existing mapping is discarded.
@@ -4682,8 +4714,12 @@ static void unixRemapfile(
if( (pFd->ctrlFlags & UNIXFILE_RDONLY)==0 ) flags |= PROT_WRITE;
if( pOrig ){
const int szSyspage = unixGetPagesize();
#if HAVE_MREMAP
i64 nReuse = pFd->mmapSize;
#else
const int szSyspage = osGetpagesize();
i64 nReuse = (pFd->mmapSize & ~(szSyspage-1));
#endif
u8 *pReq = &pOrig[nReuse];
/* Unmap any pages of the existing mapping that cannot be reused. */
@@ -7429,7 +7465,7 @@ int sqlite3_os_init(void){
/* Double-check that the aSyscall[] array has been constructed
** correctly. See ticket [bb3a86e890c8e96ab] */
assert( ArraySize(aSyscall)==24 );
assert( ArraySize(aSyscall)==25 );
/* Register all VFSes defined in the aVfs[] array */
for(i=0; i<(sizeof(aVfs)/sizeof(sqlite3_vfs)); i++){
+25 -5
View File
@@ -5135,15 +5135,29 @@ static int winFullPathname(
** Interfaces for opening a shared library, finding entry points
** within the shared library, and closing the shared library.
*/
/*
** Interfaces for opening a shared library, finding entry points
** within the shared library, and closing the shared library.
*/
static void *winDlOpen(sqlite3_vfs *pVfs, const char *zFilename){
HANDLE h;
#if defined(__CYGWIN__)
int nFull = pVfs->mxPathname+1;
char *zFull = sqlite3MallocZero( nFull );
void *zConverted = 0;
if( zFull==0 ){
OSTRACE(("DLOPEN name=%s, handle=%p\n", zFilename, (void*)0));
return 0;
}
if( winFullPathname(pVfs, zFilename, nFull, zFull)!=SQLITE_OK ){
sqlite3_free(zFull);
OSTRACE(("DLOPEN name=%s, handle=%p\n", zFilename, (void*)0));
return 0;
}
zConverted = winConvertFromUtf8Filename(zFull);
sqlite3_free(zFull);
#else
void *zConverted = winConvertFromUtf8Filename(zFilename);
UNUSED_PARAMETER(pVfs);
#endif
if( zConverted==0 ){
OSTRACE(("DLOPEN name=%s, handle=%p\n", zFilename, (void*)0));
return 0;
}
if( osIsNT() ){
@@ -5158,6 +5172,7 @@ static void *winDlOpen(sqlite3_vfs *pVfs, const char *zFilename){
h = osLoadLibraryA((char*)zConverted);
}
#endif
OSTRACE(("DLOPEN name=%s, handle=%p\n", zFilename, (void*)h));
sqlite3_free(zConverted);
return (void*)h;
}
@@ -5166,12 +5181,17 @@ static void winDlError(sqlite3_vfs *pVfs, int nBuf, char *zBufOut){
winGetLastErrorMsg(osGetLastError(), nBuf, zBufOut);
}
static void (*winDlSym(sqlite3_vfs *pVfs,void *pH,const char *zSym))(void){
FARPROC proc;
UNUSED_PARAMETER(pVfs);
return (void(*)(void))osGetProcAddressA((HANDLE)pH, zSym);
proc = osGetProcAddressA((HANDLE)pH, zSym);
OSTRACE(("DLSYM handle=%p, symbol=%s, address=%p\n",
(void*)pH, zSym, (void*)proc));
return (void(*)(void))proc;
}
static void winDlClose(sqlite3_vfs *pVfs, void *pHandle){
UNUSED_PARAMETER(pVfs);
osFreeLibrary((HANDLE)pHandle);
OSTRACE(("DLCLOSE handle=%p\n", (void*)pHandle));
}
#else /* if SQLITE_OMIT_LOAD_EXTENSION is defined: */
#define winDlOpen 0
+9 -7
View File
@@ -4889,15 +4889,17 @@ static int hasHotJournal(Pager *pPager, int *pExists){
if( rc==SQLITE_OK && !locked ){
Pgno nPage; /* Number of pages in database file */
/* Check the size of the database file. If it consists of 0 pages,
** then delete the journal file. See the header comment above for
** the reasoning here. Delete the obsolete journal file under
** a RESERVED lock to avoid race conditions and to avoid violating
** [H33020].
*/
rc = pagerPagecount(pPager, &nPage);
if( rc==SQLITE_OK ){
if( nPage==0 ){
/* If the database is zero pages in size, that means that either (1) the
** journal is a remnant from a prior database with the same name where
** the database file but not the journal was deleted, or (2) the initial
** transaction that populates a new database is being rolled back.
** In either case, the journal file can be deleted. However, take care
** not to delete the journal file if it is already open due to
** journal_mode=PERSIST.
*/
if( nPage==0 && !jrnlOpen ){
sqlite3BeginBenignMalloc();
if( pagerLockDb(pPager, RESERVED_LOCK)==SQLITE_OK ){
sqlite3OsDelete(pVfs, pPager->zJournal, 0);
+12 -4
View File
@@ -437,14 +437,22 @@ select(A) ::= with(W) selectnowith(X). {
selectnowith(A) ::= oneselect(X). {A = X;}
%ifndef SQLITE_OMIT_COMPOUND_SELECT
selectnowith(A) ::= selectnowith(X) multiselect_op(Y) oneselect(Z). {
if( Z ){
Z->op = (u8)Y;
Z->pPrior = X;
Select *pRhs = Z;
if( pRhs && pRhs->pPrior ){
SrcList *pFrom;
Token x;
x.n = 0;
pFrom = sqlite3SrcListAppendFromTerm(pParse,0,0,0,&x,pRhs,0,0);
pRhs = sqlite3SelectNew(pParse,0,pFrom,0,0,0,0,0,0,0);
}
if( pRhs ){
pRhs->op = (u8)Y;
pRhs->pPrior = X;
if( Y!=TK_ALL ) pParse->hasCompound = 1;
}else{
sqlite3SelectDelete(pParse->db, X);
}
A = Z;
A = pRhs;
}
%type multiselect_op {int}
multiselect_op(A) ::= UNION(OP). {A = @OP;}
+4 -3
View File
@@ -824,7 +824,7 @@ void sqlite3Pragma(
** size of historical compatibility.
*/
case PragTyp_DEFAULT_CACHE_SIZE: {
static const int iLn = __LINE__+2;
static const int iLn = VDBE_OFFSET_LINENO(2);
static const VdbeOpList getCacheSize[] = {
{ OP_Transaction, 0, 0, 0}, /* 0 */
{ OP_ReadCookie, 0, 1, BTREE_DEFAULT_CACHE_SIZE}, /* 1 */
@@ -1087,7 +1087,7 @@ void sqlite3Pragma(
** file. Before writing to meta[6], check that meta[3] indicates
** that this really is an auto-vacuum capable database.
*/
static const int iLn = __LINE__+2;
static const int iLn = VDBE_OFFSET_LINENO(2);
static const VdbeOpList setMeta6[] = {
{ OP_Transaction, 0, 1, 0}, /* 0 */
{ OP_ReadCookie, 0, 1, BTREE_LARGEST_ROOT_PAGE},
@@ -1790,7 +1790,7 @@ void sqlite3Pragma(
** messages have been generated, output OK. Otherwise output the
** error message
*/
static const int iLn = __LINE__+2;
static const int iLn = VDBE_OFFSET_LINENO(2);
static const VdbeOpList endCode[] = {
{ OP_AddImm, 1, 0, 0}, /* 0 */
{ OP_IfNeg, 1, 0, 0}, /* 1 */
@@ -1942,6 +1942,7 @@ void sqlite3Pragma(
sqlite3VdbeAddOp2(v, OP_Halt, 0, 0);
sqlite3VdbeAddOp2(v, OP_Count, iIdxCur+j, 3);
sqlite3VdbeAddOp3(v, OP_Eq, 8+j, addr+8, 3); VdbeCoverage(v);
sqlite3VdbeChangeP5(v, SQLITE_NOTNULL);
sqlite3VdbeAddOp2(v, OP_AddImm, 1, -1);
sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, pIdx->zName, P4_TRANSIENT);
sqlite3VdbeAddOp3(v, OP_Concat, 3, 2, 7);
+84 -77
View File
@@ -134,20 +134,6 @@ static char et_getdigit(LONGDOUBLE_TYPE *val, int *cnt){
}
#endif /* SQLITE_OMIT_FLOATING_POINT */
/*
** Append N space characters to the given string buffer.
*/
void sqlite3AppendSpace(StrAccum *pAccum, int N){
static const char zSpaces[] = " ";
while( N>=(int)sizeof(zSpaces)-1 ){
sqlite3StrAccumAppend(pAccum, zSpaces, sizeof(zSpaces)-1);
N -= sizeof(zSpaces)-1;
}
if( N>0 ){
sqlite3StrAccumAppend(pAccum, zSpaces, N);
}
}
/*
** Set the StrAccum object to an error mode.
*/
@@ -237,11 +223,9 @@ void sqlite3VXPrintf(
}
for(; (c=(*fmt))!=0; ++fmt){
if( c!='%' ){
int amt;
bufpt = (char *)fmt;
amt = 1;
while( (c=(*++fmt))!='%' && c!=0 ) amt++;
sqlite3StrAccumAppend(pAccum, bufpt, amt);
while( (c=(*++fmt))!='%' && c!=0 ){};
sqlite3StrAccumAppend(pAccum, bufpt, (int)(fmt - bufpt));
if( c==0 ) break;
}
if( (c=(*++fmt))==0 ){
@@ -422,10 +406,8 @@ void sqlite3VXPrintf(
*(--bufpt) = zOrd[x*2];
}
{
register const char *cset; /* Use registers for speed */
register int base;
cset = &aDigits[infop->charset];
base = infop->base;
const char *cset = &aDigits[infop->charset];
u8 base = infop->base;
do{ /* Convert to ascii */
*(--bufpt) = cset[longvalue%base];
longvalue = longvalue/base;
@@ -729,29 +711,89 @@ void sqlite3VXPrintf(
** "length" characters long. The field width is "width". Do
** the output.
*/
if( !flag_leftjustify ){
register int nspace;
nspace = width-length;
if( nspace>0 ){
sqlite3AppendSpace(pAccum, nspace);
}
}
if( length>0 ){
sqlite3StrAccumAppend(pAccum, bufpt, length);
}
if( flag_leftjustify ){
register int nspace;
nspace = width-length;
if( nspace>0 ){
sqlite3AppendSpace(pAccum, nspace);
}
}
width -= length;
if( width>0 && !flag_leftjustify ) sqlite3AppendSpace(pAccum, width);
sqlite3StrAccumAppend(pAccum, bufpt, length);
if( width>0 && flag_leftjustify ) sqlite3AppendSpace(pAccum, width);
if( zExtra ) sqlite3_free(zExtra);
}/* End for loop over the format string */
} /* End of function */
/*
** Append N bytes of text from z to the StrAccum object.
** Enlarge the memory allocation on a StrAccum object so that it is
** able to accept at least N more bytes of text.
**
** Return the number of bytes of text that StrAccum is able to accept
** after the attempted enlargement. The value returned might be zero.
*/
static int sqlite3StrAccumEnlarge(StrAccum *p, int N){
char *zNew;
assert( p->nChar+N >= p->nAlloc ); /* Only called if really needed */
if( p->accError ){
testcase(p->accError==STRACCUM_TOOBIG);
testcase(p->accError==STRACCUM_NOMEM);
return 0;
}
if( !p->useMalloc ){
N = p->nAlloc - p->nChar - 1;
setStrAccumError(p, STRACCUM_TOOBIG);
return N;
}else{
char *zOld = (p->zText==p->zBase ? 0 : p->zText);
i64 szNew = p->nChar;
szNew += N + 1;
if( szNew > p->mxAlloc ){
sqlite3StrAccumReset(p);
setStrAccumError(p, STRACCUM_TOOBIG);
return 0;
}else{
p->nAlloc = (int)szNew;
}
if( p->useMalloc==1 ){
zNew = sqlite3DbRealloc(p->db, zOld, p->nAlloc);
}else{
zNew = sqlite3_realloc(zOld, p->nAlloc);
}
if( zNew ){
if( zOld==0 && p->nChar>0 ) memcpy(zNew, p->zText, p->nChar);
p->zText = zNew;
}else{
sqlite3StrAccumReset(p);
setStrAccumError(p, STRACCUM_NOMEM);
return 0;
}
}
return N;
}
/*
** Append N space characters to the given string buffer.
*/
void sqlite3AppendSpace(StrAccum *p, int N){
if( p->nChar+N >= p->nAlloc && (N = sqlite3StrAccumEnlarge(p, N))<=0 ) return;
while( (N--)>0 ) p->zText[p->nChar++] = ' ';
}
/*
** The StrAccum "p" is not large enough to accept N new bytes of z[].
** So enlarge if first, then do the append.
**
** This is a helper routine to sqlite3StrAccumAppend() that does special-case
** work (enlarging the buffer) using tail recursion, so that the
** sqlite3StrAccumAppend() routine can use fast calling semantics.
*/
static void enlargeAndAppend(StrAccum *p, const char *z, int N){
N = sqlite3StrAccumEnlarge(p, N);
if( N>0 ){
memcpy(&p->zText[p->nChar], z, N);
p->nChar += N;
}
}
/*
** Append N bytes of text from z to the StrAccum object. Increase the
** size of the memory allocation for StrAccum if necessary.
*/
void sqlite3StrAccumAppend(StrAccum *p, const char *z, int N){
assert( z!=0 );
@@ -759,43 +801,8 @@ void sqlite3StrAccumAppend(StrAccum *p, const char *z, int N){
assert( N>=0 );
assert( p->accError==0 || p->nAlloc==0 );
if( p->nChar+N >= p->nAlloc ){
char *zNew;
if( p->accError ){
testcase(p->accError==STRACCUM_TOOBIG);
testcase(p->accError==STRACCUM_NOMEM);
return;
}
if( !p->useMalloc ){
N = p->nAlloc - p->nChar - 1;
setStrAccumError(p, STRACCUM_TOOBIG);
if( N<=0 ){
return;
}
}else{
char *zOld = (p->zText==p->zBase ? 0 : p->zText);
i64 szNew = p->nChar;
szNew += N + 1;
if( szNew > p->mxAlloc ){
sqlite3StrAccumReset(p);
setStrAccumError(p, STRACCUM_TOOBIG);
return;
}else{
p->nAlloc = (int)szNew;
}
if( p->useMalloc==1 ){
zNew = sqlite3DbRealloc(p->db, zOld, p->nAlloc);
}else{
zNew = sqlite3_realloc(zOld, p->nAlloc);
}
if( zNew ){
if( zOld==0 && p->nChar>0 ) memcpy(zNew, p->zText, p->nChar);
p->zText = zNew;
}else{
sqlite3StrAccumReset(p);
setStrAccumError(p, STRACCUM_NOMEM);
return;
}
}
enlargeAndAppend(p,z,N);
return;
}
assert( p->zText );
memcpy(&p->zText[p->nChar], z, N);
+2
View File
@@ -337,6 +337,8 @@ static int lookupName(
}else if( op!=TK_INSERT && sqlite3StrICmp("old",zTab)==0 ){
pExpr->iTable = 0;
pTab = pParse->pTriggerTab;
}else{
pTab = 0;
}
if( pTab ){
+9 -7
View File
@@ -609,7 +609,7 @@ static void selectInnerLoop(
** values returned by the SELECT are not required.
*/
sqlite3ExprCodeExprList(pParse, pEList, regResult,
(eDest==SRT_Output)?SQLITE_ECEL_DUP:0);
(eDest==SRT_Output||eDest==SRT_Coroutine)?SQLITE_ECEL_DUP:0);
}
/* If the DISTINCT keyword was present on the SELECT statement
@@ -818,14 +818,16 @@ static void selectInnerLoop(
r1 = sqlite3GetTempReg(pParse);
r2 = sqlite3GetTempRange(pParse, nKey+2);
r3 = r2+nKey+1;
sqlite3VdbeAddOp3(v, OP_MakeRecord, regResult, nResultCol, r3);
if( eDest==SRT_DistQueue ){
/* If the destination is DistQueue, then cursor (iParm+1) is open
** on a second ephemeral index that holds all values every previously
** added to the queue. Only add this new value if it has never before
** been added */
addrTest = sqlite3VdbeAddOp4Int(v, OP_Found, iParm+1, 0, r3, 0);
** added to the queue. */
addrTest = sqlite3VdbeAddOp4Int(v, OP_Found, iParm+1, 0,
regResult, nResultCol);
VdbeCoverage(v);
}
sqlite3VdbeAddOp3(v, OP_MakeRecord, regResult, nResultCol, r3);
if( eDest==SRT_DistQueue ){
sqlite3VdbeAddOp2(v, OP_IdxInsert, iParm+1, r3);
sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT);
}
@@ -1520,7 +1522,7 @@ static int selectColumnsFromExprList(
char *zNewName;
int k;
for(k=nName-1; k>1 && sqlite3Isdigit(zName[k]); k--){}
if( zName[k]==':' ) nName = k;
if( k>=0 && zName[k]==':' ) nName = k;
zName[nName] = 0;
zNewName = sqlite3MPrintf(db, "%s:%d", zName, ++cnt);
sqlite3DbFree(db, zName);
@@ -4595,7 +4597,7 @@ int sqlite3Select(
/* If the subquery is not correlated and if we are not inside of
** a trigger, then we only need to compute the value of the subquery
** once. */
onceAddr = sqlite3CodeOnce(pParse);
onceAddr = sqlite3CodeOnce(pParse); VdbeCoverage(v);
VdbeComment((v, "materialize \"%s\"", pItem->pTab->zName));
}else{
VdbeNoopComment((v, "materialize \"%s\"", pItem->pTab->zName));
+47 -10
View File
@@ -65,7 +65,9 @@
#if defined(_WIN32) || defined(WIN32)
# include <io.h>
#define isatty(h) _isatty(h)
#define access(f,m) _access((f),(m))
#ifndef access
# define access(f,m) _access((f),(m))
#endif
#undef popen
#define popen _popen
#undef pclose
@@ -444,6 +446,7 @@ struct previous_mode_data {
struct callback_data {
sqlite3 *db; /* The database */
int echoOn; /* True to echo input commands */
int autoEQP; /* Run EXPLAIN QUERY PLAN prior to seach SQL statement */
int statsOn; /* True to display memory stats before each finalize */
int cnt; /* Number of records displayed so far */
FILE *out; /* Write results here */
@@ -1008,7 +1011,7 @@ static int run_table_dump_query(
int nResult;
int i;
const char *z;
rc = sqlite3_prepare(p->db, zSelect, -1, &pSelect, 0);
rc = sqlite3_prepare_v2(p->db, zSelect, -1, &pSelect, 0);
if( rc!=SQLITE_OK || !pSelect ){
fprintf(p->out, "/**** ERROR: (%d) %s *****/\n", rc, sqlite3_errmsg(p->db));
if( (rc&0xff)!=SQLITE_CORRUPT ) p->nErr++;
@@ -1181,6 +1184,7 @@ static int str_in_array(const char *zStr, const char **azArray){
** * For each "Goto", if the jump destination is earlier in the program
** and ends on one of:
** Yield SeekGt SeekLt RowSetRead Rewind
** or if the P1 parameter is one instead of zero,
** then indent all opcodes between the earlier instruction
** and "Goto" by 2 spaces.
*/
@@ -1228,7 +1232,9 @@ static void explain_data_prepare(struct callback_data *p, sqlite3_stmt *pSql){
if( str_in_array(zOp, azNext) ){
for(i=p2op; i<iOp; i++) p->aiIndent[i] += 2;
}
if( str_in_array(zOp, azGoto) && p2op<p->nIndent && abYield[p2op] ){
if( str_in_array(zOp, azGoto) && p2op<p->nIndent
&& (abYield[p2op] || sqlite3_column_int(pSql, 2))
){
for(i=p2op+1; i<iOp; i++) p->aiIndent[i] += 2;
}
}
@@ -1300,6 +1306,23 @@ static int shell_exec(
fprintf(pArg->out, "%s\n", zStmtSql ? zStmtSql : zSql);
}
/* Show the EXPLAIN QUERY PLAN if .eqp is on */
if( pArg && pArg->autoEQP ){
sqlite3_stmt *pExplain;
char *zEQP = sqlite3_mprintf("EXPLAIN QUERY PLAN %s", sqlite3_sql(pStmt));
rc = sqlite3_prepare_v2(db, zEQP, -1, &pExplain, 0);
if( rc==SQLITE_OK ){
while( sqlite3_step(pExplain)==SQLITE_ROW ){
fprintf(pArg->out,"--EQP-- %d,", sqlite3_column_int(pExplain, 0));
fprintf(pArg->out,"%d,", sqlite3_column_int(pExplain, 1));
fprintf(pArg->out,"%d,", sqlite3_column_int(pExplain, 2));
fprintf(pArg->out,"%s\n", sqlite3_column_text(pExplain, 3));
}
}
sqlite3_finalize(pExplain);
sqlite3_free(zEQP);
}
/* Output TESTCTRL_EXPLAIN text of requested */
if( pArg && pArg->mode==MODE_Explain ){
const char *zExplain = 0;
@@ -1456,7 +1479,7 @@ static int dump_callback(void *pArg, int nArg, char **azArg, char **azCol){
zTableInfo = appendText(zTableInfo, zTable, '"');
zTableInfo = appendText(zTableInfo, ");", 0);
rc = sqlite3_prepare(p->db, zTableInfo, -1, &pTableInfo, 0);
rc = sqlite3_prepare_v2(p->db, zTableInfo, -1, &pTableInfo, 0);
free(zTableInfo);
if( rc!=SQLITE_OK || !pTableInfo ){
return 1;
@@ -1893,7 +1916,7 @@ static char *csv_read_one_field(CSVReader *p){
}
if( c=='\n' ){
p->nLine++;
if( p->n>1 && p->z[p->n-1]=='\r' ) p->n--;
if( p->n>0 && p->z[p->n-1]=='\r' ) p->n--;
}
p->cTerm = c;
}
@@ -2299,6 +2322,10 @@ static int do_meta_command(char *zLine, struct callback_data *p){
p->echoOn = booleanValue(azArg[1]);
}else
if( c=='e' && strncmp(azArg[0], "eqp", n)==0 && nArg>1 && nArg<3 ){
p->autoEQP = booleanValue(azArg[1]);
}else
if( c=='e' && strncmp(azArg[0], "exit", n)==0 ){
if( nArg>1 && (rc = (int)integerValue(azArg[1]))!=0 ) exit(rc);
rc = 2;
@@ -2399,7 +2426,7 @@ static int do_meta_command(char *zLine, struct callback_data *p){
return 1;
}
nByte = strlen30(zSql);
rc = sqlite3_prepare(p->db, zSql, -1, &pStmt, 0);
rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
if( rc && sqlite3_strglob("no such table: *", sqlite3_errmsg(db))==0 ){
char *zCreate = sqlite3_mprintf("CREATE TABLE %s", zTable);
char cSep = '(';
@@ -2425,7 +2452,7 @@ static int do_meta_command(char *zLine, struct callback_data *p){
xCloser(sCsv.in);
return 1;
}
rc = sqlite3_prepare(p->db, zSql, -1, &pStmt, 0);
rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
}
sqlite3_free(zSql);
if( rc ){
@@ -2452,7 +2479,7 @@ static int do_meta_command(char *zLine, struct callback_data *p){
}
zSql[j++] = ')';
zSql[j] = 0;
rc = sqlite3_prepare(p->db, zSql, -1, &pStmt, 0);
rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
sqlite3_free(zSql);
if( rc ){
fprintf(stderr, "Error: %s\n", sqlite3_errmsg(db));
@@ -2871,6 +2898,7 @@ static int do_meta_command(char *zLine, struct callback_data *p){
if( c=='s' && strncmp(azArg[0], "show", n)==0 && nArg==1 ){
int i;
fprintf(p->out,"%9.9s: %s\n","echo", p->echoOn ? "on" : "off");
fprintf(p->out,"%9.9s: %s\n","eqp", p->autoEQP ? "on" : "off");
fprintf(p->out,"%9.9s: %s\n","explain", p->explainPrev.valid ? "on" :"off");
fprintf(p->out,"%9.9s: %s\n","headers", p->showHeader ? "on" : "off");
fprintf(p->out,"%9.9s: %s\n","mode", modeDescr[p->mode]);
@@ -3548,11 +3576,13 @@ int main(int argc, char **argv){
int rc = 0;
int warnInmemoryDb = 0;
#if USE_SYSTEM_SQLITE+0!=1
if( strcmp(sqlite3_sourceid(),SQLITE_SOURCE_ID)!=0 ){
fprintf(stderr, "SQLite header and source version mismatch\n%s\n%s\n",
sqlite3_sourceid(), SQLITE_SOURCE_ID);
exit(1);
}
#endif
Argv0 = argv[0];
main_init(&data);
stdin_is_interactive = isatty(0);
@@ -3645,6 +3675,11 @@ int main(int argc, char **argv){
#else
fprintf(stderr,"%s: Error: no database filename specified\n", Argv0);
return 1;
#endif
#ifdef SQLITE_SHELL_DBNAME_PROC
{ extern void SQLITE_SHELL_DBNAME_PROC(const char**);
SQLITE_SHELL_DBNAME_PROC(&data.zDbFilename);
warnInmemoryDb = 0; }
#endif
}
data.out = stdout;
@@ -3701,6 +3736,8 @@ int main(int argc, char **argv){
data.showHeader = 0;
}else if( strcmp(z,"-echo")==0 ){
data.echoOn = 1;
}else if( strcmp(z,"-eqp")==0 ){
data.autoEQP = 1;
}else if( strcmp(z,"-stats")==0 ){
data.statsOn = 1;
}else if( strcmp(z,"-bail")==0 ){
@@ -3783,8 +3820,8 @@ int main(int argc, char **argv){
);
if( warnInmemoryDb ){
printf("Connected to a ");
printBold("transient in-memory database.");
printf("\nUse \".open FILENAME\" to reopen on a "
printBold("transient in-memory database");
printf(".\nUse \".open FILENAME\" to reopen on a "
"persistent database.\n");
}
zHome = find_home_dir();
+52 -11
View File
@@ -12,7 +12,6 @@
** Internal interface definitions for SQLite.
**
*/
#include "sqlite3.h"
#ifndef _SQLITEINT_H_
#define _SQLITEINT_H_
@@ -48,6 +47,44 @@
# define _LARGEFILE_SOURCE 1
#endif
/*
** For MinGW, check to see if we can include the header file containing its
** version information, among other things. Normally, this internal MinGW
** header file would [only] be included automatically by other MinGW header
** files; however, the contained version information is now required by this
** header file to work around binary compatibility issues (see below) and
** this is the only known way to reliably obtain it. This entire #if block
** would be completely unnecessary if there was any other way of detecting
** MinGW via their preprocessor (e.g. if they customized their GCC to define
** some MinGW-specific macros). When compiling for MinGW, either the
** _HAVE_MINGW_H or _HAVE__MINGW_H (note the extra underscore) macro must be
** defined; otherwise, detection of conditions specific to MinGW will be
** disabled.
*/
#if defined(_HAVE_MINGW_H)
# include "mingw.h"
#elif defined(_HAVE__MINGW_H)
# include "_mingw.h"
#endif
/*
** For MinGW version 4.x (and higher), check to see if the _USE_32BIT_TIME_T
** define is required to maintain binary compatibility with the MSVC runtime
** library in use (e.g. for Windows XP).
*/
#if !defined(_USE_32BIT_TIME_T) && !defined(_USE_64BIT_TIME_T) && \
defined(_WIN32) && !defined(_WIN64) && \
defined(__MINGW_MAJOR_VERSION) && __MINGW_MAJOR_VERSION >= 4 && \
defined(__MSVCRT__)
# define _USE_32BIT_TIME_T
#endif
/* The public SQLite interface. The _FILE_OFFSET_BITS macro must appear
** first in QNX. Also, the _USE_32BIT_TIME_T macro must appear first for
** MinGW.
*/
#include "sqlite3.h"
/*
** Include the configuration header output by 'configure' if we're using the
** autoconf-based build
@@ -1314,10 +1351,16 @@ struct CollSeq {
/*
** Additional bit values that can be ORed with an affinity without
** changing the affinity.
**
** The SQLITE_NOTNULL flag is a combination of NULLEQ and JUMPIFNULL.
** It causes an assert() to fire if either operand to a comparison
** operator is NULL. It is added to certain comparison operators to
** prove that the operands are always NOT NULL.
*/
#define SQLITE_JUMPIFNULL 0x08 /* jumps if either operand is NULL */
#define SQLITE_STOREP2 0x10 /* Store result in reg[P2] rather than jump */
#define SQLITE_NULLEQ 0x80 /* NULL=NULL */
#define SQLITE_NOTNULL 0x88 /* Assert that operands are never NULL */
/*
** An object of this type is created for each virtual table present in
@@ -1576,19 +1619,19 @@ struct KeyInfo {
**
** This structure holds a record that has already been disassembled
** into its constituent fields.
**
** The r1 and r2 member variables are only used by the optimized comparison
** functions vdbeRecordCompareInt() and vdbeRecordCompareString().
*/
struct UnpackedRecord {
KeyInfo *pKeyInfo; /* Collation and sort-order information */
u16 nField; /* Number of entries in apMem[] */
u8 flags; /* Boolean settings. UNPACKED_... below */
i8 default_rc; /* Comparison result if keys are equal */
Mem *aMem; /* Values */
int r1; /* Value to return if (lhs > rhs) */
int r2; /* Value to return if (rhs < lhs) */
};
/*
** Allowed values of UnpackedRecord.flags
*/
#define UNPACKED_INCRKEY 0x01 /* Make this key an epsilon larger */
#define UNPACKED_PREFIX_MATCH 0x02 /* A prefix match is considered OK */
/*
** Each SQL index is represented in memory by an
@@ -2008,8 +2051,8 @@ typedef u64 Bitmask;
** contains more than 63 columns and the 64-th or later column is used.
*/
struct SrcList {
u8 nSrc; /* Number of tables or subqueries in the FROM clause */
u8 nAlloc; /* Number of entries allocated in a[] below */
int nSrc; /* Number of tables or subqueries in the FROM clause */
u32 nAlloc; /* Number of entries allocated in a[] below */
struct SrcList_item {
Schema *pSchema; /* Schema to which this item is fixed */
char *zDatabase; /* Name of database holding this table */
@@ -2348,7 +2391,6 @@ struct Parse {
u8 checkSchema; /* Causes schema cookie check after an error */
u8 nested; /* Number of nested calls to the parser/code generator */
u8 nTempReg; /* Number of temporary registers in aTempReg[] */
u8 nTempInUse; /* Number of aTempReg[] currently checked out */
u8 nColCache; /* Number of entries in aColCache[] */
u8 iColCache; /* Next entry in aColCache[] to replace */
u8 isMultiWrite; /* True if statement may modify/insert multiple rows */
@@ -3087,7 +3129,6 @@ int sqlite3ExprIsConstantNotJoin(Expr*);
int sqlite3ExprIsConstantOrFunction(Expr*);
int sqlite3ExprIsInteger(Expr*, int*);
int sqlite3ExprCanBeNull(const Expr*);
void sqlite3ExprCodeIsNullJump(Vdbe*, const Expr*, int, int);
int sqlite3ExprNeedsNoAffinityChange(const Expr*, char);
int sqlite3IsRowid(const char*);
void sqlite3GenerateRowDelete(Parse*,Table*,Trigger*,int,int,int,i16,u8,u8,u8);
-1
View File
@@ -76,7 +76,6 @@ static int test_value_overhead(
val.flags = MEM_Str|MEM_Term|MEM_Static;
val.z = "hello world";
val.memType = MEM_Str;
val.enc = SQLITE_UTF8;
for(i=0; i<repeat_count; i++){
-2
View File
@@ -499,7 +499,6 @@ static void test_extract(
mem.enc = ENC(db);
pHdr += sqlite3GetVarint(pHdr, &iSerialType);
pBody += sqlite3VdbeSerialGet(pBody, (u32)iSerialType, &mem);
sqlite3VdbeMemStoreType(&mem);
if( iCurrent==iIdx ){
sqlite3_result_value(context, &mem);
@@ -549,7 +548,6 @@ static void test_decode(
pHdr += sqlite3GetVarint(pHdr, &iSerialType);
pBody += sqlite3VdbeSerialGet(pBody, (u32)iSerialType, &mem);
sqlite3VdbeMemStoreType(&mem);
switch( sqlite3_value_type(&mem) ){
case SQLITE_TEXT:
pVal = Tcl_NewStringObj((const char*)sqlite3_value_text(&mem), -1);
+6
View File
@@ -91,6 +91,9 @@ static void statusFunc(
/*
** Extension load function.
*/
#ifdef _WIN32
__declspec(dllexport)
#endif
int testloadext_init(
sqlite3 *db,
char **pzErrMsg,
@@ -109,6 +112,9 @@ int testloadext_init(
/*
** Another extension entry point. This one always fails.
*/
#ifdef _WIN32
__declspec(dllexport)
#endif
int testbrokenext_init(
sqlite3 *db,
char **pzErrMsg,
+48 -1
View File
@@ -67,6 +67,11 @@
** test_syscall list
** Return a list of all system calls. The list is constructed using
** the xNextSystemCall() VFS method.
**
** test_syscall pagesize PGSZ
** If PGSZ is a power of two greater than 256, install a wrapper around
** OS function getpagesize() that reports the system page size as PGSZ.
** Or, if PGSZ is less than zero, remove any wrapper already installed.
*/
#include "sqliteInt.h"
@@ -89,7 +94,9 @@ static struct TestSyscallGlobal {
int bPersist; /* 1 for persistent errors, 0 for transient */
int nCount; /* Fail after this many more calls */
int nFail; /* Number of failures that have occurred */
} gSyscall = { 0, 0 };
int pgsz;
sqlite3_syscall_ptr orig_getpagesize;
} gSyscall = { 0, 0, 0, 0, 0 };
static int ts_open(const char *, int, int);
static int ts_close(int fd);
@@ -650,6 +657,45 @@ static int test_syscall_defaultvfs(
return TCL_OK;
}
static int ts_getpagesize(void){
return gSyscall.pgsz;
}
static int test_syscall_pagesize(
void * clientData,
Tcl_Interp *interp,
int objc,
Tcl_Obj *CONST objv[]
){
sqlite3_vfs *pVfs = sqlite3_vfs_find(0);
int pgsz;
if( objc!=3 ){
Tcl_WrongNumArgs(interp, 2, objv, "PGSZ");
return TCL_ERROR;
}
if( Tcl_GetIntFromObj(interp, objv[2], &pgsz) ){
return TCL_ERROR;
}
if( pgsz<0 ){
if( gSyscall.orig_getpagesize ){
pVfs->xSetSystemCall(pVfs, "getpagesize", gSyscall.orig_getpagesize);
}
}else{
if( pgsz<512 || (pgsz & (pgsz-1)) ){
Tcl_AppendResult(interp, "pgsz out of range", 0);
return TCL_ERROR;
}
gSyscall.orig_getpagesize = pVfs->xGetSystemCall(pVfs, "getpagesize");
gSyscall.pgsz = pgsz;
pVfs->xSetSystemCall(
pVfs, "getpagesize", (sqlite3_syscall_ptr)ts_getpagesize
);
}
return TCL_OK;
}
static int test_syscall(
void * clientData,
Tcl_Interp *interp,
@@ -668,6 +714,7 @@ static int test_syscall(
{ "exists", test_syscall_exists },
{ "list", test_syscall_list },
{ "defaultvfs", test_syscall_defaultvfs },
{ "pagesize", test_syscall_pagesize },
{ 0, 0 }
};
int iCmd;
+1 -1
View File
@@ -566,7 +566,7 @@ void sqlite3DropTriggerPtr(Parse *pParse, Trigger *pTrigger){
assert( pTable!=0 );
if( (v = sqlite3GetVdbe(pParse))!=0 ){
int base;
static const int iLn = __LINE__+2;
static const int iLn = VDBE_OFFSET_LINENO(2);
static const VdbeOpList dropTrigger[] = {
{ OP_Rewind, 0, ADDR(9), 0},
{ OP_String8, 0, 1, 0}, /* 1 */
+2 -3
View File
@@ -434,7 +434,7 @@ void sqlite3Update(
if( aToOpen[iDataCur-iBaseCur] ){
assert( pPk!=0 );
sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, labelBreak, regKey, nKey);
VdbeCoverage(v);
VdbeCoverageNeverTaken(v);
}
labelContinue = labelBreak;
sqlite3VdbeAddOp2(v, OP_IsNull, pPk ? regKey : regOldRowid, labelBreak);
@@ -577,11 +577,10 @@ void sqlite3Update(
if( bReplace || chngKey ){
if( pPk ){
j1 = sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, 0, regKey, nKey);
VdbeCoverage(v);
}else{
j1 = sqlite3VdbeAddOp3(v, OP_NotExists, iDataCur, 0, regOldRowid);
VdbeCoverage(v);
}
VdbeCoverageNeverTaken(v);
}
sqlite3GenerateRowIndexDelete(pParse, pTab, iDataCur, iIdxCur, aRegIdx);
+1 -2
View File
@@ -317,7 +317,7 @@ int sqlite3VdbeMemTranslate(Mem *pMem, u8 desiredEnc){
sqlite3VdbeMemRelease(pMem);
pMem->flags &= ~(MEM_Static|MEM_Dyn|MEM_Ephem);
pMem->enc = desiredEnc;
pMem->flags |= (MEM_Term|MEM_Dyn);
pMem->flags |= (MEM_Term);
pMem->z = (char*)zOut;
pMem->zMalloc = pMem->z;
@@ -445,7 +445,6 @@ char *sqlite3Utf16to8(sqlite3 *db, const void *z, int nByte, u8 enc){
}
assert( (m.flags & MEM_Term)!=0 || db->mallocFailed );
assert( (m.flags & MEM_Str)!=0 || db->mallocFailed );
assert( (m.flags & MEM_Dyn)!=0 || db->mallocFailed );
assert( m.z || db->mallocFailed );
return m.z;
}
+60 -47
View File
@@ -28,7 +28,7 @@
** pointer to the string or blob, not the content. If the original
** is changed while the copy is still in use, the string or blob might
** be changed out from under the copy. This macro verifies that nothing
** like that every happens.
** like that ever happens.
*/
#ifdef SQLITE_DEBUG
# define memAboutToChange(P,M) sqlite3VdbeMemAboutToChange(P,M)
@@ -108,15 +108,31 @@ int sqlite3_found_count = 0;
#endif
/*
** Invoke the VDBE coverage callback, if defined
** Invoke the VDBE coverage callback, if that callback is defined. This
** feature is used for test suite validation only and does not appear an
** production builds.
**
** M is an integer, 2 or 3, that indices how many different ways the
** branch can go. It is usually 2. "I" is the direction the branch
** goes. 0 means falls through. 1 means branch is taken. 2 means the
** second alternative branch is taken.
*/
#if !defined(SQLITE_VDBE_COVERAGE)
# define VdbeBranchTaken(I,M)
#else
# define VdbeBranchTaken(I,M) \
if( sqlite3GlobalConfig.xVdbeBranch!=0 ){ \
sqlite3GlobalConfig.xVdbeBranch(sqlite3GlobalConfig.pVdbeBranchArg, \
pOp->iSrcLine,(I),(M)); }
# define VdbeBranchTaken(I,M) vdbeTakeBranch(pOp->iSrcLine,I,M)
static void vdbeTakeBranch(int iSrcLine, u8 I, u8 M){
if( iSrcLine<=2 && ALWAYS(iSrcLine>0) ){
M = iSrcLine;
/* Assert the truth of VdbeCoverageAlwaysTaken() and
** VdbeCoverageNeverTaken() */
assert( (M & I)==I );
}else{
if( sqlite3GlobalConfig.xVdbeBranch==0 ) return; /*NO_TEST*/
sqlite3GlobalConfig.xVdbeBranch(sqlite3GlobalConfig.pVdbeBranchArg,
iSrcLine,I,M);
}
}
#endif
/*
@@ -136,7 +152,7 @@ int sqlite3_found_count = 0;
**
** This routine converts an ephemeral string into a dynamically allocated
** string that the register itself controls. In other words, it
** converts an MEM_Ephem string into an MEM_Dyn string.
** converts an MEM_Ephem string into a string with P.z==P.zMalloc.
*/
#define Deephemeralize(P) \
if( ((P)->flags&MEM_Ephem)!=0 \
@@ -277,7 +293,6 @@ int sqlite3_value_numeric_type(sqlite3_value *pVal){
if( eType==SQLITE_TEXT ){
Mem *pMem = (Mem*)pVal;
applyNumericAffinity(pMem);
sqlite3VdbeMemStoreType(pMem);
eType = sqlite3_value_type(pVal);
}
return eType;
@@ -476,7 +491,6 @@ int sqlite3VdbeExec(
i64 lastRowid = db->lastRowid; /* Saved value of the last insert ROWID */
#ifdef VDBE_PROFILE
u64 start; /* CPU clock count at start of opcode */
int origPc; /* Program counter at start of opcode */
#endif
/*** INSERT STACK UNION HERE ***/
@@ -538,7 +552,6 @@ int sqlite3VdbeExec(
assert( pc>=0 && pc<p->nOp );
if( db->mallocFailed ) goto no_mem;
#ifdef VDBE_PROFILE
origPc = pc;
start = sqlite3Hwtime();
#endif
nVmStep++;
@@ -586,18 +599,21 @@ int sqlite3VdbeExec(
assert( pOp->p1>0 );
assert( pOp->p1<=(p->nMem-p->nCursor) );
assert( memIsValid(&aMem[pOp->p1]) );
assert( sqlite3VdbeCheckMemInvariants(&aMem[pOp->p1]) );
REGISTER_TRACE(pOp->p1, &aMem[pOp->p1]);
}
if( (pOp->opflags & OPFLG_IN2)!=0 ){
assert( pOp->p2>0 );
assert( pOp->p2<=(p->nMem-p->nCursor) );
assert( memIsValid(&aMem[pOp->p2]) );
assert( sqlite3VdbeCheckMemInvariants(&aMem[pOp->p2]) );
REGISTER_TRACE(pOp->p2, &aMem[pOp->p2]);
}
if( (pOp->opflags & OPFLG_IN3)!=0 ){
assert( pOp->p3>0 );
assert( pOp->p3<=(p->nMem-p->nCursor) );
assert( memIsValid(&aMem[pOp->p3]) );
assert( sqlite3VdbeCheckMemInvariants(&aMem[pOp->p3]) );
REGISTER_TRACE(pOp->p3, &aMem[pOp->p3]);
}
if( (pOp->opflags & OPFLG_OUT2)!=0 ){
@@ -655,6 +671,11 @@ int sqlite3VdbeExec(
** The next instruction executed will be
** the one at index P2 from the beginning of
** the program.
**
** The P1 parameter is not actually used by this opcode. However, it
** is sometimes set to 1 instead of 0 as a hint to the command-line shell
** that this Goto is the bottom of a loop and that the lines from P2 down
** to the current line should be indented for EXPLAIN output.
*/
case OP_Goto: { /* jump */
pc = pOp->p2 - 1;
@@ -699,7 +720,7 @@ check_for_interrupt:
case OP_Gosub: { /* jump */
assert( pOp->p1>0 && pOp->p1<=(p->nMem-p->nCursor) );
pIn1 = &aMem[pOp->p1];
assert( (pIn1->flags & MEM_Dyn)==0 );
assert( VdbeMemDynamic(pIn1)==0 );
memAboutToChange(p, pIn1);
pIn1->flags = MEM_Int;
pIn1->u.i = pc;
@@ -772,7 +793,7 @@ case OP_EndCoroutine: { /* in1 */
case OP_Yield: { /* in1, jump */
int pcDest;
pIn1 = &aMem[pOp->p1];
assert( (pIn1->flags & MEM_Dyn)==0 );
assert( VdbeMemDynamic(pIn1)==0 );
pIn1->flags = MEM_Int;
pcDest = (int)pIn1->u.i;
pIn1->u.i = pc;
@@ -945,10 +966,9 @@ case OP_String8: { /* same as TK_STRING, out2-prerelease */
if( rc==SQLITE_TOOBIG ) goto too_big;
if( SQLITE_OK!=sqlite3VdbeChangeEncoding(pOut, encoding) ) goto no_mem;
assert( pOut->zMalloc==pOut->z );
assert( pOut->flags & MEM_Dyn );
assert( VdbeMemDynamic(pOut)==0 );
pOut->zMalloc = 0;
pOut->flags |= MEM_Static;
pOut->flags &= ~MEM_Dyn;
if( pOp->p4type==P4_DYNAMIC ){
sqlite3DbFree(db, pOp->p4.z);
}
@@ -1084,14 +1104,16 @@ case OP_Move: {
assert( pIn1<=&aMem[(p->nMem-p->nCursor)] );
assert( memIsValid(pIn1) );
memAboutToChange(p, pOut);
VdbeMemRelease(pOut);
zMalloc = pOut->zMalloc;
pOut->zMalloc = 0;
sqlite3VdbeMemMove(pOut, pIn1);
memcpy(pOut, pIn1, sizeof(Mem));
#ifdef SQLITE_DEBUG
if( pOut->pScopyFrom>=&aMem[p1] && pOut->pScopyFrom<&aMem[p1+pOp->p3] ){
pOut->pScopyFrom += p1 - pOp->p2;
}
#endif
pIn1->flags = MEM_Undefined;
pIn1->xDel = 0;
pIn1->zMalloc = zMalloc;
REGISTER_TRACE(p2++, pOut);
pIn1++;
@@ -1159,7 +1181,7 @@ case OP_SCopy: { /* out2 */
** The registers P1 through P1+P2-1 contain a single row of
** results. This opcode causes the sqlite3_step() call to terminate
** with an SQLITE_ROW return code and it sets up the sqlite3_stmt
** structure to provide access to the r[P1]..r[P1+P2-1] values as
** structure to provide access to the r(P1)..r(P1+P2-1) values as
** the result row.
*/
case OP_ResultRow: {
@@ -1225,7 +1247,6 @@ case OP_ResultRow: {
assert( (pMem[i].flags & MEM_Ephem)==0
|| (pMem[i].flags & (MEM_Str|MEM_Blob))==0 );
sqlite3VdbeMemNulTerminate(&pMem[i]);
sqlite3VdbeMemStoreType(&pMem[i]);
REGISTER_TRACE(pOp->p1+i, &pMem[i]);
}
if( db->mallocFailed ) goto no_mem;
@@ -1268,10 +1289,10 @@ case OP_Concat: { /* same as TK_CONCAT, in1, in2, out3 */
if( nByte>db->aLimit[SQLITE_LIMIT_LENGTH] ){
goto too_big;
}
MemSetTypeFlag(pOut, MEM_Str);
if( sqlite3VdbeMemGrow(pOut, (int)nByte+2, pOut==pIn2) ){
goto no_mem;
}
MemSetTypeFlag(pOut, MEM_Str);
if( pOut!=pIn2 ){
memcpy(pOut->z, pIn2->z, pIn2->n);
}
@@ -1471,7 +1492,6 @@ case OP_Function: {
assert( memIsValid(pArg) );
apVal[i] = pArg;
Deephemeralize(pArg);
sqlite3VdbeMemStoreType(pArg);
REGISTER_TRACE(pOp->p2+i, pArg);
}
@@ -1891,6 +1911,7 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
*/
assert( pOp->opcode==OP_Eq || pOp->opcode==OP_Ne );
assert( (flags1 & MEM_Cleared)==0 );
assert( (pOp->p5 & SQLITE_JUMPIFNULL)==0 );
if( (flags1&MEM_Null)!=0
&& (flags3&MEM_Null)!=0
&& (flags3&MEM_Cleared)==0
@@ -1909,7 +1930,7 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
MemSetTypeFlag(pOut, MEM_Null);
REGISTER_TRACE(pOp->p2, pOut);
}else{
VdbeBranchTaken((pOp->p5 & SQLITE_JUMPIFNULL)?2:3,4);
VdbeBranchTaken(2,3);
if( pOp->p5 & SQLITE_JUMPIFNULL ){
pc = pOp->p2-1;
}
@@ -1946,7 +1967,7 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
pOut->u.i = res;
REGISTER_TRACE(pOp->p2, pOut);
}else{
VdbeBranchTaken(res!=0, 4);
VdbeBranchTaken(res!=0, (pOp->p5 & SQLITE_NULLEQ)?2:3);
if( res ){
pc = pOp->p2-1;
}
@@ -2150,8 +2171,8 @@ case OP_BitNot: { /* same as TK_BITNOT, in1, out2 */
**
** Check if OP_Once flag P1 is set. If so, jump to instruction P2. Otherwise,
** set the flag and fall through to the next instruction. In other words,
** this opcode causes all following up codes up through P2 (but not including
** P2) to run just once and skipped on subsequent times through the loop.
** this opcode causes all following opcodes up through P2 (but not including
** P2) to run just once and to be skipped on subsequent times through the loop.
*/
case OP_Once: { /* jump */
assert( pOp->p1<p->nOnceFlag );
@@ -2445,6 +2466,7 @@ case OP_Column: {
*/
assert( p2<pC->nHdrParsed );
assert( rc==SQLITE_OK );
assert( sqlite3VdbeCheckMemInvariants(pDest) );
if( pC->szRow>=aOffset[p2+1] ){
/* This is the common case where the desired content fits on the original
** page - where the content is not on an overflow page */
@@ -2482,8 +2504,8 @@ case OP_Column: {
** This prevents a memory copy. */
if( sMem.zMalloc ){
assert( sMem.z==sMem.zMalloc );
assert( !(pDest->flags & MEM_Dyn) );
assert( !(pDest->flags & (MEM_Blob|MEM_Str)) || pDest->z==sMem.z );
assert( VdbeMemDynamic(pDest)==0 );
assert( (pDest->flags & (MEM_Blob|MEM_Str))==0 || pDest->z==sMem.z );
pDest->flags &= ~(MEM_Ephem|MEM_Static);
pDest->flags |= MEM_Term;
pDest->z = sMem.z;
@@ -2666,7 +2688,7 @@ case OP_MakeRecord: {
assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) );
pOut->n = (int)nByte;
pOut->flags = MEM_Blob | MEM_Dyn;
pOut->flags = MEM_Blob;
pOut->xDel = 0;
if( nZero ){
pOut->u.nZero = nZero;
@@ -3540,16 +3562,16 @@ case OP_SeekGT: { /* jump, in3 */
/* The next line of code computes as follows, only faster:
** if( oc==OP_SeekGT || oc==OP_SeekLE ){
** r.flags = UNPACKED_INCRKEY;
** r.default_rc = -1;
** }else{
** r.flags = 0;
** r.default_rc = +1;
** }
*/
r.flags = (u8)(UNPACKED_INCRKEY * (1 & (oc - OP_SeekLT)));
assert( oc!=OP_SeekGT || r.flags==UNPACKED_INCRKEY );
assert( oc!=OP_SeekLE || r.flags==UNPACKED_INCRKEY );
assert( oc!=OP_SeekGE || r.flags==0 );
assert( oc!=OP_SeekLT || r.flags==0 );
r.default_rc = ((1 & (oc - OP_SeekLT)) ? -1 : +1);
assert( oc!=OP_SeekGT || r.default_rc==-1 );
assert( oc!=OP_SeekLE || r.default_rc==-1 );
assert( oc!=OP_SeekGE || r.default_rc==+1 );
assert( oc!=OP_SeekLT || r.default_rc==+1 );
r.aMem = &aMem[pOp->p3];
#ifdef SQLITE_DEBUG
@@ -3707,7 +3729,6 @@ case OP_Found: { /* jump, in3 */
if( ii ) REGISTER_TRACE(pOp->p3+ii, &r.aMem[ii]);
#endif
}
r.flags = UNPACKED_PREFIX_MATCH;
pIdxKey = &r;
}else{
pIdxKey = sqlite3VdbeAllocUnpackedRecord(
@@ -3717,8 +3738,8 @@ case OP_Found: { /* jump, in3 */
assert( pIn3->flags & MEM_Blob );
assert( (pIn3->flags & MEM_Zero)==0 ); /* zeroblobs already expanded */
sqlite3VdbeRecordUnpack(pC->pKeyInfo, pIn3->n, pIn3->z, pIdxKey);
pIdxKey->flags |= UNPACKED_PREFIX_MATCH;
}
pIdxKey->default_rc = 0;
if( pOp->opcode==OP_NoConflict ){
/* For the OP_NoConflict opcode, take the jump if any of the
** input fields are NULL, since any key with a NULL will not
@@ -4607,7 +4628,7 @@ case OP_IdxDelete: {
assert( pOp->p5==0 );
r.pKeyInfo = pC->pKeyInfo;
r.nField = (u16)pOp->p3;
r.flags = UNPACKED_PREFIX_MATCH;
r.default_rc = 0;
r.aMem = &aMem[pOp->p2];
#ifdef SQLITE_DEBUG
{ int i; for(i=0; i<r.nField; i++) assert( memIsValid(&r.aMem[i]) ); }
@@ -4721,10 +4742,10 @@ case OP_IdxGE: { /* jump */
r.nField = (u16)pOp->p4.i;
if( pOp->opcode<OP_IdxLT ){
assert( pOp->opcode==OP_IdxLE || pOp->opcode==OP_IdxGT );
r.flags = UNPACKED_INCRKEY | UNPACKED_PREFIX_MATCH;
r.default_rc = -1;
}else{
assert( pOp->opcode==OP_IdxGE || pOp->opcode==OP_IdxLT );
r.flags = UNPACKED_PREFIX_MATCH;
r.default_rc = 0;
}
r.aMem = &aMem[pOp->p3];
#ifdef SQLITE_DEBUG
@@ -4833,7 +4854,6 @@ case OP_Clear: {
nChange = 0;
assert( p->readOnly==0 );
assert( pOp->p1!=1 );
assert( (p->btreeMask & (((yDbMask)1)<<pOp->p2))!=0 );
rc = sqlite3BtreeClearTable(
db->aDb[pOp->p2].pBt, pOp->p1, (pOp->p3 ? &nChange : 0)
@@ -5476,7 +5496,6 @@ case OP_AggStep: {
assert( memIsValid(pRec) );
apVal[i] = pRec;
memAboutToChange(p, pRec);
sqlite3VdbeMemStoreType(pRec);
}
ctx.pFunc = pOp->p4.pFunc;
assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) );
@@ -5910,7 +5929,6 @@ case OP_VFilter: { /* jump */
apArg = p->apArg;
for(i = 0; i<nArg; i++){
apArg[i] = &pArgc[i+1];
sqlite3VdbeMemStoreType(apArg[i]);
}
p->inVtabMethod = 1;
@@ -6117,7 +6135,6 @@ case OP_VUpdate: {
for(i=0; i<nArg; i++){
assert( memIsValid(pX) );
memAboutToChange(p, pX);
sqlite3VdbeMemStoreType(pX);
apArg[i] = pX;
pX++;
}
@@ -6259,10 +6276,6 @@ default: { /* This is really OP_Noop and OP_Explain */
u64 elapsed = sqlite3Hwtime() - start;
pOp->cycles += elapsed;
pOp->cnt++;
#if 0
fprintf(stdout, "%10llu ", elapsed);
sqlite3VdbePrintOp(stdout, origPc, &aOp[origPc]);
#endif
}
#endif
+33 -3
View File
@@ -65,7 +65,7 @@ struct VdbeOp {
char *zComment; /* Comment to improve readability */
#endif
#ifdef VDBE_PROFILE
int cnt; /* Number of times this instruction was executed */
u32 cnt; /* Number of times this instruction was executed */
u64 cycles; /* Total time spent executing this instruction */
#endif
#ifdef SQLITE_VDBE_COVERAGE
@@ -211,9 +211,12 @@ void sqlite3VdbeSetVarmask(Vdbe*, int);
#endif
void sqlite3VdbeRecordUnpack(KeyInfo*,int,const void*,UnpackedRecord*);
int sqlite3VdbeRecordCompare(int,const void*,UnpackedRecord*);
int sqlite3VdbeRecordCompare(int,const void*,const UnpackedRecord*,int);
UnpackedRecord *sqlite3VdbeAllocUnpackedRecord(KeyInfo *, char *, int, char **);
typedef int (*RecordCompare)(int,const void*,const UnpackedRecord*,int);
RecordCompare sqlite3VdbeFindCompare(UnpackedRecord*);
#ifndef SQLITE_OMIT_TRIGGER
void sqlite3VdbeLinkSubProgram(Vdbe *, SubProgram *);
#endif
@@ -241,14 +244,41 @@ void sqlite3VdbeLinkSubProgram(Vdbe *, SubProgram *);
# define VdbeModuleComment(X)
#endif
/* Set the Opcode.iSrcline field of the previous opcode */
/*
** The VdbeCoverage macros are used to set a coverage testing point
** for VDBE branch instructions. The coverage testing points are line
** numbers in the sqlite3.c source file. VDBE branch coverage testing
** only works with an amalagmation build. That's ok since a VDBE branch
** coverage build designed for testing the test suite only. No application
** should ever ship with VDBE branch coverage measuring turned on.
**
** VdbeCoverage(v) // Mark the previously coded instruction
** // as a branch
**
** VdbeCoverageIf(v, conditional) // Mark previous if conditional true
**
** VdbeCoverageAlwaysTaken(v) // Previous branch is always taken
**
** VdbeCoverageNeverTaken(v) // Previous branch is never taken
**
** Every VDBE branch operation must be tagged with one of the macros above.
** If not, then when "make test" is run with -DSQLITE_VDBE_COVERAGE and
** -DSQLITE_DEBUG then an ALWAYS() will fail in the vdbeTakeBranch()
** routine in vdbe.c, alerting the developer to the missed tag.
*/
#ifdef SQLITE_VDBE_COVERAGE
void sqlite3VdbeSetLineNumber(Vdbe*,int);
# define VdbeCoverage(v) sqlite3VdbeSetLineNumber(v,__LINE__)
# define VdbeCoverageIf(v,x) if(x)sqlite3VdbeSetLineNumber(v,__LINE__)
# define VdbeCoverageAlwaysTaken(v) sqlite3VdbeSetLineNumber(v,2);
# define VdbeCoverageNeverTaken(v) sqlite3VdbeSetLineNumber(v,1);
# define VDBE_OFFSET_LINENO(x) (__LINE__+x)
#else
# define VdbeCoverage(v)
# define VdbeCoverageIf(v,x)
# define VdbeCoverageAlwaysTaken(v)
# define VdbeCoverageNeverTaken(v)
# define VDBE_OFFSET_LINENO(x) 0
#endif
#endif
+4 -5
View File
@@ -168,7 +168,6 @@ struct Mem {
} u;
int n; /* Number of characters in string value, excluding '\0' */
u16 flags; /* Some combination of MEM_Null, MEM_Str, MEM_Dyn, etc. */
u8 memType; /* Lower 5 bits of flags */
u8 enc; /* SQLITE_UTF8, SQLITE_UTF16BE, SQLITE_UTF16LE */
#ifdef SQLITE_DEBUG
Mem *pScopyFrom; /* This Mem is a shallow copy of pScopyFrom */
@@ -195,6 +194,7 @@ struct Mem {
#define MEM_Int 0x0004 /* Value is an integer */
#define MEM_Real 0x0008 /* Value is a real number */
#define MEM_Blob 0x0010 /* Value is a BLOB */
#define MEM_AffMask 0x001f /* Mask of affinity bits */
#define MEM_RowSet 0x0020 /* Value is a RowSet object */
#define MEM_Frame 0x0040 /* Value is a VdbeFrame object */
#define MEM_Undefined 0x0080 /* Value is undefined */
@@ -208,7 +208,7 @@ struct Mem {
** string is \000 or \u0000 terminated
*/
#define MEM_Term 0x0200 /* String rep is nul terminated */
#define MEM_Dyn 0x0400 /* Need to call sqliteFree() on Mem.z */
#define MEM_Dyn 0x0400 /* Need to call Mem.xDel() on Mem.z */
#define MEM_Static 0x0800 /* Mem.z points to a static string */
#define MEM_Ephem 0x1000 /* Mem.z points to an ephemeral string */
#define MEM_Agg 0x2000 /* Mem.z points to an agg function context */
@@ -391,7 +391,7 @@ u32 sqlite3VdbeSerialGet(const unsigned char*, u32, Mem*);
void sqlite3VdbeDeleteAuxData(Vdbe*, int, int);
int sqlite2BtreeKeyCompare(BtCursor *, const void *, int, int, int *);
int sqlite3VdbeIdxKeyCompare(VdbeCursor*,UnpackedRecord*,int*);
int sqlite3VdbeIdxKeyCompare(VdbeCursor*,const UnpackedRecord*,int*);
int sqlite3VdbeIdxRowid(sqlite3*, BtCursor *, i64 *);
int sqlite3MemCompare(const Mem*, const Mem*, const CollSeq*);
int sqlite3VdbeExec(Vdbe*);
@@ -434,8 +434,6 @@ int sqlite3VdbeMemGrow(Mem *pMem, int n, int preserve);
int sqlite3VdbeCloseStatement(Vdbe *, int);
void sqlite3VdbeFrameDelete(VdbeFrame*);
int sqlite3VdbeFrameRestore(VdbeFrame *);
#define sqlite3VdbeMemStoreType(X) (X)->memType = (u8)((X)->flags&0x1f)
/* void sqlite3VdbeMemStoreType(Mem *pMem); */
int sqlite3VdbeTransferError(Vdbe *p);
int sqlite3VdbeSorterInit(sqlite3 *, VdbeCursor *);
@@ -456,6 +454,7 @@ int sqlite3VdbeSorterCompare(const VdbeCursor *, Mem *, int, int *);
#ifdef SQLITE_DEBUG
void sqlite3VdbeMemAboutToChange(Vdbe*,Mem*);
int sqlite3VdbeCheckMemInvariants(Mem*);
#endif
#ifndef SQLITE_OMIT_FOREIGN_KEY
+26 -24
View File
@@ -135,7 +135,6 @@ const void *sqlite3_value_blob(sqlite3_value *pVal){
Mem *p = (Mem*)pVal;
if( p->flags & (MEM_Blob|MEM_Str) ){
sqlite3VdbeMemExpandBlob(p);
p->flags &= ~MEM_Str;
p->flags |= MEM_Blob;
return p->n ? p->z : 0;
}else{
@@ -206,7 +205,7 @@ int sqlite3_value_type(sqlite3_value* pVal){
SQLITE_INTEGER, /* 0x1e */
SQLITE_NULL, /* 0x1f */
};
return aType[pVal->memType&0x1f];
return aType[pVal->flags&MEM_AffMask];
}
/**************************** sqlite3_result_ *******************************
@@ -727,6 +726,30 @@ int sqlite3_data_count(sqlite3_stmt *pStmt){
return pVm->nResColumn;
}
/*
** Return a pointer to static memory containing an SQL NULL value.
*/
static const Mem *columnNullValue(void){
/* Even though the Mem structure contains an element
** of type i64, on certain architectures (x86) with certain compiler
** switches (-Os), gcc may align this Mem object on a 4-byte boundary
** instead of an 8-byte one. This all works fine, except that when
** running with SQLITE_DEBUG defined the SQLite code sometimes assert()s
** that a Mem structure is located on an 8-byte boundary. To prevent
** these assert()s from failing, when building with SQLITE_DEBUG defined
** using gcc, we force nullMem to be 8-byte aligned using the magical
** __attribute__((aligned(8))) macro. */
static const Mem nullMem
#if defined(SQLITE_DEBUG) && defined(__GNUC__)
__attribute__((aligned(8)))
#endif
= {0, "", (double)0, {0}, 0, MEM_Null, 0,
#ifdef SQLITE_DEBUG
0, 0, /* pScopyFrom, pFiller */
#endif
0, 0 };
return &nullMem;
}
/*
** Check to see if column iCol of the given statement is valid. If
@@ -743,32 +766,11 @@ static Mem *columnMem(sqlite3_stmt *pStmt, int i){
sqlite3_mutex_enter(pVm->db->mutex);
pOut = &pVm->pResultSet[i];
}else{
/* If the value passed as the second argument is out of range, return
** a pointer to the following static Mem object which contains the
** value SQL NULL. Even though the Mem structure contains an element
** of type i64, on certain architectures (x86) with certain compiler
** switches (-Os), gcc may align this Mem object on a 4-byte boundary
** instead of an 8-byte one. This all works fine, except that when
** running with SQLITE_DEBUG defined the SQLite code sometimes assert()s
** that a Mem structure is located on an 8-byte boundary. To prevent
** these assert()s from failing, when building with SQLITE_DEBUG defined
** using gcc, we force nullMem to be 8-byte aligned using the magical
** __attribute__((aligned(8))) macro. */
static const Mem nullMem
#if defined(SQLITE_DEBUG) && defined(__GNUC__)
__attribute__((aligned(8)))
#endif
= {0, "", (double)0, {0}, 0, MEM_Null, SQLITE_NULL, 0,
#ifdef SQLITE_DEBUG
0, 0, /* pScopyFrom, pFiller */
#endif
0, 0 };
if( pVm && ALWAYS(pVm->db) ){
sqlite3_mutex_enter(pVm->db->mutex);
sqlite3Error(pVm->db, SQLITE_RANGE, 0);
}
pOut = (Mem*)&nullMem;
pOut = (Mem*)columnNullValue();
}
return pOut;
}
+613 -65
View File
@@ -1220,6 +1220,7 @@ static void releaseMemArray(Mem *p, int N){
}
for(pEnd=&p[N]; p<pEnd; p++){
assert( (&p[1])==pEnd || p[0].db==p[1].db );
assert( sqlite3VdbeCheckMemInvariants(p) );
/* This block is really an inlined version of sqlite3VdbeMemRelease()
** that takes advantage of the fact that the memory cell value is
@@ -1233,6 +1234,10 @@ static void releaseMemArray(Mem *p, int N){
** with no indexes using a single prepared INSERT statement, bind()
** and reset(). Inserts are grouped into a transaction.
*/
testcase( p->flags & MEM_Agg );
testcase( p->flags & MEM_Dyn );
testcase( p->flags & MEM_Frame );
testcase( p->flags & MEM_RowSet );
if( p->flags&(MEM_Agg|MEM_Dyn|MEM_Frame|MEM_RowSet) ){
sqlite3VdbeMemRelease(p);
}else if( p->zMalloc ){
@@ -1362,7 +1367,6 @@ int sqlite3VdbeList(
}
if( p->explain==1 ){
pMem->flags = MEM_Int;
pMem->memType = MEM_Int;
pMem->u.i = i; /* Program counter */
pMem++;
@@ -1370,7 +1374,6 @@ int sqlite3VdbeList(
pMem->z = (char*)sqlite3OpcodeName(pOp->opcode); /* Opcode */
assert( pMem->z!=0 );
pMem->n = sqlite3Strlen30(pMem->z);
pMem->memType = MEM_Str;
pMem->enc = SQLITE_UTF8;
pMem++;
@@ -1396,24 +1399,21 @@ int sqlite3VdbeList(
pMem->flags = MEM_Int;
pMem->u.i = pOp->p1; /* P1 */
pMem->memType = MEM_Int;
pMem++;
pMem->flags = MEM_Int;
pMem->u.i = pOp->p2; /* P2 */
pMem->memType = MEM_Int;
pMem++;
pMem->flags = MEM_Int;
pMem->u.i = pOp->p3; /* P3 */
pMem->memType = MEM_Int;
pMem++;
if( sqlite3VdbeMemGrow(pMem, 32, 0) ){ /* P4 */
assert( p->db->mallocFailed );
return SQLITE_ERROR;
}
pMem->flags = MEM_Dyn|MEM_Str|MEM_Term;
pMem->flags = MEM_Str|MEM_Term;
zP4 = displayP4(pOp, pMem->z, 32);
if( zP4!=pMem->z ){
sqlite3VdbeMemSetStr(pMem, zP4, -1, SQLITE_UTF8, 0);
@@ -1422,7 +1422,6 @@ int sqlite3VdbeList(
pMem->n = sqlite3Strlen30(pMem->z);
pMem->enc = SQLITE_UTF8;
}
pMem->memType = MEM_Str;
pMem++;
if( p->explain==1 ){
@@ -1430,10 +1429,9 @@ int sqlite3VdbeList(
assert( p->db->mallocFailed );
return SQLITE_ERROR;
}
pMem->flags = MEM_Dyn|MEM_Str|MEM_Term;
pMem->flags = MEM_Str|MEM_Term;
pMem->n = 2;
sqlite3_snprintf(3, pMem->z, "%.2x", pOp->p5); /* P5 */
pMem->memType = MEM_Str;
pMem->enc = SQLITE_UTF8;
pMem++;
@@ -1442,13 +1440,11 @@ int sqlite3VdbeList(
assert( p->db->mallocFailed );
return SQLITE_ERROR;
}
pMem->flags = MEM_Dyn|MEM_Str|MEM_Term;
pMem->flags = MEM_Str|MEM_Term;
pMem->n = displayComment(pOp, zP4, pMem->z, 500);
pMem->memType = MEM_Str;
pMem->enc = SQLITE_UTF8;
#else
pMem->flags = MEM_Null; /* Comment */
pMem->memType = MEM_Null;
#endif
}
@@ -2580,11 +2576,13 @@ int sqlite3VdbeReset(Vdbe *p){
if( pc!='\n' ) fprintf(out, "\n");
}
for(i=0; i<p->nOp; i++){
fprintf(out, "%6d %10lld %8lld ",
char zHdr[100];
sqlite3_snprintf(sizeof(zHdr), zHdr, "%6u %12llu %8llu ",
p->aOp[i].cnt,
p->aOp[i].cycles,
p->aOp[i].cnt>0 ? p->aOp[i].cycles/p->aOp[i].cnt : 0
);
fprintf(out, "%s", zHdr);
sqlite3VdbePrintOp(out, i, &p->aOp[i]);
}
fclose(out);
@@ -2939,6 +2937,14 @@ u32 sqlite3VdbeSerialPut(u8 *buf, Mem *pMem, u32 serial_type){
return 0;
}
/* Input "x" is a sequence of unsigned characters that represent a
** big-endian integer. Return the equivalent native integer
*/
#define ONE_BYTE_INT(x) ((i8)(x)[0])
#define TWO_BYTE_INT(x) (256*(i8)((x)[0])|(x)[1])
#define THREE_BYTE_INT(x) (65536*(i8)((x)[0])|((x)[1]<<8)|(x)[2])
#define FOUR_BYTE_UINT(x) (((u32)(x)[0]<<24)|((x)[1]<<16)|((x)[2]<<8)|(x)[3])
/*
** Deserialize the data blob pointed to by buf as serial type serial_type
** and store the result in pMem. Return the number of bytes read.
@@ -2950,7 +2956,6 @@ u32 sqlite3VdbeSerialGet(
){
u64 x;
u32 y;
int i;
switch( serial_type ){
case 10: /* Reserved for future use */
case 11: /* Reserved for future use */
@@ -2959,34 +2964,34 @@ u32 sqlite3VdbeSerialGet(
break;
}
case 1: { /* 1-byte signed integer */
pMem->u.i = (signed char)buf[0];
pMem->u.i = ONE_BYTE_INT(buf);
pMem->flags = MEM_Int;
testcase( pMem->u.i<0 );
return 1;
}
case 2: { /* 2-byte signed integer */
i = 256*(signed char)buf[0] | buf[1];
pMem->u.i = (i64)i;
pMem->u.i = TWO_BYTE_INT(buf);
pMem->flags = MEM_Int;
testcase( pMem->u.i<0 );
return 2;
}
case 3: { /* 3-byte signed integer */
i = 65536*(signed char)buf[0] | (buf[1]<<8) | buf[2];
pMem->u.i = (i64)i;
pMem->u.i = THREE_BYTE_INT(buf);
pMem->flags = MEM_Int;
testcase( pMem->u.i<0 );
return 3;
}
case 4: { /* 4-byte signed integer */
y = ((unsigned)buf[0]<<24) | (buf[1]<<16) | (buf[2]<<8) | buf[3];
y = FOUR_BYTE_UINT(buf);
pMem->u.i = (i64)*(int*)&y;
pMem->flags = MEM_Int;
testcase( pMem->u.i<0 );
return 4;
}
case 5: { /* 6-byte signed integer */
x = 256*(signed char)buf[0] + buf[1];
y = ((unsigned)buf[2]<<24) | (buf[3]<<16) | (buf[4]<<8) | buf[5];
x = (x<<32) | y;
pMem->u.i = *(i64*)&x;
pMem->u.i = FOUR_BYTE_UINT(buf+2) + (((i64)1)<<32)*TWO_BYTE_INT(buf);
pMem->flags = MEM_Int;
testcase( pMem->u.i<0 );
return 6;
}
case 6: /* 8-byte signed integer */
@@ -3003,12 +3008,13 @@ u32 sqlite3VdbeSerialGet(
swapMixedEndianFloat(t2);
assert( sizeof(r1)==sizeof(t2) && memcmp(&r1, &t2, sizeof(r1))==0 );
#endif
x = ((unsigned)buf[0]<<24) | (buf[1]<<16) | (buf[2]<<8) | buf[3];
y = ((unsigned)buf[4]<<24) | (buf[5]<<16) | (buf[6]<<8) | buf[7];
x = FOUR_BYTE_UINT(buf);
y = FOUR_BYTE_UINT(buf+4);
x = (x<<32) | y;
if( serial_type==6 ){
pMem->u.i = *(i64*)&x;
pMem->flags = MEM_Int;
testcase( pMem->u.i<0 );
}else{
assert( sizeof(x)==8 && sizeof(pMem->r)==8 );
swapMixedEndianFloat(x);
@@ -3100,7 +3106,7 @@ void sqlite3VdbeRecordUnpack(
u32 szHdr;
Mem *pMem = p->aMem;
p->flags = 0;
p->default_rc = 0;
assert( EIGHT_BYTE_ALIGNMENT(pMem) );
idx = getVarint32(aKey, szHdr);
d = szHdr;
@@ -3121,26 +3127,18 @@ void sqlite3VdbeRecordUnpack(
p->nField = u;
}
#if SQLITE_DEBUG
/*
** This function compares the two table rows or index records
** specified by {nKey1, pKey1} and pPKey2. It returns a negative, zero
** or positive integer if key1 is less than, equal to or
** greater than key2. The {nKey1, pKey1} key must be a blob
** created by th OP_MakeRecord opcode of the VDBE. The pPKey2
** key must be a parsed key such as obtained from
** sqlite3VdbeParseRecord.
**
** Key1 and Key2 do not have to contain the same number of fields.
** The key with fewer fields is usually compares less than the
** longer key. However if the UNPACKED_INCRKEY flags in pPKey2 is set
** and the common prefixes are equal, then key1 is less than key2.
** Or if the UNPACKED_MATCH_PREFIX flag is set and the prefixes are
** equal, then the keys are considered to be equal and
** the parts beyond the common prefix are ignored.
** This function compares two index or table record keys in the same way
** as the sqlite3VdbeRecordCompare() routine. Unlike VdbeRecordCompare(),
** this function deserializes and compares values using the
** sqlite3VdbeSerialGet() and sqlite3MemCompare() functions. It is used
** in assert() statements to ensure that the optimized code in
** sqlite3VdbeRecordCompare() returns results with these two primitives.
*/
int sqlite3VdbeRecordCompare(
static int vdbeRecordCompareDebug(
int nKey1, const void *pKey1, /* Left key */
UnpackedRecord *pPKey2 /* Right key */
const UnpackedRecord *pPKey2 /* Right key */
){
u32 d1; /* Offset into aKey[] of next data element */
u32 idx1; /* Offset into aKey[] of next header element */
@@ -3214,24 +3212,576 @@ int sqlite3VdbeRecordCompare(
assert( mem1.zMalloc==0 );
/* rc==0 here means that one of the keys ran out of fields and
** all the fields up to that point were equal. If the UNPACKED_INCRKEY
** flag is set, then break the tie by treating key2 as larger.
** If the UPACKED_PREFIX_MATCH flag is set, then keys with common prefixes
** are considered to be equal. Otherwise, the longer key is the
** larger. As it happens, the pPKey2 will always be the longer
** if there is a difference.
** all the fields up to that point were equal. Return the the default_rc
** value. */
return pPKey2->default_rc;
}
#endif
/*
** Both *pMem1 and *pMem2 contain string values. Compare the two values
** using the collation sequence pColl. As usual, return a negative , zero
** or positive value if *pMem1 is less than, equal to or greater than
** *pMem2, respectively. Similar in spirit to "rc = (*pMem1) - (*pMem2);".
*/
static int vdbeCompareMemString(
const Mem *pMem1,
const Mem *pMem2,
const CollSeq *pColl
){
if( pMem1->enc==pColl->enc ){
/* The strings are already in the correct encoding. Call the
** comparison function directly */
return pColl->xCmp(pColl->pUser,pMem1->n,pMem1->z,pMem2->n,pMem2->z);
}else{
int rc;
const void *v1, *v2;
int n1, n2;
Mem c1;
Mem c2;
memset(&c1, 0, sizeof(c1));
memset(&c2, 0, sizeof(c2));
sqlite3VdbeMemShallowCopy(&c1, pMem1, MEM_Ephem);
sqlite3VdbeMemShallowCopy(&c2, pMem2, MEM_Ephem);
v1 = sqlite3ValueText((sqlite3_value*)&c1, pColl->enc);
n1 = v1==0 ? 0 : c1.n;
v2 = sqlite3ValueText((sqlite3_value*)&c2, pColl->enc);
n2 = v2==0 ? 0 : c2.n;
rc = pColl->xCmp(pColl->pUser, n1, v1, n2, v2);
sqlite3VdbeMemRelease(&c1);
sqlite3VdbeMemRelease(&c2);
return rc;
}
}
/*
** Compare the values contained by the two memory cells, returning
** negative, zero or positive if pMem1 is less than, equal to, or greater
** than pMem2. Sorting order is NULL's first, followed by numbers (integers
** and reals) sorted numerically, followed by text ordered by the collating
** sequence pColl and finally blob's ordered by memcmp().
**
** Two NULL values are considered equal by this function.
*/
int sqlite3MemCompare(const Mem *pMem1, const Mem *pMem2, const CollSeq *pColl){
int rc;
int f1, f2;
int combined_flags;
f1 = pMem1->flags;
f2 = pMem2->flags;
combined_flags = f1|f2;
assert( (combined_flags & MEM_RowSet)==0 );
/* If one value is NULL, it is less than the other. If both values
** are NULL, return 0.
*/
assert( rc==0 );
if( pPKey2->flags & UNPACKED_INCRKEY ){
rc = -1;
}else if( pPKey2->flags & UNPACKED_PREFIX_MATCH ){
/* Leave rc==0 */
}else if( idx1<szHdr1 ){
rc = 1;
if( combined_flags&MEM_Null ){
return (f2&MEM_Null) - (f1&MEM_Null);
}
/* If one value is a number and the other is not, the number is less.
** If both are numbers, compare as reals if one is a real, or as integers
** if both values are integers.
*/
if( combined_flags&(MEM_Int|MEM_Real) ){
double r1, r2;
if( (f1 & f2 & MEM_Int)!=0 ){
if( pMem1->u.i < pMem2->u.i ) return -1;
if( pMem1->u.i > pMem2->u.i ) return 1;
return 0;
}
if( (f1&MEM_Real)!=0 ){
r1 = pMem1->r;
}else if( (f1&MEM_Int)!=0 ){
r1 = (double)pMem1->u.i;
}else{
return 1;
}
if( (f2&MEM_Real)!=0 ){
r2 = pMem2->r;
}else if( (f2&MEM_Int)!=0 ){
r2 = (double)pMem2->u.i;
}else{
return -1;
}
if( r1<r2 ) return -1;
if( r1>r2 ) return 1;
return 0;
}
/* If one value is a string and the other is a blob, the string is less.
** If both are strings, compare using the collating functions.
*/
if( combined_flags&MEM_Str ){
if( (f1 & MEM_Str)==0 ){
return 1;
}
if( (f2 & MEM_Str)==0 ){
return -1;
}
assert( pMem1->enc==pMem2->enc );
assert( pMem1->enc==SQLITE_UTF8 ||
pMem1->enc==SQLITE_UTF16LE || pMem1->enc==SQLITE_UTF16BE );
/* The collation sequence must be defined at this point, even if
** the user deletes the collation sequence after the vdbe program is
** compiled (this was not always the case).
*/
assert( !pColl || pColl->xCmp );
if( pColl ){
return vdbeCompareMemString(pMem1, pMem2, pColl);
}
/* If a NULL pointer was passed as the collate function, fall through
** to the blob case and use memcmp(). */
}
/* Both values must be blobs. Compare using memcmp(). */
rc = memcmp(pMem1->z, pMem2->z, (pMem1->n>pMem2->n)?pMem2->n:pMem1->n);
if( rc==0 ){
rc = pMem1->n - pMem2->n;
}
return rc;
}
/*
** The first argument passed to this function is a serial-type that
** corresponds to an integer - all values between 1 and 9 inclusive
** except 7. The second points to a buffer containing an integer value
** serialized according to serial_type. This function deserializes
** and returns the value.
*/
static i64 vdbeRecordDecodeInt(u32 serial_type, const u8 *aKey){
u32 y;
assert( CORRUPT_DB || (serial_type>=1 && serial_type<=9 && serial_type!=7) );
switch( serial_type ){
case 0:
case 1:
testcase( aKey[0]&0x80 );
return ONE_BYTE_INT(aKey);
case 2:
testcase( aKey[0]&0x80 );
return TWO_BYTE_INT(aKey);
case 3:
testcase( aKey[0]&0x80 );
return THREE_BYTE_INT(aKey);
case 4: {
testcase( aKey[0]&0x80 );
y = FOUR_BYTE_UINT(aKey);
return (i64)*(int*)&y;
}
case 5: {
testcase( aKey[0]&0x80 );
return FOUR_BYTE_UINT(aKey+2) + (((i64)1)<<32)*TWO_BYTE_INT(aKey);
}
case 6: {
u64 x = FOUR_BYTE_UINT(aKey);
testcase( aKey[0]&0x80 );
x = (x<<32) | FOUR_BYTE_UINT(aKey+4);
return (i64)*(i64*)&x;
}
}
return (serial_type - 8);
}
/*
** This function compares the two table rows or index records
** specified by {nKey1, pKey1} and pPKey2. It returns a negative, zero
** or positive integer if key1 is less than, equal to or
** greater than key2. The {nKey1, pKey1} key must be a blob
** created by th OP_MakeRecord opcode of the VDBE. The pPKey2
** key must be a parsed key such as obtained from
** sqlite3VdbeParseRecord.
**
** If argument bSkip is non-zero, it is assumed that the caller has already
** determined that the first fields of the keys are equal.
**
** Key1 and Key2 do not have to contain the same number of fields. If all
** fields that appear in both keys are equal, then pPKey2->default_rc is
** returned.
*/
int sqlite3VdbeRecordCompare(
int nKey1, const void *pKey1, /* Left key */
const UnpackedRecord *pPKey2, /* Right key */
int bSkip /* If true, skip the first field */
){
u32 d1; /* Offset into aKey[] of next data element */
int i; /* Index of next field to compare */
u32 szHdr1; /* Size of record header in bytes */
u32 idx1; /* Offset of first type in header */
int rc = 0; /* Return value */
Mem *pRhs = pPKey2->aMem; /* Next field of pPKey2 to compare */
KeyInfo *pKeyInfo = pPKey2->pKeyInfo;
const unsigned char *aKey1 = (const unsigned char *)pKey1;
Mem mem1;
/* If bSkip is true, then the caller has already determined that the first
** two elements in the keys are equal. Fix the various stack variables so
** that this routine begins comparing at the second field. */
if( bSkip ){
u32 s1;
idx1 = 1 + getVarint32(&aKey1[1], s1);
szHdr1 = aKey1[0];
d1 = szHdr1 + sqlite3VdbeSerialTypeLen(s1);
i = 1;
pRhs++;
}else{
idx1 = getVarint32(aKey1, szHdr1);
d1 = szHdr1;
i = 0;
}
VVA_ONLY( mem1.zMalloc = 0; ) /* Only needed by assert() statements */
assert( pPKey2->pKeyInfo->nField+pPKey2->pKeyInfo->nXField>=pPKey2->nField
|| CORRUPT_DB );
assert( pPKey2->pKeyInfo->aSortOrder!=0 );
assert( pPKey2->pKeyInfo->nField>0 );
assert( idx1<=szHdr1 || CORRUPT_DB );
do{
u32 serial_type;
/* RHS is an integer */
if( pRhs->flags & MEM_Int ){
serial_type = aKey1[idx1];
testcase( serial_type==12 );
if( serial_type>=12 ){
rc = +1;
}else if( serial_type==0 ){
rc = -1;
}else if( serial_type==7 ){
double rhs = (double)pRhs->u.i;
sqlite3VdbeSerialGet(&aKey1[d1], serial_type, &mem1);
if( mem1.r<rhs ){
rc = -1;
}else if( mem1.r>rhs ){
rc = +1;
}
}else{
i64 lhs = vdbeRecordDecodeInt(serial_type, &aKey1[d1]);
i64 rhs = pRhs->u.i;
if( lhs<rhs ){
rc = -1;
}else if( lhs>rhs ){
rc = +1;
}
}
}
/* RHS is real */
else if( pRhs->flags & MEM_Real ){
serial_type = aKey1[idx1];
if( serial_type>=12 ){
rc = +1;
}else if( serial_type==0 ){
rc = -1;
}else{
double rhs = pRhs->r;
double lhs;
sqlite3VdbeSerialGet(&aKey1[d1], serial_type, &mem1);
if( serial_type==7 ){
lhs = mem1.r;
}else{
lhs = (double)mem1.u.i;
}
if( lhs<rhs ){
rc = -1;
}else if( lhs>rhs ){
rc = +1;
}
}
}
/* RHS is a string */
else if( pRhs->flags & MEM_Str ){
getVarint32(&aKey1[idx1], serial_type);
testcase( serial_type==12 );
if( serial_type<12 ){
rc = -1;
}else if( !(serial_type & 0x01) ){
rc = +1;
}else{
mem1.n = (serial_type - 12) / 2;
testcase( (d1+mem1.n)==(unsigned)nKey1 );
testcase( (d1+mem1.n+1)==(unsigned)nKey1 );
if( (d1+mem1.n) > (unsigned)nKey1 ){
rc = 1; /* Corruption */
}else if( pKeyInfo->aColl[i] ){
mem1.enc = pKeyInfo->enc;
mem1.db = pKeyInfo->db;
mem1.flags = MEM_Str;
mem1.z = (char*)&aKey1[d1];
rc = vdbeCompareMemString(&mem1, pRhs, pKeyInfo->aColl[i]);
}else{
int nCmp = MIN(mem1.n, pRhs->n);
rc = memcmp(&aKey1[d1], pRhs->z, nCmp);
if( rc==0 ) rc = mem1.n - pRhs->n;
}
}
}
/* RHS is a blob */
else if( pRhs->flags & MEM_Blob ){
getVarint32(&aKey1[idx1], serial_type);
testcase( serial_type==12 );
if( serial_type<12 || (serial_type & 0x01) ){
rc = -1;
}else{
int nStr = (serial_type - 12) / 2;
testcase( (d1+nStr)==(unsigned)nKey1 );
testcase( (d1+nStr+1)==(unsigned)nKey1 );
if( (d1+nStr) > (unsigned)nKey1 ){
rc = 1; /* Corruption */
}else{
int nCmp = MIN(nStr, pRhs->n);
rc = memcmp(&aKey1[d1], pRhs->z, nCmp);
if( rc==0 ) rc = nStr - pRhs->n;
}
}
}
/* RHS is null */
else{
serial_type = aKey1[idx1];
rc = (serial_type!=0);
}
if( rc!=0 ){
if( pKeyInfo->aSortOrder[i] ){
rc = -rc;
}
assert( CORRUPT_DB
|| (rc<0 && vdbeRecordCompareDebug(nKey1, pKey1, pPKey2)<0)
|| (rc>0 && vdbeRecordCompareDebug(nKey1, pKey1, pPKey2)>0)
|| pKeyInfo->db->mallocFailed
);
assert( mem1.zMalloc==0 ); /* See comment below */
return rc;
}
i++;
pRhs++;
d1 += sqlite3VdbeSerialTypeLen(serial_type);
idx1 += sqlite3VarintLen(serial_type);
}while( idx1<(unsigned)szHdr1 && i<pPKey2->nField && d1<=(unsigned)nKey1 );
/* No memory allocation is ever used on mem1. Prove this using
** the following assert(). If the assert() fails, it indicates a
** memory leak and a need to call sqlite3VdbeMemRelease(&mem1). */
assert( mem1.zMalloc==0 );
/* rc==0 here means that one or both of the keys ran out of fields and
** all the fields up to that point were equal. Return the the default_rc
** value. */
assert( CORRUPT_DB
|| pPKey2->default_rc==vdbeRecordCompareDebug(nKey1, pKey1, pPKey2)
);
return pPKey2->default_rc;
}
/*
** This function is an optimized version of sqlite3VdbeRecordCompare()
** that (a) the first field of pPKey2 is an integer, and (b) the
** size-of-header varint at the start of (pKey1/nKey1) fits in a single
** byte (i.e. is less than 128).
*/
static int vdbeRecordCompareInt(
int nKey1, const void *pKey1, /* Left key */
const UnpackedRecord *pPKey2, /* Right key */
int bSkip /* Ignored */
){
const u8 *aKey = &((const u8*)pKey1)[*(const u8*)pKey1 & 0x3F];
int serial_type = ((const u8*)pKey1)[1];
int res;
u32 y;
u64 x;
i64 v = pPKey2->aMem[0].u.i;
i64 lhs;
UNUSED_PARAMETER(bSkip);
assert( bSkip==0 );
switch( serial_type ){
case 1: { /* 1-byte signed integer */
lhs = ONE_BYTE_INT(aKey);
testcase( lhs<0 );
break;
}
case 2: { /* 2-byte signed integer */
lhs = TWO_BYTE_INT(aKey);
testcase( lhs<0 );
break;
}
case 3: { /* 3-byte signed integer */
lhs = THREE_BYTE_INT(aKey);
testcase( lhs<0 );
break;
}
case 4: { /* 4-byte signed integer */
y = FOUR_BYTE_UINT(aKey);
lhs = (i64)*(int*)&y;
testcase( lhs<0 );
break;
}
case 5: { /* 6-byte signed integer */
lhs = FOUR_BYTE_UINT(aKey+2) + (((i64)1)<<32)*TWO_BYTE_INT(aKey);
testcase( lhs<0 );
break;
}
case 6: { /* 8-byte signed integer */
x = FOUR_BYTE_UINT(aKey);
x = (x<<32) | FOUR_BYTE_UINT(aKey+4);
lhs = *(i64*)&x;
testcase( lhs<0 );
break;
}
case 8:
lhs = 0;
break;
case 9:
lhs = 1;
break;
/* This case could be removed without changing the results of running
** this code. Including it causes gcc to generate a faster switch
** statement (since the range of switch targets now starts at zero and
** is contiguous) but does not cause any duplicate code to be generated
** (as gcc is clever enough to combine the two like cases). Other
** compilers might be similar. */
case 0: case 7:
return sqlite3VdbeRecordCompare(nKey1, pKey1, pPKey2, 0);
default:
return sqlite3VdbeRecordCompare(nKey1, pKey1, pPKey2, 0);
}
if( v>lhs ){
res = pPKey2->r1;
}else if( v<lhs ){
res = pPKey2->r2;
}else if( pPKey2->nField>1 ){
/* The first fields of the two keys are equal. Compare the trailing
** fields. */
res = sqlite3VdbeRecordCompare(nKey1, pKey1, pPKey2, 1);
}else{
/* The first fields of the two keys are equal and there are no trailing
** fields. Return pPKey2->default_rc in this case. */
res = pPKey2->default_rc;
}
assert( (res==0 && vdbeRecordCompareDebug(nKey1, pKey1, pPKey2)==0)
|| (res<0 && vdbeRecordCompareDebug(nKey1, pKey1, pPKey2)<0)
|| (res>0 && vdbeRecordCompareDebug(nKey1, pKey1, pPKey2)>0)
|| CORRUPT_DB
);
return res;
}
/*
** This function is an optimized version of sqlite3VdbeRecordCompare()
** that (a) the first field of pPKey2 is a string, that (b) the first field
** uses the collation sequence BINARY and (c) that the size-of-header varint
** at the start of (pKey1/nKey1) fits in a single byte.
*/
static int vdbeRecordCompareString(
int nKey1, const void *pKey1, /* Left key */
const UnpackedRecord *pPKey2, /* Right key */
int bSkip
){
const u8 *aKey1 = (const u8*)pKey1;
int serial_type;
int res;
UNUSED_PARAMETER(bSkip);
assert( bSkip==0 );
getVarint32(&aKey1[1], serial_type);
if( serial_type<12 ){
res = pPKey2->r1; /* (pKey1/nKey1) is a number or a null */
}else if( !(serial_type & 0x01) ){
res = pPKey2->r2; /* (pKey1/nKey1) is a blob */
}else{
int nCmp;
int nStr;
int szHdr = aKey1[0];
nStr = (serial_type-12) / 2;
if( (szHdr + nStr) > nKey1 ) return 0; /* Corruption */
nCmp = MIN( pPKey2->aMem[0].n, nStr );
res = memcmp(&aKey1[szHdr], pPKey2->aMem[0].z, nCmp);
if( res==0 ){
res = nStr - pPKey2->aMem[0].n;
if( res==0 ){
if( pPKey2->nField>1 ){
res = sqlite3VdbeRecordCompare(nKey1, pKey1, pPKey2, 1);
}else{
res = pPKey2->default_rc;
}
}else if( res>0 ){
res = pPKey2->r2;
}else{
res = pPKey2->r1;
}
}else if( res>0 ){
res = pPKey2->r2;
}else{
res = pPKey2->r1;
}
}
assert( (res==0 && vdbeRecordCompareDebug(nKey1, pKey1, pPKey2)==0)
|| (res<0 && vdbeRecordCompareDebug(nKey1, pKey1, pPKey2)<0)
|| (res>0 && vdbeRecordCompareDebug(nKey1, pKey1, pPKey2)>0)
|| CORRUPT_DB
);
return res;
}
/*
** Return a pointer to an sqlite3VdbeRecordCompare() compatible function
** suitable for comparing serialized records to the unpacked record passed
** as the only argument.
*/
RecordCompare sqlite3VdbeFindCompare(UnpackedRecord *p){
/* varintRecordCompareInt() and varintRecordCompareString() both assume
** that the size-of-header varint that occurs at the start of each record
** fits in a single byte (i.e. is 127 or less). varintRecordCompareInt()
** also assumes that it is safe to overread a buffer by at least the
** maximum possible legal header size plus 8 bytes. Because there is
** guaranteed to be at least 74 (but not 136) bytes of padding following each
** buffer passed to varintRecordCompareInt() this makes it convenient to
** limit the size of the header to 64 bytes in cases where the first field
** is an integer.
**
** The easiest way to enforce this limit is to consider only records with
** 13 fields or less. If the first field is an integer, the maximum legal
** header size is (12*5 + 1 + 1) bytes. */
if( (p->pKeyInfo->nField + p->pKeyInfo->nXField)<=13 ){
int flags = p->aMem[0].flags;
if( p->pKeyInfo->aSortOrder[0] ){
p->r1 = 1;
p->r2 = -1;
}else{
p->r1 = -1;
p->r2 = 1;
}
if( (flags & MEM_Int) ){
return vdbeRecordCompareInt;
}
testcase( flags & MEM_Real );
testcase( flags & MEM_Null );
testcase( flags & MEM_Blob );
if( (flags & (MEM_Real|MEM_Null|MEM_Blob))==0 && p->pKeyInfo->aColl[0]==0 ){
assert( flags & MEM_Str );
return vdbeRecordCompareString;
}
}
return sqlite3VdbeRecordCompare;
}
/*
** pCur points at an index entry created using the OP_MakeRecord opcode.
@@ -3322,9 +3872,9 @@ idx_rowid_corruption:
** of the keys prior to the final rowid, not the entire key.
*/
int sqlite3VdbeIdxKeyCompare(
VdbeCursor *pC, /* The cursor to compare against */
UnpackedRecord *pUnpacked, /* Unpacked version of key to compare against */
int *res /* Write the comparison result here */
VdbeCursor *pC, /* The cursor to compare against */
const UnpackedRecord *pUnpacked, /* Unpacked version of key */
int *res /* Write the comparison result here */
){
i64 nCellKey = 0;
int rc;
@@ -3334,7 +3884,7 @@ int sqlite3VdbeIdxKeyCompare(
assert( sqlite3BtreeCursorIsValid(pCur) );
VVA_ONLY(rc =) sqlite3BtreeKeySize(pCur, &nCellKey);
assert( rc==SQLITE_OK ); /* pCur is always valid so KeySize cannot fail */
/* nCellKey will always be between 0 and 0xffffffff because of the say
/* nCellKey will always be between 0 and 0xffffffff because of the way
** that btreeParseCellPtr() and sqlite3GetVarint32() are implemented */
if( nCellKey<=0 || nCellKey>0x7fffffff ){
*res = 0;
@@ -3345,8 +3895,7 @@ int sqlite3VdbeIdxKeyCompare(
if( rc ){
return rc;
}
assert( pUnpacked->flags & UNPACKED_PREFIX_MATCH );
*res = sqlite3VdbeRecordCompare(m.n, m.z, pUnpacked);
*res = sqlite3VdbeRecordCompare(m.n, m.z, pUnpacked, 0);
sqlite3VdbeMemRelease(&m);
return SQLITE_OK;
}
@@ -3410,7 +3959,6 @@ sqlite3_value *sqlite3VdbeGetBoundValue(Vdbe *v, int iVar, u8 aff){
if( pRet ){
sqlite3VdbeMemCopy((Mem *)pRet, pMem);
sqlite3ValueApplyAffinity(pRet, aff, SQLITE_UTF8);
sqlite3VdbeMemStoreType((Mem *)pRet);
}
return pRet;
}
+1 -1
View File
@@ -133,7 +133,7 @@ int sqlite3_blob_open(
** which closes the b-tree cursor and (possibly) commits the
** transaction.
*/
static const int iLn = __LINE__+4;
static const int iLn = VDBE_OFFSET_LINENO(4);
static const VdbeOpList openBlob[] = {
/* {OP_Transaction, 0, 0, 0}, // 0: Inserted separately */
{OP_TableLock, 0, 0, 0}, /* 1: Acquire a read or write lock */
+56 -148
View File
@@ -18,6 +18,42 @@
#include "sqliteInt.h"
#include "vdbeInt.h"
#ifdef SQLITE_DEBUG
/*
** Check invariants on a Mem object.
**
** This routine is intended for use inside of assert() statements, like
** this: assert( sqlite3VdbeCheckMemInvariants(pMem) );
*/
int sqlite3VdbeCheckMemInvariants(Mem *p){
/* The MEM_Dyn bit is set if and only if Mem.xDel is a non-NULL destructor
** function for Mem.z
*/
assert( (p->flags & MEM_Dyn)==0 || p->xDel!=0 );
assert( (p->flags & MEM_Dyn)!=0 || p->xDel==0 );
/* If p holds a string or blob, the Mem.z must point to exactly
** one of the following:
**
** (1) Memory in Mem.zMalloc and managed by the Mem object
** (2) Memory to be freed using Mem.xDel
** (3) An ephermal string or blob
** (4) A static string or blob
*/
if( (p->flags & (MEM_Str|MEM_Blob)) && p->z!=0 ){
assert(
((p->z==p->zMalloc)? 1 : 0) +
((p->flags&MEM_Dyn)!=0 ? 1 : 0) +
((p->flags&MEM_Ephem)!=0 ? 1 : 0) +
((p->flags&MEM_Static)!=0 ? 1 : 0) == 1
);
}
return 1;
}
#endif
/*
** If pMem is an object with a valid string representation, this routine
** ensures the internal encoding for the string representation is
@@ -67,12 +103,7 @@ int sqlite3VdbeChangeEncoding(Mem *pMem, int desiredEnc){
** in pMem->z is discarded.
*/
int sqlite3VdbeMemGrow(Mem *pMem, int n, int bPreserve){
assert( 1 >=
((pMem->zMalloc && pMem->zMalloc==pMem->z) ? 1 : 0) +
(((pMem->flags&MEM_Dyn)&&pMem->xDel) ? 1 : 0) +
((pMem->flags&MEM_Ephem) ? 1 : 0) +
((pMem->flags&MEM_Static) ? 1 : 0)
);
assert( sqlite3VdbeCheckMemInvariants(pMem) );
assert( (pMem->flags&MEM_RowSet)==0 );
/* If the bPreserve flag is set to true, then the memory cell must already
@@ -90,7 +121,8 @@ int sqlite3VdbeMemGrow(Mem *pMem, int n, int bPreserve){
pMem->zMalloc = sqlite3DbMallocRaw(pMem->db, n);
}
if( pMem->zMalloc==0 ){
sqlite3VdbeMemRelease(pMem);
VdbeMemRelease(pMem);
pMem->z = 0;
pMem->flags = MEM_Null;
return SQLITE_NOMEM;
}
@@ -99,13 +131,13 @@ int sqlite3VdbeMemGrow(Mem *pMem, int n, int bPreserve){
if( pMem->z && bPreserve && pMem->z!=pMem->zMalloc ){
memcpy(pMem->zMalloc, pMem->z, pMem->n);
}
if( (pMem->flags&MEM_Dyn)!=0 && pMem->xDel ){
assert( pMem->xDel!=SQLITE_DYNAMIC );
if( (pMem->flags&MEM_Dyn)!=0 ){
assert( pMem->xDel!=0 && pMem->xDel!=SQLITE_DYNAMIC );
pMem->xDel((void *)(pMem->z));
}
pMem->z = pMem->zMalloc;
pMem->flags &= ~(MEM_Ephem|MEM_Static);
pMem->flags &= ~(MEM_Dyn|MEM_Ephem|MEM_Static);
pMem->xDel = 0;
return SQLITE_OK;
}
@@ -274,9 +306,9 @@ void sqlite3VdbeMemReleaseExternal(Mem *p){
sqlite3VdbeMemFinalize(p, p->u.pDef);
assert( (p->flags & MEM_Agg)==0 );
sqlite3VdbeMemRelease(p);
}else if( p->flags&MEM_Dyn && p->xDel ){
}else if( p->flags&MEM_Dyn ){
assert( (p->flags&MEM_RowSet)==0 );
assert( p->xDel!=SQLITE_DYNAMIC );
assert( p->xDel!=SQLITE_DYNAMIC && p->xDel!=0 );
p->xDel((void *)p->z);
p->xDel = 0;
}else if( p->flags&MEM_RowSet ){
@@ -289,9 +321,10 @@ void sqlite3VdbeMemReleaseExternal(Mem *p){
/*
** Release any memory held by the Mem. This may leave the Mem in an
** inconsistent state, for example with (Mem.z==0) and
** (Mem.memType==MEM_Str).
** (Mem.flags==MEM_Str).
*/
void sqlite3VdbeMemRelease(Mem *p){
assert( sqlite3VdbeCheckMemInvariants(p) );
VdbeMemRelease(p);
if( p->zMalloc ){
sqlite3DbFree(p->db, p->zMalloc);
@@ -480,7 +513,6 @@ void sqlite3VdbeMemSetNull(Mem *pMem){
sqlite3RowSetClear(pMem->u.pRowSet);
}
MemSetTypeFlag(pMem, MEM_Null);
pMem->memType = MEM_Null;
}
void sqlite3ValueSetNull(sqlite3_value *p){
sqlite3VdbeMemSetNull((Mem*)p);
@@ -493,7 +525,6 @@ void sqlite3ValueSetNull(sqlite3_value *p){
void sqlite3VdbeMemSetZeroBlob(Mem *pMem, int n){
sqlite3VdbeMemRelease(pMem);
pMem->flags = MEM_Blob|MEM_Zero;
pMem->memType = MEM_Blob;
pMem->n = 0;
if( n<0 ) n = 0;
pMem->u.nZero = n;
@@ -516,7 +547,6 @@ void sqlite3VdbeMemSetInt64(Mem *pMem, i64 val){
sqlite3VdbeMemRelease(pMem);
pMem->u.i = val;
pMem->flags = MEM_Int;
pMem->memType = MEM_Int;
}
#ifndef SQLITE_OMIT_FLOATING_POINT
@@ -531,7 +561,6 @@ void sqlite3VdbeMemSetDouble(Mem *pMem, double val){
sqlite3VdbeMemRelease(pMem);
pMem->r = val;
pMem->flags = MEM_Real;
pMem->memType = MEM_Real;
}
}
#endif
@@ -629,6 +658,7 @@ int sqlite3VdbeMemCopy(Mem *pTo, const Mem *pFrom){
VdbeMemRelease(pTo);
memcpy(pTo, pFrom, MEMCELLSIZE);
pTo->flags &= ~MEM_Dyn;
pTo->xDel = 0;
if( pTo->flags&(MEM_Str|MEM_Blob) ){
if( 0==(pFrom->flags&MEM_Static) ){
@@ -739,7 +769,6 @@ int sqlite3VdbeMemSetStr(
pMem->n = nByte;
pMem->flags = flags;
pMem->enc = (enc==0 ? SQLITE_UTF8 : enc);
pMem->memType = flags&0x1f;
#ifndef SQLITE_OMIT_UTF16
if( pMem->enc!=SQLITE_UTF8 && sqlite3VdbeMemHandleBom(pMem) ){
@@ -754,119 +783,6 @@ int sqlite3VdbeMemSetStr(
return SQLITE_OK;
}
/*
** Compare the values contained by the two memory cells, returning
** negative, zero or positive if pMem1 is less than, equal to, or greater
** than pMem2. Sorting order is NULL's first, followed by numbers (integers
** and reals) sorted numerically, followed by text ordered by the collating
** sequence pColl and finally blob's ordered by memcmp().
**
** Two NULL values are considered equal by this function.
*/
int sqlite3MemCompare(const Mem *pMem1, const Mem *pMem2, const CollSeq *pColl){
int rc;
int f1, f2;
int combined_flags;
f1 = pMem1->flags;
f2 = pMem2->flags;
combined_flags = f1|f2;
assert( (combined_flags & MEM_RowSet)==0 );
/* If one value is NULL, it is less than the other. If both values
** are NULL, return 0.
*/
if( combined_flags&MEM_Null ){
return (f2&MEM_Null) - (f1&MEM_Null);
}
/* If one value is a number and the other is not, the number is less.
** If both are numbers, compare as reals if one is a real, or as integers
** if both values are integers.
*/
if( combined_flags&(MEM_Int|MEM_Real) ){
double r1, r2;
if( (f1 & f2 & MEM_Int)!=0 ){
if( pMem1->u.i < pMem2->u.i ) return -1;
if( pMem1->u.i > pMem2->u.i ) return 1;
return 0;
}
if( (f1&MEM_Real)!=0 ){
r1 = pMem1->r;
}else if( (f1&MEM_Int)!=0 ){
r1 = (double)pMem1->u.i;
}else{
return 1;
}
if( (f2&MEM_Real)!=0 ){
r2 = pMem2->r;
}else if( (f2&MEM_Int)!=0 ){
r2 = (double)pMem2->u.i;
}else{
return -1;
}
if( r1<r2 ) return -1;
if( r1>r2 ) return 1;
return 0;
}
/* If one value is a string and the other is a blob, the string is less.
** If both are strings, compare using the collating functions.
*/
if( combined_flags&MEM_Str ){
if( (f1 & MEM_Str)==0 ){
return 1;
}
if( (f2 & MEM_Str)==0 ){
return -1;
}
assert( pMem1->enc==pMem2->enc );
assert( pMem1->enc==SQLITE_UTF8 ||
pMem1->enc==SQLITE_UTF16LE || pMem1->enc==SQLITE_UTF16BE );
/* The collation sequence must be defined at this point, even if
** the user deletes the collation sequence after the vdbe program is
** compiled (this was not always the case).
*/
assert( !pColl || pColl->xCmp );
if( pColl ){
if( pMem1->enc==pColl->enc ){
/* The strings are already in the correct encoding. Call the
** comparison function directly */
return pColl->xCmp(pColl->pUser,pMem1->n,pMem1->z,pMem2->n,pMem2->z);
}else{
const void *v1, *v2;
int n1, n2;
Mem c1;
Mem c2;
memset(&c1, 0, sizeof(c1));
memset(&c2, 0, sizeof(c2));
sqlite3VdbeMemShallowCopy(&c1, pMem1, MEM_Ephem);
sqlite3VdbeMemShallowCopy(&c2, pMem2, MEM_Ephem);
v1 = sqlite3ValueText((sqlite3_value*)&c1, pColl->enc);
n1 = v1==0 ? 0 : c1.n;
v2 = sqlite3ValueText((sqlite3_value*)&c2, pColl->enc);
n2 = v2==0 ? 0 : c2.n;
rc = pColl->xCmp(pColl->pUser, n1, v1, n2, v2);
sqlite3VdbeMemRelease(&c1);
sqlite3VdbeMemRelease(&c2);
return rc;
}
}
/* If a NULL pointer was passed as the collate function, fall through
** to the blob case and use memcmp(). */
}
/* Both values must be blobs. Compare using memcmp(). */
rc = memcmp(pMem1->z, pMem2->z, (pMem1->n>pMem2->n)?pMem2->n:pMem1->n);
if( rc==0 ){
rc = pMem1->n - pMem2->n;
}
return rc;
}
/*
** Move data out of a btree key or data field and into a Mem structure.
** The data or key is taken from the entry that pCur is currently pointing
@@ -907,22 +823,22 @@ int sqlite3VdbeMemFromBtree(
sqlite3VdbeMemRelease(pMem);
pMem->z = &zData[offset];
pMem->flags = MEM_Blob|MEM_Ephem;
pMem->n = (int)amt;
}else if( SQLITE_OK==(rc = sqlite3VdbeMemGrow(pMem, amt+2, 0)) ){
pMem->flags = MEM_Blob|MEM_Dyn|MEM_Term;
pMem->enc = 0;
pMem->memType = MEM_Blob;
if( key ){
rc = sqlite3BtreeKey(pCur, offset, amt, pMem->z);
}else{
rc = sqlite3BtreeData(pCur, offset, amt, pMem->z);
}
pMem->z[amt] = 0;
pMem->z[amt+1] = 0;
if( rc!=SQLITE_OK ){
if( rc==SQLITE_OK ){
pMem->z[amt] = 0;
pMem->z[amt+1] = 0;
pMem->flags = MEM_Blob|MEM_Term;
pMem->n = (int)amt;
}else{
sqlite3VdbeMemRelease(pMem);
}
}
pMem->n = (int)amt;
return rc;
}
@@ -980,7 +896,6 @@ sqlite3_value *sqlite3ValueNew(sqlite3 *db){
Mem *p = sqlite3DbMallocZero(db, sizeof(*p));
if( p ){
p->flags = MEM_Null;
p->memType = MEM_Null;
p->db = db;
}
return p;
@@ -1026,11 +941,9 @@ static sqlite3_value *valueNew(sqlite3 *db, struct ValueNewStat4Ctx *p){
if( pRec->pKeyInfo ){
assert( pRec->pKeyInfo->nField+pRec->pKeyInfo->nXField==nCol );
assert( pRec->pKeyInfo->enc==ENC(db) );
pRec->flags = UNPACKED_PREFIX_MATCH;
pRec->aMem = (Mem *)((u8*)pRec + ROUND8(sizeof(UnpackedRecord)));
for(i=0; i<nCol; i++){
pRec->aMem[i].flags = MEM_Null;
pRec->aMem[i].memType = MEM_Null;
pRec->aMem[i].db = db;
}
}else{
@@ -1103,7 +1016,6 @@ static int valueFromExpr(
zVal = sqlite3MPrintf(db, "%s%s", zNeg, pExpr->u.zToken);
if( zVal==0 ) goto no_mem;
sqlite3ValueSetStr(pVal, -1, zVal, SQLITE_UTF8, SQLITE_DYNAMIC);
if( op==TK_FLOAT ) pVal->memType = MEM_Real;
}
if( (op==TK_INTEGER || op==TK_FLOAT ) && affinity==SQLITE_AFF_NONE ){
sqlite3ValueApplyAffinity(pVal, SQLITE_AFF_NUMERIC, SQLITE_UTF8);
@@ -1121,9 +1033,9 @@ static int valueFromExpr(
){
sqlite3VdbeMemNumerify(pVal);
if( pVal->u.i==SMALLEST_INT64 ){
pVal->flags &= MEM_Int;
pVal->flags &= ~MEM_Int;
pVal->flags |= MEM_Real;
pVal->r = (double)LARGEST_INT64;
pVal->r = (double)SMALLEST_INT64;
}else{
pVal->u.i = -pVal->u.i;
}
@@ -1149,9 +1061,6 @@ static int valueFromExpr(
}
#endif
if( pVal ){
sqlite3VdbeMemStoreType(pVal);
}
*ppVal = pVal;
return rc;
@@ -1315,7 +1224,6 @@ int sqlite3Stat4ProbeSetValue(
sqlite3ValueApplyAffinity(pVal, affinity, ENC(db));
}
pVal->db = pParse->db;
sqlite3VdbeMemStoreType((Mem*)pVal);
}
}
}else{
+49 -8
View File
@@ -409,10 +409,10 @@ static void vdbeSorterCompare(
return;
}
}
r2->flags |= UNPACKED_PREFIX_MATCH;
assert( r2->default_rc==0 );
}
*pRes = sqlite3VdbeRecordCompare(nKey1, pKey1, r2);
*pRes = sqlite3VdbeRecordCompare(nKey1, pKey1, r2, 0);
}
/*
@@ -956,14 +956,55 @@ int sqlite3VdbeSorterNext(sqlite3 *db, const VdbeCursor *pCsr, int *pbEof){
if( pSorter->aTree ){
int iPrev = pSorter->aTree[1];/* Index of iterator to advance */
int i; /* Index of aTree[] to recalculate */
rc = vdbeSorterIterNext(db, &pSorter->aIter[iPrev]);
for(i=(pSorter->nTree+iPrev)/2; rc==SQLITE_OK && i>0; i=i/2){
rc = vdbeSorterDoCompare(pCsr, i);
}
if( rc==SQLITE_OK ){
int i; /* Index of aTree[] to recalculate */
VdbeSorterIter *pIter1; /* First iterator to compare */
VdbeSorterIter *pIter2; /* Second iterator to compare */
u8 *pKey2; /* To pIter2->aKey, or 0 if record cached */
*pbEof = (pSorter->aIter[pSorter->aTree[1]].pFile==0);
/* Find the first two iterators to compare. The one that was just
** advanced (iPrev) and the one next to it in the array. */
pIter1 = &pSorter->aIter[(iPrev & 0xFFFE)];
pIter2 = &pSorter->aIter[(iPrev | 0x0001)];
pKey2 = pIter2->aKey;
for(i=(pSorter->nTree+iPrev)/2; i>0; i=i/2){
/* Compare pIter1 and pIter2. Store the result in variable iRes. */
int iRes;
if( pIter1->pFile==0 ){
iRes = +1;
}else if( pIter2->pFile==0 ){
iRes = -1;
}else{
vdbeSorterCompare(pCsr, 0,
pIter1->aKey, pIter1->nKey, pKey2, pIter2->nKey, &iRes
);
}
/* If pIter1 contained the smaller value, set aTree[i] to its index.
** Then set pIter2 to the next iterator to compare to pIter1. In this
** case there is no cache of pIter2 in pSorter->pUnpacked, so set
** pKey2 to point to the record belonging to pIter2.
**
** Alternatively, if pIter2 contains the smaller of the two values,
** set aTree[i] to its index and update pIter1. If vdbeSorterCompare()
** was actually called above, then pSorter->pUnpacked now contains
** a value equivalent to pIter2. So set pKey2 to NULL to prevent
** vdbeSorterCompare() from decoding pIter2 again. */
if( iRes<=0 ){
pSorter->aTree[i] = (pIter1 - pSorter->aIter);
pIter2 = &pSorter->aIter[ pSorter->aTree[i ^ 0x0001] ];
pKey2 = pIter2->aKey;
}else{
if( pIter1->pFile ) pKey2 = 0;
pSorter->aTree[i] = (pIter2 - pSorter->aIter);
pIter1 = &pSorter->aIter[ pSorter->aTree[i ^ 0x0001] ];
}
}
*pbEof = (pSorter->aIter[pSorter->aTree[1]].pFile==0);
}
}else{
SorterRecord *pFree = pSorter->pRecord;
pSorter->pRecord = pFree->pNext;
+69 -58
View File
@@ -1601,7 +1601,7 @@ static void constructAutomaticIndex(
** transient index on 2nd and subsequent iterations of the loop. */
v = pParse->pVdbe;
assert( v!=0 );
addrInit = sqlite3CodeOnce(pParse);
addrInit = sqlite3CodeOnce(pParse); VdbeCoverage(v);
/* Count the number of columns that will be added to the index
** and used to match WHERE clause constraints */
@@ -1913,7 +1913,7 @@ static void whereKeyStats(
assert( pRec->nField>0 && iCol<pIdx->nSampleCol );
do{
iTest = (iMin+i)/2;
res = sqlite3VdbeRecordCompare(aSample[iTest].n, aSample[iTest].p, pRec);
res = sqlite3VdbeRecordCompare(aSample[iTest].n, aSample[iTest].p, pRec, 0);
if( res<0 ){
iMin = iTest+1;
}else{
@@ -1928,16 +1928,16 @@ static void whereKeyStats(
if( res==0 ){
/* If (res==0) is true, then sample $i must be equal to pRec */
assert( i<pIdx->nSample );
assert( 0==sqlite3VdbeRecordCompare(aSample[i].n, aSample[i].p, pRec)
assert( 0==sqlite3VdbeRecordCompare(aSample[i].n, aSample[i].p, pRec, 0)
|| pParse->db->mallocFailed );
}else{
/* Otherwise, pRec must be smaller than sample $i and larger than
** sample ($i-1). */
assert( i==pIdx->nSample
|| sqlite3VdbeRecordCompare(aSample[i].n, aSample[i].p, pRec)>0
|| sqlite3VdbeRecordCompare(aSample[i].n, aSample[i].p, pRec, 0)>0
|| pParse->db->mallocFailed );
assert( i==0
|| sqlite3VdbeRecordCompare(aSample[i-1].n, aSample[i-1].p, pRec)<0
|| sqlite3VdbeRecordCompare(aSample[i-1].n, aSample[i-1].p, pRec, 0)<0
|| pParse->db->mallocFailed );
}
#endif /* ifdef SQLITE_DEBUG */
@@ -2388,7 +2388,9 @@ static int codeEqualityTerm(
bRev = !bRev;
}
iTab = pX->iTable;
sqlite3VdbeAddOp2(v, bRev ? OP_Last : OP_Rewind, iTab, 0); VdbeCoverage(v);
sqlite3VdbeAddOp2(v, bRev ? OP_Last : OP_Rewind, iTab, 0);
VdbeCoverageIf(v, bRev);
VdbeCoverageIf(v, !bRev);
assert( (pLoop->wsFlags & WHERE_MULTI_OR)==0 );
pLoop->wsFlags |= WHERE_IN_ABLE;
if( pLevel->u.in.nIn==0 ){
@@ -2502,11 +2504,15 @@ static int codeAllEqualityTerms(
if( nSkip ){
int iIdxCur = pLevel->iIdxCur;
sqlite3VdbeAddOp1(v, (bRev?OP_Last:OP_Rewind), iIdxCur); VdbeCoverage(v);
sqlite3VdbeAddOp1(v, (bRev?OP_Last:OP_Rewind), iIdxCur);
VdbeCoverageIf(v, bRev==0);
VdbeCoverageIf(v, bRev!=0);
VdbeComment((v, "begin skip-scan on %s", pIdx->zName));
j = sqlite3VdbeAddOp0(v, OP_Goto);
pLevel->addrSkip = sqlite3VdbeAddOp4Int(v, (bRev?OP_SeekLT:OP_SeekGT),
iIdxCur, 0, regBase, nSkip); VdbeCoverage(v);
iIdxCur, 0, regBase, nSkip);
VdbeCoverageIf(v, bRev==0);
VdbeCoverageIf(v, bRev!=0);
sqlite3VdbeJumpHere(v, j);
for(j=0; j<nSkip; j++){
sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, j, regBase+j);
@@ -2539,7 +2545,10 @@ static int codeAllEqualityTerms(
testcase( pTerm->eOperator & WO_IN );
if( (pTerm->eOperator & (WO_ISNULL|WO_IN))==0 ){
Expr *pRight = pTerm->pExpr->pRight;
sqlite3ExprCodeIsNullJump(v, pRight, regBase+j, pLevel->addrBrk);
if( sqlite3ExprCanBeNull(pRight) ){
sqlite3VdbeAddOp2(v, OP_IsNull, regBase+j, pLevel->addrBrk);
VdbeCoverage(v);
}
if( zAff ){
if( sqlite3CompareAffinity(pRight, zAff[j])==SQLITE_AFF_NONE ){
zAff[j] = SQLITE_AFF_NONE;
@@ -2844,13 +2853,14 @@ static Bitmask codeOneLoopStart(
** construct.
*/
assert( pLoop->u.btree.nEq==1 );
iReleaseReg = sqlite3GetTempReg(pParse);
pTerm = pLoop->aLTerm[0];
assert( pTerm!=0 );
assert( pTerm->pExpr!=0 );
assert( omitTable==0 );
testcase( pTerm->wtFlags & TERM_VIRTUAL );
iReleaseReg = ++pParse->nMem;
iRowidReg = codeEqualityTerm(pParse, pTerm, pLevel, 0, bRev, iReleaseReg);
if( iRowidReg!=iReleaseReg ) sqlite3ReleaseTempReg(pParse, iReleaseReg);
addrNxt = pLevel->addrNxt;
sqlite3VdbeAddOp2(v, OP_MustBeInt, iRowidReg, addrNxt); VdbeCoverage(v);
sqlite3VdbeAddOp3(v, OP_NotExists, iCur, addrNxt, iRowidReg);
@@ -2904,13 +2914,18 @@ static Bitmask codeOneLoopStart(
testcase( pStart->leftCursor!=iCur ); /* transitive constraints */
r1 = sqlite3ExprCodeTemp(pParse, pX->pRight, &rTemp);
sqlite3VdbeAddOp3(v, aMoveOp[pX->op-TK_GT], iCur, addrBrk, r1);
VdbeComment((v, "pk")); VdbeCoverage(v);
VdbeComment((v, "pk"));
VdbeCoverageIf(v, pX->op==TK_GT);
VdbeCoverageIf(v, pX->op==TK_LE);
VdbeCoverageIf(v, pX->op==TK_LT);
VdbeCoverageIf(v, pX->op==TK_GE);
sqlite3ExprCacheAffinityChange(pParse, r1, 1);
sqlite3ReleaseTempReg(pParse, rTemp);
disableTerm(pLevel, pStart);
}else{
sqlite3VdbeAddOp2(v, bRev ? OP_Last : OP_Rewind, iCur, addrBrk);
VdbeCoverage(v);
VdbeCoverageIf(v, bRev==0);
VdbeCoverageIf(v, bRev!=0);
}
if( pEnd ){
Expr *pX;
@@ -2934,11 +2949,14 @@ static Bitmask codeOneLoopStart(
pLevel->p2 = start;
assert( pLevel->p5==0 );
if( testOp!=OP_Noop ){
iRowidReg = iReleaseReg = sqlite3GetTempReg(pParse);
iRowidReg = ++pParse->nMem;
sqlite3VdbeAddOp2(v, OP_Rowid, iCur, iRowidReg);
sqlite3ExprCacheStore(pParse, iCur, -1, iRowidReg);
sqlite3VdbeAddOp3(v, testOp, memEndValue, addrBrk, iRowidReg);
VdbeCoverage(v);
VdbeCoverageIf(v, testOp==OP_Le);
VdbeCoverageIf(v, testOp==OP_Lt);
VdbeCoverageIf(v, testOp==OP_Ge);
VdbeCoverageIf(v, testOp==OP_Gt);
sqlite3VdbeChangeP5(v, SQLITE_AFF_NUMERIC | SQLITE_JUMPIFNULL);
}
}else if( pLoop->wsFlags & WHERE_INDEXED ){
@@ -3039,13 +3057,13 @@ static Bitmask codeOneLoopStart(
pRangeEnd = pLoop->aLTerm[j++];
nExtraReg = 1;
if( pRangeStart==0
&& (pRangeEnd->wtFlags & TERM_VNULL)==0
&& (j = pIdx->aiColumn[nEq])>=0
&& pIdx->pTable->aCol[j].notNull==0
){
bSeekPastNull = 1;
}
}
assert( pRangeEnd==0 || (pRangeEnd->wtFlags & TERM_VNULL)==0 );
/* Generate code to evaluate all constraint terms using == or IN
** and store the values of those terms in an array of registers
@@ -3080,8 +3098,11 @@ static Bitmask codeOneLoopStart(
if( pRangeStart ){
Expr *pRight = pRangeStart->pExpr->pRight;
sqlite3ExprCode(pParse, pRight, regBase+nEq);
if( (pRangeStart->wtFlags & TERM_VNULL)==0 ){
sqlite3ExprCodeIsNullJump(v, pRight, regBase+nEq, addrNxt);
if( (pRangeStart->wtFlags & TERM_VNULL)==0
&& sqlite3ExprCanBeNull(pRight)
){
sqlite3VdbeAddOp2(v, OP_IsNull, regBase+nEq, addrNxt);
VdbeCoverage(v);
}
if( zStartAff ){
if( sqlite3CompareAffinity(pRight, zStartAff[nEq])==SQLITE_AFF_NONE){
@@ -3105,20 +3126,14 @@ static Bitmask codeOneLoopStart(
codeApplyAffinity(pParse, regBase, nConstraint - bSeekPastNull, zStartAff);
op = aStartOp[(start_constraints<<2) + (startEq<<1) + bRev];
assert( op!=0 );
testcase( op==OP_Rewind );
testcase( op==OP_Last );
testcase( op==OP_SeekGT );
testcase( op==OP_SeekGE );
testcase( op==OP_SeekLE );
testcase( op==OP_SeekLT );
sqlite3VdbeAddOp4Int(v, op, iIdxCur, addrNxt, regBase, nConstraint);
VdbeCoverage(v);
VdbeCoverageIf(v, op==OP_Rewind);
VdbeCoverageIf(v, op==OP_Last);
VdbeCoverageIf(v, op==OP_SeekGT);
VdbeCoverageIf(v, op==OP_SeekGE);
VdbeCoverageIf(v, op==OP_SeekLE);
VdbeCoverageIf(v, op==OP_SeekLT);
VdbeCoverageIf(v, op==OP_Rewind); testcase( op==OP_Rewind );
VdbeCoverageIf(v, op==OP_Last); testcase( op==OP_Last );
VdbeCoverageIf(v, op==OP_SeekGT); testcase( op==OP_SeekGT );
VdbeCoverageIf(v, op==OP_SeekGE); testcase( op==OP_SeekGE );
VdbeCoverageIf(v, op==OP_SeekLE); testcase( op==OP_SeekLE );
VdbeCoverageIf(v, op==OP_SeekLT); testcase( op==OP_SeekLT );
/* Load the value for the inequality constraint at the end of the
** range (if any).
@@ -3128,8 +3143,11 @@ static Bitmask codeOneLoopStart(
Expr *pRight = pRangeEnd->pExpr->pRight;
sqlite3ExprCacheRemove(pParse, regBase+nEq, 1);
sqlite3ExprCode(pParse, pRight, regBase+nEq);
if( (pRangeEnd->wtFlags & TERM_VNULL)==0 ){
sqlite3ExprCodeIsNullJump(v, pRight, regBase+nEq, addrNxt);
if( (pRangeEnd->wtFlags & TERM_VNULL)==0
&& sqlite3ExprCanBeNull(pRight)
){
sqlite3VdbeAddOp2(v, OP_IsNull, regBase+nEq, addrNxt);
VdbeCoverage(v);
}
if( sqlite3CompareAffinity(pRight, cEndAff)!=SQLITE_AFF_NONE
&& !sqlite3ExprNeedsNoAffinityChange(pRight, cEndAff)
@@ -3151,12 +3169,11 @@ static Bitmask codeOneLoopStart(
/* Check if the index cursor is past the end of the range. */
if( nConstraint ){
op = aEndOp[bRev*2 + endEq];
testcase( op==OP_IdxGT );
testcase( op==OP_IdxGE );
testcase( op==OP_IdxLT );
testcase( op==OP_IdxLE );
sqlite3VdbeAddOp4Int(v, op, iIdxCur, addrNxt, regBase, nConstraint);
VdbeCoverage(v);
testcase( op==OP_IdxGT ); VdbeCoverageIf(v, op==OP_IdxGT );
testcase( op==OP_IdxGE ); VdbeCoverageIf(v, op==OP_IdxGE );
testcase( op==OP_IdxLT ); VdbeCoverageIf(v, op==OP_IdxLT );
testcase( op==OP_IdxLE ); VdbeCoverageIf(v, op==OP_IdxLE );
}
/* Seek the table cursor, if required */
@@ -3165,7 +3182,7 @@ static Bitmask codeOneLoopStart(
if( omitTable ){
/* pIdx is a covering index. No need to access the main table. */
}else if( HasRowid(pIdx->pTable) ){
iRowidReg = iReleaseReg = sqlite3GetTempReg(pParse);
iRowidReg = ++pParse->nMem;
sqlite3VdbeAddOp2(v, OP_IdxRowid, iIdxCur, iRowidReg);
sqlite3ExprCacheStore(pParse, iCur, -1, iRowidReg);
sqlite3VdbeAddOp2(v, OP_Seek, iCur, iRowidReg); /* Deferred seek */
@@ -3430,8 +3447,8 @@ static Bitmask codeOneLoopStart(
pLevel->op = aStep[bRev];
pLevel->p1 = iCur;
pLevel->p2 = 1 + sqlite3VdbeAddOp2(v, aStart[bRev], iCur, addrBrk);
VdbeCoverageIf(v, bRev);
VdbeCoverageIf(v, !bRev);
VdbeCoverageIf(v, bRev==0);
VdbeCoverageIf(v, bRev!=0);
pLevel->p5 = SQLITE_STMTSTATUS_FULLSCAN_STEP;
}
}
@@ -3513,7 +3530,6 @@ static Bitmask codeOneLoopStart(
pTerm->wtFlags |= TERM_CODED;
}
}
sqlite3ReleaseTempReg(pParse, iReleaseReg);
return pLevel->notReady;
}
@@ -3958,7 +3974,10 @@ static int whereLoopAddBtreeIndex(
pNew->aLTerm[pNew->nLTerm++] = 0;
pNew->wsFlags |= WHERE_SKIPSCAN;
nIter = sqlite3LogEst(pProbe->aiRowEst[0]/pProbe->aiRowEst[saved_nEq+1]);
pNew->rRun = rLogSize + nIter;
pNew->nOut += nIter;
whereLoopAddBtreeIndex(pBuilder, pSrc, pProbe, nIter);
pNew->nOut = saved_nOut;
}
for(; rc==SQLITE_OK && pTerm!=0; pTerm = whereScanNext(&scan)){
int nIn = 0;
@@ -4885,9 +4904,12 @@ static int wherePathSatisfiesOrderBy(
orderDistinctMask |= pLoop->maskSelf;
for(i=0; i<nOrderBy; i++){
Expr *p;
Bitmask mTerm;
if( MASKBIT(i) & obSat ) continue;
p = pOrderBy->a[i].pExpr;
if( (exprTableUsage(&pWInfo->sMaskSet, p)&~orderDistinctMask)==0 ){
mTerm = exprTableUsage(&pWInfo->sMaskSet,p);
if( mTerm==0 && !sqlite3ExprIsConstant(p) ) continue;
if( (mTerm&~orderDistinctMask)==0 ){
obSat |= MASKBIT(i);
}
}
@@ -5510,22 +5532,6 @@ WhereInfo *sqlite3WhereBegin(
goto whereBeginError;
}
/* If the ORDER BY (or GROUP BY) clause contains references to general
** expressions, then we won't be able to satisfy it using indices, so
** go ahead and disable it now.
*/
if( pOrderBy && (wctrlFlags & WHERE_WANT_DISTINCT)!=0 ){
for(ii=0; ii<pOrderBy->nExpr; ii++){
Expr *pExpr = sqlite3ExprSkipCollate(pOrderBy->a[ii].pExpr);
if( pExpr->op!=TK_COLUMN ){
pWInfo->pOrderBy = pOrderBy = 0;
break;
}else if( pExpr->iColumn<0 ){
break;
}
}
}
if( wctrlFlags & WHERE_WANT_DISTINCT ){
if( isDistinctRedundant(pParse, pTabList, &pWInfo->sWC, pResultSet) ){
/* The DISTINCT marking is pointless. Ignore it. */
@@ -5802,6 +5808,9 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){
sqlite3VdbeAddOp3(v, pLevel->op, pLevel->p1, pLevel->p2, pLevel->p3);
sqlite3VdbeChangeP5(v, pLevel->p5);
VdbeCoverage(v);
VdbeCoverageIf(v, pLevel->op==OP_Next);
VdbeCoverageIf(v, pLevel->op==OP_Prev);
VdbeCoverageIf(v, pLevel->op==OP_VNext);
}
if( pLoop->wsFlags & WHERE_IN_ABLE && pLevel->u.in.nIn>0 ){
struct InLoop *pIn;
@@ -5811,6 +5820,8 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){
sqlite3VdbeJumpHere(v, pIn->addrInTop+1);
sqlite3VdbeAddOp2(v, pIn->eEndLoopOp, pIn->iCur, pIn->addrInTop);
VdbeCoverage(v);
VdbeCoverageIf(v, pIn->eEndLoopOp==OP_PrevIfOpen);
VdbeCoverageIf(v, pIn->eEndLoopOp==OP_NextIfOpen);
sqlite3VdbeJumpHere(v, pIn->addrInTop-1);
}
sqlite3DbFree(db, pLevel->u.in.aInLoop);
@@ -5862,7 +5873,7 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){
** the co-routine into OP_SCopy of result contained in a register.
** OP_Rowid becomes OP_Null.
*/
if( pTabItem->viaCoroutine ){
if( pTabItem->viaCoroutine && !db->mallocFailed ){
last = sqlite3VdbeCurrentAddr(v);
k = pLevel->addrBody;
pOp = sqlite3VdbeGetOp(v, k);
+21
View File
@@ -334,4 +334,25 @@ do_test alter4-8.2 {
}
} [list $::sql]
# Test that a default value equal to -1 multipied by the smallest possible
# 64-bit integer is correctly converted to a real.
do_execsql_test alter4-9.1 {
CREATE TABLE t5(
a INTEGER DEFAULT -9223372036854775808,
b INTEGER DEFAULT (-(-9223372036854775808))
);
INSERT INTO t5 DEFAULT VALUES;
}
do_execsql_test alter4-9.2 { SELECT typeof(a), a, typeof(b), b FROM t5; } {
integer -9223372036854775808
real 9.22337203685478e+18
}
do_execsql_test alter4-9.3 {
ALTER TABLE t5 ADD COLUMN c INTEGER DEFAULT (-(-9223372036854775808));
SELECT typeof(c), c FROM t5;
} {real 9.22337203685478e+18}
finish_test
+3
View File
@@ -326,6 +326,7 @@ do_execsql_test 6.2 {
reset_db
sqlite3_db_config_lookaside db 0 0 0
database_may_be_corrupt
do_execsql_test 7.1 {
CREATE TABLE t1(a, b);
CREATE INDEX i1 ON t1(a, b);
@@ -366,6 +367,8 @@ do_execsql_test 7.5 {
SELECT * FROM t1 WHERE a = 5;
} {5 5}
database_never_corrupt
#-------------------------------------------------------------------------
#
reset_db
+18
View File
@@ -16,6 +16,7 @@
set testdir [file dirname $argv0]
source $testdir/tester.tcl
set ::testprefix capi3
# Do not use a codec for tests in this file, as the database file is
# manipulated directly using tcl scripts (using the [hexio_write] command).
@@ -1221,6 +1222,23 @@ do_test capi3-19.1 {
sqlite3_prepare_tkt3134 db
} {}
# Test that calling sqlite3_column_blob() on a TEXT value does not change
# the return type of subsequent calls to sqlite3_column_type().
#
do_execsql_test 20.1 {
CREATE TABLE t4(x);
INSERT INTO t4 VALUES('abcdefghij');
}
do_test 20.2 {
set stmt [sqlite3_prepare db "SELECT * FROM t4" -1 dummy]
sqlite3_step $stmt
} {SQLITE_ROW}
do_test 20.3 { sqlite3_column_type $stmt 0 } {TEXT}
do_test 20.4 { sqlite3_column_blob $stmt 0 } {abcdefghij}
do_test 20.5 { sqlite3_column_type $stmt 0 } {TEXT}
do_test 20.6 { sqlite3_finalize $stmt } SQLITE_OK
# Tests of the interface when no VFS is registered.
#
if {![info exists tester_do_binarylog]} {
+1 -1
View File
@@ -76,6 +76,6 @@ do_test 2.1 {
# incorrect answer from a corrupt database file, that is OK. If the
# result below changes, that just means that "undefined behavior" has
# changed.
} {0 52}
} {/0 .*/}
finish_test
+13 -11
View File
@@ -20,6 +20,18 @@ set testprefix corruptH
do_not_use_codec
database_may_be_corrupt
# The corruption migrations tested by the code in this file are not detected
# mmap mode.
#
# The reason is that in mmap mode, the different queries may use different
# PgHdr objects for the same page (same data, but different PgHdr container
# objects). And so the corruption is not detected.
#
if {[permutation]=="mmap"} {
finish_test
return
}
# Initialize the database.
#
do_execsql_test 1.1 {
@@ -52,6 +64,7 @@ do_test 1.2 {
} {}
do_test 1.3 {
breakpoint
db eval { PRAGMA secure_delete=1 }
list [catch {
db eval { SELECT * FROM t1 WHERE a IN (1, 2) } {
@@ -97,9 +110,6 @@ do_test 2.2 {
} {}
# The corruption migration caused by the test case below does not
# cause corruption to be detected in mmap mode.
#
# The trick here is that the root page of the tree scanned by the outer
# query is also currently on the free-list. So while the first seek on
# the table (for a==1) works, by the time the second is attempted The
@@ -109,15 +119,7 @@ do_test 2.2 {
# the cursor (as it is now marked with PgHdr.intKey==0) and returns
# SQLITE_CORRUPT.
#
# However, in mmap mode, the outer query and the inner queries use
# different PgHdr objects (same data, but different PgHdr container
# objects). And so the corruption is not detected. Instead, the second
# seek fails to find anything and only a single row is returned.
#
set res23 {1 {database disk image is malformed}}
if {[permutation]=="mmap"} {
set res23 {0 one}
}
do_test 2.3 {
list [catch {
set res [list]
+52
View File
@@ -0,0 +1,52 @@
# 2014-01-20
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
# May you find forgiveness for yourself and forgive others.
# May you share freely, never taking more than you give.
#
#***********************************************************************
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix corruptI
if {[permutation]=="mmap"} {
finish_test
return
}
# Do not use a codec for tests in this file, as the database file is
# manipulated directly using tcl scripts (using the [hexio_write] command).
#
do_not_use_codec
database_may_be_corrupt
# Initialize the database.
#
do_execsql_test 1.1 {
PRAGMA page_size=1024;
PRAGMA auto_vacuum=0;
CREATE TABLE t1(a);
CREATE INDEX i1 ON t1(a);
INSERT INTO t1 VALUES('a');
} {}
db close
do_test 1.2 {
set offset [hexio_get_int [hexio_read test.db [expr 2*1024 + 8] 2]]
set off [expr 2*1024 + $offset + 1]
hexio_write test.db $off FF06
breakpoint
sqlite3 db test.db
catchsql { SELECT * FROM t1 WHERE a = 10 }
} {1 {database disk image is malformed}}
finish_test
+28
View File
@@ -219,4 +219,32 @@ do_execsql_test 5.2 {
SELECT count(*) FROM sqlite_master WHERE name LIKE 't8%';
} {0 6}
# At one point this was causing a memory leak.
#
foreach {tn sql} {
1 {}
2 { INSERT INTO ft(ft) VALUES('merge=2,2'); }
} {
reset_db
do_execsql_test 6.$tn.1 "
CREATE TABLE t1(x);
CREATE VIRTUAL TABLE ft USING fts3;
INSERT INTO ft VALUES('hello world');
$sql
"
db close
sqlite3 db test.db
do_execsql_test 6.$tn.2 { SELECT * FROM t1 } {}
do_test 6.$tn.3 {
sqlite3 db2 test.db
db2 eval { DROP TABLE t1 }
db2 close
set stmt [sqlite3_prepare db { SELECT * FROM ft } -1 dummy]
sqlite3_finalize $stmt
} {SQLITE_OK}
db close
}
finish_test
+11
View File
@@ -354,6 +354,17 @@ do_test fts3d-6.5 {
SELECT name FROM sqlite_master WHERE name GLOB '???_*' ORDER BY 1;
}
} {xyz_content xyz_segdir xyz_segments}
# ALTER TABLE RENAME on an FTS3 table following an incr-merge op.
#
do_test fts3d-6.6 {
execsql { INSERT INTO xyz(xyz) VALUES('merge=2,2') }
sqlite3 db test.db
execsql {
ALTER TABLE xyz RENAME TO ott;
SELECT name FROM sqlite_master WHERE name GLOB '???_*' ORDER BY 1;
}
} {ott_content ott_segdir ott_segments ott_stat}
finish_test
+5
View File
@@ -1361,4 +1361,9 @@ for {set i 65536} {$i<=0x10ffff} {incr i 139} {
do_execsql_test func-30.5.$i {SELECT unicode(char($i))} $i
}
# Test char().
#
do_execsql_test func-31.1 {
SELECT char(), length(char()), typeof(char())
} {{} 0 text}
finish_test
+35
View File
@@ -641,4 +641,39 @@ do_test join-11.10 {
execsql { SELECT * FROM t2 NATURAL JOIN t1 }
} {1 one 2 two}
#-------------------------------------------------------------------------
# Test that at most 64 tables are allowed in a join.
#
do_execsql_test join-12.1 {
CREATE TABLE t14(x);
INSERT INTO t14 VALUES('abcdefghij');
}
proc jointest {tn nTbl res} {
set sql "SELECT 1 FROM [string repeat t14, [expr $nTbl-1]] t14;"
uplevel [list do_catchsql_test $tn $sql $res]
}
jointest join-12.2 30 {0 1}
jointest join-12.3 63 {0 1}
jointest join-12.4 64 {0 1}
jointest join-12.5 65 {1 {at most 64 tables in a join}}
jointest join-12.6 66 {1 {at most 64 tables in a join}}
jointest join-12.7 127 {1 {at most 64 tables in a join}}
jointest join-12.8 128 {1 {at most 64 tables in a join}}
jointest join-12.9 1000 {1 {at most 64 tables in a join}}
# If SQLite is built with SQLITE_MEMDEBUG, then the huge number of realloc()
# calls made by the following test cases are too time consuming to run.
# Without SQLITE_MEMDEBUG, realloc() is fast enough that these are not
# a problem.
ifcapable pragma&&compileoption_diags {
if {[lsearch [db eval {PRAGMA compile_options}] MEMDEBUG]<0} {
jointest join-12.10 65534 {1 {at most 64 tables in a join}}
jointest join-12.11 65535 {1 {too many references to "t14": max 65535}}
jointest join-12.12 65536 {1 {too many references to "t14": max 65535}}
jointest join-12.13 65537 {1 {too many references to "t14": max 65535}}
}
}
finish_test
+17 -4
View File
@@ -66,6 +66,12 @@ if {$::tcl_platform(os) eq "Darwin"} {
set dlerror_nosymbol {dlsym(XXX, %2$s): symbol not found}
}
if {$::tcl_platform(platform) eq "windows"} {
set dlerror_nosuchfile {The specified module could not be found.*}
set dlerror_notadll {%%1 is not a valid Win32 application.*}
set dlerror_nosymbol {The specified procedure could not be found.*}
}
# Make sure the test extension actually exists. If it does not
# exist, try to create it. If unable to create it, then skip this
# test file.
@@ -167,7 +173,7 @@ do_test loadext-2.3 {
regsub {0x[1234567890abcdefABCDEF]*} $msg XXX msg
}
list $rc $msg
} [list 1 [format $dlerror_nosymbol $testextension icecream]]
} /[list 1 [format $dlerror_nosymbol $testextension icecream]]/
# Try to load an extension for which the entry point fails (returns non-zero)
#
@@ -267,10 +273,17 @@ do_malloc_test loadext-5 -tclprep {
} -tclbody {
if {[autoinstall_test_functions]==7} {error "out of memory"}
}
do_malloc_test loadext-6 -tclbody {
db enable_load_extension 1
sqlite3_load_extension db $::testextension testloadext_init
# On Windows, this malloc test must be skipped because the winDlOpen
# function itself can fail due to "out of memory" conditions.
#
if {$::tcl_platform(platform) ne "windows"} {
do_malloc_test loadext-6 -tclbody {
db enable_load_extension 1
sqlite3_load_extension db $::testextension testloadext_init
}
}
autoinstall_test_functions
finish_test
+13 -5
View File
@@ -1575,6 +1575,8 @@ do_test pragma-20.8 {
forcedelete data_dir
} ;# endif windows
database_may_be_corrupt
do_test 21.1 {
# Create a corrupt database in testerr.db. And a non-corrupt at test.db.
#
@@ -1600,11 +1602,16 @@ Multiple uses for byte 672 of page 15}
set auxerr {*** in database aux ***
Multiple uses for byte 672 of page 15}
set mainerr {/{\*\*\* in database main \*\*\*
Multiple uses for byte 672 of page 15}.*/}
set auxerr {/{\*\*\* in database aux \*\*\*
Multiple uses for byte 672 of page 15}.*/}
do_test 22.2 {
catch { db close }
sqlite3 db testerr.db
execsql { PRAGMA integrity_check }
} [list $mainerr]
} $mainerr
do_test 22.3.1 {
catch { db close }
@@ -1613,13 +1620,13 @@ do_test 22.3.1 {
ATTACH 'testerr.db' AS 'aux';
PRAGMA integrity_check;
}
} [list $auxerr]
} $auxerr
do_test 22.3.2 {
execsql { PRAGMA main.integrity_check; }
} {ok}
do_test 22.3.3 {
execsql { PRAGMA aux.integrity_check; }
} [list $auxerr]
} $auxerr
do_test 22.4.1 {
catch { db close }
@@ -1628,10 +1635,10 @@ do_test 22.4.1 {
ATTACH 'test.db' AS 'aux';
PRAGMA integrity_check;
}
} [list $mainerr]
} $mainerr
do_test 22.4.2 {
execsql { PRAGMA main.integrity_check; }
} [list $mainerr]
} $mainerr
do_test 22.4.3 {
execsql { PRAGMA aux.integrity_check; }
} {ok}
@@ -1680,4 +1687,5 @@ do_test 23.5 {
}
} {0 0 t1 y {} {NO ACTION} {NO ACTION} NONE}
database_never_corrupt
finish_test
+36
View File
@@ -824,4 +824,40 @@ do_test select4-13.1 {
}
} {1 2}
# 2014-02-18: Make sure compound SELECTs work with VALUES clauses
#
do_execsql_test select4-14.1 {
CREATE TABLE t14(a,b,c);
INSERT INTO t14 VALUES(1,2,3),(4,5,6);
SELECT * FROM t14 INTERSECT VALUES(3,2,1),(2,3,1),(1,2,3),(2,1,3);
} {1 2 3}
do_execsql_test select4-14.2 {
SELECT * FROM t14 INTERSECT VALUES(1,2,3);
} {1 2 3}
do_execsql_test select4-14.3 {
SELECT * FROM t14
UNION VALUES(3,2,1),(2,3,1),(1,2,3),(7,8,9),(4,5,6)
UNION SELECT * FROM t14 ORDER BY 1, 2, 3
} {1 2 3 2 3 1 3 2 1 4 5 6 7 8 9}
do_execsql_test select4-14.4 {
SELECT * FROM t14
UNION VALUES(3,2,1)
UNION SELECT * FROM t14 ORDER BY 1, 2, 3
} {1 2 3 3 2 1 4 5 6}
do_execsql_test select4-14.5 {
SELECT * FROM t14 EXCEPT VALUES(3,2,1),(2,3,1),(1,2,3),(2,1,3);
} {4 5 6}
do_execsql_test select4-14.6 {
SELECT * FROM t14 EXCEPT VALUES(1,2,3)
} {4 5 6}
do_execsql_test select4-14.7 {
SELECT * FROM t14 EXCEPT VALUES(1,2,3) EXCEPT VALUES(4,5,6)
} {}
do_execsql_test select4-14.8 {
SELECT * FROM t14 EXCEPT VALUES('a','b','c') EXCEPT VALUES(4,5,6)
} {1 2 3}
do_execsql_test select4-14.9 {
SELECT * FROM t14 UNION ALL VALUES(3,2,1),(2,3,1),(1,2,3),(2,1,3);
} {1 2 3 4 5 6 3 2 1 2 3 1 1 2 3 2 1 3}
finish_test
+49
View File
@@ -0,0 +1,49 @@
# 2014-03-03
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
# May you find forgiveness for yourself and forgive others.
# May you share freely, never taking more than you give.
#
#***********************************************************************
#
# This file verifies that an OP_Copy operation is used instead of OP_SCopy
# in a compound select in a case where the source register might be changed
# before the copy is used.
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix selectF
do_execsql_test 1 {
BEGIN TRANSACTION;
CREATE TABLE t1(a, b, c);
INSERT INTO "t1" VALUES(1,'one','I');
CREATE TABLE t2(d, e, f);
INSERT INTO "t2" VALUES(5,'ten','XX');
INSERT INTO "t2" VALUES(6,NULL,NULL);
CREATE INDEX i1 ON t1(b, a);
COMMIT;
}
#explain_i {
# SELECT * FROM t2
# UNION ALL
# SELECT * FROM t1 WHERE a<5
# ORDER BY 2, 1
#}
do_execsql_test 2 {
SELECT * FROM t2
UNION ALL
SELECT * FROM t1 WHERE a<5
ORDER BY 2, 1
} {6 {} {} 1 one I 5 ten XX}
finish_test
+19
View File
@@ -285,6 +285,25 @@ do_test shell5-1.10 {
db eval {SELECT hex(c) FROM t1 ORDER BY rowid}
} {636F6C756D6E33 783320220D0A64617461222033 783320220A64617461222033}
# Blank last column with \r\n line endings.
do_test shell5-1.11 {
set out [open shell5.csv w]
fconfigure $out -translation binary
puts $out "column1,column2,column3\r"
puts $out "a,b, \r"
puts $out "x,y,\r"
puts $out "p,q,r\r"
close $out
catch {db close}
forcedelete test.db
catchcmd test.db {.mode csv
.import shell5.csv t1
}
sqlite3 db test.db
db eval {SELECT *, '|' FROM t1}
} {a b { } | x y {} | p q r |}
db close
finish_test
+38
View File
@@ -209,4 +209,42 @@ do_execsql_test skipscan1-4.1 {
SELECT i FROM t4 WHERE h=8;
} {9 9 9 9 9 9 9 9}
# Make sure skip-scan cost computation in the query planner takes into
# account the fact that the seek must occur multiple times.
#
# Prior to 2014-03-10, the costs were computed incorrectly which would
# cause index t5i2 to be used instead of t5i1 on the skipscan1-5.3.
#
do_execsql_test skipscan1-5.1 {
CREATE TABLE t5(
id INTEGER PRIMARY KEY,
loc TEXT,
lang INTEGER,
utype INTEGER,
xa INTEGER,
xd INTEGER,
xh INTEGER
);
CREATE INDEX t5i1 on t5(loc, xh, xa, utype, lang);
CREATE INDEX t5i2 ON t5(xd,loc,utype,lang);
EXPLAIN QUERY PLAN
SELECT xh, loc FROM t5 WHERE loc >= 'M' AND loc < 'N';
} {/.*COVERING INDEX t5i1 .*/}
do_execsql_test skipscan1-5.2 {
ANALYZE;
DELETE FROM sqlite_stat1;
DROP TABLE IF EXISTS sqlite_stat4;
DROP TABLE IF EXISTS sqlite_stat3;
INSERT INTO sqlite_stat1 VALUES('t5','t5i1','2702931 3 2 2 2 2');
INSERT INTO sqlite_stat1 VALUES('t5','t5i2','2702931 686 2 2 2');
ANALYZE sqlite_master;
} {}
db cache flush
do_execsql_test skipscan1-5.3 {
EXPLAIN QUERY PLAN
SELECT xh, loc FROM t5 WHERE loc >= 'M' AND loc < 'N';
} {/.*COVERING INDEX t5i1 .*/}
finish_test
+1
View File
@@ -61,6 +61,7 @@ foreach s {
fcntl read pread write pwrite fchmod fallocate
pread64 pwrite64 unlink openDirectory mkdir rmdir
statvfs fchown umask mmap munmap mremap
getpagesize
} {
if {[test_syscall exists $s]} {lappend syscall_list $s}
}
+11 -4
View File
@@ -1062,10 +1062,17 @@ proc explain_i {sql {db db}} {
# Blue: Opcodes that reposition or seek a cursor.
# Green: The ResultRow opcode.
#
set R "\033\[31;1m" ;# Red fg
set G "\033\[32;1m" ;# Green fg
set B "\033\[34;1m" ;# Red fg
set D "\033\[39;0m" ;# Default fg
if { [catch {fconfigure stdout -mode}]==0 } {
set R "\033\[31;1m" ;# Red fg
set G "\033\[32;1m" ;# Green fg
set B "\033\[34;1m" ;# Red fg
set D "\033\[39;0m" ;# Default fg
} else {
set R ""
set G ""
set B ""
set D ""
}
foreach opcode {
Seek SeekGe SeekGt SeekLe SeekLt NotFound Last Rewind
NoConflict Next Prev VNext VPrev VFilter
+68
View File
@@ -0,0 +1,68 @@
# 2014-03-04
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
# May you find forgiveness for yourself and forgive others.
# May you share freely, never taking more than you give.
#
#***********************************************************************
#
# This file implements tests to verify that ticket [4ef7e3cfca] has been
# fixed.
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix tkt-4ef7e3cfca
do_catchsql_test 1.1 {
CREATE TABLE x(a);
CREATE TRIGGER t AFTER INSERT ON x BEGIN
SELECT * FROM x WHERE abc.a = 1;
END;
INSERT INTO x VALUES('assert');
} {1 {no such column: abc.a}}
reset_db
do_execsql_test 2.1 {
CREATE TABLE w(a);
CREATE TABLE x(a);
CREATE TABLE y(a);
CREATE TABLE z(a);
INSERT INTO x(a) VALUES(5);
INSERT INTO y(a) VALUES(10);
CREATE TRIGGER t AFTER INSERT ON w BEGIN
INSERT INTO z
SELECT (SELECT x.a + y.a FROM y) FROM x;
END;
INSERT INTO w VALUES('incorrect');
}
do_execsql_test 2.2 {
SELECT * FROM z;
} {15}
reset_db
do_execsql_test 3.1 {
CREATE TABLE w(a);
CREATE TABLE x(b);
CREATE TABLE y(a);
CREATE TABLE z(a);
INSERT INTO x(b) VALUES(5);
INSERT INTO y(a) VALUES(10);
CREATE TRIGGER t AFTER INSERT ON w BEGIN
INSERT INTO z
SELECT (SELECT x.b + y.a FROM y) FROM x;
END;
INSERT INTO w VALUES('assert');
}
do_execsql_test 3.2 {
SELECT * FROM z;
} {15}
finish_test
+48
View File
@@ -0,0 +1,48 @@
# 2014-02-25
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
# May you find forgiveness for yourself and forgive others.
# May you share freely, never taking more than you give.
#
#***********************************************************************
#
# Test cases to show that ticket [8c63ff0eca81a9132d8d67b31cd6ae9712a2cc6f]
# "Incorrect query result on a UNION ALL" which was caused by using the same
# temporary register in concurrent co-routines, as been fixed.
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
set ::testprefix tkt-8c63ff0ec
do_execsql_test 1.1 {
CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c, d, e);
INSERT INTO t1 VALUES(1,20,30,40,50),(3,60,70,80,90);
CREATE TABLE t2(x INTEGER PRIMARY KEY);
INSERT INTO t2 VALUES(2);
CREATE TABLE t3(z);
INSERT INTO t3 VALUES(2),(2),(2),(2);
SELECT a, b+c FROM t1
UNION ALL
SELECT x, 5 FROM t2 JOIN t3 ON z=x WHERE x=2
ORDER BY a;
} {1 50 2 5 2 5 2 5 2 5 3 130}
do_execsql_test 1.2 {
SELECT a, b+c+d FROM t1
UNION ALL
SELECT x, 5 FROM t2 JOIN t3 ON z=x WHERE x=2
ORDER BY a;
} {1 90 2 5 2 5 2 5 2 5 3 210}
do_execsql_test 1.3 {
SELECT a, b+c+d+e FROM t1
UNION ALL
SELECT x, 5 FROM t2 JOIN t3 ON z=x WHERE x=2
ORDER BY a;
} {1 140 2 5 2 5 2 5 2 5 3 300}
finish_test
+2
View File
@@ -238,12 +238,14 @@ ifcapable wal {
tvfs1 script tvfs1_callback
proc tvfs1_callback {method filename args} {
set ::T1([file tail $filename]) 1
return SQLITE_OK
}
testvfs tvfs2
tvfs2 filter {xOpen xDelete xAccess xFullPathname}
tvfs2 script tvfs2_callback
proc tvfs2_callback {method filename args} {
set ::T2([file tail $filename]) 1
return SQLITE_OK
}
catch {db close}
+13
View File
@@ -611,4 +611,17 @@ ifcapable progress {
} {1 interrupted}
}
db close
sqlite3 db :memory:
do_execsql_test view-22.1 {
CREATE VIEW x1 AS SELECT 123 AS '', 234 AS '', 345 AS '';
SELECT * FROM x1;
} {123 234 345}
do_test view-22.2 {
unset -nocomplain x
db eval {SELECT * FROM x1} x break
lsort [array names x]
} {{} * :1 :2}
finish_test
+47
View File
@@ -15,6 +15,7 @@
set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix vtab_shared
ifcapable !vtab||!shared_cache {
finish_test
@@ -228,5 +229,51 @@ do_test vtab_shared_1.15.3 {
db close
db2 close
#---------------------------------------------------------------
# Test calling sqlite3_close() with vtabs on the disconnect list.
#
ifcapable rtree {
reset_db
do_test 2.1.1 {
sqlite3 db test.db
sqlite3 db2 test.db
# Create a virtual table using [db].
execsql {
CREATE VIRTUAL TABLE rt USING rtree(id, x1, x2);
INSERT INTO rt VALUES(1, 2 ,3);
SELECT * FROM rt;
}
# Drop the virtual table using [db2]. The sqlite3_vtab object belonging
# to [db] is moved to the sqlite3.pDisconnect list.
execsql { DROP TABLE rt } db2
# Immediately close [db]. At one point this would fail due to the
# unfinalized statements held by the un-xDisconnect()ed sqlite3_vtab.
db close
} {}
db2 close
}
ifcapable fts3 {
# Same test as above, except using fts3 instead of rtree.
reset_db
do_test 2.2.1 {
sqlite3 db test.db
sqlite3 db2 test.db
execsql {
CREATE VIRTUAL TABLE ft USING fts3;
INSERT INTO ft VALUES('hello world');
SELECT * FROM ft;
}
execsql { DROP TABLE ft } db2
db close
} {}
db2 close
}
sqlite3_enable_shared_cache 0
finish_test
+47
View File
@@ -0,0 +1,47 @@
# 2010 April 13
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
# May you find forgiveness for yourself and forgive others.
# May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library. The
# focus of this file is testing the operation of the library in
# "PRAGMA journal_mode=WAL" mode.
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix wal64k
ifcapable !wal {finish_test ; return }
db close
test_syscall pagesize 65536
sqlite3 db test.db
do_execsql_test 1.0 {
PRAGMA journal_mode = WAL;
CREATE TABLE t1(x);
CREATE INDEX i1 ON t1(x);
} {wal}
do_test 1.1 { file size test.db-shm } {65536}
do_test 1.2 {
execsql BEGIN
while {[file size test.db-shm]==65536} {
execsql { INSERT INTO t1 VALUES( randstr(900,1100) ) }
}
execsql COMMIT
file size test.db-shm
} {131072}
integrity_check 1.3
db close
test_syscall pagesize -1
finish_test
+8 -6
View File
@@ -32,9 +32,6 @@ ifcapable !wal {
}
do_multiclient_test tn {
# Do not run tests with the connections in the same process.
#
if {$tn==2} continue
# Close all connections and delete the database.
#
@@ -43,6 +40,10 @@ do_multiclient_test tn {
code3 { db3 close }
forcedelete test.db
forcedelete walro
# Do not run tests with the connections in the same process.
#
if {$tn==2} continue
foreach c {code1 code2 code3} {
$c {
@@ -232,9 +233,6 @@ forcedelete test.db
# database file while a checkpoint operation is ongoing.
#
do_multiclient_test tn {
# Do not run tests with the connections in the same process.
#
if {$tn==2} continue
# Close all connections and delete the database.
#
@@ -243,6 +241,10 @@ do_multiclient_test tn {
code3 { db3 close }
forcedelete test.db
forcedelete walro
# Do not run tests with the connections in the same process.
#
if {$tn==2} continue
foreach c {code1 code2 code3} {
$c {
+36
View File
@@ -121,6 +121,42 @@ do_test where2-2.3 {
}
} {85 6 7396 7402 nosort t1 *}
# Ticket [65bdeb9739605cc22966f49208452996ff29a640] 2014-02-26
# Make sure "ORDER BY random" does not gets optimized out.
#
do_test where2-2.4 {
db eval {
CREATE TABLE x1(a INTEGER PRIMARY KEY, b DEFAULT 1);
WITH RECURSIVE
cnt(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM cnt WHERE x<50)
INSERT INTO x1 SELECT x, 1 FROM cnt;
CREATE TABLE x2(x INTEGER PRIMARY KEY);
INSERT INTO x2 VALUES(1);
}
set sql {SELECT * FROM x1, x2 WHERE x=1 ORDER BY random()}
set out1 [db eval $sql]
set out2 [db eval $sql]
set out3 [db eval $sql]
expr {$out1!=$out2 && $out2!=$out3}
} {1}
do_execsql_test where2-2.5 {
-- random() is not optimized out
EXPLAIN SELECT * FROM x1, x2 WHERE x=1 ORDER BY random();
} {/ random/}
do_execsql_test where2-2.5b {
-- random() is not optimized out
EXPLAIN SELECT * FROM x1, x2 WHERE x=1 ORDER BY random();
} {/ SorterOpen /}
do_execsql_test where2-2.6 {
-- other constant functions are optimized out
EXPLAIN SELECT * FROM x1, x2 WHERE x=1 ORDER BY abs(5);
} {~/ abs/}
do_execsql_test where2-2.6b {
-- other constant functions are optimized out
EXPLAIN SELECT * FROM x1, x2 WHERE x=1 ORDER BY abs(5);
} {~/ SorterOpen /}
# Efficient handling of forward and reverse table scans.
#
-2
View File
@@ -121,7 +121,6 @@ foreach hdr {
set available_hdr($hdr) 1
}
set available_hdr(sqliteInt.h) 0
set available_hdr(sqlite3.h) 0
# 78 stars used for comment formatting.
set s78 \
@@ -229,7 +228,6 @@ proc copy_file {filename} {
# inlining opportunities.
#
foreach file {
sqlite3.h
sqliteInt.h
global.c