Compare commits

...

90 Commits

Author SHA1 Message Date
mistachkin f1dacbfc5b Manually define the Win32 file-mapping APIs for WAL if SQLITE_WIN32_FILEMAPPING_API is defined.
FossilOrigin-Name: 585e2070eef3bc273f23d8e384a1261ee5fff5bd
2012-10-07 00:52:22 +00:00
mistachkin 08c1c3150b Changes for WinRT compatibility. Also, allow version resource compilation and embedding to be disabled at compile-time.
FossilOrigin-Name: 4b0facc13b1026419f9b89dab3453ba43071455c
2012-10-06 03:48:25 +00:00
dan 6b9bb59f82 Fix a problem in shared-cache mode where a COMMIT statement might cause a busy-handler belonging to a shared-cache connection other than the current writer to be invoked.
FossilOrigin-Name: e0c889d66ccf4af12cc77ac38c1e6477da63ac72
2012-10-05 19:43:02 +00:00
dan aedf9ee73a Merge the shared-cache related fixes from the shared-cache-fix branch to the trunk.
FossilOrigin-Name: 698ec7769d4feea1782401479c61ce67d2113fd4
2012-10-05 17:44:51 +00:00
dan a2ebe4b418 Add a test for the collation-sequence/CHECK constraint problem fixed by the previous commit.
FossilOrigin-Name: 82b6aa77c8d8de4c6fad1960f5958457a929a821
2012-10-05 17:18:16 +00:00
dan 1e92fb59b2 Fix a problem with shared-cache mode and CHECK constraints causing one db handle to invoke a collation sequence function registered with another.
FossilOrigin-Name: c2c776ab73828374836af008aa320cc670c081b5
2012-10-05 16:30:10 +00:00
drh 79e72a50aa Consolidate all occurrences of the "no such collation sequence" error message
into a single spot.

FossilOrigin-Name: 8ea67522fb03134f355ecb776b70c6917241cab2
2012-10-05 14:43:40 +00:00
mistachkin d744fccdbd Rename a tool batch file subroutine to avoid confusion about its purpose.
FossilOrigin-Name: 43155b1543bddbb84a8bc13a5b7344b228ddacb9
2012-10-05 07:36:34 +00:00
dan 41fb5cd103 Shared-cache mode fixes for views and virtual tables.
FossilOrigin-Name: 2b370dea704b59262c604af0efcef5660b194454
2012-10-04 19:33:00 +00:00
drh 613a53a029 Fix an out-of-order memset() that occurs before all variable declarations
are finished.  Also fix a line that exceeds the 80-character line length
limit.

FossilOrigin-Name: ba2f492f957ab5556cd540e21a76ebb75efea725
2012-10-03 18:09:32 +00:00
drh 325eff58d6 Update the query planner to recognize more cases where ORDER BY clauses
can be optimized out.  Add test cases to verify correct behavior of the
ORDER BY optimization when the covering-index-scan optimization is disabled.
Fix a harmless compiler warning in the TCL interface.

FossilOrigin-Name: 956e4d7f8958e7065ff2d61cd71519d6f4113d4a
2012-10-03 12:56:18 +00:00
drh 6f0e400cba Fix a query planner problem that only occurs when covering-index-scan is
disabled.  Fix to tests whose output changed due to the new and more
aggressive ORDER BY optimization.

FossilOrigin-Name: 0f9bb90100aa304a7f28023ca4173e68b445e8bd
2012-10-03 12:38:19 +00:00
drh c45e67162d Fix the TCL interface so that SQL functions implemented in TCL honor the
"nullvalue" setting.  Also remove from the TCL interface some unused 
legacy UTF8 translation code left over from SQLite2.

FossilOrigin-Name: c1f10a2643179ec58f3879764e9e89676d4b5f91
2012-10-03 11:02:33 +00:00
drh d663b5bdef Further attempts to optimize out unnecessary ORDER BY clauses.
FossilOrigin-Name: 6744d9a37faffed59b4d5cb96c8671ec46a87ea7
2012-10-03 00:25:54 +00:00
mistachkin e7c54168fa Work around an optimization issue with the MSVC compiler for ARM.
FossilOrigin-Name: 7d301fdfeec540e4a58f43bff04d219e9f769dc4
2012-10-02 22:54:27 +00:00
drh afcd522af8 More lenient handling of ORDER BY optimization in joins with mixed ASC/DESC.
This is a better and less restrictive fix for the problem addressed by
the previous check-in.

FossilOrigin-Name: abcf6a5d054559ee5a093ba39180c47b4958d9cd
2012-10-02 15:19:19 +00:00
drh 178eb61c6b Only continue an ORDER BY optimization into inner loops if the equality
constraints on the inner loop match terms of an outer ordered index that
are actually used by the ORDER BY clause.

FossilOrigin-Name: b0e7b4df6c2a8c479f8d210bde50c737eaa248f0
2012-10-02 14:11:29 +00:00
drh 3be57d2aba Factor an invariant out the loop termination condition for the ORDER BY
satisfied-by-index analyzer routine.

FossilOrigin-Name: 545bb33688663066cf3f09e4cdc4d5cfe59fb8db
2012-10-02 01:46:48 +00:00
drh a578d048c6 Make sure the outer loop cursor numbers are recorded in time for them to be
used by the ORDER BY optimizer.

FossilOrigin-Name: 351dc8d9cab8a222f28fb865d3a7d1c622d60d6f
2012-10-02 01:25:16 +00:00
drh 1afcaaea7a Improvements to the wheretrace output.
FossilOrigin-Name: 76b277655646a9fe0f336ff106157f1efcd32019
2012-10-02 01:10:00 +00:00
drh 5ff00f4b00 Fix harmless compiler warnings.
FossilOrigin-Name: 59c2be75ff8b8ccd77320b45e4088e5bf456a1d9
2012-10-01 20:32:38 +00:00
mistachkin c197eedbb4 Fix several compiler warnings seen with MSVC.
FossilOrigin-Name: 8b5f617c2a5f0bf7bdbd9144aee58d69564db1e2
2012-10-01 20:12:30 +00:00
dan 80bb6f8217 Add SQLITE_FCNTL_BUSYHANDLER. Invoked to provide access to the busy-handler callback to custom VFS implementations.
FossilOrigin-Name: 1262d2f471214a3417dd02159a7aa2355b18f789
2012-10-01 18:44:33 +00:00
drh 04b85bc609 Minor changes to the query planner for improved test coverage.
FossilOrigin-Name: c12044df322283c9deb0d7dacd8a699ac53f27b6
2012-10-01 17:44:05 +00:00
drh a1f3853793 Omit the sqlite3GetReservedNoMutex() routine in build configurations where
it is not used.

FossilOrigin-Name: f193dbb6b96b2f49dd0d6345802c9c006cd99e3c
2012-10-01 12:44:26 +00:00
drh c1fd2cfed2 Make sure the size parameter to read and write VFS methods in the unix VFS
do not become too big or go negative.  This was not actually possible in the
current code.  The checks are added to make sure some future bug does not
make it possible.

FossilOrigin-Name: daebe3bd2d9bd7b6f876a8110cf5045eb3fee078
2012-10-01 12:16:26 +00:00
dan c9a5326974 Ensure that the value returned by xSectorSize() is reasonable (currently defined as between 2^5 and 2^16 bytes) before using it to calculate the amount of padding to add to a wal file.
FossilOrigin-Name: 6b4ff83bff07d427af585c9fd03be90abf2fc82f
2012-10-01 06:50:55 +00:00
drh 60441af4f2 Improved ORDER BY optimization when outer loops of a join return a single row.
FossilOrigin-Name: 62225b4a4c4bfe1820ef54cb202edf2cd866429f
2012-09-29 19:10:29 +00:00
drh befda46598 Disable the bigfile tests on Macs.
FossilOrigin-Name: d869eddaf208c4bf03f6bd1848f510392f9dba49
2012-09-29 15:45:12 +00:00
drh b3f787f4c7 Fix compiler warnings found on Lion.
FossilOrigin-Name: fd74d3d91721ca404537f195fed04c9edef20bf2
2012-09-29 14:45:54 +00:00
dan 0094f37e1f Avoid calling sqlite3BtreeEnter() in a corner case where the corresponding database handle mutex (sqlite3.mutex) may not be held. This prevents a potential deadlock or crash that can occur if the backup API, shared-cache mode and SQLITE_HAVE_CODEC are all in use.
FossilOrigin-Name: 89b8c377a6f03d9fa885f3f94c1f0b1eec263dea
2012-09-28 20:23:42 +00:00
mistachkin 70a1b71fb6 Modify the clearCell function to use SQLITE_CORRUPT_BKPT in the one place it was not.
FossilOrigin-Name: 472beb306a4fa7103837d4417aef7d66eef49993
2012-09-28 18:13:35 +00:00
drh f784c1ede9 Query planner enhancements to be more agressive about optimizing out ORDER BY
clauses - in particular the query planner now has the ability to omit ORDER BY
clauses that span multiple tables in a join.

FossilOrigin-Name: 1e874629d7cf568368b912b295bd3001147d0b52
2012-09-28 00:44:28 +00:00
drh a9e3fc05f5 Fix some corner case behavior in the new ORDER BY optimization logic.
Remove the SQLITE_OrderByIdx bit from the 
SQLITE_TESTCTRL_OPTIMIZATIONS mask, since enabling it caused many
TH3 tests to fail when the NO_OPT configuration parameter was engaged,
and since there really isn't any need to turn that optimization off.
The SQLITE_OrderByIdxJoin bit remains.

FossilOrigin-Name: 98b633717a1c9a08f6a1d00bc6bc891564ae7e9b
2012-09-27 23:27:23 +00:00
mistachkin 8ccc6d4076 Modify generation of resource header file for MSVC so that it can work from outside the working directory.
FossilOrigin-Name: 20caf80cb3b65e69a99dbc142db8ee435fb2dbdc
2012-09-27 21:03:53 +00:00
drh 5343b2d4a8 More test cases an bug fixes for the ORDER BY optimization of joins. All
veryquick tests now pass.

FossilOrigin-Name: 0d573320057b0903a5589cabfb1b1ece1c57958e
2012-09-27 19:53:38 +00:00
drh 6b10a6a7ed Test cases and bug fixes applied to the ORDER BY optimization for joins.
Some test cases fail, but except for the new orderby1.test failures, all
failures appear to be issues with the tests, not with the core code.

FossilOrigin-Name: 75cda864ededb6dc0f84bd52ed3311753a58e351
2012-09-27 17:31:32 +00:00
drh 7e5418e4a4 Add more bits to the bit vector that is used to disable optimizations for
built-in test.  Add specific bit patterns to disable ORDER BY using an
index in general and for joins.  Use macros to test for bits in the 
disabled-optimization bit vector, in order to make the code clearer.

FossilOrigin-Name: d2fcba1e143beca8c45724d2108870657c269e17
2012-09-27 15:05:54 +00:00
drh 32634d270c Enable ORDER BY clauses that span joins to be optimized out.
FossilOrigin-Name: c29538f9b1ee4d4869999570604c9618ca0d08ac
2012-09-27 14:11:36 +00:00
drh cec320fb0e Merge the "PRAGMA busy_timeout" change into trunk.
FossilOrigin-Name: 1a679a1ef3b4f2d898c8cd83432d2b4c12bd93fa
2012-09-27 12:11:25 +00:00
drh ff2d52117b Further tweaks to the query planner logic in preparation for adding
ORDER BY opt-out for joins.

FossilOrigin-Name: 53efc10af990d3f293551f3cd8ef2f8be2d9d716
2012-09-27 12:05:09 +00:00
drh 46c35f9b20 Further refactoring of the ORDER BY related query-planning logic in order
to make it easier to extend to support optimizing out ORDER BY on joins.
No actual behavior changes, yet.

FossilOrigin-Name: 96496ddae12a239b30a1fc997fbea43e3a75bfe7
2012-09-26 23:17:01 +00:00
drh 9cd1c99fe1 Augment the WhereBestIdx structure to pass down into the query planner
information that might be used to better detect ORDER BY and DISTINCT
optimizations spanning multiple tables of a join.

FossilOrigin-Name: 4226e51ff837f0ffe16355491a655d919d13488e
2012-09-25 20:43:35 +00:00
drh 56f1b99d4d Pass information around between the major routines of the query planner
using a single pointer to a structure rather than a long list of parameters.

FossilOrigin-Name: 1104d42e104d561ce60d05d158acfe499ee9fd50
2012-09-25 14:29:39 +00:00
drh 4d85fa760f Remove an unused subfunction parameter and an obsolete comment from the
query planner logic in where.c.

FossilOrigin-Name: 349a55cd8ba9ce65ebfd987ecfebd1204f7d0a85
2012-09-24 19:50:00 +00:00
drh 46ec5b63e2 Change the internal sqlite3WhereBegin() to report that the ORDER BY clause
is satisfied by indices using the WhereInfo.nOBSat field of the returned
structure.

FossilOrigin-Name: 22989f3588531efd555cc29d6c576e7a34b7edc4
2012-09-24 15:30:54 +00:00
drh 86ae51c991 Update documentation to describe the threadsafety of
sqlite3_enable_shared_cache().

FossilOrigin-Name: e081890cd77ad8de4bf55a8f8cf9d63bfaaf8218
2012-09-24 11:43:43 +00:00
drh cef4fc89c4 Enable query planner tracing using the new (and undocumented) ".wheretrace 1"
command in the command-line shell if both the shell and the core are
compiled with SQLITE_DEBUG and SQLITE_ENABLE_WHERETRACE.  This is not a 
supported API. Use for testing and debugging only.

FossilOrigin-Name: 1be4b16b9e900181ae6848f2920ea646f407c9dc
2012-09-21 22:50:45 +00:00
drh 078b1fda34 Command-line shell enhancements: Added the ".print" command. Enhanced
the ".width" command so that negative widths will right-justify.

FossilOrigin-Name: a1d8269da3868e41a6603c1a683e324fe21fb317
2012-09-21 13:40:02 +00:00
drh e8e4af7697 Consolidate more of the DISTINCT processing logic into a single spot in the
code.  Reduce the number of OP_Column operations needed to perform a
WHERE_DISTINCT_ORDERED.

FossilOrigin-Name: 79e922f7ae29bbe06d639d648fbd72523cf9a28e
2012-09-21 00:04:28 +00:00
drh 634d81dee0 Continuing incremental enhancements of SELECT code generation:
Remove the Select.affinity field.  Use SelectDest.affSdst instead.

FossilOrigin-Name: cf40b7b5ebdacc3215d769aadacce8c9e7e9dfbb
2012-09-20 15:41:31 +00:00
drh 2c79733f3c Refactoring of DISTINCT code. Change the name of the local variable
"distinct" to "distinctTab".  Generate cleaner code w/o unnecessary P4
and P5 values on the OP_Null for WHERE_DISTINCT_ORDERED.

FossilOrigin-Name: 0cda241a2bcb3c6f2ae6c48f522780bc4eddfc02
2012-09-20 14:26:22 +00:00
drh 053a128f55 Tighter VDBE code for the WHERE_DISTINCT_ORDERED case of DISTINCT keyword
handling.

FossilOrigin-Name: 94b48064db3cbb43e911fdf7183218b08146ec10
2012-09-19 21:15:46 +00:00
drh ae651d614e Add comments to the WHERE_DISTINCT_* macros. No changes to code.
FossilOrigin-Name: 82320501904f65030622a67836ba30f412169056
2012-09-19 17:31:15 +00:00
drh c35dfbb677 Merge the covering-index-scan optimization into trunk.
FossilOrigin-Name: ddd5d789e7ae4a66cd7b7fa79e48d2777f95350b
2012-09-19 00:35:31 +00:00
mistachkin ba2bba3c32 Silence harmless compiler warning seen with SQLITE_OMIT_DEPRECATED.
FossilOrigin-Name: c5cee969322d14114e4136510c3891a2e743520d
2012-09-18 23:21:32 +00:00
drh dbaee5e342 Enhance IN processing to allow efficient use of indices with numeric affinities.
Add test cases for IN processing that would have spotted the error in the
[2be661a48023f4] check-in.

FossilOrigin-Name: 5ded9b68388f4024425c11f09b03529ac89454ce
2012-09-18 19:29:06 +00:00
drh d4305ca61c Enhancements to the comments on sqlite3FindInIndex(). No code changes.
FossilOrigin-Name: b1a4c394995eb90b3fb43ab204704bda03799303
2012-09-18 17:08:33 +00:00
drh c65714ddf0 Add the stack_usage.tcl script for analyzing the output of objdump on the
amalgamation and estimating the sizes of stack frames on each function.

FossilOrigin-Name: 030013ff0c7af5f146a64f9ede31297ff003e0c4
2012-09-18 14:00:54 +00:00
drh 3a94987819 Update the vdbe-compress.tcl script so that it accepts variable declarations
inside of #ifdef...#endif.
This enhancement is needed due to the change of check-in [39866c0ede5d6ef4].

FossilOrigin-Name: e7db056a0d76b2411cadbae077890df189e49414
2012-09-18 13:20:13 +00:00
drh d2e2bf9ff7 Make sure the WHERE_IDX_ONLY flag is not set on query plans that will not
be using an index.

FossilOrigin-Name: 698b2a28004a9a2f0eabaadf36d833da4400b2bf
2012-09-17 21:24:01 +00:00
drh de9a7b8a94 Add the ability to disable the covering-index-scan optimization at compile-time,
start-time, or at run-time.  Add test cases to check this configurability.

FossilOrigin-Name: ccb8ecc30c8e6c7760131250297c2e452bbac43b
2012-09-17 20:44:46 +00:00
drh ee4b21e9f3 Merge recent trunk changes into the fullscan-covering-index branch.
FossilOrigin-Name: 1c0bf0305ce9528a0d07c86a390c5872e16bdb57
2012-09-17 19:26:02 +00:00
drh f4af1089ab Remove obsolete bits from the bitvector that defines disabled optimizations
in the SQLITE_TESTCTRL_OPTIMIZATIONS verb of sqlite3_test_control().

FossilOrigin-Name: 4c21ee2d26466f83dec525153e2b1506bd956701
2012-09-17 19:12:39 +00:00
drh 4261096124 Remove an unnecessary parameter from sqlite3Utf8Read() resulting in a slight
performance increase.

FossilOrigin-Name: 8b962c94a2f829f71efdd0ca770469b02feea3e1
2012-09-17 18:56:32 +00:00
drh e1a022e48b Make sure the KeyInfo.aSortOrder array is always allocated so that we never
have to test for KeyInfo.aSortOrder==0 in performance-critical loops.

FossilOrigin-Name: 45793f0b844fee7445bc9269b403f89a58f77150
2012-09-17 17:16:53 +00:00
drh 56690b3d49 Performance enhancement in the sqlite3VdbeSerialType() routine.
FossilOrigin-Name: ad298f52efd0ff123a1a4d6a0fa16fbd4c6b6dad
2012-09-17 15:36:31 +00:00
drh 3f4d1d1b02 Attempt to use a covering index even on a full table scan, under the theory
that the index will be smaller and require less disk I/O and thus be faster.

FossilOrigin-Name: cfaa7bc12847a7006ccc93815f2395ad5259744a
2012-09-15 18:45:54 +00:00
drh 55b4c226d1 Make sure the name of rollback journal files are double-zero terminated
when they are passed into the VFS.

FossilOrigin-Name: 8711a8447d28275602287faf533de3d6e50d535d
2012-09-15 13:39:24 +00:00
drh 5f08526937 Factor out the code that generates a co-routine for evaluating the SELECT
on the RHS of an INSERT statement so that the same code can potentially
be reused in other places.

FossilOrigin-Name: a93ee09cdc15987848bf9023e69892ce9a5f989e
2012-09-15 13:29:23 +00:00
drh 6ec6549158 Improved alignment of fields in the Expr object gives an 8-byte size
reduction on 64-bit machines.

FossilOrigin-Name: 6b252a0d1a78db7bf2d650bafc214ea4064eef9e
2012-09-13 19:59:09 +00:00
mistachkin 66498ae871 Fix WAL capability checking in one of the test files.
FossilOrigin-Name: 0ebe7cc57408d6d85910cc976fb8af4436d6e594
2012-09-13 16:12:20 +00:00
mistachkin 59ee77c7d1 Fix an unused variable warning with SQLITE_OMIT_WAL.
FossilOrigin-Name: 39866c0ede5d6ef4dd4fd57c797f0e86a2d0dc5d
2012-09-13 15:26:44 +00:00
mistachkin 7ea11af2d6 Improved reporting of filename translation errors in the Windows VFS.
FossilOrigin-Name: eb0f1c292e6fb00c4d9dbb2317fdc4717c5be96b
2012-09-13 15:24:29 +00:00
drh d815f17dab Reduce the size of the Table object by 16 bytes on 64-bit machines, mostly
by avoiding intermixing pointer fields with integer fields.

FossilOrigin-Name: 1cb9aedfcf81f0086fa741cb29a062ee87724a5e
2012-09-13 14:42:43 +00:00
drh a371ace426 Change boolean fields in the Column object from unsigned characters into
bits in a single bit mask variable.

FossilOrigin-Name: 4163f5f194741bc2bdf141973912661c6aac70f1
2012-09-13 14:22:47 +00:00
drh df32414d99 Add the RTREE_INT_ONLY configuration parameter to the compile-time options
logic.

FossilOrigin-Name: 98b971fb24e0ee5f881b13401c7af51fc6effd0e
2012-09-13 12:10:55 +00:00
mistachkin c60941f814 Allow SQLite to work on Win32 with SQLITE_OS_WINNT=0 as long as WAL is disabled.
FossilOrigin-Name: c1a8557008e56aa9bcb4565e4178fc57295c563d
2012-09-13 01:51:02 +00:00
drh 8cca95d7aa Update version number to 3.7.15. Delete some obsolete build scripts.
FossilOrigin-Name: 9402f81fade5fcae0a3a6efdc7a5cdf71fc2e79f
2012-09-12 00:11:20 +00:00
mistachkin 5dac843233 Added sqlite3_errstr API to translate a result code to the corresponding error message.
FossilOrigin-Name: bf8a9ca5b58404112a8af666f5840b462b7bbfe1
2012-09-11 02:00:25 +00:00
mistachkin 1c9ee26837 Correct two duplicated test names.
FossilOrigin-Name: ced49974a969f11e5ebe2280bd7eec20b059e501
2012-09-10 23:44:12 +00:00
drh 0fdbdbea03 Remove the stale implementation of the ifnull and coalesce functions - code
that has been commented out for ages.  No functional changes.

FossilOrigin-Name: c2ad691174b8af2e8b158d8840cfc93f75d7db71
2012-09-10 15:02:32 +00:00
mistachkin 9dc2a73662 Avoid using the sqlite3ErrStr function in the Tcl package if USE_SYSTEM_SQLITE is defined.
FossilOrigin-Name: a716b9a3091072774d067c0a1258b0f4c39a4180
2012-09-10 09:33:09 +00:00
mistachkin 8765b4660e Make header comments for some Tcl test commands more consistent. No changes to code.
FossilOrigin-Name: af870ca9827d2079a35dbb545660f670c7ca9512
2012-09-10 08:48:05 +00:00
mistachkin 540ebf8271 Refine error messages in the sqlite3 Tcl command when a NULL database connection is returned from sqlite3_open_v2.
FossilOrigin-Name: f260d7d567a1239c483c437d0b18a95bd0c96724
2012-09-10 07:29:29 +00:00
mistachkin 60a7523bd3 Fix typo in documentation for sqlite3_open_v2. No changes to code.
FossilOrigin-Name: b532120a4a567a3fa54b87dd8ab94cc2c0347c7c
2012-09-10 06:02:57 +00:00
mistachkin 50610df8ae Correct two test names to make them unique.
FossilOrigin-Name: 43e474d3e9364e6ed417db06e98faa3e5bc2eb26
2012-09-07 20:10:30 +00:00
drh c0c7b5ee74 Have PRAGMA busy_timeout return 0 if the busy handler has been changed
or cancelled.

FossilOrigin-Name: 7be5bc36798d30f50658b70fc0bd31af897f3a87
2012-09-07 18:49:57 +00:00
drh f360396c47 Add an experimental busy_timeout pragma to facilitate access to the
sqlite3_busy_timeout() interfaces for programmers that are working from
behind a language wrapper that does not expose that interface.

FossilOrigin-Name: 22ebc668516bc3dd5782d6d3d42dc7fd2eed7d79
2012-09-07 16:46:59 +00:00
drh 37f58e9902 Avoid repeating calls to the sqlite3_trace() callback when the same statement
is evaluted multiple times by sqlite3_step() due to an SQLITE_SCHEMA
reprepare.

FossilOrigin-Name: 39f763bfc04174ee0fe2cdf6a92b7c12f726bd1b
2012-09-04 21:34:26 +00:00
95 changed files with 3120 additions and 1462 deletions
+3
View File
@@ -889,6 +889,9 @@ fulltest: testfixture$(TEXE) sqlite3$(TEXE)
soaktest: testfixture$(TEXE) sqlite3$(TEXE)
./testfixture$(TEXE) $(TOP)/test/all.test -soak=1
fulltestonly: testfixture$(TEXE) sqlite3$(TEXE)
./testfixture$(TEXE) $(TOP)/test/full.test
test: testfixture$(TEXE) sqlite3$(TEXE)
./testfixture$(TEXE) $(TOP)/test/veryquick.test
+38 -17
View File
@@ -30,6 +30,10 @@ XCOMPILE = 0
#
USE_NATIVE_LIBPATHS = 0
# Set this 0 to skip the compiling and embedding of version resources.
#
USE_RC = 1
# Set this non-0 to compile binaries suitable for the WinRT environment.
# This setting does not apply to any binaries that require Tcl to operate
# properly (i.e. the text fixture, etc).
@@ -157,8 +161,8 @@ NLTLIBPATHS = "/LIBPATH:$(NCRTLIBPATH)" "/LIBPATH:$(NSDKLIBPATH)"
# will run on the target platform. (BCC and TCC are usually the
# same unless your are cross-compiling.)
#
TCC = $(CC) -W3 -DSQLITE_OS_WIN=1 -I. -I$(TOP)\src -fp:precise
RCC = $(RC) -DSQLITE_OS_WIN=1 -I. -I$(TOP)\src
TCC = $(CC) -W3 -DSQLITE_OS_WIN=1 -I$(TOP) -I$(TOP)\src -fp:precise
RCC = $(RC) -DSQLITE_OS_WIN=1 -I$(TOP) -I$(TOP)\src
# When compiling the library for use in the WinRT environment,
# the following compile-time options must be used as well to
@@ -168,8 +172,8 @@ RCC = $(RC) -DSQLITE_OS_WIN=1 -I. -I$(TOP)\src
!IF $(FOR_WINRT)!=0
TCC = $(TCC) -DSQLITE_OS_WINRT=1
RCC = $(RCC) -DSQLITE_OS_WINRT=1
TCC = $(TCC) -DWINAPI_FAMILY=WINAPI_PARTITION_APP
RCC = $(RCC) -DWINAPI_FAMILY=WINAPI_PARTITION_APP
TCC = $(TCC) -DWINAPI_FAMILY=WINAPI_FAMILY_APP
RCC = $(RCC) -DWINAPI_FAMILY=WINAPI_FAMILY_APP
!ENDIF
# Also, we need to dynamically link to the correct MSVC runtime
@@ -180,14 +184,18 @@ RCC = $(RCC) -DWINAPI_FAMILY=WINAPI_PARTITION_APP
!IF $(FOR_WINRT)!=0 || $(USE_CRT_DLL)!=0
!IF $(DEBUG)>0
TCC = $(TCC) -MDd
BCC = $(BCC) -MDd
!ELSE
TCC = $(TCC) -MD
BCC = $(BCC) -MD
!ENDIF
!ELSE
!IF $(DEBUG)>0
TCC = $(TCC) -MTd
BCC = $(BCC) -MTd
!ELSE
TCC = $(TCC) -MT
BCC = $(BCC) -MT
!ENDIF
!ENDIF
@@ -472,6 +480,14 @@ LIBOBJ = $(LIBOBJS0)
LIBOBJ = $(LIBOBJS1)
!ENDIF
# Determine if embedded resource compilation and usage are enabled.
#
!IF $(USE_RC)!=0
LIBRESOBJS = sqlite3res.lo
!ELSE
LIBRESOBJS =
!ENDIF
# All of the source code files.
#
SRC = \
@@ -766,10 +782,10 @@ libsqlite3.lib: $(LIBOBJ)
libtclsqlite3.lib: tclsqlite.lo libsqlite3.lib
$(LTLIB) $(LTLIBOPTS) $(LTLIBPATHS) /OUT:$@ tclsqlite.lo libsqlite3.lib $(LIBTCL:tcl=tclstub) $(TLIBS)
sqlite3.exe: $(TOP)\src\shell.c libsqlite3.lib sqlite3res.lo sqlite3.h
sqlite3.exe: $(TOP)\src\shell.c libsqlite3.lib $(LIBRESOBJS) sqlite3.h
$(LTLINK) $(READLINE_FLAGS) \
$(TOP)\src\shell.c \
/link $(LTLINKOPTS) $(LTLIBPATHS) libsqlite3.lib sqlite3res.lo $(LIBREADLINE) $(LTLIBS) $(TLIBS)
/link $(LTLINKOPTS) $(LTLIBPATHS) libsqlite3.lib $(LIBRESOBJS) $(LIBREADLINE) $(LTLIBS) $(TLIBS)
# This target creates a directory named "tsrc" and fills it with
# copies of all of the C source code and header files needed to
@@ -819,14 +835,16 @@ opcodes.lo: opcodes.c
# Rule to build the Win32 resources object file.
#
sqlite3res.lo: $(TOP)\src\sqlite3.rc $(HDR)
!IF $(USE_RC)!=0
$(LIBRESOBJS): $(TOP)\src\sqlite3.rc $(HDR)
echo #ifndef SQLITE_RESOURCE_VERSION > sqlite3rc.h
for /F %%V in ('type VERSION') do ( \
for /F %%V in ('type "$(TOP)\VERSION"') do ( \
echo #define SQLITE_RESOURCE_VERSION %%V \
| $(NAWK) "/.*/ { gsub(/[.]/,\",\");print }" >> sqlite3rc.h \
)
echo #endif >> sqlite3rc.h
$(LTRCOMPILE) -fo sqlite3res.lo $(TOP)\src\sqlite3.rc
$(LTRCOMPILE) -fo $(LIBRESOBJS) $(TOP)\src\sqlite3.rc
!ENDIF
# Rules to build individual *.lo files from files in the src directory.
#
@@ -1043,8 +1061,8 @@ tclsqlite.lo: $(TOP)\src\tclsqlite.c $(HDR)
tclsqlite-shell.lo: $(TOP)\src\tclsqlite.c $(HDR)
$(LTCOMPILE) -DTCLSH=1 -DBUILD_sqlite -I$(TCLINCDIR) -c $(TOP)\src\tclsqlite.c
tclsqlite3.exe: tclsqlite-shell.lo libsqlite3.lib sqlite3res.lo
$(LD) $(LDFLAGS) $(LTLINKOPTS) $(LTLIBPATHS) /OUT:$@ libsqlite3.lib tclsqlite-shell.lo sqlite3res.lo $(LTLIBS) $(TLIBS)
tclsqlite3.exe: tclsqlite-shell.lo libsqlite3.lib $(LIBRESOBJS)
$(LD) $(LDFLAGS) $(LTLINKOPTS) $(LTLIBPATHS) /OUT:$@ libsqlite3.lib tclsqlite-shell.lo $(LIBRESOBJS) $(LTLIBS) $(TLIBS)
# Rules to build opcodes.c and opcodes.h
#
@@ -1157,11 +1175,11 @@ TESTFIXTURE_SRC = $(TESTSRC) $(TOP)\src\tclsqlite.c $(TESTFIXTURE_SRC0)
TESTFIXTURE_SRC = $(TESTSRC) $(TOP)\src\tclsqlite.c $(TESTFIXTURE_SRC1)
!ENDIF
testfixture.exe: $(TESTFIXTURE_SRC) sqlite3res.lo $(HDR)
testfixture.exe: $(TESTFIXTURE_SRC) $(LIBRESOBJS) $(HDR)
$(LTLINK) -DSQLITE_NO_SYNC=1 $(TESTFIXTURE_FLAGS) \
-DBUILD_sqlite -I$(TCLINCDIR) \
$(TESTFIXTURE_SRC) \
/link $(LTLINKOPTS) $(LTLIBPATHS) sqlite3res.lo $(LTLIBS) $(TLIBS)
/link $(LTLINKOPTS) $(LTLIBPATHS) $(LIBRESOBJS) $(LTLIBS) $(TLIBS)
fulltest: testfixture.exe sqlite3.exe
.\testfixture.exe $(TOP)\test\all.test
@@ -1169,6 +1187,9 @@ fulltest: testfixture.exe sqlite3.exe
soaktest: testfixture.exe sqlite3.exe
.\testfixture.exe $(TOP)\test\all.test -soak=1
fulltestonly: testfixture.exe sqlite3.exe
.\testfixture.exe $(TOP)\test\full.test
test: testfixture.exe sqlite3.exe
.\testfixture.exe $(TOP)\test\veryquick.test
@@ -1179,9 +1200,9 @@ sqlite3_analyzer.c: sqlite3.c $(TOP)\src\test_stat.c $(TOP)\src\tclsqlite.c $(TO
$(NAWK) -f $(TOP)\tool\tostr.awk $(TOP)\tool\spaceanal.tcl >> $@
echo ; return zMainloop; } >> $@
sqlite3_analyzer.exe: sqlite3_analyzer.c sqlite3res.lo
sqlite3_analyzer.exe: sqlite3_analyzer.c $(LIBRESOBJS)
$(LTLINK) -DBUILD_sqlite -DTCLSH=2 -I$(TCLINCDIR) sqlite3_analyzer.c \
/link $(LTLINKOPTS) $(LTLIBPATHS) sqlite3res.lo $(LTLIBS) $(TLIBS)
/link $(LTLINKOPTS) $(LTLIBPATHS) $(LIBRESOBJS) $(LTLIBS) $(TLIBS)
clean:
del /Q *.lo *.ilk *.lib *.obj *.pdb sqlite3.exe libsqlite3.lib
@@ -1214,5 +1235,5 @@ sqlite3.def: libsqlite3.lib
| $(NAWK) "/ 1 _?sqlite3_/ { sub(/^.* _?/,\"\");print }" \
| sort >> sqlite3.def
sqlite3.dll: $(LIBOBJ) sqlite3res.lo sqlite3.def
$(LD) $(LDFLAGS) $(LTLINKOPTS) $(LTLIBPATHS) /DLL /DEF:sqlite3.def /OUT:$@ $(LIBOBJ) sqlite3res.lo $(LTLIBS) $(TLIBS)
sqlite3.dll: $(LIBOBJ) $(LIBRESOBJS) sqlite3.def
$(LD) $(LDFLAGS) $(LTLINKOPTS) $(LTLIBPATHS) /DLL /DEF:sqlite3.def /OUT:$@ $(LIBOBJ) $(LIBRESOBJS) $(LTLIBS) $(TLIBS)
+3
View File
@@ -625,6 +625,9 @@ fulltest: testfixture$(EXE) sqlite3$(EXE)
soaktest: testfixture$(EXE) sqlite3$(EXE)
./testfixture$(EXE) $(TOP)/test/all.test -soak=1
fulltestonly: testfixture$(EXE) sqlite3$(EXE)
./testfixture$(EXE) $(TOP)/test/full.test
test: testfixture$(EXE) sqlite3$(EXE)
./testfixture$(EXE) $(TOP)/test/veryquick.test
+1 -1
View File
@@ -1 +1 @@
3.7.14
3.7.15
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.7.14.
# Generated by GNU Autoconf 2.62 for sqlite 3.7.15.
#
# 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.7.14'
PACKAGE_STRING='sqlite 3.7.14'
PACKAGE_VERSION='3.7.15'
PACKAGE_STRING='sqlite 3.7.15'
PACKAGE_BUGREPORT=''
# Factoring default headers for most tests.
@@ -1485,7 +1485,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.7.14 to adapt to many kinds of systems.
\`configure' configures sqlite 3.7.15 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1550,7 +1550,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
short | recursive ) echo "Configuration of sqlite 3.7.14:";;
short | recursive ) echo "Configuration of sqlite 3.7.15:";;
esac
cat <<\_ACEOF
@@ -1666,7 +1666,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
sqlite configure 3.7.14
sqlite configure 3.7.15
generated by GNU Autoconf 2.62
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
@@ -1680,7 +1680,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.7.14, which was
It was created by sqlite $as_me 3.7.15, which was
generated by GNU Autoconf 2.62. Invocation command line was
$ $0 $@
@@ -14034,7 +14034,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.7.14, which was
This file was extended by sqlite $as_me 3.7.15, which was
generated by GNU Autoconf 2.62. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -14087,7 +14087,7 @@ Report bugs to <bug-autoconf@gnu.org>."
_ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_version="\\
sqlite config.status 3.7.14
sqlite config.status 3.7.15
configured by $0, generated by GNU Autoconf 2.62,
with options \\"`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"
+2 -2
View File
@@ -2660,7 +2660,7 @@ static int newRowid(Rtree *pRtree, i64 *piRowid){
*/
static int rtreeDeleteRowid(Rtree *pRtree, sqlite3_int64 iDelete){
int rc; /* Return code */
RtreeNode *pLeaf; /* Leaf node containing record iDelete */
RtreeNode *pLeaf = 0; /* Leaf node containing record iDelete */
int iCell; /* Index of iDelete cell in pLeaf */
RtreeNode *pRoot; /* Root node of rtree structure */
@@ -2863,7 +2863,7 @@ static int rtreeUpdate(
*/
if( rc==SQLITE_OK && nData>1 ){
/* Insert the new record into the r-tree */
RtreeNode *pLeaf;
RtreeNode *pLeaf = 0;
/* Figure out the rowid of the new row. */
if( bHaveRowid==0 ){
+3
View File
@@ -565,6 +565,9 @@ fulltest: testfixture$(EXE) sqlite3$(EXE)
soaktest: testfixture$(EXE) sqlite3$(EXE)
./testfixture$(EXE) $(TOP)/test/all.test -soak=1
fulltestonly: testfixture$(EXE) sqlite3$(EXE)
./testfixture$(EXE) $(TOP)/test/full.test
test: testfixture$(EXE) sqlite3$(EXE)
./testfixture$(EXE) $(TOP)/test/veryquick.test
+100 -95
View File
@@ -1,12 +1,12 @@
C Version\s3.7.14
D 2012-09-03T15:42:36.217
C Manually\sdefine\sthe\sWin32\sfile-mapping\sAPIs\sfor\sWAL\sif\sSQLITE_WIN32_FILEMAPPING_API\sis\sdefined.
D 2012-10-07T00:52:22.053
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in abd5c10d21d1395f140d9e50ea999df8fa4d6376
F Makefile.in 5f4f26109f9d80829122e0e09f9cda008fa065fb
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
F Makefile.msc 2d696f01c228995e98b3b953a08b7bba1d48c130
F Makefile.vxworks 879f034a64062a364b21000266bbd5bc6e0c19b9
F Makefile.msc a8495ef567c1872cd9e0679c96a02aafbf9c43b5
F Makefile.vxworks b18ad88e9a8c6a001f5cf4a389116a4f1a7ab45f
F README cd04a36fbc7ea56932a4052d7d0b7f09f27c33d6
F VERSION a71848df48082f1d6585d4b0819d530fc455485d
F VERSION edab4af5a4623f8198833ea481ce98ab53750a8d
F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50
F addopcodes.awk 17dc593f791f874d2c23a0f9360850ded0286531
F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2
@@ -15,7 +15,7 @@ F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2
F config.guess 226d9a188c6196f3033ffc651cbc9dcee1a42977
F config.h.in 0921066a13130082764ab4ab6456f7b5bebe56de
F config.sub 9ebe4c3b3dab6431ece34f16828b594fb420da55
F configure e2d0e3b67d2b1b1049d389fd671275d79bb80457 x
F configure 4907207e1627a394e8892cce8dcc8068fbe5f7cd x
F configure.ac 6e909664785b8184db2179013cd9d574f96ca3a3
F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad
F doc/lemon.html 334dbf6621b8fb8790297ec1abf3cfa4621709d1
@@ -83,7 +83,7 @@ F ext/icu/README.txt bf8461d8cdc6b8f514c080e4e10dc3b2bbdfefa9
F ext/icu/icu.c eb9ae1d79046bd7871aa97ee6da51eb770134b5a
F ext/icu/sqliteicu.h 728867a802baa5a96de7495e9689a8e01715ef37
F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761
F ext/rtree/rtree.c d17aecb7a92762efa7b1f5d5fd7c88fd77d70827
F ext/rtree/rtree.c 47064ee2995a396bfb626337d2b43f12cc0af687
F ext/rtree/rtree.h 834dbcb82dc85b2481cde6a07cdadfddc99e9b9e
F ext/rtree/rtree1.test e474a2b5eff231496dbd073fe67e5fbaf7f444c9
F ext/rtree/rtree2.test acbb3a4ce0f4fbc2c304d2b4b784cfa161856bba
@@ -103,49 +103,47 @@ F ext/rtree/tkt3363.test 142ab96eded44a3615ec79fba98c7bde7d0f96de
F ext/rtree/viewrtree.tcl eea6224b3553599ae665b239bd827e182b466024
F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x
F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8
F main.mk 72026405046ed5b1f0368943b89c0aa29ad558b6
F main.mk 7b60c2663388270258f01b59fbf8b9bd78f946bf
F mkdll.sh 7d09b23c05d56532e9d44a50868eb4b12ff4f74a
F mkextu.sh 416f9b7089d80e5590a29692c9d9280a10dbad9f
F mkextw.sh 4123480947681d9b434a5e7b1ee08135abe409ac
F mkopcodec.awk f6fccee29e68493bfd90a2e0466ede5fa94dd2fc
F mkopcodeh.awk 29b84656502eee5f444c3147f331ee686956ab0e
F mkso.sh fd21c06b063bb16a5d25deea1752c2da6ac3ed83
F publish.sh 313c5b2425f2cf5e547db7549a9796acc4508f22
F publish_osx.sh 2ad2ee7d50632dff99949edc9c162dbb052f7534
F spec.template 86a4a43b99ebb3e75e6b9a735d5fd293a24e90ca
F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b
F sqlite3.1 6be1ad09113570e1fc8dcaff84c9b0b337db5ffc
F sqlite3.pc.in ae6f59a76e862f5c561eb32a380228a02afc3cad
F src/alter.c 149cc80d9257971b0bff34e58fb2263e01998289
F src/alter.c f8db986c03eb0bfb221523fc9bbb9d0b70de3168
F src/analyze.c 7553068d21e32a57fc33ab6b2393fc8c1ba41410
F src/attach.c 577bf5675b0c50495fc28549f2fcbdb1bac71143
F src/attach.c 34c15ecd686e58f08e5bb1389e28a0b65c2c83db
F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34
F src/backup.c 5b31b24d6814b11de763debf342c8cd0a15a4910
F src/backup.c afc067b9a9050ff48b9d46285c53d096c556a73d
F src/bitvec.c 26675fe8e431dc555e6f2d0e11e651d172234aa1
F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7
F src/btree.c 9cf6de113d23d47967df24b8d8ce6501c879d7e6
F src/btree.h 4aee02e879211bfcfd3f551769578d2e940ab6c2
F src/btree.c 14de53ebb334633ee632ab3c5b9262cfe7cbe455
F src/btree.h 078f76b28c338ab6eb6dd7324d63ee54463aeb6c
F src/btreeInt.h 4e5c2bd0f9b36b2a815a6d84f771a61a65830621
F src/build.c a3b700afd475e6387da59be6f2e86161e80d6d87
F src/callback.c 0cb4228cdcd827dcc5def98fb099edcc9142dbcd
F src/build.c aaff8dbeb50c4a7fc48c4f9b65e633b991755ccf
F src/callback.c d7e46f40c3cf53c43550b7da7a1d0479910b62cc
F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac
F src/ctime.c 500d019da966631ad957c37705642be87524463b
F src/ctime.c 72a70dcfda75d3a1f81041ce4573e7afddcd8e4e
F src/date.c 067a81c9942c497aafd2c260e13add8a7d0c7dd4
F src/delete.c 335f36750dc6ac88d580aa36a6487459be9889de
F src/expr.c 217840a107dcc1e5dbb57cea311daad04bedbb9a
F src/delete.c e35684ad93c741266b086610d2efd709b7946853
F src/expr.c 57fb8e7a05d4147e40b9f4c439e37ed2abab9332
F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
F src/fkey.c 9c77d842dc9961d92a06a65abb80c64ef1750296
F src/func.c 18dfedfb857e100b05755a1b12e88b389f957879
F src/global.c 4cfdca5cb0edd33c4d021baec4ede958cb2c793b
F src/fkey.c c82a04e7a92bb728f9ab972b76590403283be2af
F src/func.c cbb90dc84b22eea25caf39528d342279e61b8898
F src/global.c fb44b11e02e06c995e6ed6642509edd23599d584
F src/hash.c a4031441741932da9e7a65bee2b36b5d0e81c073
F src/hash.h 2894c932d84d9f892d4b4023a75e501f83050970
F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08
F src/insert.c b090d0a9fb9ff2dbdeaf66aedccf98cd13b1af60
F src/insert.c b1d413e792e8f5e6747647625cb7c0e9f2e89e50
F src/journal.c 552839e54d1bf76fb8f7abe51868b66acacf6a0e
F src/legacy.c a199d7683d60cef73089e892409113e69c23a99f
F src/lempar.c 0ee69fca0be54cd93939df98d2aca4ca46f44416
F src/loadext.c f20382fbaeec832438a1ba7797bee3d3c8a6d51d
F src/main.c 02255cf1da50956c5427c469abddb15bccc4ba09
F src/main.c ca6784455f3207524b82d24141676d641d44f137
F src/malloc.c fe085aa851b666b7c375c1ff957643dc20a04bf6
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
F src/mem1.c 437c7c4af964895d4650f29881df63535caaa1fa
@@ -162,31 +160,31 @@ F src/notify.c 976dd0f6171d4588e89e874fcc765e92914b6d30
F src/os.c e1acdc09ff3ac2412945cca9766e2dcf4675f31c
F src/os.h 027491c77d2404c0a678bb3fb06286f331eb9b57
F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04
F src/os_unix.c 69b2fe66316524eebf5f1ce85c1fdfe2952307e9
F src/os_win.c 5dec8fe85ee547152075c020db72aec4382f0d0a
F src/pager.c 5665fa9ecec51f11dabdfd8eefefa89391856007
F src/pager.h 8b8c9bc065a3c66769df8724dfdf492ee1aab3c5
F src/os_unix.c a5a45a2857c43b37bac145b521064a85a544cd7a
F src/os_win.c 8a549824ca5cf85a06b550fa95090fa911c4e5ee
F src/pager.c a7ad8c38809edf0be545e8f52da5bcbb88885b38
F src/pager.h bdbc379557eb2e233dfec10986b3086877e72db7
F src/parse.y f29df90bd3adc64b33114ab1de9fb7768fcf2099
F src/pcache.c f8043b433a57aba85384a531e3937a804432a346
F src/pcache.h 1b5dcc3dc8103d03e625b177023ee67764fa6b7c
F src/pcache1.c 9fd22671c270b35131ef480bbc00392b8b5f8ab9
F src/pragma.c 97f9357f0e7e5fb46a2519f14539550aa07db49f
F src/prepare.c 33291b83cca285718048d219c67b8298501fa3a5
F src/pragma.c 4f31fe4ae4b885a8be8b1db9d94f9f5b6c8b5624
F src/prepare.c 931ad0d852a0df48f79adcba6ce79ca5f475625c
F src/printf.c 4a9f882f1c1787a8b494a2987765acf9d97ac21f
F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50
F src/resolve.c 9e28280ec98035f31900fdd1db01f86f68ca6c32
F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0
F src/select.c f843c872a97baa1594c2cc3d4c003409a7bd03af
F src/shell.c 87953c5d9c73d9494db97d1607e2e2280418f261
F src/sqlite.h.in c447d35212736c4c77d86bc2d00f6cf4d4c12131
F src/select.c 2a82736faeca1fe93315eda20c691d68ec13bb6c
F src/shell.c 8ee5a3cb502e2d574f97b43972e6c1e275e7bec7
F src/sqlite.h.in c7be05ad191d2634292fcc77bdb2bcfa4526eb98
F src/sqlite3.rc fea433eb0a59f4c9393c8e6d76a6e2596b1fe0c0
F src/sqlite3ext.h 6904f4aadf976f95241311fbffb00823075d9477
F src/sqliteInt.h 053e03a532beb909ead2df0721db67cdb4c48ae8
F src/sqliteInt.h 1c5c35cc835e4c4e26be43e663661a237db74c59
F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d
F src/status.c 35939e7e03abf1b7577ce311f48f682c40de3208
F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e
F src/tclsqlite.c fe5406573e1527957e00dcaf51edd9d8bd31b918
F src/test1.c 3d70f7c5987f186884cfebbfa7151a7d3d67d86e
F src/tclsqlite.c 515abd8e33e82aa330eeb54675185a7e1e5b6778
F src/test1.c 936afc02766403e5debca49a1817a780e116df7e
F src/test2.c 4178056dd1e7d70f954ad8a1e3edb71a2a784daf
F src/test3.c 3c3c2407fa6ec7a19e24ae23f7cb439d0275a60d
F src/test4.c bf9fa9bece01de08e6f5e02314e4af5c13590dfa
@@ -206,18 +204,18 @@ F src/test_func.c 3a8dd37c08ab43b76d38eea2836e34a3897bf170
F src/test_fuzzer.c 1d26aa965120420bc14807da29d4d4541bfa6148
F src/test_hexio.c abfdecb6fa58c354623978efceb088ca18e379cd
F src/test_init.c 3cbad7ce525aec925f8fda2192d576d47f0d478a
F src/test_intarray.c d879bbf8e4ce085ab966d1f3c896a7c8b4f5fc99
F src/test_intarray.c 07ddcebe4097d400ffca362770f1d883c112387a
F src/test_intarray.h 489edb9068bb926583445cb02589344961054207
F src/test_journal.c f5c0a05b7b3d5930db769b5ee6c3766dc2221a64
F src/test_loadext.c df586c27176e3c2cb2e099c78da67bf14379a56e
F src/test_malloc.c 3f5903a1528fd32fe4c472a3bd0259128d8faaef
F src/test_malloc.c 01cd65ae7ae93de9fbf8214d1ee6b4eba4850700
F src/test_multiplex.c ac0fbc1748e5b86a41a1d7a84654fae0d53a881d
F src/test_multiplex.h e99c571bc4968b7a9363b661481f3934bfead61d
F src/test_mutex.c a6bd7b9cf6e19d989e31392b06ac8d189f0d573e
F src/test_onefile.c 0396f220561f3b4eedc450cef26d40c593c69a25
F src/test_osinst.c 90a845c8183013d80eccb1f29e8805608516edba
F src/test_pcache.c a5cd24730cb43c5b18629043314548c9169abb00
F src/test_quota.c 8ab295092c70903ca6f3209fa4c75f5cb6c1bf8e
F src/test_quota.c e5fdb7d28e5afae1b619922804e544db0041ec81
F src/test_quota.h 8761e463b25e75ebc078bd67d70e39b9c817a0cb
F src/test_rtree.c aba603c949766c4193f1068b91c787f57274e0d9
F src/test_schema.c 8c06ef9ddb240c7a0fcd31bc221a6a2aade58bf0
@@ -235,23 +233,23 @@ F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9
F src/tokenize.c 1e86210d3976717a19238ea7b047fac481fe8c12
F src/trigger.c 3f258307040173aff383eb23fb74c44fe829078c
F src/update.c 28d2d098b43a2c70dae399896ea8a02f622410ef
F src/utf.c 890c67dcfcc7a74623c95baac7535aadfe265e84
F src/utf.c 8d819e2e5104a430fc2005f018db14347c95a38f
F src/util.c 0af2e515dc0dabacec931bca39525f6c3f1c5455
F src/vacuum.c 587a52bb8833d7ac15af8916f25437e2575028bd
F src/vdbe.c 9c524bded348fd0a53adc19f2d7cad76ba3442b2
F src/vdbe.c 31523df2b986fc6c959dd54ca640ba865884641b
F src/vdbe.h 18f581cac1f4339ec3299f3e0cc6e11aec654cdb
F src/vdbeInt.h 986b6b11a13c517337355009e5438703ba5b0a40
F src/vdbeapi.c 88ea823bbcb4320f5a6607f39cd7c2d3cc4c26b1
F src/vdbeaux.c 9c293fd3040211687e83d5d27bef2382933146c2
F src/vdbeInt.h 573a43ab5697b648a1e8f3dfc7d8667d5ca55729
F src/vdbeapi.c 4c2418161cf45392ba76a7ca92f9a5f06b96f89c
F src/vdbeaux.c 674e969e026d1af1938942eba17071127839fc15
F src/vdbeblob.c 32f2a4899d67f69634ea4dd93e3f651936d732cb
F src/vdbemem.c cb55e84b8e2c15704968ee05f0fae25883299b74
F src/vdbesort.c 0dc1b274dcb4d4c8e71b0b2b15261f286caba39b
F src/vdbetrace.c 8bd5da325fc90f28464335e4cc4ad1407fe30835
F src/vtab.c d2c54fd22aa83eb34fc6f7cd9b097f2fc2b1e9de
F src/wal.c 5acb3e7bbd31f10ba39acad9ce6b399055337a9d
F src/vtab.c c7671587d07b76582c495d9305b35c0172cad5d3
F src/wal.c e1fe8f92a0ea0fef8faa87ec43a127a478589d22
F src/wal.h 29c197540b19044e6cd73487017e5e47a1d3dac6
F src/walker.c 3d75ba73de15e0f8cd0737643badbeb0e002f07b
F src/where.c 22783f4275f6fc09b663115a6091837cb5c510e0
F src/where.c bf45ec770aa6e5da55d6e9e9405ce990ff6ca201
F test/8_3_names.test 631ea964a3edb091cf73c3b540f6bcfdb36ce823
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
F test/aggnested.test 0be144b453e0622a085fae8665c32f5676708e00
@@ -266,7 +264,7 @@ F test/analyze.test f8ab7d15858b4093b06caf5e57e2a5ff7104bdae
F test/analyze3.test c3c7f6c3951900c188cf94b2d5ee3246d6b3ff89
F test/analyze4.test 757b37875cf9bb528d46f74497bc789c88365045
F test/analyze5.test 713354664c5ff1853ab2cbcb740f0cf5cb7c802e
F test/analyze6.test bd3625806a5ee6f7bef72d06295bd319f0290af2
F test/analyze6.test aa8dae5066bbed35c5f45a507fb87f2d342f2c99
F test/analyze7.test d3587aa5af75c9048d031b94fceca2534fa75d1d
F test/analyze8.test 4ca170de2ba30ccb1af2c0406803db72262f9691
F test/async.test 1d0e056ba1bb9729283a0f22718d3a25e82c277b
@@ -285,10 +283,10 @@ F test/auth2.test 270baddc8b9c273682760cffba6739d907bd2882
F test/auth3.test a4755e6a2a2fea547ffe63c874eb569e60a28eb5
F test/autoinc.test bd30d372d00045252f6c2e41b5f41455e1975acf
F test/autoindex1.test 058d0b331ae6840a61bbee910d8cbae27bfd5991
F test/autovacuum.test fcaf4616ae5bb18098db1cb36262565e5c841c3c
F test/autovacuum.test 9f22a7733f39c56ef6a5665d10145ac25d8cb574
F test/autovacuum_ioerr2.test 8a367b224183ad801e0e24dcb7d1501f45f244b4
F test/avtrans.test 0252654f4295ddda3b2cce0e894812259e655a85
F test/backcompat.test bccbc64769d9c755ad65ee7c2f7336b86e3cc0c8
F test/backcompat.test ecd841f3a3bfb81518721879cc56a760670e3198
F test/backup.test c9cdd23a495864b9edf75a9fa66f5cb7e10fcf62
F test/backup2.test 34986ef926ea522911a51dfdb2f8e99b7b75ebcf
F test/backup_ioerr.test 40d208bc9224b666ee3ed423f49bc9062a36a9d0
@@ -297,8 +295,8 @@ F test/badutf.test d5360fc31f643d37a973ab0d8b4fb85799c3169f
F test/badutf2.test f5bc7f2d280670ecd79b9cf4f0f1760c607fe51f
F test/bc_common.tcl 5c8689cc6d2fb44b7c0968ae4f85eb26d50022fa
F test/between.test 16b1776c6323faadb097a52d673e8e3d8be7d070
F test/bigfile.test 8f88b5ef065e31c615c49d725ede94155fbe9609
F test/bigfile2.test 8a3c242c3c3481e7cde5a6ef2a66fdc367a095f7
F test/bigfile.test aa74f4e5db51c8e54a1d9de9fa65d01d1eb20b59
F test/bigfile2.test 7c79f1ef0c6c2c2bc1e7bd895596fab32bfb4796
F test/bigrow.test f0aeb7573dcb8caaafea76454be3ade29b7fc747
F test/bind.test 3c7b320969000c441a70952b0b15938fbb66237c
F test/bindxfer.test efecd12c580c14df5f4ad3b3e83c667744a4f7e0
@@ -326,8 +324,8 @@ F test/coalesce.test cee0dccb9fbd2d494b77234bccf9dc6c6786eb91
F test/collate1.test e3eaa48c21e150814be1a7b852d2a8af24458d04
F test/collate2.test 04cebe4a033be319d6ddbb3bbc69464e01700b49
F test/collate3.test d28d2cfab2c3a3d4628ae4b2b7afc9965daa3b4c
F test/collate4.test 3d3f123f83fd8ccda6f48d617e44e661b9870c7d
F test/collate5.test 67f1d3e848e230ff4802815a79acb0a8b5e69bd7
F test/collate4.test d37682293d3c32223dec2e6afdeaf9de18415248
F test/collate5.test 65d928034d30d2d263a80f6359f7549ee1598ec6
F test/collate6.test 8be65a182abaac8011a622131486dafb8076e907
F test/collate7.test 8ec29d98f3ee4ccebce6e16ce3863fb6b8c7b868
F test/collate8.test df26649cfcbddf109c04122b340301616d3a88f6
@@ -348,10 +346,11 @@ F test/corrupt9.test 959179e68dc0b7b99f424cf3e0381c86dcdd0112
F test/corruptA.test fafa652aa585753be4f6b62ff0bb250266eaf7ce
F test/corruptB.test 20d4a20cbed23958888c3e8995b424a47223d647
F test/corruptC.test 62a767fe64acb1975f58cc6171192839c783edbb
F test/corruptD.test 99b1999dbfa7cc04aaeac9d695a2445d4e7c7458
F test/corruptE.test 1b9eb20a8711251ce57b44a257e241085b39b52d
F test/corruptD.test 3b09903a2e2fe07ecafe775fea94177f8a4bb34f
F test/corruptE.test d3a3d7e864a95978195741744dda4abfd8286018
F test/corruptF.test 984b1706c9c0e4248141b056c21124612628d12e
F test/count.test 454e1ce985c94d13efeac405ce54439f49336163
F test/coveridxscan.test cdb47d01acc4a634a34fd25abe85189e0d0f1e62
F test/crash.test fb9dc4a02dcba30d4aa5c2c226f98b220b2b959f
F test/crash2.test 5b14d4eb58b880e231361d3b609b216acda86651
F test/crash3.test 8f5de9d32ab9ab95475a9efe7f47a940aa889418
@@ -366,7 +365,7 @@ F test/cse.test 277350a26264495e86b1785f34d2d0c8600e021c
F test/ctime.test 7bd009071e242aac4f18521581536b652b789a47
F test/date.test f3228180c87bbe5d39c9397bf001c0095c3821b9
F test/dbstatus.test 207e5b63fcb7b9c3bb8e1fdf38ebd4654ad0e54b
F test/dbstatus2.test b1de8250fde1f3474d6b86f0e89de38d84794f56
F test/dbstatus2.test bf7396af964b89e39435babbcdf296ae8fc5f10a
F test/default.test 6faf23ccb300114924353007795aa9a8ec0aa9dc
F test/delete.test a065b05d2ebf60fd16639c579a4adfb7c381c701
F test/delete2.test 3a03f2cca1f9a67ec469915cb8babd6485db43fa
@@ -375,19 +374,19 @@ F test/descidx1.test 533dcbda614b0463b0ea029527fd27e5a9ab2d66
F test/descidx2.test 9f1a0c83fd57f8667c82310ca21b30a350888b5d
F test/descidx3.test fe720e8b37d59f4cef808b0bf4e1b391c2e56b6f
F test/diskfull.test 106391384780753ea6896b7b4f005d10e9866b6e
F test/distinct.test da36612d05b9ed17e0425d4bfd7ab978d28a7e46
F test/distinct.test c239558222e5ae357aade535bfe61aaabcb00bbf
F test/distinctagg.test 1a6ef9c87a58669438fc771450d7a72577417376
F test/e_createtable.test 48598b15e8fe6554d301e7b65a10c9851f177e84
F test/e_createtable.test 0a2465736199cb5e084645a8714ee04299b81721
F test/e_delete.test 89aa84d3d1bd284a0689ede04bce10226a5aeaa5
F test/e_droptrigger.test afd5c4d27dec607f5997a66bf7e2498a082cb235
F test/e_dropview.test 583411e470458c5d76148542cfb5a5fa84c8f93e
F test/e_expr.test 5489424d3d9a452ac3701cdf4b680ae31a157894
F test/e_fkey.test 057eed81a41a2b21b1790032f4e8aaba0b2b0e17
F test/e_fkey.test a79ab1d3213c7ac64621eec28f8e8bb219775445
F test/e_fts3.test 5c02288842e4f941896fd44afdef564dd5fc1459
F test/e_insert.test c6ac239a97cb16dfbd0c16496f8cd871b4068c0c
F test/e_reindex.test dfedfc32c5a282b0596c6537cbcd4217fbb1a216
F test/e_resolve.test dcce9308fb13b934ce29591105d031d3e14fbba6
F test/e_select.test f5d4b81205701deacfae42051ae200969c41d2c0
F test/e_select.test 07e8d81268ba1ffcaf1dc4bec48956af150c42f9
F test/e_select2.test 5c3d3da19c7b3e90ae444579db2b70098599ab92
F test/e_update.test 161d5dc6a3ed9dd08f5264d13e20735d7a89f00c
F test/e_uri.test 9e190ca799d9190eec6e43f2aadf1d10c06a57a3
@@ -396,7 +395,7 @@ F test/enc.test e54531cd6bf941ee6760be041dff19a104c7acea
F test/enc2.test 796c59832e2b9a52842f382ffda8f3e989db03ad
F test/enc3.test 90683ad0e6ea587b9d5542ca93568af9a9858c40
F test/enc4.test c8f1ce3618508fd0909945beb8b8831feef2c020
F test/eqp.test 6a389bba6ea113fd5179515001be788a38d53ec7
F test/eqp.test 46aa946dd55c90635327898275d3e533d23a9845
F test/errmsg.test 3bb606db9d040cc6854459f8f5e5a2bcd9b7fd2a
F test/eval.test bc269c365ba877554948441e91ad5373f9f91be3
F test/exclusive.test a1b324cb21834a490cd052d409d34789cfef57cb
@@ -503,6 +502,7 @@ F test/fts4merge.test c424309743fdd203f8e56a1f1cd7872cd66cc0ee
F test/fts4merge2.test 5faa558d1b672f82b847d2a337465fa745e46891
F test/fts4merge3.test aab02a09f50fe6baaddc2e159c3eabc116d45fc7
F test/fts4unicode.test aad033abdcfa0f87ce5f56468f59fdf2a0acbcef
F test/full.test 6b3c8fb43c6beab6b95438c1675374b95fab245d
F test/func.test 0d89043dab9a8853358d14c68e028ee0093bf066
F test/func2.test 772d66227e4e6684b86053302e2d74a2500e1e0f
F test/func3.test 001021e5b88bd02a3b365a5c5fd8f6f49d39744a
@@ -512,7 +512,7 @@ F test/fuzz2.test 207d0f9d06db3eaf47a6b7bfc835b8e2fc397167
F test/fuzz3.test aec64345184d1662bd30e6a17851ff659d596dc5
F test/fuzz_common.tcl a87dfbb88c2a6b08a38e9a070dabd129e617b45b
F test/fuzz_malloc.test 328f70aaca63adf29b4c6f06505ed0cf57ca7c26
F test/fuzzer1.test 69cf1036b92fd3b8e1fd65bef4d7ee3f085c28fb
F test/fuzzer1.test a2e93bb1e19513dd6bf9c63d3d7c4673c983ca19
F test/fuzzerfault.test ff2282c81797b6a355f0748d8b54c7287c5d2b25
F test/hook.test 5f3749de6462a6b87b4209b74adf7df5ac2df639
F test/icu.test 70df4faca133254c042d02ae342c0a141f2663f4
@@ -520,7 +520,8 @@ F test/in.test 5941096407d8c133b9eff15bd3e666624b6cbde3
F test/in2.test 5d4c61d17493c832f7d2d32bef785119e87bde75
F test/in3.test 3cbf58c87f4052cee3a58b37b6389777505aa0c0
F test/in4.test 64f3cc1acde1b9161ccdd8e5bde3daefdb5b2617
F test/incrblob.test 26fde912a1e0aff158b3a84ef3b265f046aad3be
F test/in5.test 99f9a40af01711b06d2d614ecfe96129f334fba3
F test/incrblob.test 34765fa6fb5d8e0f256fc7d6497c04b205398849
F test/incrblob2.test edc3a96e557bd61fb39acc8d2edd43371fbbaa19
F test/incrblob3.test aedbb35ea1b6450c33b98f2b6ed98e5020be8dc7
F test/incrblob4.test 09be37d3dd996a31ea6993bba7837ece549414a8
@@ -544,7 +545,7 @@ F test/insert4.test 87f6798f31d60c4e177622fcc3663367e6ecbd90
F test/insert5.test 394f96728d1258f406fe5f5aeb0aaf29487c39a6
F test/intarray.test 066b7d7ac38d25bf96f87f1b017bfc687551cdd4
F test/interrupt.test 42e7cf98646fd9cb4a3b131a93ed3c50b9e149f1
F test/intpkey.test 537669fd535f62632ca64828e435b9e54e8d677f
F test/intpkey.test 7af30f6ae852d8d1c2b70e4bf1551946742e92d8
F test/io.test 36d251507d72e92b965fb2f0801c2f0b56335bcf
F test/ioerr.test 40bb2cfcab63fb6aa7424cd97812a84bc16b5fb8
F test/ioerr2.test 9d71166f8466eda510f1af6137bdabaa82b5408d
@@ -566,12 +567,12 @@ F test/jrnlmode3.test 556b447a05be0e0963f4311e95ab1632b11c9eaa
F test/keyword1.test a2400977a2e4fde43bf33754c2929fda34dbca05
F test/lastinsert.test 474d519c68cb79d07ecae56a763aa7f322c72f51
F test/laststmtchanges.test ae613f53819206b3222771828d024154d51db200
F test/like.test 7b4aaa4a8192fdec90e0a905984c92a688c51e48
F test/like.test 0e5412f4dac4a849f613e1ef8b529d56a6e31d08
F test/like2.test 3b2ee13149ba4a8a60b59756f4e5d345573852da
F test/limit.test 2db7b3b34fb925b8e847d583d2eb67531d0ce67e
F test/loadext.test 2b5e249c51c986a5aff1f0950cf7ba30976c8f22
F test/loadext2.test 0bcaeb4d81cd5b6e883fdfea3c1bdbe1f173cbca
F test/lock.test db74fdf5a73bad29ab3d862ea78bf1068972cc1d
F test/lock.test 87af515b0c4cf928576d0f89946d67d7c265dfb4
F test/lock2.test 5242d8ac4e2d59c403aebff606af449b455aceff
F test/lock3.test f271375930711ae044080f4fe6d6eda930870d00
F test/lock4.test e175ae13865bc87680607563bafba21f31a26f12
@@ -633,6 +634,8 @@ F test/notify3.test a86259abbfb923aa27d30f0fc038c88e5251488a
F test/notnull.test cc7c78340328e6112a13c3e311a9ab3127114347
F test/null.test a8b09b8ed87852742343b33441a9240022108993
F test/openv2.test 0d3040974bf402e19b7df4b783e447289d7ab394
F test/orderby1.test 4875a2a0a87d81920f3600a3405dc42f233b8c82
F test/orderby2.test bc11009f7cd99d96b1b11e57b199b00633eb5b04
F test/oserror.test 50417780d0e0d7cd23cf12a8277bb44024765df3
F test/pager1.test 2163c6ef119f497a71a84137c957c63763e640ab
F test/pager2.test 745b911dde3d1f24ae0870bd433dfa83d7c658c1
@@ -644,7 +647,7 @@ F test/pageropt.test 9191867ed19a2b3db6c42d1b36b6fbc657cd1ab0
F test/pagesize.test 1dd51367e752e742f58e861e65ed7390603827a0
F test/pcache.test 065aa286e722ab24f2e51792c1f093bf60656b16
F test/pcache2.test a83efe2dec0d392f814bfc998def1d1833942025
F test/permutations.test 1a8ac849b659445a0b3883caf42fa2c2a289f4a1
F test/permutations.test 360b92859c0af814b3fe10b68746936389606501
F test/pragma.test a62f73293b0f0d79b0c87f8dd32d46fe53b0bd17
F test/pragma2.test 3a55f82b954242c642f8342b17dffc8b47472947
F test/printf.test ec9870c4dce8686a37818e0bf1aba6e6a1863552
@@ -699,9 +702,10 @@ F test/shared4.test 72d90821e8d2fc918a08f16d32880868d8ee8e9d
F test/shared6.test 866bb4982c45ce216c61ded5e8fde4e7e2f3ffa9
F test/shared7.test 960760bc8d03e1419e70dea69cf41db62853616e
F test/shared8.test b27befbefbe7f4517f1d6b7ff8f64a41ec74165d
F test/shared9.test 43cbbe6f59bd49abd7e40ac653a4aa8596feafcd
F test/shared_err.test 91e26ec4f3fbe07951967955585137e2f18993de
F test/sharedlock.test ffa0a3c4ac192145b310f1254f8afca4d553eabf
F test/shell1.test 9895ee3013742a02e5afd8d77793729967ffd195
F test/shell1.test 272384163432c0efd2c6817396beb0d119565d53
F test/shell2.test 037d6ad16e873354195d30bb2dc4b5321788154a
F test/shell3.test 9196c42772d575685e722c92b4b39053c6ebba59
F test/shell4.test aa4eef8118b412d1a01477a53426ece169ea86a9
@@ -722,7 +726,7 @@ F test/speed4p.explain 6b5f104ebeb34a038b2f714150f51d01143e59aa
F test/speed4p.test 0e51908951677de5a969b723e03a27a1c45db38b
F test/spellfix.test 2953e9da0e46dab5f83059ef6bfdebca66e13418
F test/sqllimits1.test b1aae27cc98eceb845e7f7adf918561256e31298
F test/stat.test 08e8185b3fd5b010c90d7ad82b9dd4ea1cbf14b0
F test/stat.test be8d477306006ec696bc86757cfb34bec79447ce
F test/stmt.test 25d64e3dbf9a3ce89558667d7f39d966fe2a71b9
F test/subquery.test d4aea23ac267463d4aa604bf937c3992347b20f7
F test/subquery2.test edcad5c118f0531c2e21bf16a09bbb105252d4cd
@@ -734,11 +738,11 @@ F test/syscall.test bea9bf329bff733c791310244617c2a76974e64a
F test/sysfault.test c79441d88d23696fbec7b147dba98d42a04f523f
F test/table.test a59d985ca366e39b17b175f387f9d5db5a18d4e2
F test/tableapi.test 2674633fa95d80da917571ebdd759a14d9819126
F test/tclsqlite.test 1597d353308531527583481d14d9da52ea8ed0af
F test/tclsqlite.test 37a61c2da7e3bfe3b8c1a2867199f6b860df5d43
F test/tempdb.test 19d0f66e2e3eeffd68661a11c83ba5e6ace9128c
F test/temptable.test 51edd31c65ed1560dd600b1796e8325df96318e2
F test/temptrigger.test 26670ed7a39cf2296a7f0a9e0a1d7bdb7abe936d
F test/tester.tcl 2665f64c9ce71944b4d41269114e658fb81bda05
F test/tester.tcl 2f383e811010b05a83c0f00fc168cae1dd63a6d9
F test/thread001.test 7cc2ce08f9cde95964736d11e91f9ab610f82f91
F test/thread002.test e630504f8a06c00bf8bbe68528774dd96aeb2e58
F test/thread003.test ee4c9efc3b86a6a2767516a37bd64251272560a7
@@ -757,20 +761,20 @@ F test/tkt-2d1a5c67d.test b028a811049eb472cb2d3a43fc8ce4f6894eebda
F test/tkt-2ea2425d34.test 1cf13e6f75d149b3209a0cb32927a82d3d79fb28
F test/tkt-31338dca7e.test 1f714c14b6682c5db715e0bda347926a3456f7a9
F test/tkt-313723c356.test c47f8a9330523e6f35698bf4489bcb29609b53ac
F test/tkt-385a5b56b9.test 8eb87c4bbcc3fd4f33d73719de7e9d64973fa196
F test/tkt-385a5b56b9.test 7782a382912a51f09f1d1a1442bca1e75f9c549b
F test/tkt-38cb5df375.test f3cc8671f1eb604d4ae9cf886ed4366bec656678
F test/tkt-3998683a16.test 6d1d04d551ed1704eb3396ca87bb9ccc8c5c1eb7
F test/tkt-3a77c9714e.test 32bb28afa8c63fc76e972e996193139b63551ed9
F test/tkt-3fe897352e.test 10de1a67bd5c66b238a4c96abe55531b37bb4f00
F test/tkt-4a03edc4c8.test 2865e4edbc075b954daa82f8da7cc973033ec76e
F test/tkt-54844eea3f.test a12b851128f46a695e4e378cca67409b9b8f5894
F test/tkt-5d863f876e.test 884072c2de496ddbb90c387c9ebc0d4f44a91b8e
F test/tkt-5d863f876e.test c9f36ca503fa154a3655f92a69d2c30da1747bfa
F test/tkt-5e10420e8d.test 904d1687b3c06d43e5b3555bbcf6802e7c0ffd84
F test/tkt-5ee23731f.test 9db6e1d7209dc0794948b260d6f82b2b1de83a9f
F test/tkt-752e1646fc.test ea78d88d14fe9866bdd991c634483334639e13bf
F test/tkt-78e04e52ea.test ab52f0c1e2de6e46c910f4cc16b086bba05952b7
F test/tkt-78e04e52ea.test 703e0bfb23d543edf0426a97e3bbd0ca346508ec
F test/tkt-7bbfb7d442.test dfa5c8097a8c353ae40705d6cddeb1f99c18b81a
F test/tkt-80ba201079.test 9eb040d81c404f56838a6af93593f42790def63f
F test/tkt-80ba201079.test 105a721e6aad0ae3c5946d7615d1e4d03f6145b8
F test/tkt-80e031a00f.test 9a154173461a4dbe2de49cda73963e04842d52f7
F test/tkt-8454a207b9.test c583a9f814a82a2b5ba95207f55001c9f0cd816c
F test/tkt-91e2e8ba6f.test 08c4f94ae07696b05c9b822da0b4e5337a2f54c5
@@ -782,7 +786,7 @@ F test/tkt-b72787b1.test a95e8cdad0b98af1853ac7f0afd4ab27b77bf5f3
F test/tkt-bd484a090c.test 60460bf946f79a79712b71f202eda501ca99b898
F test/tkt-bdc6bbbb38.test fc38bb09bdd440e3513a1f5f98fc60a075182d7d
F test/tkt-c48d99d690.test bed446e3513ae10eec1b86fdd186ef750226c408
F test/tkt-cbd054fa6b.test bd9fb546f63bc0c79d1776978d059fa51c5b1c63
F test/tkt-cbd054fa6b.test 9c27ed07b333eed458e5d4543f91ecdcf05aeb19
F test/tkt-d11f09d36e.test fb44f7961aa6d4b632fb7b9768239832210b5fc7
F test/tkt-d635236375.test 9d37e988b47d87505bc9445be0ca447002df5d09
F test/tkt-d82e3f3721.test bcc0dfba658d15bab30fd4a9320c9e35d214ce30
@@ -881,7 +885,7 @@ F test/trace2.test c1dc104a8d11a347c870cfea6235e3fc6f6cb06d
F test/trans.test 6e1b4c6a42dba31bd65f8fa5e61a2708e08ddde6
F test/trans2.test d5337e61de45e66b1fcbf9db833fa8c82e624b22
F test/trans3.test 373ac5183cc56be69f48ae44090e7f672939f732
F test/trigger1.test de42feb7cd442787d38185ae74f5a1d7afa400cb
F test/trigger1.test 70acedb76532117bbcc873f8601cdc6905f1f455
F test/trigger2.test 834187beafd1db383af0c659cfa49b0576832816
F test/trigger3.test d2c60d8be271c355d61727411e753181e877230a
F test/trigger4.test 74700b76ebf3947b2f7a92405141eb2cf2a5d359
@@ -892,7 +896,7 @@ F test/trigger8.test 30cb0530bd7c4728055420e3f739aa00412eafa4
F test/trigger9.test 5b0789f1c5c4600961f8e68511b825b87be53e31
F test/triggerA.test e0aaba16d3547193d36bbd82a1b0ed75e9c88d40
F test/triggerB.test 56780c031b454abac2340dbb3b71ac5c56c3d7fe
F test/triggerC.test 4d4bdaf0230c206b50d350330107ef9802bc2d4f
F test/triggerC.test 29173df06f8e91bec2b95ea7048b30d1e1c7b9db
F test/triggerD.test 8e7f3921a92a5797d472732108109e44575fa650
F test/tt3_checkpoint.c 415eccce672d681b297485fc20f44cdf0eac93af
F test/types.test bf816ce73c7dfcfe26b700c19f97ef4050d194ff
@@ -900,7 +904,7 @@ F test/types2.test 3555aacf8ed8dc883356e59efc314707e6247a84
F test/types3.test 99e009491a54f4dc02c06bdbc0c5eea56ae3e25a
F test/unique.test 083c7fff74695bcc27a71d75699deba3595bc9c2
F test/unixexcl.test a9870e46cc6f8390a494513d4f2bf55b5a8b3e46
F test/unordered.test f53095cee37851bf30130fa1bf299a8845e837bb
F test/unordered.test 93dce7b6c97a817a4fe26980c484605a4511f614
F test/update.test 8bc86fd7ef1a00014f76dc6a6a7c974df4aef172
F test/uri.test 63e03df051620a18f794b4f4adcdefb3c23b6751
F test/utf16align.test 54cd35a27c005a9b6e7815d887718780b6a462ae
@@ -936,7 +940,7 @@ F test/wal4.test 4744e155cd6299c6bd99d3eab1c82f77db9cdb3c
F test/wal5.test f58ed4b8b542f71c7441da12fbd769d99b362437
F test/wal6.test 2e3bc767d9c2ce35c47106148d43fcbd072a93b3
F test/wal7.test 2ae8f427d240099cc4b2dfef63cff44e2a68a1bd
F test/wal8.test 5ab217d21f7e5e86af2933a4ffd0d8357cc2c0bd
F test/wal8.test b3ee739fe8f7586aaebdc2367f477ebcf3e3b034
F test/wal_common.tcl a98f17fba96206122eff624db0ab13ec377be4fe
F test/walbak.test b9f68e39646375c2b877be906babcc15d38b4877
F test/walbig.test f437473a16cfb314867c6b5d1dbcd519e73e3434
@@ -953,7 +957,7 @@ F test/walro.test a31deb621033442a76c3a61e44929250d06f81b1
F test/walshared.test 6dda2293880c300baf5d791c307f653094585761
F test/walslow.test e7be6d9888f83aa5d3d3c7c08aa9b5c28b93609a
F test/walthread.test de8dbaf6d9e41481c460ba31ca61e163d7348f8e
F test/where.test 4c9f69987ed2aa0173fa930f2b41ab9879478cd8
F test/where.test 41b65069a227a61238c1387b050f029480ca5677
F test/where2.test 43d4becaf5a5df854e6c21d624a1cb84c6904554
F test/where3.test 667e75642102c97a00bf9b23d3cb267db321d006
F test/where4.test e9b9e2f2f98f00379e6031db6a6fca29bae782a2
@@ -962,7 +966,7 @@ F test/where6.test 5da5a98cec820d488e82708301b96cb8c18a258b
F test/where7.test 5c566388f0cc318b0032ce860f4ac5548e3c265a
F test/where8.test a6c740fd286d7883e274e17b6230a9d672a7ab1f
F test/where8m.test da346596e19d54f0aba35ebade032a7c47d79739
F test/where9.test ae98dc22ef9b6f2bc81e9f164e41b38faa9bda06
F test/where9.test bcab47eff78f1412a6aec1d6b8a3939d4a9db098
F test/whereA.test 24c234263c8fe358f079d5e57d884fb569d2da0a
F test/whereB.test 0def95db3bdec220a731c7e4bec5930327c1d8c5
F test/whereC.test 13ff5ec0dba407c0e0c075980c75b3275a6774e5
@@ -970,8 +974,8 @@ F test/whereD.test 304ccbe3c77e0d0764f37c91d43b8c4792a5e02f
F test/wherelimit.test 5e9fd41e79bb2b2d588ed999d641d9c965619b31
F test/win32lock.test b2a539e85ae6b2d78475e016a9636b4451dc7fb9
F test/zeroblob.test caaecfb4f908f7bc086ed238668049f96774d688
F test/zerodamage.test 0de750389990b1078bab203c712dc3fefd1d8b82
F tool/build-all-msvc.bat 1a18aa39983ae7354d834bc55a850a54fc007576 x
F test/zerodamage.test e7f77fded01dfcdf92ac2c5400f1e35d7a21463c
F tool/build-all-msvc.bat cd505f24717ca4ecd94c651f763d7bb4e7fe68af x
F tool/build-shell.sh b64a481901fc9ffe5ca8812a2a9255b6cfb77381
F tool/checkSpacing.c 810e51703529a204fc4e1eb060e9ab663e3c06d2
F tool/diffdb.c 7524b1b5df217c20cd0431f6789851a4e0cb191b
@@ -1007,17 +1011,18 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
F tool/split-sqlite3c.tcl d9be87f1c340285a3e081eb19b4a247981ed290c
F tool/stack_usage.tcl f8e71b92cdb099a147dad572375595eae55eca43
F tool/symbols-mingw.sh 4dbcea7e74768305384c9fd2ed2b41bbf9f0414d
F tool/symbols.sh fec58532668296d7c7dc48be9c87f75ccdb5814f
F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06
F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381
F tool/win/sqlite.vsix 67d8a99aceb56384a81b3f30d6c71743146d2cc9
P ebb08d0b4d1ed674e4a23c3754206ca2df9063ff
R 8bdf9ef517616ac5a5043f12bec4acdb
T +bgcolor * #d0c0ff
T +sym-release *
T +sym-version-3.7.14 *
U drh
Z 126ab1aaea0f3a8cb5c4792cf0a82989
P 4b0facc13b1026419f9b89dab3453ba43071455c
R 3a4914baa2fdfc1f1361069820af579b
T *branch * winFileMapping
T *sym-winFileMapping *
T -sym-trunk *
U mistachkin
Z 4c6d5f7ae10ca61313253da78e41bee6
+1 -1
View File
@@ -1 +1 @@
c0d89d4a9752922f9e367362366efde4f1b06f2a
585e2070eef3bc273f23d8e384a1261ee5fff5bd
-138
View File
@@ -1,138 +0,0 @@
#!/bin/sh
#
# This script is used to compile SQLite and package everything up
# so that it is ready to move to the SQLite website.
#
# Set srcdir to the name of the directory that contains the publish.sh
# script.
#
srcdir=`echo "$0" | sed 's%\(^.*\)/[^/][^/]*$%\1%'`
# Get the makefile.
#
cp $srcdir/Makefile.linux-gcc ./Makefile
chmod +x $srcdir/install-sh
# Get the current version number - needed to help build filenames
#
VERS=`cat $srcdir/VERSION`
VERSW=`sed 's/\./_/g' $srcdir/VERSION`
echo "VERSIONS: $VERS $VERSW"
# Start by building an sqlite shell for linux.
#
make clean
make sqlite3.c
CFLAGS="-Os -DSQLITE_ENABLE_FTS3=0 -DSQLITE_ENABLE_RTREE=0"
CFLAGS="$CFLAGS -DSQLITE_THREADSAFE=0"
echo '***** '"COMPILING sqlite3-$VERS.bin..."
gcc $CFLAGS -Itsrc sqlite3.c tsrc/shell.c -o sqlite3 -ldl
strip sqlite3
mv sqlite3 sqlite3-$VERS.bin
gzip sqlite3-$VERS.bin
chmod 644 sqlite3-$VERS.bin.gz
mv sqlite3-$VERS.bin.gz doc
# Build the sqlite.so and tclsqlite.so shared libraries
# under Linux
#
TCLDIR=/home/drh/tcltk/846/linux/846linux
TCLSTUBLIB=$TCLDIR/libtclstub8.4g.a
CFLAGS="-Os -DSQLITE_ENABLE_FTS3=3 -DSQLITE_ENABLE_RTREE=1"
CFLAGS="$CFLAGS -DHAVE_LOCALTIME_R=1 -DHAVE_GMTIME_R=1"
CFLAGS="$CFLAGS -DSQLITE_ENABLE_COLUMN_METADATA=1"
echo '***** BUILDING shared libraries for linux'
gcc $CFLAGS -shared tclsqlite3.c $TCLSTUBLIB -o tclsqlite3.so -lpthread
strip tclsqlite3.so
chmod 644 tclsqlite3.so
mv tclsqlite3.so tclsqlite-$VERS.so
gzip tclsqlite-$VERS.so
mv tclsqlite-$VERS.so.gz doc
gcc $CFLAGS -shared sqlite3.c -o sqlite3.so -lpthread
strip sqlite3.so
chmod 644 sqlite3.so
mv sqlite3.so sqlite-$VERS.so
gzip sqlite-$VERS.so
mv sqlite-$VERS.so.gz doc
# Build the tclsqlite3.dll and sqlite3.dll shared libraries.
#
. $srcdir/mkdll.sh
echo '***** PACKAGING shared libraries for windows'
echo zip doc/tclsqlite-$VERSW.zip tclsqlite3.dll
zip doc/tclsqlite-$VERSW.zip tclsqlite3.dll
echo zip doc/sqlitedll-$VERSW.zip sqlite3.dll sqlite3.def
zip doc/sqlitedll-$VERSW.zip sqlite3.dll sqlite3.def
# Build the sqlite.exe executable for windows.
#
OPTS='-DSTATIC_BUILD=1 -DNDEBUG=1 -DSQLITE_THREADSAFE=0'
OPTS="$OPTS -DSQLITE_ENABLE_FTS3=1 -DSQLITE_ENABLE_RTREE=1"
i386-mingw32msvc-gcc -Os $OPTS -Itsrc -I$TCLDIR sqlite3.c tsrc/shell.c \
-o sqlite3.exe
zip doc/sqlite-$VERSW.zip sqlite3.exe
# Build a source archive useful for windows.
#
make target_source
cd tsrc
echo '***** BUILDING preprocessed source archives'
rm fts[12]* icu*
rm -f ../doc/sqlite-source-$VERSW.zip
zip ../doc/sqlite-source-$VERSW.zip *
cd ..
cp tsrc/sqlite3.h tsrc/sqlite3ext.h .
cp tsrc/shell.c .
pwd
zip doc/sqlite-amalgamation-$VERSW.zip sqlite3.c sqlite3.h sqlite3ext.h shell.c sqlite3.def
# Construct a tarball of the source tree
#
echo '***** BUILDING source archive'
ORIGIN=`pwd`
cd $srcdir
chmod +x configure
cd ..
mv sqlite sqlite-$VERS
EXCLUDE=`find sqlite-$VERS -print | egrep '(www/|art/|doc/|contrib/|_FOSSIL_)' | sed 's,^, --exclude ,'`
echo "tar czf $ORIGIN/doc/sqlite-$VERS.tar.gz $EXCLUDE sqlite-$VERS"
tar czf $ORIGIN/doc/sqlite-$VERS.tar.gz $EXCLUDE sqlite-$VERS
mv sqlite-$VERS sqlite
cd $ORIGIN
#
# Build RPMS (binary) and Source RPM
#
# Make sure we are properly setup to build RPMs
#
echo "%HOME %{expand:%%(cd; pwd)}" > $HOME/.rpmmacros
echo "%_topdir %{HOME}/rpm" >> $HOME/.rpmmacros
mkdir $HOME/rpm
mkdir $HOME/rpm/BUILD
mkdir $HOME/rpm/SOURCES
mkdir $HOME/rpm/RPMS
mkdir $HOME/rpm/SRPMS
mkdir $HOME/rpm/SPECS
# create the spec file from the template
sed s/SQLITE_VERSION/$VERS/g $srcdir/spec.template > $HOME/rpm/SPECS/sqlite.spec
# copy the source tarball to the rpm directory
cp doc/sqlite-$VERS.tar.gz $HOME/rpm/SOURCES/.
# build all the rpms
rpm -ba $HOME/rpm/SPECS/sqlite.spec >& rpm-$vers.log
# copy the RPMs into the build directory.
mv $HOME/rpm/RPMS/i386/sqlite*-$vers*.rpm doc
mv $HOME/rpm/SRPMS/sqlite-$vers*.rpm doc
# Build the website
#
#cp $srcdir/../historical/* doc
#make doc
#cd doc
#chmod 644 *.gz
-35
View File
@@ -1,35 +0,0 @@
#!/bin/sh
#
# This script is used to compile SQLite and package everything up
# so that it is ready to move to the SQLite website.
#
# Set srcdir to the name of the directory that contains the publish.sh
# script.
#
srcdir=`echo "$0" | sed 's%\(^.*\)/[^/][^/]*$%\1%'`
# Get the makefile.
#
cp $srcdir/Makefile.linux-gcc ./Makefile
chmod +x $srcdir/install-sh
# Get the current version number - needed to help build filenames
#
VERS=`cat $srcdir/VERSION`
VERSW=`sed 's/\./_/g' $srcdir/VERSION`
echo "VERSIONS: $VERS $VERSW"
# Start by building an sqlite shell for linux.
#
make clean
make sqlite3.c
CFLAGS="-Os -DSQLITE_ENABLE_FTS3=1 -DSQLITE_THREADSAFE=0"
NAME=sqlite3-$VERS-osx-x86.bin
echo '***** '"COMPILING $NAME..."
gcc $CFLAGS -Itsrc sqlite3.c tsrc/shell.c -o $NAME -ldl
strip $NAME
chmod 644 $NAME
gzip $NAME
mkdir -p doc
mv $NAME.gz doc
+3 -3
View File
@@ -414,7 +414,7 @@ void sqlite3AlterRenameTable(
assert( pSrc->nSrc==1 );
assert( sqlite3BtreeHoldsAllMutexes(pParse->db) );
pTab = sqlite3LocateTable(pParse, 0, pSrc->a[0].zName, pSrc->a[0].zDatabase);
pTab = sqlite3LocateTableItem(pParse, 0, &pSrc->a[0]);
if( !pTab ) goto exit_rename_table;
iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);
zDb = db->aDb[iDb].zName;
@@ -664,7 +664,7 @@ void sqlite3AlterFinishAddColumn(Parse *pParse, Token *pColDef){
** If there is a NOT NULL constraint, then the default value for the
** column must not be NULL.
*/
if( pCol->isPrimKey ){
if( pCol->colFlags & COLFLAG_PRIMKEY ){
sqlite3ErrorMsg(pParse, "Cannot add a PRIMARY KEY column");
return;
}
@@ -757,7 +757,7 @@ void sqlite3AlterBeginAddColumn(Parse *pParse, SrcList *pSrc){
assert( pParse->pNewTable==0 );
assert( sqlite3BtreeHoldsAllMutexes(db) );
if( db->mallocFailed ) goto exit_begin_add_column;
pTab = sqlite3LocateTable(pParse, 0, pSrc->a[0].zName, pSrc->a[0].zDatabase);
pTab = sqlite3LocateTableItem(pParse, 0, &pSrc->a[0]);
if( !pTab ) goto exit_begin_add_column;
#ifndef SQLITE_OMIT_VIRTUALTABLE
+5 -3
View File
@@ -434,6 +434,7 @@ int sqlite3FixInit(
assert( db->nDb>iDb );
pFix->pParse = pParse;
pFix->zDb = db->aDb[iDb].zName;
pFix->pSchema = db->aDb[iDb].pSchema;
pFix->zType = zType;
pFix->pName = pName;
return 1;
@@ -464,14 +465,15 @@ int sqlite3FixSrcList(
if( NEVER(pList==0) ) return 0;
zDb = pFix->zDb;
for(i=0, pItem=pList->a; i<pList->nSrc; i++, pItem++){
if( pItem->zDatabase==0 ){
pItem->zDatabase = sqlite3DbStrDup(pFix->pParse->db, zDb);
}else if( sqlite3StrICmp(pItem->zDatabase,zDb)!=0 ){
if( pItem->zDatabase && sqlite3StrICmp(pItem->zDatabase, zDb) ){
sqlite3ErrorMsg(pFix->pParse,
"%s %T cannot reference objects in database %s",
pFix->zType, pFix->pName, pItem->zDatabase);
return 1;
}
sqlite3_free(pItem->zDatabase);
pItem->zDatabase = 0;
pItem->pSchema = pFix->pSchema;
#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_TRIGGER)
if( sqlite3FixSelect(pFix, pItem->pSelect) ) return 1;
if( sqlite3FixExpr(pFix, pItem->pOn) ) return 1;
+5 -2
View File
@@ -219,13 +219,16 @@ static int backupOnePage(sqlite3_backup *p, Pgno iSrcPg, const u8 *zSrcData){
const int nCopy = MIN(nSrcPgsz, nDestPgsz);
const i64 iEnd = (i64)iSrcPg*(i64)nSrcPgsz;
#ifdef SQLITE_HAS_CODEC
int nSrcReserve = sqlite3BtreeGetReserve(p->pSrc);
/* Use BtreeGetReserveNoMutex() for the source b-tree, as although it is
** guaranteed that the shared-mutex is held by this thread, handle
** p->pSrc may not actually be the owner. */
int nSrcReserve = sqlite3BtreeGetReserveNoMutex(p->pSrc);
int nDestReserve = sqlite3BtreeGetReserve(p->pDest);
#endif
int rc = SQLITE_OK;
i64 iOff;
assert( sqlite3BtreeGetReserveNoMutex(p->pSrc)>=0 );
assert( p->bDestLocked );
assert( !isFatalError(p->rc) );
assert( iSrcPg!=PENDING_BYTE_PAGE(p->pSrc->pBt) );
+25 -1
View File
@@ -2200,6 +2200,24 @@ int sqlite3BtreeGetPageSize(Btree *p){
return p->pBt->pageSize;
}
#if defined(SQLITE_HAS_CODEC) || defined(SQLITE_DEBUG)
/*
** This function is similar to sqlite3BtreeGetReserve(), except that it
** may only be called if it is guaranteed that the b-tree mutex is already
** held.
**
** This is useful in one special case in the backup API code where it is
** known that the shared b-tree mutex is held, but the mutex on the
** database handle that owns *p is not. In this case if sqlite3BtreeEnter()
** were to be called, it might collide with some other operation on the
** database handle that owns *p, causing undefined behaviour.
*/
int sqlite3BtreeGetReserveNoMutex(Btree *p){
assert( sqlite3_mutex_held(p->pBt->mutex) );
return p->pBt->pageSize - p->pBt->usableSize;
}
#endif /* SQLITE_HAS_CODEC || SQLITE_DEBUG */
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) || !defined(SQLITE_OMIT_VACUUM)
/*
** Return the number of bytes of space at the end of every page that
@@ -5256,7 +5274,7 @@ static int clearCell(MemPage *pPage, unsigned char *pCell){
return SQLITE_OK; /* No overflow pages. Return without doing anything */
}
if( pCell+info.iOverflow+3 > pPage->aData+pPage->maskPage ){
return SQLITE_CORRUPT; /* Cell extends past end of page */
return SQLITE_CORRUPT_BKPT; /* Cell extends past end of page */
}
ovflPgno = get4byte(&pCell[info.iOverflow]);
assert( pBt->usableSize > 4 );
@@ -5922,6 +5940,9 @@ static void copyNodeContent(MemPage *pFrom, MemPage *pTo, int *pRC){
** If aOvflSpace is set to a null pointer, this function returns
** SQLITE_NOMEM.
*/
#if defined(_MSC_VER) && _MSC_VER >= 1700 && defined(_M_ARM)
#pragma optimize("", off)
#endif
static int balance_nonroot(
MemPage *pParent, /* Parent page of siblings being balanced */
int iParentIdx, /* Index of "the page" in pParent */
@@ -6552,6 +6573,9 @@ balance_cleanup:
return rc;
}
#if defined(_MSC_VER) && _MSC_VER >= 1700 && defined(_M_ARM)
#pragma optimize("", on)
#endif
/*
+3
View File
@@ -71,6 +71,9 @@ int sqlite3BtreeMaxPageCount(Btree*,int);
u32 sqlite3BtreeLastPage(Btree*);
int sqlite3BtreeSecureDelete(Btree*,int);
int sqlite3BtreeGetReserve(Btree*);
#if defined(SQLITE_HAS_CODEC) || defined(SQLITE_DEBUG)
int sqlite3BtreeGetReserveNoMutex(Btree *p);
#endif
int sqlite3BtreeSetAutoVacuum(Btree *, int);
int sqlite3BtreeGetAutoVacuum(Btree *);
int sqlite3BtreeBeginTrans(Btree*,int);
+30 -10
View File
@@ -319,6 +319,31 @@ Table *sqlite3LocateTable(
return p;
}
/*
** Locate the table identified by *p.
**
** This is a wrapper around sqlite3LocateTable(). The difference between
** sqlite3LocateTable() and this function is that this function restricts
** the search to schema (p->pSchema) if it is not NULL. p->pSchema may be
** non-NULL if it is part of a view or trigger program definition. See
** sqlite3FixSrcList() for details.
*/
Table *sqlite3LocateTableItem(
Parse *pParse,
int isView,
struct SrcList_item *p
){
const char *zDb;
assert( p->pSchema==0 || p->zDatabase==0 );
if( p->pSchema ){
int iDb = sqlite3SchemaToIndex(pParse->db, p->pSchema);
zDb = pParse->db->aDb[iDb].zName;
}else{
zDb = p->zDatabase;
}
return sqlite3LocateTable(pParse, isView, p->zName, zDb);
}
/*
** Locate the in-memory structure that describes
** a particular index given the name of that index
@@ -1169,7 +1194,7 @@ void sqlite3AddPrimaryKey(
pTab->tabFlags |= TF_HasPrimaryKey;
if( pList==0 ){
iCol = pTab->nCol - 1;
pTab->aCol[iCol].isPrimKey = 1;
pTab->aCol[iCol].colFlags |= COLFLAG_PRIMKEY;
}else{
for(i=0; i<pList->nExpr; i++){
for(iCol=0; iCol<pTab->nCol; iCol++){
@@ -1178,7 +1203,7 @@ void sqlite3AddPrimaryKey(
}
}
if( iCol<pTab->nCol ){
pTab->aCol[iCol].isPrimKey = 1;
pTab->aCol[iCol].colFlags |= COLFLAG_PRIMKEY;
}
}
if( pList->nExpr>1 ) iCol = -1;
@@ -1295,10 +1320,7 @@ CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char *zName){
pColl = sqlite3FindCollSeq(db, enc, zName, initbusy);
if( !initbusy && (!pColl || !pColl->xCmp) ){
pColl = sqlite3GetCollSeq(db, enc, pColl, zName);
if( !pColl ){
sqlite3ErrorMsg(pParse, "no such collation sequence: %s", zName);
}
pColl = sqlite3GetCollSeq(pParse, enc, pColl, zName);
}
return pColl;
@@ -2114,8 +2136,7 @@ void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView, int noErr){
assert( pParse->nErr==0 );
assert( pName->nSrc==1 );
if( noErr ) db->suppressErr++;
pTab = sqlite3LocateTable(pParse, isView,
pName->a[0].zName, pName->a[0].zDatabase);
pTab = sqlite3LocateTableItem(pParse, isView, &pName->a[0]);
if( noErr ) db->suppressErr--;
if( pTab==0 ){
@@ -2555,8 +2576,7 @@ Index *sqlite3CreateIndex(
** sqlite3FixSrcList can never fail. */
assert(0);
}
pTab = sqlite3LocateTable(pParse, 0, pTblName->a[0].zName,
pTblName->a[0].zDatabase);
pTab = sqlite3LocateTableItem(pParse, 0, &pTblName->a[0]);
if( !pTab || db->mallocFailed ) goto exit_create_index;
assert( db->aDb[iDb].pSchema==pTab->pSchema );
}else{
+7 -5
View File
@@ -75,17 +75,18 @@ static int synthCollSeq(sqlite3 *db, CollSeq *pColl){
**
** The return value is either the collation sequence to be used in database
** db for collation type name zName, length nName, or NULL, if no collation
** sequence can be found.
** sequence can be found. If no collation is found, leave an error message.
**
** See also: sqlite3LocateCollSeq(), sqlite3FindCollSeq()
*/
CollSeq *sqlite3GetCollSeq(
sqlite3* db, /* The database connection */
Parse *pParse, /* Parsing context */
u8 enc, /* The desired encoding for the collating sequence */
CollSeq *pColl, /* Collating sequence with native encoding, or NULL */
const char *zName /* Collating sequence name */
){
CollSeq *p;
sqlite3 *db = pParse->db;
p = pColl;
if( !p ){
@@ -102,6 +103,9 @@ CollSeq *sqlite3GetCollSeq(
p = 0;
}
assert( !p || p->xCmp );
if( p==0 ){
sqlite3ErrorMsg(pParse, "no such collation sequence: %s", zName);
}
return p;
}
@@ -120,10 +124,8 @@ int sqlite3CheckCollSeq(Parse *pParse, CollSeq *pColl){
if( pColl ){
const char *zName = pColl->zName;
sqlite3 *db = pParse->db;
CollSeq *p = sqlite3GetCollSeq(db, ENC(db), pColl, zName);
CollSeq *p = sqlite3GetCollSeq(pParse, ENC(db), pColl, zName);
if( !p ){
sqlite3ErrorMsg(pParse, "no such collation sequence: %s", zName);
pParse->nErr++;
return SQLITE_ERROR;
}
assert( p==pColl );
+3
View File
@@ -338,6 +338,9 @@ static const char * const azCompileOpt[] = {
#ifdef SQLITE_PROXY_DEBUG
"PROXY_DEBUG",
#endif
#ifdef SQLITE_RTREE_INT_ONLY
"RTREE_INT_ONLY",
#endif
#ifdef SQLITE_SECURE_DELETE
"SECURE_DELETE",
#endif
+4 -2
View File
@@ -32,7 +32,7 @@ Table *sqlite3SrcListLookup(Parse *pParse, SrcList *pSrc){
struct SrcList_item *pItem = pSrc->a;
Table *pTab;
assert( pItem && pSrc->nSrc==1 );
pTab = sqlite3LocateTable(pParse, 0, pItem->zName, pItem->zDatabase);
pTab = sqlite3LocateTableItem(pParse, 0, pItem);
sqlite3DeleteTable(pParse->db, pItem->pTab);
pItem->pTab = pTab;
if( pTab ){
@@ -638,7 +638,9 @@ int sqlite3GenerateIndexKey(
}
if( doMakeRec ){
const char *zAff;
if( pTab->pSelect || (pParse->db->flags & SQLITE_IdxRealAsInt)!=0 ){
if( pTab->pSelect
|| OptimizationDisabled(pParse->db, SQLITE_IdxRealAsInt)
){
zAff = 0;
}else{
zAff = sqlite3IndexAffinityStr(v, pIdx);
+25 -25
View File
@@ -930,6 +930,7 @@ SrcList *sqlite3SrcListDup(sqlite3 *db, SrcList *p, int flags){
struct SrcList_item *pNewItem = &pNew->a[i];
struct SrcList_item *pOldItem = &p->a[i];
Table *pTab;
pNewItem->pSchema = pOldItem->pSchema;
pNewItem->zDatabase = sqlite3DbStrDup(db, pOldItem->zDatabase);
pNewItem->zName = sqlite3DbStrDup(db, pOldItem->zName);
pNewItem->zAlias = sqlite3DbStrDup(db, pOldItem->zAlias);
@@ -1420,12 +1421,16 @@ int sqlite3CodeOnce(Parse *pParse){
/*
** This function is used by the implementation of the IN (...) operator.
** It's job is to find or create a b-tree structure that may be used
** either to test for membership of the (...) set or to iterate through
** its members, skipping duplicates.
** The pX parameter is the expression on the RHS of the IN operator, which
** might be either a list of expressions or a subquery.
**
** The job of this routine is to find or create a b-tree object that can
** be used either to test for membership in the RHS set or to iterate through
** all members of the RHS set, skipping duplicates.
**
** A cursor is opened on the b-tree object that the RHS of the IN operator
** and pX->iTable is set to the index of that cursor.
**
** The index of the cursor opened on the b-tree (database table, database index
** or ephermal table) is stored in pX->iTable before this function returns.
** The returned value of this function indicates the b-tree type, as follows:
**
** IN_INDEX_ROWID - The cursor was opened on a database table.
@@ -1433,11 +1438,16 @@ int sqlite3CodeOnce(Parse *pParse){
** IN_INDEX_EPH - The cursor was opened on a specially created and
** populated epheremal table.
**
** An existing b-tree may only be used if the SELECT is of the simple
** form:
** An existing b-tree might be used if the RHS expression pX is a simple
** subquery such as:
**
** SELECT <column> FROM <table>
**
** If the RHS of the IN operator is a list or a more complex subquery, then
** an ephemeral table might need to be generated from the RHS and then
** pX->iTable made to point to the ephermeral table instead of an
** existing table.
**
** If the prNotFound parameter is 0, then the b-tree will be used to iterate
** through the set members, skipping any duplicates. In this case an
** epheremal table must be used unless the selected <column> is guaranteed
@@ -1533,8 +1543,7 @@ int sqlite3FindInIndex(Parse *pParse, Expr *pX, int *prNotFound){
** comparison is the same as the affinity of the column. If
** it is not, it is not possible to use any index.
*/
char aff = comparisonAffinity(pX);
int affinity_ok = (pTab->aCol[iCol].affinity==aff||aff==SQLITE_AFF_NONE);
int affinity_ok = sqlite3IndexAffinityOk(pX, pTab->aCol[iCol].affinity);
for(pIdx=pTab->pIndex; pIdx && eType==0 && affinity_ok; pIdx=pIdx->pNext){
if( (pIdx->aiColumn[0]==iCol)
@@ -1662,6 +1671,7 @@ int sqlite3CodeSubselect(
case TK_IN: {
char affinity; /* Affinity of the LHS of the IN */
KeyInfo keyInfo; /* Keyinfo for the generated table */
static u8 sortOrder = 0; /* Fake aSortOrder for keyInfo */
int addr; /* Address of OP_OpenEphemeral instruction */
Expr *pLeft = pExpr->pLeft; /* the LHS of the IN operator */
@@ -1689,6 +1699,7 @@ int sqlite3CodeSubselect(
if( rMayHaveNull==0 ) sqlite3VdbeChangeP5(v, BTREE_UNORDERED);
memset(&keyInfo, 0, sizeof(keyInfo));
keyInfo.nField = 1;
keyInfo.aSortOrder = &sortOrder;
if( ExprHasProperty(pExpr, EP_xIsSelect) ){
/* Case 1: expr IN (SELECT ...)
@@ -1729,6 +1740,7 @@ int sqlite3CodeSubselect(
affinity = SQLITE_AFF_NONE;
}
keyInfo.aColl[0] = sqlite3ExprCollSeq(pParse, pExpr->pLeft);
keyInfo.aSortOrder = &sortOrder;
/* Loop through each expression in <exprlist>. */
r1 = sqlite3GetTempReg(pParse);
@@ -2055,7 +2067,7 @@ void sqlite3ExprCacheStore(Parse *pParse, int iTab, int iCol, int iReg){
** for testing only - to verify that SQLite always gets the same answer
** with and without the column cache.
*/
if( pParse->db->flags & SQLITE_ColumnCache ) return;
if( OptimizationDisabled(pParse->db, SQLITE_ColumnCache) ) return;
/* First replace any existing entry.
**
@@ -2252,8 +2264,8 @@ void sqlite3ExprCacheAffinityChange(Parse *pParse, int iStart, int iCount){
void sqlite3ExprCodeMove(Parse *pParse, int iFrom, int iTo, int nReg){
int i;
struct yColCache *p;
if( NEVER(iFrom==iTo) ) return;
sqlite3VdbeAddOp3(pParse->pVdbe, OP_Move, iFrom, iTo, nReg);
assert( iFrom>=iTo+nReg || iFrom+nReg<=iTo );
sqlite3VdbeAddOp3(pParse->pVdbe, OP_Move, iFrom, iTo, nReg-1);
for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){
int x = p->iReg;
if( x>=iFrom && x<iFrom+nReg ){
@@ -2262,18 +2274,6 @@ void sqlite3ExprCodeMove(Parse *pParse, int iFrom, int iTo, int nReg){
}
}
/*
** Generate code to copy content from registers iFrom...iFrom+nReg-1
** over to iTo..iTo+nReg-1.
*/
void sqlite3ExprCodeCopy(Parse *pParse, int iFrom, int iTo, int nReg){
int i;
if( NEVER(iFrom==iTo) ) return;
for(i=0; i<nReg; i++){
sqlite3VdbeAddOp2(pParse->pVdbe, OP_Copy, iFrom+i, iTo+i);
}
}
#if defined(SQLITE_DEBUG) || defined(SQLITE_COVERAGE_TEST)
/*
** Return true if any register in the range iFrom..iTo (inclusive)
@@ -3383,7 +3383,7 @@ static int evalConstExpr(Walker *pWalker, Expr *pExpr){
void sqlite3ExprCodeConstants(Parse *pParse, Expr *pExpr){
Walker w;
if( pParse->cookieGoto ) return;
if( (pParse->db->flags & SQLITE_FactorOutConst)!=0 ) return;
if( OptimizationDisabled(pParse->db, SQLITE_FactorOutConst) ) return;
w.xExprCallback = evalConstExpr;
w.xSelectCallback = 0;
w.pParse = pParse;
+2 -1
View File
@@ -925,7 +925,8 @@ int sqlite3FkRequired(
int iKey;
for(iKey=0; iKey<pTab->nCol; iKey++){
Column *pCol = &pTab->aCol[iKey];
if( (zKey ? !sqlite3StrICmp(pCol->zName, zKey) : pCol->isPrimKey) ){
if( (zKey ? !sqlite3StrICmp(pCol->zName, zKey)
: (pCol->colFlags & COLFLAG_PRIMKEY)!=0) ){
if( aChange[iKey]>=0 ) return 1;
if( iKey==pTab->iPKey && chngRowid ) return 1;
}
+25 -44
View File
@@ -367,33 +367,14 @@ static void lowerFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
}
}
#if 0 /* This function is never used. */
/*
** The COALESCE() and IFNULL() functions used to be implemented as shown
** here. But now they are implemented as VDBE code so that unused arguments
** do not have to be computed. This legacy implementation is retained as
** comment.
** The COALESCE() and IFNULL() functions are implemented as VDBE code so
** that unused argument values do not have to be computed. However, we
** still need some kind of function implementation for this routines in
** the function table. That function implementation will never be called
** so it doesn't matter what the implementation is. We might as well use
** the "version()" function as a substitute.
*/
/*
** Implementation of the IFNULL(), NVL(), and COALESCE() functions.
** All three do the same thing. They return the first non-NULL
** argument.
*/
static void ifnullFunc(
sqlite3_context *context,
int argc,
sqlite3_value **argv
){
int i;
for(i=0; i<argc; i++){
if( SQLITE_NULL!=sqlite3_value_type(argv[i]) ){
sqlite3_result_value(context, argv[i]);
break;
}
}
}
#endif /* NOT USED */
#define ifnullFunc versionFunc /* Substitute function - never called */
/*
@@ -512,7 +493,7 @@ struct compareInfo {
** whereas only characters less than 0x80 do in ASCII.
*/
#if defined(SQLITE_EBCDIC)
# define sqlite3Utf8Read(A,C) (*(A++))
# define sqlite3Utf8Read(A) (*((*A)++))
# define GlogUpperToLower(A) A = sqlite3UpperToLower[A]
#else
# define GlogUpperToLower(A) if( !((A)&~0x7f) ){ A = sqlite3UpperToLower[A]; }
@@ -569,18 +550,18 @@ static int patternCompare(
u8 noCase = pInfo->noCase;
int prevEscape = 0; /* True if the previous character was 'escape' */
while( (c = sqlite3Utf8Read(zPattern,&zPattern))!=0 ){
if( !prevEscape && c==matchAll ){
while( (c=sqlite3Utf8Read(zPattern,&zPattern)) == matchAll
while( (c = sqlite3Utf8Read(&zPattern))!=0 ){
if( c==matchAll && !prevEscape ){
while( (c=sqlite3Utf8Read(&zPattern)) == matchAll
|| c == matchOne ){
if( c==matchOne && sqlite3Utf8Read(zString, &zString)==0 ){
if( c==matchOne && sqlite3Utf8Read(&zString)==0 ){
return 0;
}
}
if( c==0 ){
return 1;
}else if( c==esc ){
c = sqlite3Utf8Read(zPattern, &zPattern);
c = sqlite3Utf8Read(&zPattern);
if( c==0 ){
return 0;
}
@@ -592,25 +573,25 @@ static int patternCompare(
}
return *zString!=0;
}
while( (c2 = sqlite3Utf8Read(zString,&zString))!=0 ){
while( (c2 = sqlite3Utf8Read(&zString))!=0 ){
if( noCase ){
GlogUpperToLower(c2);
GlogUpperToLower(c);
while( c2 != 0 && c2 != c ){
c2 = sqlite3Utf8Read(zString, &zString);
c2 = sqlite3Utf8Read(&zString);
GlogUpperToLower(c2);
}
}else{
while( c2 != 0 && c2 != c ){
c2 = sqlite3Utf8Read(zString, &zString);
c2 = sqlite3Utf8Read(&zString);
}
}
if( c2==0 ) return 0;
if( patternCompare(zPattern,zString,pInfo,esc) ) return 1;
}
return 0;
}else if( !prevEscape && c==matchOne ){
if( sqlite3Utf8Read(zString, &zString)==0 ){
}else if( c==matchOne && !prevEscape ){
if( sqlite3Utf8Read(&zString)==0 ){
return 0;
}
}else if( c==matchSet ){
@@ -618,20 +599,20 @@ static int patternCompare(
assert( esc==0 ); /* This only occurs for GLOB, not LIKE */
seen = 0;
invert = 0;
c = sqlite3Utf8Read(zString, &zString);
c = sqlite3Utf8Read(&zString);
if( c==0 ) return 0;
c2 = sqlite3Utf8Read(zPattern, &zPattern);
c2 = sqlite3Utf8Read(&zPattern);
if( c2=='^' ){
invert = 1;
c2 = sqlite3Utf8Read(zPattern, &zPattern);
c2 = sqlite3Utf8Read(&zPattern);
}
if( c2==']' ){
if( c==']' ) seen = 1;
c2 = sqlite3Utf8Read(zPattern, &zPattern);
c2 = sqlite3Utf8Read(&zPattern);
}
while( c2 && c2!=']' ){
if( c2=='-' && zPattern[0]!=']' && zPattern[0]!=0 && prior_c>0 ){
c2 = sqlite3Utf8Read(zPattern, &zPattern);
c2 = sqlite3Utf8Read(&zPattern);
if( c>=prior_c && c<=c2 ) seen = 1;
prior_c = 0;
}else{
@@ -640,7 +621,7 @@ static int patternCompare(
}
prior_c = c2;
}
c2 = sqlite3Utf8Read(zPattern, &zPattern);
c2 = sqlite3Utf8Read(&zPattern);
}
if( c2==0 || (seen ^ invert)==0 ){
return 0;
@@ -648,7 +629,7 @@ static int patternCompare(
}else if( esc==c && !prevEscape ){
prevEscape = 1;
}else{
c2 = sqlite3Utf8Read(zString, &zString);
c2 = sqlite3Utf8Read(&zString);
if( noCase ){
GlogUpperToLower(c);
GlogUpperToLower(c2);
@@ -720,7 +701,7 @@ static void likeFunc(
"ESCAPE expression must be a single character", -1);
return;
}
escape = sqlite3Utf8Read(zEsc, &zEsc);
escape = sqlite3Utf8Read(&zEsc);
}
if( zA && zB ){
struct compareInfo *pInfo = sqlite3_user_data(context);
+5
View File
@@ -133,6 +133,10 @@ const unsigned char sqlite3CtypeMap[256] = {
# define SQLITE_USE_URI 0
#endif
#ifndef SQLITE_ALLOW_COVERING_INDEX_SCAN
# define SQLITE_ALLOW_COVERING_INDEX_SCAN 1
#endif
/*
** The following singleton contains the global configuration for
** the SQLite library.
@@ -142,6 +146,7 @@ SQLITE_WSD struct Sqlite3Config sqlite3Config = {
1, /* bCoreMutex */
SQLITE_THREADSAFE==1, /* bFullMutex */
SQLITE_USE_URI, /* bOpenUri */
SQLITE_ALLOW_COVERING_INDEX_SCAN, /* bUseCis */
0x7ffffffe, /* mxStrlen */
128, /* szLookaside */
500, /* nLookaside */
+101 -46
View File
@@ -320,6 +320,97 @@ void sqlite3AutoincrementEnd(Parse *pParse){
#endif /* SQLITE_OMIT_AUTOINCREMENT */
/*
** Generate code for a co-routine that will evaluate a subquery one
** row at a time.
**
** The pSelect parameter is the subquery that the co-routine will evaluation.
** Information about the location of co-routine and the registers it will use
** is returned by filling in the pDest object.
**
** Registers are allocated as follows:
**
** pDest->iSDParm The register holding the next entry-point of the
** co-routine. Run the co-routine to its next breakpoint
** by calling "OP_Yield $X" where $X is pDest->iSDParm.
**
** pDest->iSDParm+1 The register holding the "completed" flag for the
** co-routine. This register is 0 if the previous Yield
** generated a new result row, or 1 if the subquery
** has completed. If the Yield is called again
** after this register becomes 1, then the VDBE will
** halt with an SQLITE_INTERNAL error.
**
** pDest->iSdst First result register.
**
** pDest->nSdst Number of result registers.
**
** This routine handles all of the register allocation and fills in the
** pDest structure appropriately.
**
** Here is a schematic of the generated code assuming that X is the
** co-routine entry-point register reg[pDest->iSDParm], that EOF is the
** completed flag reg[pDest->iSDParm+1], and R and S are the range of
** registers that hold the result set, reg[pDest->iSdst] through
** reg[pDest->iSdst+pDest->nSdst-1]:
**
** X <- A
** EOF <- 0
** goto B
** A: setup for the SELECT
** loop rows in the SELECT
** load results into registers R..S
** yield X
** end loop
** cleanup after the SELECT
** EOF <- 1
** yield X
** halt-error
** B:
**
** To use this subroutine, the caller generates code as follows:
**
** [ Co-routine generated by this subroutine, shown above ]
** S: yield X
** if EOF goto E
** if skip this row, goto C
** if terminate loop, goto E
** deal with this row
** C: goto S
** E:
*/
int sqlite3CodeCoroutine(Parse *pParse, Select *pSelect, SelectDest *pDest){
int regYield; /* Register holding co-routine entry-point */
int regEof; /* Register holding co-routine completion flag */
int addrTop; /* Top of the co-routine */
int j1; /* Jump instruction */
int rc; /* Result code */
Vdbe *v; /* VDBE under construction */
regYield = ++pParse->nMem;
regEof = ++pParse->nMem;
v = sqlite3GetVdbe(pParse);
addrTop = sqlite3VdbeCurrentAddr(v);
sqlite3VdbeAddOp2(v, OP_Integer, addrTop+2, regYield); /* X <- A */
VdbeComment((v, "Co-routine entry point"));
sqlite3VdbeAddOp2(v, OP_Integer, 0, regEof); /* EOF <- 0 */
VdbeComment((v, "Co-routine completion flag"));
sqlite3SelectDestInit(pDest, SRT_Coroutine, regYield);
j1 = sqlite3VdbeAddOp2(v, OP_Goto, 0, 0);
rc = sqlite3Select(pParse, pSelect, pDest);
assert( pParse->nErr==0 || rc );
if( pParse->db->mallocFailed && rc==SQLITE_OK ) rc = SQLITE_NOMEM;
if( rc ) return rc;
sqlite3VdbeAddOp2(v, OP_Integer, 1, regEof); /* EOF <- 1 */
sqlite3VdbeAddOp1(v, OP_Yield, regYield); /* yield X */
sqlite3VdbeAddOp2(v, OP_Halt, SQLITE_INTERNAL, OE_Abort);
VdbeComment((v, "End of coroutine"));
sqlite3VdbeJumpHere(v, j1); /* label B: */
return rc;
}
/* Forward declaration */
static int xferOptimization(
Parse *pParse, /* Parser context */
@@ -568,51 +659,12 @@ void sqlite3Insert(
** co-routine is the common header to the 3rd and 4th templates.
*/
if( pSelect ){
/* Data is coming from a SELECT. Generate code to implement that SELECT
** as a co-routine. The code is common to both the 3rd and 4th
** templates:
**
** EOF <- 0
** X <- A
** goto B
** A: setup for the SELECT
** loop over the tables in the SELECT
** load value into register R..R+n
** yield X
** end loop
** cleanup after the SELECT
** EOF <- 1
** yield X
** halt-error
**
** On each invocation of the co-routine, it puts a single row of the
** SELECT result into registers dest.iMem...dest.iMem+dest.nMem-1.
** (These output registers are allocated by sqlite3Select().) When
** the SELECT completes, it sets the EOF flag stored in regEof.
*/
int rc, j1;
regEof = ++pParse->nMem;
sqlite3VdbeAddOp2(v, OP_Integer, 0, regEof); /* EOF <- 0 */
VdbeComment((v, "SELECT eof flag"));
sqlite3SelectDestInit(&dest, SRT_Coroutine, ++pParse->nMem);
addrSelect = sqlite3VdbeCurrentAddr(v)+2;
sqlite3VdbeAddOp2(v, OP_Integer, addrSelect-1, dest.iSDParm);
j1 = sqlite3VdbeAddOp2(v, OP_Goto, 0, 0);
VdbeComment((v, "Jump over SELECT coroutine"));
/* Resolve the expressions in the SELECT statement and execute it. */
rc = sqlite3Select(pParse, pSelect, &dest);
assert( pParse->nErr==0 || rc );
if( rc || NEVER(pParse->nErr) || db->mallocFailed ){
goto insert_cleanup;
}
sqlite3VdbeAddOp2(v, OP_Integer, 1, regEof); /* EOF <- 1 */
sqlite3VdbeAddOp1(v, OP_Yield, dest.iSDParm); /* yield X */
sqlite3VdbeAddOp2(v, OP_Halt, SQLITE_INTERNAL, OE_Abort);
VdbeComment((v, "End of SELECT coroutine"));
sqlite3VdbeJumpHere(v, j1); /* label B: */
/* Data is coming from a SELECT. Generate a co-routine to run that
** SELECT. */
int rc = sqlite3CodeCoroutine(pParse, pSelect, &dest);
if( rc ) goto insert_cleanup;
regEof = dest.iSDParm + 1;
regFromSelect = dest.iSdst;
assert( pSelect->pEList );
nColumn = pSelect->pEList->nExpr;
@@ -1222,7 +1274,9 @@ void sqlite3GenerateConstraintChecks(
onError = overrideError!=OE_Default ? overrideError : OE_Abort;
for(i=0; i<pCheck->nExpr; i++){
int allOk = sqlite3VdbeMakeLabel(v);
sqlite3ExprIfTrue(pParse, pCheck->a[i].pExpr, allOk, SQLITE_JUMPIFNULL);
Expr *pDup = sqlite3ExprDup(db, pCheck->a[i].pExpr, 0);
if( pDup==0 ) break;
sqlite3ExprIfTrue(pParse, pDup, allOk, SQLITE_JUMPIFNULL);
if( onError==OE_Ignore ){
sqlite3VdbeAddOp2(v, OP_Goto, 0, ignoreDest);
}else{
@@ -1236,6 +1290,7 @@ void sqlite3GenerateConstraintChecks(
sqlite3HaltConstraint(pParse, onError, zConsName, P4_DYNAMIC);
}
sqlite3VdbeResolveLabel(v, allOk);
sqlite3ExprDelete(db, pDup);
}
}
#endif /* !defined(SQLITE_OMIT_CHECK) */
@@ -1691,7 +1746,7 @@ static int xferOptimization(
** we have to check the semantics.
*/
pItem = pSelect->pSrc->a;
pSrc = sqlite3LocateTable(pParse, 0, pItem->zName, pItem->zDatabase);
pSrc = sqlite3LocateTableItem(pParse, 0, pItem);
if( pSrc==0 ){
return 0; /* FROM clause does not contain a real table */
}
+18 -4
View File
@@ -475,6 +475,11 @@ int sqlite3_config(int op, ...){
break;
}
case SQLITE_CONFIG_COVERING_INDEX_SCAN: {
sqlite3GlobalConfig.bUseCis = va_arg(ap, int);
break;
}
default: {
rc = SQLITE_ERROR;
break;
@@ -1116,6 +1121,7 @@ int sqlite3_busy_handler(
db->busyHandler.xFunc = xBusy;
db->busyHandler.pArg = pArg;
db->busyHandler.nBusy = 0;
db->busyTimeout = 0;
sqlite3_mutex_leave(db->mutex);
return SQLITE_OK;
}
@@ -1153,8 +1159,8 @@ void sqlite3_progress_handler(
*/
int sqlite3_busy_timeout(sqlite3 *db, int ms){
if( ms>0 ){
db->busyTimeout = ms;
sqlite3_busy_handler(db, sqliteDefaultBusyCallback, (void*)db);
db->busyTimeout = ms;
}else{
sqlite3_busy_handler(db, 0, 0);
}
@@ -1767,6 +1773,15 @@ int sqlite3_extended_errcode(sqlite3 *db){
return db->errCode;
}
/*
** Return a string that describes the kind of error specified in the
** argument. For now, this simply calls the internal sqlite3ErrStr()
** function.
*/
const char *sqlite3_errstr(int rc){
return sqlite3ErrStr(rc);
}
/*
** Create a new collating function for database "db". The name is zName
** and the encoding is enc.
@@ -2741,7 +2756,7 @@ int sqlite3_table_column_metadata(
zDataType = pCol->zType;
zCollSeq = pCol->zColl;
notnull = pCol->notNull!=0;
primarykey = pCol->isPrimKey!=0;
primarykey = (pCol->colFlags & COLFLAG_PRIMKEY)!=0;
autoinc = pTab->iPKey==iCol && (pTab->tabFlags & TF_Autoincrement)!=0;
}else{
zDataType = "INTEGER";
@@ -3004,8 +3019,7 @@ int sqlite3_test_control(int op, ...){
*/
case SQLITE_TESTCTRL_OPTIMIZATIONS: {
sqlite3 *db = va_arg(ap, sqlite3*);
int x = va_arg(ap,int);
db->flags = (x & SQLITE_OptMask) | (db->flags & ~SQLITE_OptMask);
db->dbOptFlags = (u8)(va_arg(ap, int) & 0xff);
break;
}
+4
View File
@@ -3010,6 +3010,8 @@ static int seekAndRead(unixFile *id, sqlite3_int64 offset, void *pBuf, int cnt){
i64 newOffset;
#endif
TIMER_START;
assert( cnt==(cnt&0x1ffff) );
cnt &= 0x1ffff;
do{
#if defined(USE_PREAD)
got = osPread(id->h, pBuf, cnt, offset);
@@ -3099,6 +3101,8 @@ static int seekAndWrite(unixFile *id, i64 offset, const void *pBuf, int cnt){
#if (!defined(USE_PREAD) && !defined(USE_PREAD64))
i64 newOffset;
#endif
assert( cnt==(cnt&0x1ffff) );
cnt &= 0x1ffff;
TIMER_START;
#if defined(USE_PREAD)
do{ got = osPwrite(id->h, pBuf, cnt, offset); }while( got<0 && errno==EINTR );
+201 -98
View File
@@ -24,6 +24,66 @@
*/
#include "os_common.h"
/*
** Compiling and using WAL mode requires several APIs that are only
** available in Windows platforms based on the NT kernel.
*/
#if !SQLITE_OS_WINNT && !defined(SQLITE_OMIT_WAL)
# error "WAL mode requires support from the Windows NT kernel, compile\
with SQLITE_OMIT_WAL."
#endif
/*
** Are most of the Win32 ANSI APIs available (i.e. with certain exceptions
** based on the sub-platform)?
*/
#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT
# define SQLITE_WIN32_HAS_ANSI
#endif
/*
** Are most of the Win32 Unicode APIs available (i.e. with certain exceptions
** based on the sub-platform)?
*/
#if SQLITE_OS_WINCE || SQLITE_OS_WINNT || SQLITE_OS_WINRT
# define SQLITE_WIN32_HAS_WIDE
#endif
/*
** Do we need to manually define the Win32 file mapping APIs for use with WAL
** mode (e.g. these APIs are available in the Windows CE SDK; however, they
** are not present in the header file)?
*/
#if SQLITE_WIN32_FILEMAPPING_API && !defined(SQLITE_OMIT_WAL)
/*
** Two of the file mapping APIs are different under WinRT. Figure out which
** set we need.
*/
#if SQLITE_OS_WINRT
HANDLE WINAPI CreateFileMappingFromApp(HANDLE, LPSECURITY_ATTRIBUTES, \
ULONG, ULONG64, LPCWSTR);
LPVOID WINAPI MapViewOfFileFromApp(HANDLE, ULONG, ULONG64, SIZE_T);
#else
#if defined(SQLITE_WIN32_HAS_ANSI)
HANDLE WINAPI CreateFileMappingA(HANDLE, LPSECURITY_ATTRIBUTES, DWORD, \
DWORD, DWORD, LPCSTR);
#endif /* defined(SQLITE_WIN32_HAS_ANSI) */
#if defined(SQLITE_WIN32_HAS_WIDE)
HANDLE WINAPI CreateFileMappingW(HANDLE, LPSECURITY_ATTRIBUTES, DWORD, \
DWORD, DWORD, LPCWSTR);
#endif /* defined(SQLITE_WIN32_HAS_WIDE) */
LPVOID WINAPI MapViewOfFile(HANDLE, DWORD, DWORD, DWORD, SIZE_T);
#endif /* SQLITE_OS_WINRT */
/*
** This file mapping API is common to both Win32 and WinRT.
*/
BOOL WINAPI UnmapViewOfFile(LPCVOID);
#endif /* SQLITE_WIN32_FILEMAPPING_API && !defined(SQLITE_OMIT_WAL) */
/*
** Macro to find the minimum of two numeric values.
*/
@@ -229,14 +289,6 @@ int sqlite3_os_type = 0;
static int sqlite3_os_type = 0;
#endif
#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT
# define SQLITE_WIN32_HAS_ANSI
#endif
#if SQLITE_OS_WINCE || SQLITE_OS_WINNT || SQLITE_OS_WINRT
# define SQLITE_WIN32_HAS_WIDE
#endif
#ifndef SYSCALL
# define SYSCALL sqlite3_syscall_ptr
#endif
@@ -308,6 +360,16 @@ static struct win_syscall {
#define osCreateFileW ((HANDLE(WINAPI*)(LPCWSTR,DWORD,DWORD, \
LPSECURITY_ATTRIBUTES,DWORD,DWORD,HANDLE))aSyscall[5].pCurrent)
#if (!SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_ANSI) && \
!defined(SQLITE_OMIT_WAL))
{ "CreateFileMappingA", (SYSCALL)CreateFileMappingA, 0 },
#else
{ "CreateFileMappingA", (SYSCALL)0, 0 },
#endif
#define osCreateFileMappingA ((HANDLE(WINAPI*)(HANDLE,LPSECURITY_ATTRIBUTES, \
DWORD,DWORD,DWORD,LPCSTR))aSyscall[6].pCurrent)
#if SQLITE_OS_WINCE || (!SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE) && \
!defined(SQLITE_OMIT_WAL))
{ "CreateFileMappingW", (SYSCALL)CreateFileMappingW, 0 },
@@ -316,7 +378,7 @@ static struct win_syscall {
#endif
#define osCreateFileMappingW ((HANDLE(WINAPI*)(HANDLE,LPSECURITY_ATTRIBUTES, \
DWORD,DWORD,DWORD,LPCWSTR))aSyscall[6].pCurrent)
DWORD,DWORD,DWORD,LPCWSTR))aSyscall[7].pCurrent)
#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE)
{ "CreateMutexW", (SYSCALL)CreateMutexW, 0 },
@@ -325,7 +387,7 @@ static struct win_syscall {
#endif
#define osCreateMutexW ((HANDLE(WINAPI*)(LPSECURITY_ATTRIBUTES,BOOL, \
LPCWSTR))aSyscall[7].pCurrent)
LPCWSTR))aSyscall[8].pCurrent)
#if defined(SQLITE_WIN32_HAS_ANSI)
{ "DeleteFileA", (SYSCALL)DeleteFileA, 0 },
@@ -333,7 +395,7 @@ static struct win_syscall {
{ "DeleteFileA", (SYSCALL)0, 0 },
#endif
#define osDeleteFileA ((BOOL(WINAPI*)(LPCSTR))aSyscall[8].pCurrent)
#define osDeleteFileA ((BOOL(WINAPI*)(LPCSTR))aSyscall[9].pCurrent)
#if defined(SQLITE_WIN32_HAS_WIDE)
{ "DeleteFileW", (SYSCALL)DeleteFileW, 0 },
@@ -341,7 +403,7 @@ static struct win_syscall {
{ "DeleteFileW", (SYSCALL)0, 0 },
#endif
#define osDeleteFileW ((BOOL(WINAPI*)(LPCWSTR))aSyscall[9].pCurrent)
#define osDeleteFileW ((BOOL(WINAPI*)(LPCWSTR))aSyscall[10].pCurrent)
#if SQLITE_OS_WINCE
{ "FileTimeToLocalFileTime", (SYSCALL)FileTimeToLocalFileTime, 0 },
@@ -350,7 +412,7 @@ static struct win_syscall {
#endif
#define osFileTimeToLocalFileTime ((BOOL(WINAPI*)(CONST FILETIME*, \
LPFILETIME))aSyscall[10].pCurrent)
LPFILETIME))aSyscall[11].pCurrent)
#if SQLITE_OS_WINCE
{ "FileTimeToSystemTime", (SYSCALL)FileTimeToSystemTime, 0 },
@@ -359,11 +421,11 @@ static struct win_syscall {
#endif
#define osFileTimeToSystemTime ((BOOL(WINAPI*)(CONST FILETIME*, \
LPSYSTEMTIME))aSyscall[11].pCurrent)
LPSYSTEMTIME))aSyscall[12].pCurrent)
{ "FlushFileBuffers", (SYSCALL)FlushFileBuffers, 0 },
#define osFlushFileBuffers ((BOOL(WINAPI*)(HANDLE))aSyscall[12].pCurrent)
#define osFlushFileBuffers ((BOOL(WINAPI*)(HANDLE))aSyscall[13].pCurrent)
#if defined(SQLITE_WIN32_HAS_ANSI)
{ "FormatMessageA", (SYSCALL)FormatMessageA, 0 },
@@ -372,7 +434,7 @@ static struct win_syscall {
#endif
#define osFormatMessageA ((DWORD(WINAPI*)(DWORD,LPCVOID,DWORD,DWORD,LPSTR, \
DWORD,va_list*))aSyscall[13].pCurrent)
DWORD,va_list*))aSyscall[14].pCurrent)
#if defined(SQLITE_WIN32_HAS_WIDE)
{ "FormatMessageW", (SYSCALL)FormatMessageW, 0 },
@@ -381,15 +443,19 @@ static struct win_syscall {
#endif
#define osFormatMessageW ((DWORD(WINAPI*)(DWORD,LPCVOID,DWORD,DWORD,LPWSTR, \
DWORD,va_list*))aSyscall[14].pCurrent)
DWORD,va_list*))aSyscall[15].pCurrent)
#if !defined(SQLITE_OMIT_LOAD_EXTENSION)
{ "FreeLibrary", (SYSCALL)FreeLibrary, 0 },
#else
{ "FreeLibrary", (SYSCALL)0, 0 },
#endif
#define osFreeLibrary ((BOOL(WINAPI*)(HMODULE))aSyscall[15].pCurrent)
#define osFreeLibrary ((BOOL(WINAPI*)(HMODULE))aSyscall[16].pCurrent)
{ "GetCurrentProcessId", (SYSCALL)GetCurrentProcessId, 0 },
#define osGetCurrentProcessId ((DWORD(WINAPI*)(VOID))aSyscall[16].pCurrent)
#define osGetCurrentProcessId ((DWORD(WINAPI*)(VOID))aSyscall[17].pCurrent)
#if !SQLITE_OS_WINCE && defined(SQLITE_WIN32_HAS_ANSI)
{ "GetDiskFreeSpaceA", (SYSCALL)GetDiskFreeSpaceA, 0 },
@@ -398,7 +464,7 @@ static struct win_syscall {
#endif
#define osGetDiskFreeSpaceA ((BOOL(WINAPI*)(LPCSTR,LPDWORD,LPDWORD,LPDWORD, \
LPDWORD))aSyscall[17].pCurrent)
LPDWORD))aSyscall[18].pCurrent)
#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE)
{ "GetDiskFreeSpaceW", (SYSCALL)GetDiskFreeSpaceW, 0 },
@@ -407,7 +473,7 @@ static struct win_syscall {
#endif
#define osGetDiskFreeSpaceW ((BOOL(WINAPI*)(LPCWSTR,LPDWORD,LPDWORD,LPDWORD, \
LPDWORD))aSyscall[18].pCurrent)
LPDWORD))aSyscall[19].pCurrent)
#if defined(SQLITE_WIN32_HAS_ANSI)
{ "GetFileAttributesA", (SYSCALL)GetFileAttributesA, 0 },
@@ -415,7 +481,7 @@ static struct win_syscall {
{ "GetFileAttributesA", (SYSCALL)0, 0 },
#endif
#define osGetFileAttributesA ((DWORD(WINAPI*)(LPCSTR))aSyscall[19].pCurrent)
#define osGetFileAttributesA ((DWORD(WINAPI*)(LPCSTR))aSyscall[20].pCurrent)
#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE)
{ "GetFileAttributesW", (SYSCALL)GetFileAttributesW, 0 },
@@ -423,7 +489,7 @@ static struct win_syscall {
{ "GetFileAttributesW", (SYSCALL)0, 0 },
#endif
#define osGetFileAttributesW ((DWORD(WINAPI*)(LPCWSTR))aSyscall[20].pCurrent)
#define osGetFileAttributesW ((DWORD(WINAPI*)(LPCWSTR))aSyscall[21].pCurrent)
#if defined(SQLITE_WIN32_HAS_WIDE)
{ "GetFileAttributesExW", (SYSCALL)GetFileAttributesExW, 0 },
@@ -432,7 +498,7 @@ static struct win_syscall {
#endif
#define osGetFileAttributesExW ((BOOL(WINAPI*)(LPCWSTR,GET_FILEEX_INFO_LEVELS, \
LPVOID))aSyscall[21].pCurrent)
LPVOID))aSyscall[22].pCurrent)
#if !SQLITE_OS_WINRT
{ "GetFileSize", (SYSCALL)GetFileSize, 0 },
@@ -440,7 +506,7 @@ static struct win_syscall {
{ "GetFileSize", (SYSCALL)0, 0 },
#endif
#define osGetFileSize ((DWORD(WINAPI*)(HANDLE,LPDWORD))aSyscall[22].pCurrent)
#define osGetFileSize ((DWORD(WINAPI*)(HANDLE,LPDWORD))aSyscall[23].pCurrent)
#if !SQLITE_OS_WINCE && defined(SQLITE_WIN32_HAS_ANSI)
{ "GetFullPathNameA", (SYSCALL)GetFullPathNameA, 0 },
@@ -449,7 +515,7 @@ static struct win_syscall {
#endif
#define osGetFullPathNameA ((DWORD(WINAPI*)(LPCSTR,DWORD,LPSTR, \
LPSTR*))aSyscall[23].pCurrent)
LPSTR*))aSyscall[24].pCurrent)
#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE)
{ "GetFullPathNameW", (SYSCALL)GetFullPathNameW, 0 },
@@ -458,12 +524,13 @@ static struct win_syscall {
#endif
#define osGetFullPathNameW ((DWORD(WINAPI*)(LPCWSTR,DWORD,LPWSTR, \
LPWSTR*))aSyscall[24].pCurrent)
LPWSTR*))aSyscall[25].pCurrent)
{ "GetLastError", (SYSCALL)GetLastError, 0 },
#define osGetLastError ((DWORD(WINAPI*)(VOID))aSyscall[25].pCurrent)
#define osGetLastError ((DWORD(WINAPI*)(VOID))aSyscall[26].pCurrent)
#if !defined(SQLITE_OMIT_LOAD_EXTENSION)
#if SQLITE_OS_WINCE
/* The GetProcAddressA() routine is only available on Windows CE. */
{ "GetProcAddressA", (SYSCALL)GetProcAddressA, 0 },
@@ -472,9 +539,12 @@ static struct win_syscall {
** an ANSI string regardless of the _UNICODE setting */
{ "GetProcAddressA", (SYSCALL)GetProcAddress, 0 },
#endif
#else
{ "GetProcAddressA", (SYSCALL)0, 0 },
#endif
#define osGetProcAddressA ((FARPROC(WINAPI*)(HMODULE, \
LPCSTR))aSyscall[26].pCurrent)
LPCSTR))aSyscall[27].pCurrent)
#if !SQLITE_OS_WINRT
{ "GetSystemInfo", (SYSCALL)GetSystemInfo, 0 },
@@ -482,11 +552,11 @@ static struct win_syscall {
{ "GetSystemInfo", (SYSCALL)0, 0 },
#endif
#define osGetSystemInfo ((VOID(WINAPI*)(LPSYSTEM_INFO))aSyscall[27].pCurrent)
#define osGetSystemInfo ((VOID(WINAPI*)(LPSYSTEM_INFO))aSyscall[28].pCurrent)
{ "GetSystemTime", (SYSCALL)GetSystemTime, 0 },
#define osGetSystemTime ((VOID(WINAPI*)(LPSYSTEMTIME))aSyscall[28].pCurrent)
#define osGetSystemTime ((VOID(WINAPI*)(LPSYSTEMTIME))aSyscall[29].pCurrent)
#if !SQLITE_OS_WINCE
{ "GetSystemTimeAsFileTime", (SYSCALL)GetSystemTimeAsFileTime, 0 },
@@ -495,7 +565,7 @@ static struct win_syscall {
#endif
#define osGetSystemTimeAsFileTime ((VOID(WINAPI*)( \
LPFILETIME))aSyscall[29].pCurrent)
LPFILETIME))aSyscall[30].pCurrent)
#if defined(SQLITE_WIN32_HAS_ANSI)
{ "GetTempPathA", (SYSCALL)GetTempPathA, 0 },
@@ -503,7 +573,7 @@ static struct win_syscall {
{ "GetTempPathA", (SYSCALL)0, 0 },
#endif
#define osGetTempPathA ((DWORD(WINAPI*)(DWORD,LPSTR))aSyscall[30].pCurrent)
#define osGetTempPathA ((DWORD(WINAPI*)(DWORD,LPSTR))aSyscall[31].pCurrent)
#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE)
{ "GetTempPathW", (SYSCALL)GetTempPathW, 0 },
@@ -511,7 +581,7 @@ static struct win_syscall {
{ "GetTempPathW", (SYSCALL)0, 0 },
#endif
#define osGetTempPathW ((DWORD(WINAPI*)(DWORD,LPWSTR))aSyscall[31].pCurrent)
#define osGetTempPathW ((DWORD(WINAPI*)(DWORD,LPWSTR))aSyscall[32].pCurrent)
#if !SQLITE_OS_WINRT
{ "GetTickCount", (SYSCALL)GetTickCount, 0 },
@@ -519,7 +589,7 @@ static struct win_syscall {
{ "GetTickCount", (SYSCALL)0, 0 },
#endif
#define osGetTickCount ((DWORD(WINAPI*)(VOID))aSyscall[32].pCurrent)
#define osGetTickCount ((DWORD(WINAPI*)(VOID))aSyscall[33].pCurrent)
#if defined(SQLITE_WIN32_HAS_ANSI)
{ "GetVersionExA", (SYSCALL)GetVersionExA, 0 },
@@ -528,12 +598,12 @@ static struct win_syscall {
#endif
#define osGetVersionExA ((BOOL(WINAPI*)( \
LPOSVERSIONINFOA))aSyscall[33].pCurrent)
LPOSVERSIONINFOA))aSyscall[34].pCurrent)
{ "HeapAlloc", (SYSCALL)HeapAlloc, 0 },
#define osHeapAlloc ((LPVOID(WINAPI*)(HANDLE,DWORD, \
SIZE_T))aSyscall[34].pCurrent)
SIZE_T))aSyscall[35].pCurrent)
#if !SQLITE_OS_WINRT
{ "HeapCreate", (SYSCALL)HeapCreate, 0 },
@@ -542,7 +612,7 @@ static struct win_syscall {
#endif
#define osHeapCreate ((HANDLE(WINAPI*)(DWORD,SIZE_T, \
SIZE_T))aSyscall[35].pCurrent)
SIZE_T))aSyscall[36].pCurrent)
#if !SQLITE_OS_WINRT
{ "HeapDestroy", (SYSCALL)HeapDestroy, 0 },
@@ -550,21 +620,21 @@ static struct win_syscall {
{ "HeapDestroy", (SYSCALL)0, 0 },
#endif
#define osHeapDestroy ((BOOL(WINAPI*)(HANDLE))aSyscall[36].pCurrent)
#define osHeapDestroy ((BOOL(WINAPI*)(HANDLE))aSyscall[37].pCurrent)
{ "HeapFree", (SYSCALL)HeapFree, 0 },
#define osHeapFree ((BOOL(WINAPI*)(HANDLE,DWORD,LPVOID))aSyscall[37].pCurrent)
#define osHeapFree ((BOOL(WINAPI*)(HANDLE,DWORD,LPVOID))aSyscall[38].pCurrent)
{ "HeapReAlloc", (SYSCALL)HeapReAlloc, 0 },
#define osHeapReAlloc ((LPVOID(WINAPI*)(HANDLE,DWORD,LPVOID, \
SIZE_T))aSyscall[38].pCurrent)
SIZE_T))aSyscall[39].pCurrent)
{ "HeapSize", (SYSCALL)HeapSize, 0 },
#define osHeapSize ((SIZE_T(WINAPI*)(HANDLE,DWORD, \
LPCVOID))aSyscall[39].pCurrent)
LPCVOID))aSyscall[40].pCurrent)
#if !SQLITE_OS_WINRT
{ "HeapValidate", (SYSCALL)HeapValidate, 0 },
@@ -573,23 +643,24 @@ static struct win_syscall {
#endif
#define osHeapValidate ((BOOL(WINAPI*)(HANDLE,DWORD, \
LPCVOID))aSyscall[40].pCurrent)
LPCVOID))aSyscall[41].pCurrent)
#if defined(SQLITE_WIN32_HAS_ANSI)
#if defined(SQLITE_WIN32_HAS_ANSI) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
{ "LoadLibraryA", (SYSCALL)LoadLibraryA, 0 },
#else
{ "LoadLibraryA", (SYSCALL)0, 0 },
#endif
#define osLoadLibraryA ((HMODULE(WINAPI*)(LPCSTR))aSyscall[41].pCurrent)
#define osLoadLibraryA ((HMODULE(WINAPI*)(LPCSTR))aSyscall[42].pCurrent)
#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE)
#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE) && \
!defined(SQLITE_OMIT_LOAD_EXTENSION)
{ "LoadLibraryW", (SYSCALL)LoadLibraryW, 0 },
#else
{ "LoadLibraryW", (SYSCALL)0, 0 },
#endif
#define osLoadLibraryW ((HMODULE(WINAPI*)(LPCWSTR))aSyscall[42].pCurrent)
#define osLoadLibraryW ((HMODULE(WINAPI*)(LPCWSTR))aSyscall[43].pCurrent)
#if !SQLITE_OS_WINRT
{ "LocalFree", (SYSCALL)LocalFree, 0 },
@@ -597,7 +668,7 @@ static struct win_syscall {
{ "LocalFree", (SYSCALL)0, 0 },
#endif
#define osLocalFree ((HLOCAL(WINAPI*)(HLOCAL))aSyscall[43].pCurrent)
#define osLocalFree ((HLOCAL(WINAPI*)(HLOCAL))aSyscall[44].pCurrent)
#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT
{ "LockFile", (SYSCALL)LockFile, 0 },
@@ -607,7 +678,7 @@ static struct win_syscall {
#ifndef osLockFile
#define osLockFile ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \
DWORD))aSyscall[44].pCurrent)
DWORD))aSyscall[45].pCurrent)
#endif
#if !SQLITE_OS_WINCE
@@ -618,7 +689,7 @@ static struct win_syscall {
#ifndef osLockFileEx
#define osLockFileEx ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD,DWORD, \
LPOVERLAPPED))aSyscall[45].pCurrent)
LPOVERLAPPED))aSyscall[46].pCurrent)
#endif
#if SQLITE_OS_WINCE || (!SQLITE_OS_WINRT && !defined(SQLITE_OMIT_WAL))
@@ -628,26 +699,26 @@ static struct win_syscall {
#endif
#define osMapViewOfFile ((LPVOID(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \
SIZE_T))aSyscall[46].pCurrent)
SIZE_T))aSyscall[47].pCurrent)
{ "MultiByteToWideChar", (SYSCALL)MultiByteToWideChar, 0 },
#define osMultiByteToWideChar ((int(WINAPI*)(UINT,DWORD,LPCSTR,int,LPWSTR, \
int))aSyscall[47].pCurrent)
int))aSyscall[48].pCurrent)
{ "QueryPerformanceCounter", (SYSCALL)QueryPerformanceCounter, 0 },
#define osQueryPerformanceCounter ((BOOL(WINAPI*)( \
LARGE_INTEGER*))aSyscall[48].pCurrent)
LARGE_INTEGER*))aSyscall[49].pCurrent)
{ "ReadFile", (SYSCALL)ReadFile, 0 },
#define osReadFile ((BOOL(WINAPI*)(HANDLE,LPVOID,DWORD,LPDWORD, \
LPOVERLAPPED))aSyscall[49].pCurrent)
LPOVERLAPPED))aSyscall[50].pCurrent)
{ "SetEndOfFile", (SYSCALL)SetEndOfFile, 0 },
#define osSetEndOfFile ((BOOL(WINAPI*)(HANDLE))aSyscall[50].pCurrent)
#define osSetEndOfFile ((BOOL(WINAPI*)(HANDLE))aSyscall[51].pCurrent)
#if !SQLITE_OS_WINRT
{ "SetFilePointer", (SYSCALL)SetFilePointer, 0 },
@@ -656,7 +727,7 @@ static struct win_syscall {
#endif
#define osSetFilePointer ((DWORD(WINAPI*)(HANDLE,LONG,PLONG, \
DWORD))aSyscall[51].pCurrent)
DWORD))aSyscall[52].pCurrent)
#if !SQLITE_OS_WINRT
{ "Sleep", (SYSCALL)Sleep, 0 },
@@ -664,12 +735,12 @@ static struct win_syscall {
{ "Sleep", (SYSCALL)0, 0 },
#endif
#define osSleep ((VOID(WINAPI*)(DWORD))aSyscall[52].pCurrent)
#define osSleep ((VOID(WINAPI*)(DWORD))aSyscall[53].pCurrent)
{ "SystemTimeToFileTime", (SYSCALL)SystemTimeToFileTime, 0 },
#define osSystemTimeToFileTime ((BOOL(WINAPI*)(CONST SYSTEMTIME*, \
LPFILETIME))aSyscall[53].pCurrent)
LPFILETIME))aSyscall[54].pCurrent)
#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT
{ "UnlockFile", (SYSCALL)UnlockFile, 0 },
@@ -679,7 +750,7 @@ static struct win_syscall {
#ifndef osUnlockFile
#define osUnlockFile ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \
DWORD))aSyscall[54].pCurrent)
DWORD))aSyscall[55].pCurrent)
#endif
#if !SQLITE_OS_WINCE
@@ -689,7 +760,7 @@ static struct win_syscall {
#endif
#define osUnlockFileEx ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \
LPOVERLAPPED))aSyscall[55].pCurrent)
LPOVERLAPPED))aSyscall[56].pCurrent)
#if SQLITE_OS_WINCE || !defined(SQLITE_OMIT_WAL)
{ "UnmapViewOfFile", (SYSCALL)UnmapViewOfFile, 0 },
@@ -697,17 +768,17 @@ static struct win_syscall {
{ "UnmapViewOfFile", (SYSCALL)0, 0 },
#endif
#define osUnmapViewOfFile ((BOOL(WINAPI*)(LPCVOID))aSyscall[56].pCurrent)
#define osUnmapViewOfFile ((BOOL(WINAPI*)(LPCVOID))aSyscall[57].pCurrent)
{ "WideCharToMultiByte", (SYSCALL)WideCharToMultiByte, 0 },
#define osWideCharToMultiByte ((int(WINAPI*)(UINT,DWORD,LPCWSTR,int,LPSTR,int, \
LPCSTR,LPBOOL))aSyscall[57].pCurrent)
LPCSTR,LPBOOL))aSyscall[58].pCurrent)
{ "WriteFile", (SYSCALL)WriteFile, 0 },
#define osWriteFile ((BOOL(WINAPI*)(HANDLE,LPCVOID,DWORD,LPDWORD, \
LPOVERLAPPED))aSyscall[58].pCurrent)
LPOVERLAPPED))aSyscall[59].pCurrent)
#if SQLITE_OS_WINRT
{ "CreateEventExW", (SYSCALL)CreateEventExW, 0 },
@@ -716,7 +787,7 @@ static struct win_syscall {
#endif
#define osCreateEventExW ((HANDLE(WINAPI*)(LPSECURITY_ATTRIBUTES,LPCWSTR, \
DWORD,DWORD))aSyscall[59].pCurrent)
DWORD,DWORD))aSyscall[60].pCurrent)
#if !SQLITE_OS_WINRT
{ "WaitForSingleObject", (SYSCALL)WaitForSingleObject, 0 },
@@ -725,7 +796,7 @@ static struct win_syscall {
#endif
#define osWaitForSingleObject ((DWORD(WINAPI*)(HANDLE, \
DWORD))aSyscall[60].pCurrent)
DWORD))aSyscall[61].pCurrent)
#if SQLITE_OS_WINRT
{ "WaitForSingleObjectEx", (SYSCALL)WaitForSingleObjectEx, 0 },
@@ -734,7 +805,7 @@ static struct win_syscall {
#endif
#define osWaitForSingleObjectEx ((DWORD(WINAPI*)(HANDLE,DWORD, \
BOOL))aSyscall[61].pCurrent)
BOOL))aSyscall[62].pCurrent)
#if SQLITE_OS_WINRT
{ "SetFilePointerEx", (SYSCALL)SetFilePointerEx, 0 },
@@ -743,7 +814,7 @@ static struct win_syscall {
#endif
#define osSetFilePointerEx ((BOOL(WINAPI*)(HANDLE,LARGE_INTEGER, \
PLARGE_INTEGER,DWORD))aSyscall[62].pCurrent)
PLARGE_INTEGER,DWORD))aSyscall[63].pCurrent)
#if SQLITE_OS_WINRT
{ "GetFileInformationByHandleEx", (SYSCALL)GetFileInformationByHandleEx, 0 },
@@ -752,7 +823,7 @@ static struct win_syscall {
#endif
#define osGetFileInformationByHandleEx ((BOOL(WINAPI*)(HANDLE, \
FILE_INFO_BY_HANDLE_CLASS,LPVOID,DWORD))aSyscall[63].pCurrent)
FILE_INFO_BY_HANDLE_CLASS,LPVOID,DWORD))aSyscall[64].pCurrent)
#if SQLITE_OS_WINRT && !defined(SQLITE_OMIT_WAL)
{ "MapViewOfFileFromApp", (SYSCALL)MapViewOfFileFromApp, 0 },
@@ -761,7 +832,7 @@ static struct win_syscall {
#endif
#define osMapViewOfFileFromApp ((LPVOID(WINAPI*)(HANDLE,ULONG,ULONG64, \
SIZE_T))aSyscall[64].pCurrent)
SIZE_T))aSyscall[65].pCurrent)
#if SQLITE_OS_WINRT
{ "CreateFile2", (SYSCALL)CreateFile2, 0 },
@@ -770,16 +841,16 @@ static struct win_syscall {
#endif
#define osCreateFile2 ((HANDLE(WINAPI*)(LPCWSTR,DWORD,DWORD,DWORD, \
LPCREATEFILE2_EXTENDED_PARAMETERS))aSyscall[65].pCurrent)
LPCREATEFILE2_EXTENDED_PARAMETERS))aSyscall[66].pCurrent)
#if SQLITE_OS_WINRT
#if SQLITE_OS_WINRT && !defined(SQLITE_OMIT_LOAD_EXTENSION)
{ "LoadPackagedLibrary", (SYSCALL)LoadPackagedLibrary, 0 },
#else
{ "LoadPackagedLibrary", (SYSCALL)0, 0 },
#endif
#define osLoadPackagedLibrary ((HMODULE(WINAPI*)(LPCWSTR, \
DWORD))aSyscall[66].pCurrent)
DWORD))aSyscall[67].pCurrent)
#if SQLITE_OS_WINRT
{ "GetTickCount64", (SYSCALL)GetTickCount64, 0 },
@@ -787,7 +858,7 @@ static struct win_syscall {
{ "GetTickCount64", (SYSCALL)0, 0 },
#endif
#define osGetTickCount64 ((ULONGLONG(WINAPI*)(VOID))aSyscall[67].pCurrent)
#define osGetTickCount64 ((ULONGLONG(WINAPI*)(VOID))aSyscall[68].pCurrent)
#if SQLITE_OS_WINRT
{ "GetNativeSystemInfo", (SYSCALL)GetNativeSystemInfo, 0 },
@@ -796,7 +867,7 @@ static struct win_syscall {
#endif
#define osGetNativeSystemInfo ((VOID(WINAPI*)( \
LPSYSTEM_INFO))aSyscall[68].pCurrent)
LPSYSTEM_INFO))aSyscall[69].pCurrent)
#if defined(SQLITE_WIN32_HAS_ANSI)
{ "OutputDebugStringA", (SYSCALL)OutputDebugStringA, 0 },
@@ -804,7 +875,7 @@ static struct win_syscall {
{ "OutputDebugStringA", (SYSCALL)0, 0 },
#endif
#define osOutputDebugStringA ((VOID(WINAPI*)(LPCSTR))aSyscall[69].pCurrent)
#define osOutputDebugStringA ((VOID(WINAPI*)(LPCSTR))aSyscall[70].pCurrent)
#if defined(SQLITE_WIN32_HAS_WIDE)
{ "OutputDebugStringW", (SYSCALL)OutputDebugStringW, 0 },
@@ -812,11 +883,11 @@ static struct win_syscall {
{ "OutputDebugStringW", (SYSCALL)0, 0 },
#endif
#define osOutputDebugStringW ((VOID(WINAPI*)(LPCWSTR))aSyscall[70].pCurrent)
#define osOutputDebugStringW ((VOID(WINAPI*)(LPCWSTR))aSyscall[71].pCurrent)
{ "GetProcessHeap", (SYSCALL)GetProcessHeap, 0 },
#define osGetProcessHeap ((HANDLE(WINAPI*)(VOID))aSyscall[71].pCurrent)
#define osGetProcessHeap ((HANDLE(WINAPI*)(VOID))aSyscall[72].pCurrent)
#if SQLITE_OS_WINRT && !defined(SQLITE_OMIT_WAL)
{ "CreateFileMappingFromApp", (SYSCALL)CreateFileMappingFromApp, 0 },
@@ -825,7 +896,7 @@ static struct win_syscall {
#endif
#define osCreateFileMappingFromApp ((HANDLE(WINAPI*)(HANDLE, \
LPSECURITY_ATTRIBUTES,ULONG,ULONG64,LPCWSTR))aSyscall[72].pCurrent)
LPSECURITY_ATTRIBUTES,ULONG,ULONG64,LPCWSTR))aSyscall[73].pCurrent)
}; /* End of the overrideable system calls */
@@ -983,6 +1054,8 @@ void sqlite3_win32_sleep(DWORD milliseconds){
*/
#if SQLITE_OS_WINCE || SQLITE_OS_WINRT
# define isNT() (1)
#elif !defined(SQLITE_WIN32_HAS_WIDE)
# define isNT() (0)
#else
static int isNT(void){
if( sqlite3_os_type==0 ){
@@ -993,7 +1066,7 @@ void sqlite3_win32_sleep(DWORD milliseconds){
}
return sqlite3_os_type==2;
}
#endif /* SQLITE_OS_WINCE */
#endif
#ifdef SQLITE_WIN32_MALLOC
/*
@@ -1203,7 +1276,7 @@ static LPWSTR utf8ToUnicode(const char *zFilename){
if( nChar==0 ){
return 0;
}
zWideFilename = sqlite3_malloc( nChar*sizeof(zWideFilename[0]) );
zWideFilename = sqlite3MallocZero( nChar*sizeof(zWideFilename[0]) );
if( zWideFilename==0 ){
return 0;
}
@@ -1228,7 +1301,7 @@ static char *unicodeToUtf8(LPCWSTR zWideFilename){
if( nByte == 0 ){
return 0;
}
zFilename = sqlite3_malloc( nByte );
zFilename = sqlite3MallocZero( nByte );
if( zFilename==0 ){
return 0;
}
@@ -1258,7 +1331,7 @@ static LPWSTR mbcsToUnicode(const char *zFilename){
if( nByte==0 ){
return 0;
}
zMbcsFilename = sqlite3_malloc( nByte*sizeof(zMbcsFilename[0]) );
zMbcsFilename = sqlite3MallocZero( nByte*sizeof(zMbcsFilename[0]) );
if( zMbcsFilename==0 ){
return 0;
}
@@ -1287,7 +1360,7 @@ static char *unicodeToMbcs(LPCWSTR zWideFilename){
if( nByte == 0 ){
return 0;
}
zFilename = sqlite3_malloc( nByte );
zFilename = sqlite3MallocZero( nByte );
if( zFilename==0 ){
return 0;
}
@@ -2934,16 +3007,14 @@ static int winOpenSharedMemory(winFile *pDbFd){
/* Allocate space for the new sqlite3_shm object. Also speculatively
** allocate space for a new winShmNode and filename.
*/
p = sqlite3_malloc( sizeof(*p) );
p = sqlite3MallocZero( sizeof(*p) );
if( p==0 ) return SQLITE_IOERR_NOMEM;
memset(p, 0, sizeof(*p));
nName = sqlite3Strlen30(pDbFd->zPath);
pNew = sqlite3_malloc( sizeof(*pShmNode) + nName + 17 );
pNew = sqlite3MallocZero( sizeof(*pShmNode) + nName + 17 );
if( pNew==0 ){
sqlite3_free(p);
return SQLITE_IOERR_NOMEM;
}
memset(pNew, 0, sizeof(*pNew) + nName + 17);
pNew->zFilename = (char*)&pNew[1];
sqlite3_snprintf(nName+15, pNew->zFilename, "%s-shm", pDbFd->zPath);
sqlite3FileSuffix3(pDbFd->zPath, pNew->zFilename);
@@ -3280,17 +3351,21 @@ static int winShmMap(
pShmNode->aRegion = apNew;
while( pShmNode->nRegion<=iRegion ){
HANDLE hMap; /* file-mapping handle */
HANDLE hMap = NULL; /* file-mapping handle */
void *pMap = 0; /* Mapped memory region */
#if SQLITE_OS_WINRT
hMap = osCreateFileMappingFromApp(pShmNode->hFile.h,
NULL, PAGE_READWRITE, nByte, NULL
);
#else
#elif defined(SQLITE_WIN32_HAS_WIDE)
hMap = osCreateFileMappingW(pShmNode->hFile.h,
NULL, PAGE_READWRITE, 0, nByte, NULL
);
#elif defined(SQLITE_WIN32_HAS_ANSI)
hMap = osCreateFileMappingA(pShmNode->hFile.h,
NULL, PAGE_READWRITE, 0, nByte, NULL
);
#endif
OSTRACE(("SHM-MAP pid-%d create region=%d nbyte=%d %s\n",
(int)osGetCurrentProcessId(), pShmNode->nRegion, nByte,
@@ -4039,7 +4114,7 @@ static int winFullPathname(
#endif
#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && !defined(__CYGWIN__)
int nByte;
DWORD nByte;
void *zConverted;
char *zOut;
@@ -4073,13 +4148,27 @@ static int winFullPathname(
}
if( isNT() ){
LPWSTR zTemp;
nByte = osGetFullPathNameW((LPCWSTR)zConverted, 0, 0, 0) + 3;
zTemp = sqlite3_malloc( nByte*sizeof(zTemp[0]) );
nByte = osGetFullPathNameW((LPCWSTR)zConverted, 0, 0, 0);
if( nByte==0 ){
winLogError(SQLITE_ERROR, osGetLastError(),
"GetFullPathNameW1", zConverted);
sqlite3_free(zConverted);
return SQLITE_CANTOPEN_FULLPATH;
}
nByte += 3;
zTemp = sqlite3MallocZero( nByte*sizeof(zTemp[0]) );
if( zTemp==0 ){
sqlite3_free(zConverted);
return SQLITE_IOERR_NOMEM;
}
osGetFullPathNameW((LPCWSTR)zConverted, nByte, zTemp, 0);
nByte = osGetFullPathNameW((LPCWSTR)zConverted, nByte, zTemp, 0);
if( nByte==0 ){
winLogError(SQLITE_ERROR, osGetLastError(),
"GetFullPathNameW2", zConverted);
sqlite3_free(zConverted);
sqlite3_free(zTemp);
return SQLITE_CANTOPEN_FULLPATH;
}
sqlite3_free(zConverted);
zOut = unicodeToUtf8(zTemp);
sqlite3_free(zTemp);
@@ -4087,13 +4176,27 @@ static int winFullPathname(
#ifdef SQLITE_WIN32_HAS_ANSI
else{
char *zTemp;
nByte = osGetFullPathNameA((char*)zConverted, 0, 0, 0) + 3;
zTemp = sqlite3_malloc( nByte*sizeof(zTemp[0]) );
nByte = osGetFullPathNameA((char*)zConverted, 0, 0, 0);
if( nByte==0 ){
winLogError(SQLITE_ERROR, osGetLastError(),
"GetFullPathNameA1", zConverted);
sqlite3_free(zConverted);
return SQLITE_CANTOPEN_FULLPATH;
}
nByte += 3;
zTemp = sqlite3MallocZero( nByte*sizeof(zTemp[0]) );
if( zTemp==0 ){
sqlite3_free(zConverted);
return SQLITE_IOERR_NOMEM;
}
osGetFullPathNameA((char*)zConverted, nByte, zTemp, 0);
nByte = osGetFullPathNameA((char*)zConverted, nByte, zTemp, 0);
if( nByte==0 ){
winLogError(SQLITE_ERROR, osGetLastError(),
"GetFullPathNameA2", zConverted);
sqlite3_free(zConverted);
sqlite3_free(zTemp);
return SQLITE_CANTOPEN_FULLPATH;
}
sqlite3_free(zConverted);
zOut = sqlite3_win32_mbcs_to_utf8(zTemp);
sqlite3_free(zTemp);
@@ -4351,7 +4454,7 @@ int sqlite3_os_init(void){
/* Double-check that the aSyscall[] array has been constructed
** correctly. See ticket [bb3a86e890c8e96ab] */
assert( ArraySize(aSyscall)==73 );
assert( ArraySize(aSyscall)==74 );
#ifndef SQLITE_OMIT_WAL
/* get memory map allocation granularity */
@@ -4370,7 +4473,7 @@ int sqlite3_os_init(void){
int sqlite3_os_end(void){
#if SQLITE_OS_WINRT
if( sleepObj != NULL ){
if( sleepObj!=NULL ){
osCloseHandle(sleepObj);
sleepObj = NULL;
}
+25 -10
View File
@@ -2509,6 +2509,21 @@ static int pager_truncate(Pager *pPager, Pgno nPage){
return rc;
}
/*
** Return a sanitized version of the sector-size of OS file pFile. The
** return value is guaranteed to lie between 32 and MAX_SECTOR_SIZE.
*/
int sqlite3SectorSize(sqlite3_file *pFile){
int iRet = sqlite3OsSectorSize(pFile);
if( iRet<32 ){
iRet = 512;
}else if( iRet>MAX_SECTOR_SIZE ){
assert( MAX_SECTOR_SIZE>=512 );
iRet = MAX_SECTOR_SIZE;
}
return iRet;
}
/*
** Set the value of the Pager.sectorSize variable for the given
** pager based on the value returned by the xSectorSize method
@@ -2544,14 +2559,7 @@ static void setSectorSize(Pager *pPager){
** call will segfault. */
pPager->sectorSize = 512;
}else{
pPager->sectorSize = sqlite3OsSectorSize(pPager->fd);
if( pPager->sectorSize<32 ){
pPager->sectorSize = 512;
}
if( pPager->sectorSize>MAX_SECTOR_SIZE ){
assert( MAX_SECTOR_SIZE>=512 );
pPager->sectorSize = MAX_SECTOR_SIZE;
}
pPager->sectorSize = sqlite3SectorSize(pPager->fd);
}
}
@@ -3468,9 +3476,16 @@ void sqlite3PagerSetBusyhandler(
Pager *pPager, /* Pager object */
int (*xBusyHandler)(void *), /* Pointer to busy-handler function */
void *pBusyHandlerArg /* Argument to pass to xBusyHandler */
){
){
pPager->xBusyHandler = xBusyHandler;
pPager->pBusyHandlerArg = pBusyHandlerArg;
if( isOpen(pPager->fd) ){
void **ap = (void **)&pPager->xBusyHandler;
assert( ((int(*)(void *))(ap[0]))==xBusyHandler );
assert( ap[1]==pBusyHandlerArg );
sqlite3OsFileControl(pPager->fd, SQLITE_FCNTL_BUSYHANDLER, (void *)ap);
}
}
/*
@@ -4448,7 +4463,7 @@ int sqlite3PagerOpen(
memcpy(pPager->zFilename, zPathname, nPathname);
if( nUri ) memcpy(&pPager->zFilename[nPathname+1], zUri, nUri);
memcpy(pPager->zJournal, zPathname, nPathname);
memcpy(&pPager->zJournal[nPathname], "-journal\000", 8+1);
memcpy(&pPager->zJournal[nPathname], "-journal\000", 8+2);
sqlite3FileSuffix3(pPager->zFilename, pPager->zJournal);
#ifndef SQLITE_OMIT_WAL
pPager->zWal = &pPager->zJournal[nPathname+8+1];
+1
View File
@@ -160,6 +160,7 @@ void *sqlite3PagerTempSpace(Pager*);
int sqlite3PagerIsMemdb(Pager*);
void sqlite3PagerCacheStat(Pager *, int, int, int *);
void sqlite3PagerClearCache(Pager *);
int sqlite3SectorSize(sqlite3_file *);
/* Functions used to truncate the database file. */
void sqlite3PagerTruncateImage(Pager*,Pgno);
+20 -2
View File
@@ -357,6 +357,7 @@ void sqlite3Pragma(
aFcntl[1] = zLeft;
aFcntl[2] = zRight;
aFcntl[3] = 0;
db->busyHandler.nBusy = 0;
rc = sqlite3_file_control(db, zDb, SQLITE_FCNTL_PRAGMA, (void*)aFcntl);
if( rc==SQLITE_OK ){
if( aFcntl[0] ){
@@ -974,7 +975,8 @@ void sqlite3Pragma(
}else{
sqlite3VdbeAddOp2(v, OP_Null, 0, 5);
}
sqlite3VdbeAddOp2(v, OP_Integer, pCol->isPrimKey, 6);
sqlite3VdbeAddOp2(v, OP_Integer,
(pCol->colFlags&COLFLAG_PRIMKEY)!=0, 6);
sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 6);
}
}
@@ -1233,7 +1235,7 @@ void sqlite3Pragma(
sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0,
sqlite3MPrintf(db, "*** in database %s ***\n", db->aDb[i].zName),
P4_DYNAMIC);
sqlite3VdbeAddOp3(v, OP_Move, 2, 4, 1);
sqlite3VdbeAddOp2(v, OP_Move, 2, 4);
sqlite3VdbeAddOp3(v, OP_Concat, 4, 3, 2);
sqlite3VdbeAddOp2(v, OP_ResultRow, 2, 1);
sqlite3VdbeJumpHere(v, addr);
@@ -1536,6 +1538,22 @@ void sqlite3Pragma(
sqlite3_db_release_memory(db);
}else
/*
** PRAGMA busy_timeout
** PRAGMA busy_timeout = N
**
** Call sqlite3_busy_timeout(db, N). Return the current timeout value
** if one is set. If no busy handler or a different busy handler is set
** then 0 is returned. Setting the busy_timeout to 0 or negative
** disables the timeout.
*/
if( sqlite3StrICmp(zLeft, "busy_timeout")==0 ){
if( zRight ){
sqlite3_busy_timeout(db, sqlite3Atoi(zRight));
}
returnSingleInt(pParse, "timeout", db->busyTimeout);
}else
#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
/*
** Report the current state of file logs for all databases
+2
View File
@@ -134,7 +134,9 @@ int sqlite3InitCallback(void *pInit, int argc, char **argv, char **NotUsed){
static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){
int rc;
int i;
#ifndef SQLITE_OMIT_DEPRECATED
int size;
#endif
Table *pTab;
Db *pDb;
char const *azArg[4];
+111 -84
View File
@@ -525,6 +525,19 @@ static int checkForMultiColumnSelectError(
}
#endif
/*
** An instance of the following object is used to record information about
** how to process the DISTINCT keyword, to simplify passing that information
** into the selectInnerLoop() routine.
*/
typedef struct DistinctCtx DistinctCtx;
struct DistinctCtx {
u8 isTnct; /* True if the DISTINCT keyword is present */
u8 eTnctType; /* One of the WHERE_DISTINCT_* operators */
int tabTnct; /* Ephemeral table used for DISTINCT processing */
int addrTnct; /* Address of OP_OpenEphemeral opcode for tabTnct */
};
/*
** This routine generates the code for the inside of the inner loop
** of a SELECT.
@@ -541,7 +554,7 @@ static void selectInnerLoop(
int srcTab, /* Pull data from this table */
int nColumn, /* Number of columns in the source table */
ExprList *pOrderBy, /* If not NULL, sort results using this key */
int distinct, /* If >=0, make sure results are distinct */
DistinctCtx *pDistinct, /* If not NULL, info on how to process DISTINCT */
SelectDest *pDest, /* How to dispose of the results */
int iContinue, /* Jump here to continue with next row */
int iBreak /* Jump here to break out of the inner loop */
@@ -557,7 +570,7 @@ static void selectInnerLoop(
assert( v );
if( NEVER(v==0) ) return;
assert( pEList!=0 );
hasDistinct = distinct>=0;
hasDistinct = pDistinct ? pDistinct->eTnctType : WHERE_DISTINCT_NOOP;
if( pOrderBy==0 && !hasDistinct ){
codeOffset(v, p, iContinue);
}
@@ -597,7 +610,55 @@ static void selectInnerLoop(
if( hasDistinct ){
assert( pEList!=0 );
assert( pEList->nExpr==nColumn );
codeDistinct(pParse, distinct, iContinue, nColumn, regResult);
switch( pDistinct->eTnctType ){
case WHERE_DISTINCT_ORDERED: {
VdbeOp *pOp; /* No longer required OpenEphemeral instr. */
int iJump; /* Jump destination */
int regPrev; /* Previous row content */
/* Allocate space for the previous row */
regPrev = pParse->nMem+1;
pParse->nMem += nColumn;
/* Change the OP_OpenEphemeral coded earlier to an OP_Null
** sets the MEM_Cleared bit on the first register of the
** previous value. This will cause the OP_Ne below to always
** fail on the first iteration of the loop even if the first
** row is all NULLs.
*/
sqlite3VdbeChangeToNoop(v, pDistinct->addrTnct);
pOp = sqlite3VdbeGetOp(v, pDistinct->addrTnct);
pOp->opcode = OP_Null;
pOp->p1 = 1;
pOp->p2 = regPrev;
iJump = sqlite3VdbeCurrentAddr(v) + nColumn;
for(i=0; i<nColumn; i++){
CollSeq *pColl = sqlite3ExprCollSeq(pParse, pEList->a[i].pExpr);
if( i<nColumn-1 ){
sqlite3VdbeAddOp3(v, OP_Ne, regResult+i, iJump, regPrev+i);
}else{
sqlite3VdbeAddOp3(v, OP_Eq, regResult+i, iContinue, regPrev+i);
}
sqlite3VdbeChangeP4(v, -1, (const char *)pColl, P4_COLLSEQ);
sqlite3VdbeChangeP5(v, SQLITE_NULLEQ);
}
assert( sqlite3VdbeCurrentAddr(v)==iJump );
sqlite3VdbeAddOp3(v, OP_Copy, regResult, regPrev, nColumn-1);
break;
}
case WHERE_DISTINCT_UNIQUE: {
sqlite3VdbeChangeToNoop(v, pDistinct->addrTnct);
break;
}
default: {
assert( pDistinct->eTnctType==WHERE_DISTINCT_UNORDERED );
codeDistinct(pParse, pDistinct->tabTnct, iContinue, nColumn, regResult);
break;
}
}
if( pOrderBy==0 ){
codeOffset(v, p, iContinue);
}
@@ -655,7 +716,8 @@ static void selectInnerLoop(
*/
case SRT_Set: {
assert( nColumn==1 );
p->affinity = sqlite3CompareAffinity(pEList->a[0].pExpr, pDest->affSdst);
pDest->affSdst =
sqlite3CompareAffinity(pEList->a[0].pExpr, pDest->affSdst);
if( pOrderBy ){
/* At first glance you would think we could optimize out the
** ORDER BY in this case since the order of entries in the set
@@ -664,7 +726,7 @@ static void selectInnerLoop(
pushOntoSorter(pParse, pOrderBy, p, regResult);
}else{
int r1 = sqlite3GetTempReg(pParse);
sqlite3VdbeAddOp4(v, OP_MakeRecord, regResult, 1, r1, &p->affinity, 1);
sqlite3VdbeAddOp4(v, OP_MakeRecord, regResult,1,r1, &pDest->affSdst, 1);
sqlite3ExprCacheAffinityChange(pParse, regResult, 1);
sqlite3VdbeAddOp2(v, OP_IdxInsert, iParm, r1);
sqlite3ReleaseTempReg(pParse, r1);
@@ -931,7 +993,8 @@ static void generateSortTail(
#ifndef SQLITE_OMIT_SUBQUERY
case SRT_Set: {
assert( nColumn==1 );
sqlite3VdbeAddOp4(v, OP_MakeRecord, regRow, 1, regRowid, &p->affinity, 1);
sqlite3VdbeAddOp4(v, OP_MakeRecord, regRow, 1, regRowid,
&pDest->affSdst, 1);
sqlite3ExprCacheAffinityChange(pParse, regRow, 1);
sqlite3VdbeAddOp2(v, OP_IdxInsert, iParm, regRowid);
break;
@@ -1246,7 +1309,7 @@ static void generateColumnNames(
static int selectColumnsFromExprList(
Parse *pParse, /* Parsing context */
ExprList *pEList, /* Expr list from which to derive column names */
int *pnCol, /* Write the number of columns here */
i16 *pnCol, /* Write the number of columns here */
Column **paCol /* Write the new column list here */
){
sqlite3 *db = pParse->db; /* Database connection */
@@ -1768,7 +1831,7 @@ static int multiSelect(
sqlite3VdbeAddOp2(v, OP_Rewind, unionTab, iBreak);
iStart = sqlite3VdbeCurrentAddr(v);
selectInnerLoop(pParse, p, p->pEList, unionTab, p->pEList->nExpr,
0, -1, &dest, iCont, iBreak);
0, 0, &dest, iCont, iBreak);
sqlite3VdbeResolveLabel(v, iCont);
sqlite3VdbeAddOp2(v, OP_Next, unionTab, iStart);
sqlite3VdbeResolveLabel(v, iBreak);
@@ -1846,7 +1909,7 @@ static int multiSelect(
sqlite3VdbeAddOp4Int(v, OP_NotFound, tab2, iCont, r1, 0);
sqlite3ReleaseTempReg(pParse, r1);
selectInnerLoop(pParse, p, p->pEList, tab1, p->pEList->nExpr,
0, -1, &dest, iCont, iBreak);
0, 0, &dest, iCont, iBreak);
sqlite3VdbeResolveLabel(v, iCont);
sqlite3VdbeAddOp2(v, OP_Next, tab1, iStart);
sqlite3VdbeResolveLabel(v, iBreak);
@@ -1892,6 +1955,7 @@ static int multiSelect(
*apColl = db->pDfltColl;
}
}
pKeyInfo->aSortOrder = (u8*)apColl;
for(pLoop=p; pLoop; pLoop=pLoop->pPrior){
for(i=0; i<2; i++){
@@ -1965,7 +2029,7 @@ static int generateOutputSubroutine(
(char*)pKeyInfo, p4type);
sqlite3VdbeAddOp3(v, OP_Jump, j2+2, iContinue, j2+2);
sqlite3VdbeJumpHere(v, j1);
sqlite3ExprCodeCopy(pParse, pIn->iSdst, regPrev+1, pIn->nSdst);
sqlite3VdbeAddOp3(v, OP_Copy, pIn->iSdst, regPrev+1, pIn->nSdst-1);
sqlite3VdbeAddOp2(v, OP_Integer, 1, regPrev);
}
if( pParse->db->mallocFailed ) return 0;
@@ -2000,10 +2064,10 @@ static int generateOutputSubroutine(
case SRT_Set: {
int r1;
assert( pIn->nSdst==1 );
p->affinity =
pDest->affSdst =
sqlite3CompareAffinity(p->pEList->a[0].pExpr, pDest->affSdst);
r1 = sqlite3GetTempReg(pParse);
sqlite3VdbeAddOp4(v, OP_MakeRecord, pIn->iSdst, 1, r1, &p->affinity, 1);
sqlite3VdbeAddOp4(v, OP_MakeRecord, pIn->iSdst, 1, r1, &pDest->affSdst,1);
sqlite3ExprCacheAffinityChange(pParse, pIn->iSdst, 1);
sqlite3VdbeAddOp2(v, OP_IdxInsert, pDest->iSDParm, r1);
sqlite3ReleaseTempReg(pParse, r1);
@@ -2745,7 +2809,7 @@ static int flattenSubquery(
*/
assert( p!=0 );
assert( p->pPrior==0 ); /* Unable to flatten compound queries */
if( db->flags & SQLITE_QueryFlattener ) return 0;
if( OptimizationDisabled(db, SQLITE_QueryFlattener) ) return 0;
pSrc = p->pSrc;
assert( pSrc && iFrom>=0 && iFrom<pSrc->nSrc );
pSubitem = &pSrc->a[iFrom];
@@ -3268,8 +3332,7 @@ static int selectExpander(Walker *pWalker, Select *p){
}else{
/* An ordinary table or view name in the FROM clause */
assert( pFrom->pTab==0 );
pFrom->pTab = pTab =
sqlite3LocateTable(pParse,0,pFrom->zName,pFrom->zDatabase);
pFrom->pTab = pTab = sqlite3LocateTableItem(pParse, 0, pFrom);
if( pTab==0 ) return WRC_Abort;
pTab->nRef++;
#if !defined(SQLITE_OMIT_VIEW) || !defined (SQLITE_OMIT_VIRTUALTABLE)
@@ -3785,11 +3848,9 @@ int sqlite3Select(
ExprList *pOrderBy; /* The ORDER BY clause. May be NULL */
ExprList *pGroupBy; /* The GROUP BY clause. May be NULL */
Expr *pHaving; /* The HAVING clause. May be NULL */
int isDistinct; /* True if the DISTINCT keyword is present */
int distinct; /* Table to use for the distinct set */
int rc = 1; /* Value to return from this function */
int addrSortIndex; /* Address of an OP_OpenEphemeral instruction */
int addrDistinctIndex; /* Address of an OP_OpenEphemeral instruction */
DistinctCtx sDistinct; /* Info on how to code the DISTINCT keyword */
AggInfo sAggInfo; /* Information used by aggregate queries */
int iEnd; /* Address of the end of the query */
sqlite3 *db; /* The database connection */
@@ -3915,7 +3976,7 @@ int sqlite3Select(
pWhere = p->pWhere;
pGroupBy = p->pGroupBy;
pHaving = p->pHaving;
isDistinct = (p->selFlags & SF_Distinct)!=0;
sDistinct.isTnct = (p->selFlags & SF_Distinct)!=0;
#ifndef SQLITE_OMIT_COMPOUND_SELECT
/* If there is are a sequence of queries, do the earlier ones first.
@@ -3950,7 +4011,7 @@ int sqlite3Select(
** to disable this optimization for testing purposes.
*/
if( sqlite3ExprListCompare(p->pGroupBy, pOrderBy)==0
&& (db->flags & SQLITE_GroupByOrder)==0 ){
&& OptimizationEnabled(db, SQLITE_GroupByOrder) ){
pOrderBy = 0;
}
@@ -3976,6 +4037,10 @@ int sqlite3Select(
p->pGroupBy = sqlite3ExprListDup(db, p->pEList, 0);
pGroupBy = p->pGroupBy;
pOrderBy = 0;
/* Notice that even thought SF_Distinct has been cleared from p->selFlags,
** the sDistinct.isTnct is still set. Hence, isTnct represents the
** original setting of the SF_Distinct flag, not the current setting */
assert( sDistinct.isTnct );
}
/* If there is an ORDER BY clause, then this sorting
@@ -4016,24 +4081,27 @@ int sqlite3Select(
/* Open a virtual index to use for the distinct set.
*/
if( p->selFlags & SF_Distinct ){
KeyInfo *pKeyInfo;
distinct = pParse->nTab++;
pKeyInfo = keyInfoFromExprList(pParse, p->pEList);
addrDistinctIndex = sqlite3VdbeAddOp4(v, OP_OpenEphemeral, distinct, 0, 0,
(char*)pKeyInfo, P4_KEYINFO_HANDOFF);
sDistinct.tabTnct = pParse->nTab++;
sDistinct.addrTnct = sqlite3VdbeAddOp4(v, OP_OpenEphemeral,
sDistinct.tabTnct, 0, 0,
(char*)keyInfoFromExprList(pParse, p->pEList),
P4_KEYINFO_HANDOFF);
sqlite3VdbeChangeP5(v, BTREE_UNORDERED);
sDistinct.eTnctType = WHERE_DISTINCT_UNORDERED;
}else{
distinct = addrDistinctIndex = -1;
sDistinct.eTnctType = WHERE_DISTINCT_NOOP;
}
/* Aggregate and non-aggregate queries are handled differently */
if( !isAgg && pGroupBy==0 ){
ExprList *pDist = (isDistinct ? p->pEList : 0);
/* No aggregate functions and no GROUP BY clause */
ExprList *pDist = (sDistinct.isTnct ? p->pEList : 0);
/* Begin the database scan. */
pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, &pOrderBy, pDist, 0,0);
pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pOrderBy, pDist, 0,0);
if( pWInfo==0 ) goto select_end;
if( pWInfo->nRowOut < p->nSelectRow ) p->nSelectRow = pWInfo->nRowOut;
if( pWInfo->eDistinct ) sDistinct.eTnctType = pWInfo->eDistinct;
if( pOrderBy && pWInfo->nOBSat==pOrderBy->nExpr ) pOrderBy = 0;
/* If sorting index that was created by a prior OP_OpenEphemeral
** instruction ended up not being needed, then change the OP_OpenEphemeral
@@ -4044,59 +4112,16 @@ int sqlite3Select(
p->addrOpenEphm[2] = -1;
}
if( pWInfo->eDistinct ){
VdbeOp *pOp; /* No longer required OpenEphemeral instr. */
assert( addrDistinctIndex>=0 );
pOp = sqlite3VdbeGetOp(v, addrDistinctIndex);
assert( isDistinct );
assert( pWInfo->eDistinct==WHERE_DISTINCT_ORDERED
|| pWInfo->eDistinct==WHERE_DISTINCT_UNIQUE
);
distinct = -1;
if( pWInfo->eDistinct==WHERE_DISTINCT_ORDERED ){
int iJump;
int iExpr;
int iFlag = ++pParse->nMem;
int iBase = pParse->nMem+1;
int iBase2 = iBase + pEList->nExpr;
pParse->nMem += (pEList->nExpr*2);
/* Change the OP_OpenEphemeral coded earlier to an OP_Integer. The
** OP_Integer initializes the "first row" flag. */
pOp->opcode = OP_Integer;
pOp->p1 = 1;
pOp->p2 = iFlag;
sqlite3ExprCodeExprList(pParse, pEList, iBase, 1);
iJump = sqlite3VdbeCurrentAddr(v) + 1 + pEList->nExpr + 1 + 1;
sqlite3VdbeAddOp2(v, OP_If, iFlag, iJump-1);
for(iExpr=0; iExpr<pEList->nExpr; iExpr++){
CollSeq *pColl = sqlite3ExprCollSeq(pParse, pEList->a[iExpr].pExpr);
sqlite3VdbeAddOp3(v, OP_Ne, iBase+iExpr, iJump, iBase2+iExpr);
sqlite3VdbeChangeP4(v, -1, (const char *)pColl, P4_COLLSEQ);
sqlite3VdbeChangeP5(v, SQLITE_NULLEQ);
}
sqlite3VdbeAddOp2(v, OP_Goto, 0, pWInfo->iContinue);
sqlite3VdbeAddOp2(v, OP_Integer, 0, iFlag);
assert( sqlite3VdbeCurrentAddr(v)==iJump );
sqlite3VdbeAddOp3(v, OP_Move, iBase, iBase2, pEList->nExpr);
}else{
pOp->opcode = OP_Noop;
}
}
/* Use the standard inner loop. */
selectInnerLoop(pParse, p, pEList, 0, 0, pOrderBy, distinct, pDest,
selectInnerLoop(pParse, p, pEList, 0, 0, pOrderBy, &sDistinct, pDest,
pWInfo->iContinue, pWInfo->iBreak);
/* End the database scan loop.
*/
sqlite3WhereEnd(pWInfo);
}else{
/* This is the processing for aggregate queries */
/* This case when there exist aggregate functions or a GROUP BY clause
** or both */
NameContext sNC; /* Name context for processing aggregate information */
int iAMem; /* First Mem address for storing current GROUP BY */
int iBMem; /* First Mem address for previous GROUP BY */
@@ -4204,14 +4229,13 @@ int sqlite3Select(
** in the right order to begin with.
*/
sqlite3VdbeAddOp2(v, OP_Gosub, regReset, addrReset);
pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, &pGroupBy, 0, 0, 0);
pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pGroupBy, 0, 0, 0);
if( pWInfo==0 ) goto select_end;
if( pGroupBy==0 ){
if( pWInfo->nOBSat==pGroupBy->nExpr ){
/* The optimizer is able to deliver rows in group by order so
** we do not have to sort. The OP_OpenEphemeral table will be
** cancelled later because we still need to use the pKeyInfo
*/
pGroupBy = p->pGroupBy;
groupBySort = 0;
}else{
/* Rows are coming out in undetermined order. We have to push
@@ -4225,7 +4249,8 @@ int sqlite3Select(
int nGroupBy;
explainTempTable(pParse,
isDistinct && !(p->selFlags&SF_Distinct)?"DISTINCT":"GROUP BY");
(sDistinct.isTnct && (p->selFlags&SF_Distinct)==0) ?
"DISTINCT" : "GROUP BY");
groupBySort = 1;
nGroupBy = pGroupBy->nExpr;
@@ -4357,7 +4382,7 @@ int sqlite3Select(
finalizeAggFunctions(pParse, &sAggInfo);
sqlite3ExprIfFalse(pParse, pHaving, addrOutputRow+1, SQLITE_JUMPIFNULL);
selectInnerLoop(pParse, p, p->pEList, 0, 0, pOrderBy,
distinct, pDest,
&sDistinct, pDest,
addrOutputRow+1, addrSetAbort);
sqlite3VdbeAddOp1(v, OP_Return, regOutputRow);
VdbeComment((v, "end groupby result generator"));
@@ -4460,6 +4485,7 @@ int sqlite3Select(
u8 flag = minMaxQuery(p);
if( flag ){
assert( !ExprHasProperty(p->pEList->a[0].pExpr, EP_xIsSelect) );
assert( p->pEList->a[0].pExpr->x.pList->nExpr==1 );
pMinMax = sqlite3ExprListDup(db, p->pEList->a[0].pExpr->x.pList,0);
pDel = pMinMax;
if( pMinMax && !db->mallocFailed ){
@@ -4473,13 +4499,14 @@ int sqlite3Select(
** of output.
*/
resetAccumulator(pParse, &sAggInfo);
pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, &pMinMax,0,flag,0);
pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pMinMax,0,flag,0);
if( pWInfo==0 ){
sqlite3ExprListDelete(db, pDel);
goto select_end;
}
updateAccumulator(pParse, &sAggInfo);
if( !pMinMax && flag ){
assert( pMinMax==0 || pMinMax->nExpr==1 );
if( pWInfo->nOBSat>0 ){
sqlite3VdbeAddOp2(v, OP_Goto, 0, pWInfo->iBreak);
VdbeComment((v, "%s() by index",
(flag==WHERE_ORDERBY_MIN?"min":"max")));
@@ -4490,7 +4517,7 @@ int sqlite3Select(
pOrderBy = 0;
sqlite3ExprIfFalse(pParse, pHaving, addrEnd, SQLITE_JUMPIFNULL);
selectInnerLoop(pParse, p, p->pEList, 0, 0, 0, -1,
selectInnerLoop(pParse, p, p->pEList, 0, 0, 0, 0,
pDest, addrEnd, addrEnd);
sqlite3ExprListDelete(db, pDel);
}
@@ -4498,7 +4525,7 @@ int sqlite3Select(
} /* endif aggregate query */
if( distinct>=0 ){
if( sDistinct.eTnctType==WHERE_DISTINCT_UNORDERED ){
explainTempTable(pParse, "DISTINCT");
}
+32 -5
View File
@@ -696,7 +696,7 @@ static int shell_callback(void *pArg, int nArg, char **azArg, char **azCol, int
}else{
w = 0;
}
if( w<=0 ){
if( w==0 ){
w = strlen30(azCol[i] ? azCol[i] : "");
if( w<10 ) w = 10;
n = strlen30(azArg && azArg[i] ? azArg[i] : p->nullvalue);
@@ -706,7 +706,11 @@ static int shell_callback(void *pArg, int nArg, char **azArg, char **azCol, int
p->actualWidth[i] = w;
}
if( p->showHeader ){
fprintf(p->out,"%-*.*s%s",w,w,azCol[i], i==nArg-1 ? "\n": " ");
if( w<0 ){
fprintf(p->out,"%*.*s%s",-w,-w,azCol[i], i==nArg-1 ? "\n": " ");
}else{
fprintf(p->out,"%-*.*s%s",w,w,azCol[i], i==nArg-1 ? "\n": " ");
}
}
}
if( p->showHeader ){
@@ -714,6 +718,7 @@ static int shell_callback(void *pArg, int nArg, char **azArg, char **azCol, int
int w;
if( i<ArraySize(p->actualWidth) ){
w = p->actualWidth[i];
if( w<0 ) w = -w;
}else{
w = 10;
}
@@ -735,8 +740,13 @@ static int shell_callback(void *pArg, int nArg, char **azArg, char **azCol, int
strlen30(azArg[i])>w ){
w = strlen30(azArg[i]);
}
fprintf(p->out,"%-*.*s%s",w,w,
azArg[i] ? azArg[i] : p->nullvalue, i==nArg-1 ? "\n": " ");
if( w<0 ){
fprintf(p->out,"%*.*s%s",-w,-w,
azArg[i] ? azArg[i] : p->nullvalue, i==nArg-1 ? "\n": " ");
}else{
fprintf(p->out,"%-*.*s%s",w,w,
azArg[i] ? azArg[i] : p->nullvalue, i==nArg-1 ? "\n": " ");
}
}
break;
}
@@ -1416,9 +1426,10 @@ static char zHelp[] =
" list Values delimited by .separator string\n"
" tabs Tab-separated values\n"
" tcl TCL list elements\n"
".nullvalue STRING Print STRING in place of NULL values\n"
".nullvalue STRING Use STRING in place of NULL values\n"
".output FILENAME Send output to FILENAME\n"
".output stdout Send output to the screen\n"
".print STRING... Print literal STRING\n"
".prompt MAIN CONTINUE Replace the standard prompts\n"
".quit Exit this program\n"
".read FILENAME Execute SQL in FILENAME\n"
@@ -2070,6 +2081,15 @@ static int do_meta_command(char *zLine, struct callback_data *p){
}
}else
if( c=='p' && n>=3 && strncmp(azArg[0], "print", n)==0 ){
int i;
for(i=1; i<nArg; i++){
if( i>1 ) fprintf(p->out, " ");
fprintf(p->out, "%s", azArg[i]);
}
fprintf(p->out, "\n");
}else
if( c=='p' && strncmp(azArg[0], "prompt", n)==0 && (nArg==2 || nArg==3)){
if( nArg >= 2) {
strncpy(mainPrompt,azArg[1],(int)ArraySize(mainPrompt)-1);
@@ -2493,6 +2513,13 @@ static int do_meta_command(char *zLine, struct callback_data *p){
}
}else
#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE)
if( c=='w' && strncmp(azArg[0], "wheretrace", n)==0 ){
extern int sqlite3WhereTrace;
sqlite3WhereTrace = atoi(azArg[1]);
}else
#endif
if( c=='w' && strncmp(azArg[0], "width", n)==0 && nArg>1 ){
int j;
assert( nArg<=ArraySize(azArg) );
+36 -1
View File
@@ -473,6 +473,7 @@ int sqlite3_exec(
#define SQLITE_BUSY_RECOVERY (SQLITE_BUSY | (1<<8))
#define SQLITE_CANTOPEN_NOTEMPDIR (SQLITE_CANTOPEN | (1<<8))
#define SQLITE_CANTOPEN_ISDIR (SQLITE_CANTOPEN | (2<<8))
#define SQLITE_CANTOPEN_FULLPATH (SQLITE_CANTOPEN | (3<<8))
#define SQLITE_CORRUPT_VTAB (SQLITE_CORRUPT | (1<<8))
#define SQLITE_READONLY_RECOVERY (SQLITE_READONLY | (1<<8))
#define SQLITE_READONLY_CANTLOCK (SQLITE_READONLY | (2<<8))
@@ -851,6 +852,17 @@ struct sqlite3_io_methods {
** file control occurs at the beginning of pragma statement analysis and so
** it is able to override built-in [PRAGMA] statements.
** </ul>
**
** <li>[[SQLITE_FCNTL_BUSYHANDLER]]
** ^This file-control may be invoked by SQLite on the database file handle
** shortly after it is opened in order to provide a custom VFS with access
** to the connections busy-handler callback. The argument is of type (void **)
** - an array of two (void *) values. The first (void *) actually points
** to a function of type (int (*)(void *)). In order to invoke the connections
** busy-handler, this function should be invoked with the second (void *) in
** the array as the only argument. If it returns non-zero, then the operation
** should be retried. If it returns zero, the custom VFS should abandon the
** current operation.
*/
#define SQLITE_FCNTL_LOCKSTATE 1
#define SQLITE_GET_LOCKPROXYFILE 2
@@ -866,6 +878,7 @@ struct sqlite3_io_methods {
#define SQLITE_FCNTL_VFSNAME 12
#define SQLITE_FCNTL_POWERSAFE_OVERWRITE 13
#define SQLITE_FCNTL_PRAGMA 14
#define SQLITE_FCNTL_BUSYHANDLER 15
/*
** CAPI3REF: Mutex Handle
@@ -1562,6 +1575,18 @@ struct sqlite3_mem_methods {
** disabled. The default value may be changed by compiling with the
** [SQLITE_USE_URI] symbol defined.
**
** [[SQLITE_CONFIG_COVERING_INDEX_SCAN]] <dt>SQLITE_CONFIG_COVERING_INDEX_SCAN
** <dd> This option taks a single integer argument which is interpreted as
** a boolean in order to enable or disable the use of covering indices for
** full table scans in the query optimizer. The default setting is determined
** by the [SQLITE_ALLOW_COVERING_INDEX_SCAN] compile-time option, or is "on"
** if that compile-time option is omitted.
** The ability to disable the use of covering indices for full table scans
** is because some incorrectly coded legacy applications might malfunction
** malfunction when the optimization is enabled. Providing the ability to
** disable the optimization allows the older, buggy application code to work
** without change even with newer versions of SQLite.
**
** [[SQLITE_CONFIG_PCACHE]] [[SQLITE_CONFIG_GETPCACHE]]
** <dt>SQLITE_CONFIG_PCACHE and SQLITE_CONFIG_GETPCACHE
** <dd> These options are obsolete and should not be used by new code.
@@ -1587,6 +1612,7 @@ struct sqlite3_mem_methods {
#define SQLITE_CONFIG_URI 17 /* int */
#define SQLITE_CONFIG_PCACHE2 18 /* sqlite3_pcache_methods2* */
#define SQLITE_CONFIG_GETPCACHE2 19 /* sqlite3_pcache_methods2* */
#define SQLITE_CONFIG_COVERING_INDEX_SCAN 20 /* int */
/*
** CAPI3REF: Database Connection Configuration Options
@@ -2595,7 +2621,7 @@ void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*);
** an error)^.
** ^If "ro" is specified, then the database is opened for read-only
** access, just as if the [SQLITE_OPEN_READONLY] flag had been set in the
** third argument to sqlite3_prepare_v2(). ^If the mode option is set to
** third argument to sqlite3_open_v2(). ^If the mode option is set to
** "rw", then the database is opened for read-write (but not create)
** access, as if SQLITE_OPEN_READWRITE (but not SQLITE_OPEN_CREATE) had
** been set. ^Value "rwc" is equivalent to setting both
@@ -2747,6 +2773,11 @@ sqlite3_int64 sqlite3_uri_int64(const char*, const char*, sqlite3_int64);
** However, the error string might be overwritten or deallocated by
** subsequent calls to other SQLite interface functions.)^
**
** ^The sqlite3_errstr() interface returns the English-language text
** that describes the [result code], as UTF-8.
** ^(Memory to hold the error message string is managed internally
** and must not be freed by the application)^.
**
** When the serialized [threading mode] is in use, it might be the
** case that a second error occurs on a separate thread in between
** the time of the first error and the call to these interfaces.
@@ -2765,6 +2796,7 @@ int sqlite3_errcode(sqlite3 *db);
int sqlite3_extended_errcode(sqlite3 *db);
const char *sqlite3_errmsg(sqlite3*);
const void *sqlite3_errmsg16(sqlite3*);
const char *sqlite3_errstr(int);
/*
** CAPI3REF: SQL Statement Object
@@ -4727,6 +4759,9 @@ void *sqlite3_update_hook(
** future releases of SQLite. Applications that care about shared
** cache setting should set it explicitly.
**
** This interface is threadsafe on processors where writing a
** 32-bit integer is atomic.
**
** See Also: [SQLite Shared-Cache Mode]
*/
int sqlite3_enable_shared_cache(int);
+102 -82
View File
@@ -661,6 +661,7 @@ typedef struct Parse Parse;
typedef struct RowSet RowSet;
typedef struct Savepoint Savepoint;
typedef struct Select Select;
typedef struct SelectDest SelectDest;
typedef struct SrcList SrcList;
typedef struct StrAccum StrAccum;
typedef struct Table Table;
@@ -826,6 +827,7 @@ struct sqlite3 {
unsigned int openFlags; /* Flags passed to sqlite3_vfs.xOpen() */
int errCode; /* Most recent error code (SQLITE_*) */
int errMask; /* & result codes with this before returning */
u8 dbOptFlags; /* Flags to enable/disable optimizations */
u8 autoCommit; /* The auto-commit flag. */
u8 temp_store; /* 1: file 2: memory 0: default */
u8 mallocFailed; /* True if we have seen a malloc failure */
@@ -930,48 +932,58 @@ struct sqlite3 {
/*
** Possible values for the sqlite3.flags.
*/
#define SQLITE_VdbeTrace 0x00000100 /* True to trace VDBE execution */
#define SQLITE_InternChanges 0x00000200 /* Uncommitted Hash table changes */
#define SQLITE_FullColNames 0x00000400 /* Show full column names on SELECT */
#define SQLITE_ShortColNames 0x00000800 /* Show short columns names */
#define SQLITE_CountRows 0x00001000 /* Count rows changed by INSERT, */
#define SQLITE_VdbeTrace 0x00000001 /* True to trace VDBE execution */
#define SQLITE_InternChanges 0x00000002 /* Uncommitted Hash table changes */
#define SQLITE_FullColNames 0x00000004 /* Show full column names on SELECT */
#define SQLITE_ShortColNames 0x00000008 /* Show short columns names */
#define SQLITE_CountRows 0x00000010 /* Count rows changed by INSERT, */
/* DELETE, or UPDATE and return */
/* the count using a callback. */
#define SQLITE_NullCallback 0x00002000 /* Invoke the callback once if the */
#define SQLITE_NullCallback 0x00000020 /* Invoke the callback once if the */
/* result set is empty */
#define SQLITE_SqlTrace 0x00004000 /* Debug print SQL as it executes */
#define SQLITE_VdbeListing 0x00008000 /* Debug listings of VDBE programs */
#define SQLITE_WriteSchema 0x00010000 /* OK to update SQLITE_MASTER */
/* 0x00020000 Unused */
#define SQLITE_IgnoreChecks 0x00040000 /* Do not enforce check constraints */
#define SQLITE_ReadUncommitted 0x0080000 /* For shared-cache mode */
#define SQLITE_LegacyFileFmt 0x00100000 /* Create new databases in format 1 */
#define SQLITE_FullFSync 0x00200000 /* Use full fsync on the backend */
#define SQLITE_CkptFullFSync 0x00400000 /* Use full fsync for checkpoint */
#define SQLITE_RecoveryMode 0x00800000 /* Ignore schema errors */
#define SQLITE_ReverseOrder 0x01000000 /* Reverse unordered SELECTs */
#define SQLITE_RecTriggers 0x02000000 /* Enable recursive triggers */
#define SQLITE_ForeignKeys 0x04000000 /* Enforce foreign key constraints */
#define SQLITE_AutoIndex 0x08000000 /* Enable automatic indexes */
#define SQLITE_PreferBuiltin 0x10000000 /* Preference to built-in funcs */
#define SQLITE_LoadExtension 0x20000000 /* Enable load_extension */
#define SQLITE_EnableTrigger 0x40000000 /* True to enable triggers */
#define SQLITE_SqlTrace 0x00000040 /* Debug print SQL as it executes */
#define SQLITE_VdbeListing 0x00000080 /* Debug listings of VDBE programs */
#define SQLITE_WriteSchema 0x00000100 /* OK to update SQLITE_MASTER */
/* 0x00000200 Unused */
#define SQLITE_IgnoreChecks 0x00000400 /* Do not enforce check constraints */
#define SQLITE_ReadUncommitted 0x0000800 /* For shared-cache mode */
#define SQLITE_LegacyFileFmt 0x00001000 /* Create new databases in format 1 */
#define SQLITE_FullFSync 0x00002000 /* Use full fsync on the backend */
#define SQLITE_CkptFullFSync 0x00004000 /* Use full fsync for checkpoint */
#define SQLITE_RecoveryMode 0x00008000 /* Ignore schema errors */
#define SQLITE_ReverseOrder 0x00010000 /* Reverse unordered SELECTs */
#define SQLITE_RecTriggers 0x00020000 /* Enable recursive triggers */
#define SQLITE_ForeignKeys 0x00040000 /* Enforce foreign key constraints */
#define SQLITE_AutoIndex 0x00080000 /* Enable automatic indexes */
#define SQLITE_PreferBuiltin 0x00100000 /* Preference to built-in funcs */
#define SQLITE_LoadExtension 0x00200000 /* Enable load_extension */
#define SQLITE_EnableTrigger 0x00400000 /* True to enable triggers */
/*
** Bits of the sqlite3.flags field that are used by the
** sqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS,...) interface.
** These must be the low-order bits of the flags field.
** Bits of the sqlite3.dbOptFlags field that are used by the
** sqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS,...) interface to
** selectively disable various optimizations.
*/
#define SQLITE_QueryFlattener 0x01 /* Disable query flattening */
#define SQLITE_ColumnCache 0x02 /* Disable the column cache */
#define SQLITE_IndexSort 0x04 /* Disable indexes for sorting */
#define SQLITE_IndexSearch 0x08 /* Disable indexes for searching */
#define SQLITE_IndexCover 0x10 /* Disable index covering table */
#define SQLITE_GroupByOrder 0x20 /* Disable GROUPBY cover of ORDERBY */
#define SQLITE_FactorOutConst 0x40 /* Disable factoring out constants */
#define SQLITE_IdxRealAsInt 0x80 /* Store REAL as INT in indices */
#define SQLITE_DistinctOpt 0x80 /* DISTINCT using indexes */
#define SQLITE_OptMask 0xff /* Mask of all disablable opts */
#define SQLITE_QueryFlattener 0x0001 /* Query flattening */
#define SQLITE_ColumnCache 0x0002 /* Column cache */
#define SQLITE_GroupByOrder 0x0004 /* GROUPBY cover of ORDERBY */
#define SQLITE_FactorOutConst 0x0008 /* Constant factoring */
#define SQLITE_IdxRealAsInt 0x0010 /* Store REAL as INT in indices */
#define SQLITE_DistinctOpt 0x0020 /* DISTINCT using indexes */
#define SQLITE_CoverIdxScan 0x0040 /* Covering index scans */
#define SQLITE_OrderByIdxJoin 0x0080 /* ORDER BY of joins via index */
#define SQLITE_AllOpts 0x00ff /* All optimizations */
/*
** Macros for testing whether or not optimizations are enabled or disabled.
*/
#ifndef SQLITE_OMIT_BUILTIN_TEST
#define OptimizationDisabled(db, mask) (((db)->dbOptFlags&(mask))!=0)
#define OptimizationEnabled(db, mask) (((db)->dbOptFlags&(mask))==0)
#else
#define OptimizationDisabled(db, mask) 0
#define OptimizationEnabled(db, mask) 1
#endif
/*
** Possible values for the sqlite.magic field.
@@ -1122,14 +1134,16 @@ struct Column {
char *zDflt; /* Original text of the default value */
char *zType; /* Data type for this column */
char *zColl; /* Collating sequence. If NULL, use the default */
u8 notNull; /* True if there is a NOT NULL constraint */
u8 isPrimKey; /* True if this column is part of the PRIMARY KEY */
u8 notNull; /* An OE_ code for handling a NOT NULL constraint */
char affinity; /* One of the SQLITE_AFF_... values */
#ifndef SQLITE_OMIT_VIRTUALTABLE
u8 isHidden; /* True if this column is 'hidden' */
#endif
u16 colFlags; /* Boolean properties. See COLFLAG_ defines below */
};
/* Allowed values for Column.colFlags:
*/
#define COLFLAG_PRIMKEY 0x0001 /* Column is part of the primary key */
#define COLFLAG_HIDDEN 0x0002 /* A hidden column in a virtual table */
/*
** A "Collating Sequence" is defined by an instance of the following
** structure. Conceptually, a collating sequence consists of a name and
@@ -1285,28 +1299,28 @@ struct VTable {
*/
struct Table {
char *zName; /* Name of the table or view */
int iPKey; /* If not negative, use aCol[iPKey] as the primary key */
int nCol; /* Number of columns in this table */
Column *aCol; /* Information about each column */
Index *pIndex; /* List of SQL indexes on this table. */
int tnum; /* Root BTree node for this table (see note above) */
tRowcnt nRowEst; /* Estimated rows in table - from sqlite_stat1 table */
Select *pSelect; /* NULL for tables. Points to definition if a view. */
u16 nRef; /* Number of pointers to this Table */
u8 tabFlags; /* Mask of TF_* values */
u8 keyConf; /* What to do in case of uniqueness conflict on iPKey */
FKey *pFKey; /* Linked list of all foreign keys in this table */
char *zColAff; /* String defining the affinity of each column */
#ifndef SQLITE_OMIT_CHECK
ExprList *pCheck; /* All CHECK constraints */
#endif
tRowcnt nRowEst; /* Estimated rows in table - from sqlite_stat1 table */
int tnum; /* Root BTree node for this table (see note above) */
i16 iPKey; /* If not negative, use aCol[iPKey] as the primary key */
i16 nCol; /* Number of columns in this table */
u16 nRef; /* Number of pointers to this Table */
u8 tabFlags; /* Mask of TF_* values */
u8 keyConf; /* What to do in case of uniqueness conflict on iPKey */
#ifndef SQLITE_OMIT_ALTERTABLE
int addColOffset; /* Offset in CREATE TABLE stmt to add a new column */
#endif
#ifndef SQLITE_OMIT_VIRTUALTABLE
VTable *pVTable; /* List of VTable objects. */
int nModuleArg; /* Number of arguments to the module */
char **azModuleArg; /* Text of all module args. [0] is module name */
VTable *pVTable; /* List of VTable objects. */
#endif
Trigger *pTrigger; /* List of triggers stored in pSchema */
Schema *pSchema; /* Schema that contains this table */
@@ -1330,7 +1344,7 @@ struct Table {
*/
#ifndef SQLITE_OMIT_VIRTUALTABLE
# define IsVirtual(X) (((X)->tabFlags & TF_Virtual)!=0)
# define IsHiddenColumn(X) ((X)->isHidden)
# define IsHiddenColumn(X) (((X)->colFlags & COLFLAG_HIDDEN)!=0)
#else
# define IsVirtual(X) 0
# define IsHiddenColumn(X) 0
@@ -1682,6 +1696,9 @@ struct Expr {
** access them will result in a segfault or malfunction.
*********************************************************************/
#if SQLITE_MAX_EXPR_DEPTH>0
int nHeight; /* Height of the tree headed by this node */
#endif
int iTable; /* TK_COLUMN: cursor number of table holding column
** TK_REGISTER: register number
** TK_TRIGGER: 1 -> new, 0 -> old */
@@ -1695,9 +1712,6 @@ struct Expr {
** TK_AGG_FUNCTION: nesting depth */
AggInfo *pAggInfo; /* Used by TK_AGG_COLUMN and TK_AGG_FUNCTION */
Table *pTab; /* Table for TK_COLUMN expressions. */
#if SQLITE_MAX_EXPR_DEPTH>0
int nHeight; /* Height of the tree headed by this node */
#endif
};
/*
@@ -1855,6 +1869,7 @@ struct SrcList {
i16 nSrc; /* Number of tables or subqueries in the FROM clause */
i16 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 */
char *zName; /* Name of the table */
char *zAlias; /* The "B" part of a "A AS B" phrase. zName is the "A" */
@@ -1905,7 +1920,8 @@ struct SrcList {
*/
struct WherePlan {
u32 wsFlags; /* WHERE_* flags that describe the strategy */
u32 nEq; /* Number of == constraints */
u16 nEq; /* Number of == constraints */
u16 nOBSat; /* Number of ORDER BY terms satisfied */
double nRow; /* Estimated number of rows (for EQP) */
union {
Index *pIdx; /* Index when WHERE_INDEXED is true */
@@ -1981,24 +1997,28 @@ struct WhereLevel {
** into the second half to give some continuity.
*/
struct WhereInfo {
Parse *pParse; /* Parsing and code generating context */
u16 wctrlFlags; /* Flags originally passed to sqlite3WhereBegin() */
u8 okOnePass; /* Ok to use one-pass algorithm for UPDATE or DELETE */
u8 untestedTerms; /* Not all WHERE terms resolved by outer loop */
u8 eDistinct;
SrcList *pTabList; /* List of tables in the join */
int iTop; /* The very beginning of the WHERE loop */
int iContinue; /* Jump here to continue with next record */
int iBreak; /* Jump here to break out of the loop */
int nLevel; /* Number of nested loop */
struct WhereClause *pWC; /* Decomposition of the WHERE clause */
double savedNQueryLoop; /* pParse->nQueryLoop outside the WHERE loop */
double nRowOut; /* Estimated number of output rows */
WhereLevel a[1]; /* Information about each nest loop in WHERE */
Parse *pParse; /* Parsing and code generating context */
SrcList *pTabList; /* List of tables in the join */
u16 nOBSat; /* Number of ORDER BY terms satisfied by indices */
u16 wctrlFlags; /* Flags originally passed to sqlite3WhereBegin() */
u8 okOnePass; /* Ok to use one-pass algorithm for UPDATE/DELETE */
u8 untestedTerms; /* Not all WHERE terms resolved by outer loop */
u8 eDistinct; /* One of the WHERE_DISTINCT_* values below */
int iTop; /* The very beginning of the WHERE loop */
int iContinue; /* Jump here to continue with next record */
int iBreak; /* Jump here to break out of the loop */
int nLevel; /* Number of nested loop */
struct WhereClause *pWC; /* Decomposition of the WHERE clause */
double savedNQueryLoop; /* pParse->nQueryLoop outside the WHERE loop */
double nRowOut; /* Estimated number of output rows */
WhereLevel a[1]; /* Information about each nest loop in WHERE */
};
#define WHERE_DISTINCT_UNIQUE 1
#define WHERE_DISTINCT_ORDERED 2
/* Allowed values for WhereInfo.eDistinct and DistinctCtx.eTnctType */
#define WHERE_DISTINCT_NOOP 0 /* DISTINCT keyword not used */
#define WHERE_DISTINCT_UNIQUE 1 /* No duplicates */
#define WHERE_DISTINCT_ORDERED 2 /* All duplicates are adjacent */
#define WHERE_DISTINCT_UNORDERED 3 /* Duplicates are scattered */
/*
** A NameContext defines a context in which to resolve table and column
@@ -2057,13 +2077,12 @@ struct NameContext {
** as the OP_OpenEphm instruction is coded because not
** enough information about the compound query is known at that point.
** The KeyInfo for addrOpenTran[0] and [1] contains collating sequences
** for the result set. The KeyInfo for addrOpenTran[2] contains collating
** for the result set. The KeyInfo for addrOpenEphm[2] contains collating
** sequences for the ORDER BY clause.
*/
struct Select {
ExprList *pEList; /* The fields of the result */
u8 op; /* One of: TK_UNION TK_ALL TK_INTERSECT TK_EXCEPT */
char affinity; /* MakeRecord with this affinity for SRT_Set */
u16 selFlags; /* Various SF_* values */
int iLimit, iOffset; /* Memory registers holding LIMIT & OFFSET counters */
int addrOpenEphm[3]; /* OP_OpenEphem opcodes related to this select */
@@ -2114,13 +2133,12 @@ struct Select {
#define SRT_Coroutine 10 /* Generate a single row of result */
/*
** A structure used to customize the behavior of sqlite3Select(). See
** comments above sqlite3Select() for details.
** An instance of this object describes where to put of the results of
** a SELECT statement.
*/
typedef struct SelectDest SelectDest;
struct SelectDest {
u8 eDest; /* How to dispose of the results */
u8 affSdst; /* Affinity used when eDest==SRT_Set */
u8 eDest; /* How to dispose of the results. On of SRT_* above. */
char affSdst; /* Affinity used when eDest==SRT_Set */
int iSDParm; /* A parameter used by the eDest disposal method */
int iSdst; /* Base register where results are written */
int nSdst; /* Number of registers allocated */
@@ -2420,6 +2438,7 @@ struct TriggerStep {
typedef struct DbFixer DbFixer;
struct DbFixer {
Parse *pParse; /* The parsing context. Error messages written here */
Schema *pSchema; /* Fix items to this schema */
const char *zDb; /* Make sure all objects are contained in this database */
const char *zType; /* Type of the container - used for error messages */
const Token *pName; /* Name of the container - used for error messages */
@@ -2462,6 +2481,7 @@ struct Sqlite3Config {
int bCoreMutex; /* True to enable core mutexing */
int bFullMutex; /* True to enable full mutexing */
int bOpenUri; /* True to interpret filenames as URIs */
int bUseCis; /* Use covering indices for full-scans */
int mxStrlen; /* Maximum string length */
int szLookaside; /* Default lookaside buffer size */
int nLookaside; /* Default lookaside buffer count */
@@ -2778,6 +2798,7 @@ void sqlite3DeleteTable(sqlite3*, Table*);
# define sqlite3AutoincrementBegin(X)
# define sqlite3AutoincrementEnd(X)
#endif
int sqlite3CodeCoroutine(Parse*, Select*, SelectDest*);
void sqlite3Insert(Parse*, SrcList*, ExprList*, Select*, IdList*, int);
void *sqlite3ArrayAllocate(sqlite3*,void*,int,int*,int*);
IdList *sqlite3IdListAppend(sqlite3*, IdList*, Token*);
@@ -2807,13 +2828,11 @@ Expr *sqlite3LimitWhere(Parse *, SrcList *, Expr *, ExprList *, Expr *, Expr *,
#endif
void sqlite3DeleteFrom(Parse*, SrcList*, Expr*);
void sqlite3Update(Parse*, SrcList*, ExprList*, Expr*, int);
WhereInfo *sqlite3WhereBegin(
Parse*,SrcList*,Expr*,ExprList**,ExprList*,u16,int);
WhereInfo *sqlite3WhereBegin(Parse*,SrcList*,Expr*,ExprList*,ExprList*,u16,int);
void sqlite3WhereEnd(WhereInfo*);
int sqlite3ExprCodeGetColumn(Parse*, Table*, int, int, int, u8);
void sqlite3ExprCodeGetColumnOfTable(Vdbe*, Table*, int, int, int);
void sqlite3ExprCodeMove(Parse*, int, int, int);
void sqlite3ExprCodeCopy(Parse*, int, int, int);
void sqlite3ExprCacheStore(Parse*, int, int, int);
void sqlite3ExprCachePush(Parse*);
void sqlite3ExprCachePop(Parse*, int);
@@ -2830,6 +2849,7 @@ void sqlite3ExprIfTrue(Parse*, Expr*, int, int);
void sqlite3ExprIfFalse(Parse*, Expr*, int, int);
Table *sqlite3FindTable(sqlite3*,const char*, const char*);
Table *sqlite3LocateTable(Parse*,int isView,const char*, const char*);
Table *sqlite3LocateTableItem(Parse*,int isView,struct SrcList_item *);
Index *sqlite3FindIndex(sqlite3*,const char*, const char*);
void sqlite3UnlinkAndDeleteTable(sqlite3*,int,const char*);
void sqlite3UnlinkAndDeleteIndex(sqlite3*,int,const char*);
@@ -2953,7 +2973,7 @@ int sqlite3GetInt32(const char *, int*);
int sqlite3Atoi(const char*);
int sqlite3Utf16ByteLen(const void *pData, int nChar);
int sqlite3Utf8CharLen(const char *pData, int nByte);
u32 sqlite3Utf8Read(const u8*, const u8**);
u32 sqlite3Utf8Read(const u8**);
/*
** Routines to read and write variable-length integers. These used to
@@ -3060,7 +3080,7 @@ int sqlite3ResolveOrderGroupBy(Parse*, Select*, ExprList*, const char*);
void sqlite3ColumnDefault(Vdbe *, Table *, int, int);
void sqlite3AlterFinishAddColumn(Parse *, Token *);
void sqlite3AlterBeginAddColumn(Parse *, SrcList *);
CollSeq *sqlite3GetCollSeq(sqlite3*, u8, CollSeq *, const char*);
CollSeq *sqlite3GetCollSeq(Parse*, u8, CollSeq *, const char*);
char sqlite3AffinityType(const char*);
void sqlite3Analyze(Parse*, Token*, Token*);
int sqlite3InvokeBusyHandler(BusyHandler*);
+26 -45
View File
@@ -53,15 +53,8 @@
#define NUM_PREPARED_STMTS 10
#define MAX_PREPARED_STMTS 100
/*
** If TCL uses UTF-8 and SQLite is configured to use iso8859, then we
** have to do a translation when going between the two. Set the
** UTF_TRANSLATION_NEEDED macro to indicate that we need to do
** this translation.
*/
#if defined(TCL_UTF_MAX) && !defined(SQLITE_UTF8)
# define UTF_TRANSLATION_NEEDED 1
#endif
/* Forward declaration */
typedef struct SqliteDb SqliteDb;
/*
** New SQL functions can be created as TCL scripts. Each such function
@@ -71,6 +64,7 @@ typedef struct SqlFunc SqlFunc;
struct SqlFunc {
Tcl_Interp *interp; /* The TCL interpret to execute the function */
Tcl_Obj *pScript; /* The Tcl_Obj representation of the script */
SqliteDb *pDb; /* Database connection that owns this function */
int useEvalObjv; /* True if it is safe to use Tcl_EvalObjv */
char *zName; /* Name of this function */
SqlFunc *pNext; /* Next function on the list of them all */
@@ -113,7 +107,6 @@ typedef struct IncrblobChannel IncrblobChannel;
** sqlite3_prepare_v2() or sqlite3_prepare() to prepare SQL statements.
** If SqliteDb.bLegacyPrepare is true, sqlite3_prepare() is used.
*/
typedef struct SqliteDb SqliteDb;
struct SqliteDb {
sqlite3 *db; /* The "real" database structure. MUST BE FIRST */
Tcl_Interp *interp; /* The interpreter used for this database */
@@ -431,6 +424,7 @@ static SqlFunc *findSqlFunc(SqliteDb *pDb, const char *zName){
}
}
pNew->interp = pDb->interp;
pNew->pDb = pDb;
pNew->pScript = 0;
pNew->pNext = pDb->pFunc;
pDb->pFunc = pNew;
@@ -478,6 +472,7 @@ static void DbDeleteCmd(void *db){
while( pDb->pFunc ){
SqlFunc *pFunc = pDb->pFunc;
pDb->pFunc = pFunc->pNext;
assert( pFunc->pDb==pDb );
Tcl_DecrRefCount(pFunc->pScript);
Tcl_Free((char*)pFunc);
}
@@ -794,7 +789,7 @@ static void tclSqlFunc(sqlite3_context *context, int argc, sqlite3_value**argv){
break;
}
case SQLITE_NULL: {
pVal = Tcl_NewStringObj("", 0);
pVal = Tcl_NewStringObj(p->pDb->zNull, -1);
break;
}
default: {
@@ -933,26 +928,6 @@ static int auth_callback(
}
#endif /* SQLITE_OMIT_AUTHORIZATION */
/*
** zText is a pointer to text obtained via an sqlite3_result_text()
** or similar interface. This routine returns a Tcl string object,
** reference count set to 0, containing the text. If a translation
** between iso8859 and UTF-8 is required, it is preformed.
*/
static Tcl_Obj *dbTextToObj(char const *zText){
Tcl_Obj *pVal;
#ifdef UTF_TRANSLATION_NEEDED
Tcl_DString dCol;
Tcl_DStringInit(&dCol);
Tcl_ExternalToUtfDString(NULL, zText, -1, &dCol);
pVal = Tcl_NewStringObj(Tcl_DStringValue(&dCol), -1);
Tcl_DStringFree(&dCol);
#else
pVal = Tcl_NewStringObj(zText, -1);
#endif
return pVal;
}
/*
** This routine reads a line of text from FILE in, stores
** the text in memory obtained from malloc() and returns a pointer
@@ -1140,13 +1115,13 @@ static int dbPrepareAndBind(
int nByte;
if( SQLITE_OK!=dbPrepare(pDb, zSql, &pStmt, pzOut) ){
Tcl_SetObjResult(interp, dbTextToObj(sqlite3_errmsg(pDb->db)));
Tcl_SetObjResult(interp, Tcl_NewStringObj(sqlite3_errmsg(pDb->db), -1));
return TCL_ERROR;
}
if( pStmt==0 ){
if( SQLITE_OK!=sqlite3_errcode(pDb->db) ){
/* A compile-time error in the statement. */
Tcl_SetObjResult(interp, dbTextToObj(sqlite3_errmsg(pDb->db)));
Tcl_SetObjResult(interp, Tcl_NewStringObj(sqlite3_errmsg(pDb->db), -1));
return TCL_ERROR;
}else{
/* The statement was a no-op. Continue to the next statement
@@ -1365,7 +1340,7 @@ static void dbEvalRowInfo(
if( nCol>0 && (papColName || p->pArray) ){
apColName = (Tcl_Obj**)Tcl_Alloc( sizeof(Tcl_Obj*)*nCol );
for(i=0; i<nCol; i++){
apColName[i] = dbTextToObj(sqlite3_column_name(pStmt,i));
apColName[i] = Tcl_NewStringObj(sqlite3_column_name(pStmt,i), -1);
Tcl_IncrRefCount(apColName[i]);
}
p->apColName = apColName;
@@ -1452,7 +1427,8 @@ static int dbEvalStep(DbEvalContext *p){
continue;
}
#endif
Tcl_SetObjResult(pDb->interp, dbTextToObj(sqlite3_errmsg(pDb->db)));
Tcl_SetObjResult(pDb->interp,
Tcl_NewStringObj(sqlite3_errmsg(pDb->db), -1));
return TCL_ERROR;
}else{
dbReleaseStmt(pDb, pPreStmt, 0);
@@ -1509,11 +1485,11 @@ static Tcl_Obj *dbEvalColumnValue(DbEvalContext *p, int iCol){
return Tcl_NewDoubleObj(sqlite3_column_double(pStmt, iCol));
}
case SQLITE_NULL: {
return dbTextToObj(p->pDb->zNull);
return Tcl_NewStringObj(p->pDb->zNull, -1);
}
}
return dbTextToObj((char *)sqlite3_column_text(pStmt, iCol));
return Tcl_NewStringObj((char*)sqlite3_column_text(pStmt, iCol), -1);
}
/*
@@ -2367,7 +2343,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
const char *zDb = "main";
const char *zTable;
const char *zColumn;
sqlite_int64 iRow;
Tcl_WideInt iRow;
/* Check for the -readonly option */
if( objc>3 && strcmp(Tcl_GetString(objv[2]), "-readonly")==0 ){
@@ -2433,7 +2409,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
pDb->zNull = 0;
}
}
Tcl_SetObjResult(interp, dbTextToObj(pDb->zNull));
Tcl_SetObjResult(interp, Tcl_NewStringObj(pDb->zNull, -1));
break;
}
@@ -2558,7 +2534,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
pKey = Tcl_GetByteArrayFromObj(objv[2], &nKey);
rc = sqlite3_rekey(pDb->db, pKey, nKey);
if( rc ){
Tcl_AppendResult(interp, sqlite3ErrStr(rc), 0);
Tcl_AppendResult(interp, sqlite3_errstr(rc), 0);
rc = TCL_ERROR;
}
#endif
@@ -2929,6 +2905,7 @@ static int DbMain(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
void *pKey = 0;
int nKey = 0;
#endif
int rc;
/* In normal use, each TCL interpreter runs in a single thread. So
** by default, we can turn of mutexing on SQLite database connections.
@@ -3033,12 +3010,16 @@ static int DbMain(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
memset(p, 0, sizeof(*p));
zFile = Tcl_GetStringFromObj(objv[2], 0);
zFile = Tcl_TranslateFileName(interp, zFile, &translatedFilename);
sqlite3_open_v2(zFile, &p->db, flags, zVfs);
rc = sqlite3_open_v2(zFile, &p->db, flags, zVfs);
Tcl_DStringFree(&translatedFilename);
if( SQLITE_OK!=sqlite3_errcode(p->db) ){
zErrMsg = sqlite3_mprintf("%s", sqlite3_errmsg(p->db));
sqlite3_close(p->db);
p->db = 0;
if( p->db ){
if( SQLITE_OK!=sqlite3_errcode(p->db) ){
zErrMsg = sqlite3_mprintf("%s", sqlite3_errmsg(p->db));
sqlite3_close(p->db);
p->db = 0;
}
}else{
zErrMsg = sqlite3_mprintf("%s", sqlite3_errstr(rc));
}
#ifdef SQLITE_HAS_CODEC
if( p->db ){
+7 -7
View File
@@ -3067,7 +3067,7 @@ static int test_bind_int64(
){
sqlite3_stmt *pStmt;
int idx;
i64 value;
Tcl_WideInt value;
int rc;
if( objc!=4 ){
@@ -4703,7 +4703,7 @@ static int test_soft_heap_limit(
Tcl_Obj *CONST objv[]
){
sqlite3_int64 amt;
sqlite3_int64 N = -1;
Tcl_WideInt N = -1;
if( objc!=1 && objc!=2 ){
Tcl_WrongNumArgs(interp, 1, objv, "?N?");
return TCL_ERROR;
@@ -5096,7 +5096,7 @@ static int file_control_sizehint_test(
int objc, /* Number of arguments */
Tcl_Obj *CONST objv[] /* Command arguments */
){
sqlite3_int64 nSize; /* Hinted size */
Tcl_WideInt nSize; /* Hinted size */
char *zDb; /* Db name ("main", "temp" etc.) */
sqlite3 *db; /* Database handle */
int rc; /* file_control() return code */
@@ -5933,15 +5933,15 @@ static int optimization_control(
const char *zOptName;
int mask;
} aOpt[] = {
{ "all", SQLITE_OptMask },
{ "all", SQLITE_AllOpts },
{ "query-flattener", SQLITE_QueryFlattener },
{ "column-cache", SQLITE_ColumnCache },
{ "index-sort", SQLITE_IndexSort },
{ "index-search", SQLITE_IndexSearch },
{ "index-cover", SQLITE_IndexCover },
{ "groupby-order", SQLITE_GroupByOrder },
{ "factor-constants", SQLITE_FactorOutConst },
{ "real-as-int", SQLITE_IdxRealAsInt },
{ "distinct-opt", SQLITE_DistinctOpt },
{ "cover-idx-scan", SQLITE_CoverIdxScan },
{ "order-by-idx-join",SQLITE_OrderByIdxJoin },
};
if( objc!=4 ){
+3 -2
View File
@@ -346,8 +346,9 @@ static int test_intarray_bind(
return TCL_ERROR;
}
for(i=0; i<n; i++){
a[i] = 0;
Tcl_GetWideIntFromObj(0, objv[i+2], &a[i]);
Tcl_WideInt x = 0;
Tcl_GetWideIntFromObj(0, objv[i+2], &x);
a[i] = x;
}
rc = sqlite3_intarray_bind(pArray, n, a, sqlite3_free);
if( rc!=SQLITE_OK ){
+36 -10
View File
@@ -1094,9 +1094,7 @@ static int test_db_config_lookaside(
}
/*
** Usage:
**
** sqlite3_config_heap NBYTE NMINALLOC
** Usage: sqlite3_config_heap NBYTE NMINALLOC
*/
static int test_config_heap(
void * clientData,
@@ -1133,7 +1131,7 @@ static int test_config_heap(
}
/*
** tclcmd: sqlite3_config_error [DB]
** Usage: sqlite3_config_error [DB]
**
** Invoke sqlite3_config() or sqlite3_db_config() with invalid
** opcodes and verify that they return errors.
@@ -1171,10 +1169,10 @@ static int test_config_error(
}
/*
** tclcmd: sqlite3_config_uri BOOLEAN
** Usage: sqlite3_config_uri BOOLEAN
**
** Invoke sqlite3_config() or sqlite3_db_config() with invalid
** opcodes and verify that they return errors.
** Enables or disables interpretation of URI parameters by default using
** SQLITE_CONFIG_URI.
*/
static int test_config_uri(
void * clientData,
@@ -1200,10 +1198,37 @@ static int test_config_uri(
}
/*
** Usage:
** Usage: sqlite3_config_cis BOOLEAN
**
** sqlite3_dump_memsys3 FILENAME
** sqlite3_dump_memsys5 FILENAME
** Enables or disables the use of the covering-index scan optimization.
** SQLITE_CONFIG_COVERING_INDEX_SCAN.
*/
static int test_config_cis(
void * clientData,
Tcl_Interp *interp,
int objc,
Tcl_Obj *CONST objv[]
){
int rc;
int bUseCis;
if( objc!=2 ){
Tcl_WrongNumArgs(interp, 1, objv, "BOOL");
return TCL_ERROR;
}
if( Tcl_GetBooleanFromObj(interp, objv[1], &bUseCis) ){
return TCL_ERROR;
}
rc = sqlite3_config(SQLITE_CONFIG_COVERING_INDEX_SCAN, bUseCis);
Tcl_SetResult(interp, (char *)sqlite3TestErrorName(rc), TCL_VOLATILE);
return TCL_OK;
}
/*
** Usage: sqlite3_dump_memsys3 FILENAME
** sqlite3_dump_memsys5 FILENAME
**
** Write a summary of unfreed memsys3 allocations to FILENAME.
*/
@@ -1451,6 +1476,7 @@ int Sqlitetest_malloc_Init(Tcl_Interp *interp){
{ "sqlite3_config_lookaside", test_config_lookaside ,0 },
{ "sqlite3_config_error", test_config_error ,0 },
{ "sqlite3_config_uri", test_config_uri ,0 },
{ "sqlite3_config_cis", test_config_cis ,0 },
{ "sqlite3_db_config_lookaside",test_db_config_lookaside ,0 },
{ "sqlite3_dump_memsys3", test_dump_memsys3 ,3 },
{ "sqlite3_dump_memsys5", test_dump_memsys3 ,5 },
+5 -4
View File
@@ -1073,7 +1073,7 @@ size_t sqlite3_quota_fwrite(
/* If the write was incomplete, adjust the file size and group size
** downward */
if( rc<nmemb && pFile ){
size_t nWritten = rc>=0 ? rc : 0;
size_t nWritten = rc;
sqlite3_int64 iNewEnd = iOfst + size*nWritten;
if( iNewEnd<iEnd ) iNewEnd = iEnd;
quotaEnter();
@@ -1354,8 +1354,10 @@ static void tclQuotaCallback(
rc = Tcl_EvalObjEx(p->interp, pEval, TCL_EVAL_GLOBAL);
if( rc==TCL_OK ){
Tcl_WideInt x;
Tcl_Obj *pLimit = Tcl_ObjGetVar2(p->interp, pVarname, 0, 0);
rc = Tcl_GetWideIntFromObj(p->interp, pLimit, piLimit);
rc = Tcl_GetWideIntFromObj(p->interp, pLimit, &x);
*piLimit = x;
Tcl_UnsetVar(p->interp, Tcl_GetString(pVarname), 0);
}
@@ -1437,7 +1439,7 @@ static int test_quota_set(
Tcl_Obj *CONST objv[]
){
const char *zPattern; /* File pattern to configure */
sqlite3_int64 iLimit; /* Initial quota in bytes */
Tcl_WideInt iLimit; /* Initial quota in bytes */
Tcl_Obj *pScript; /* Tcl script to invoke to increase quota */
int rc; /* Value returned by quota_set() */
TclQuotaCallback *p; /* Callback object */
@@ -1613,7 +1615,6 @@ static int test_quota_fread(
return TCL_ERROR;
}
got = sqlite3_quota_fread(zBuf, sz, nElem, p);
if( got<0 ) got = 0;
zBuf[got*sz] = 0;
Tcl_SetResult(interp, zBuf, TCL_VOLATILE);
sqlite3_free(zBuf);
+6 -10
View File
@@ -164,25 +164,23 @@ static const unsigned char sqlite3Utf8Trans1[] = {
|| (c&0xFFFFFFFE)==0xFFFE ){ c = 0xFFFD; } \
}
u32 sqlite3Utf8Read(
const unsigned char *zIn, /* First byte of UTF-8 character */
const unsigned char **pzNext /* Write first byte past UTF-8 char here */
const unsigned char **pz /* Pointer to string from which to read char */
){
unsigned int c;
/* Same as READ_UTF8() above but without the zTerm parameter.
** For this routine, we assume the UTF8 string is always zero-terminated.
*/
c = *(zIn++);
c = *((*pz)++);
if( c>=0xc0 ){
c = sqlite3Utf8Trans1[c-0xc0];
while( (*zIn & 0xc0)==0x80 ){
c = (c<<6) + (0x3f & *(zIn++));
while( (*(*pz) & 0xc0)==0x80 ){
c = (c<<6) + (0x3f & *((*pz)++));
}
if( c<0x80
|| (c&0xFFFFF800)==0xD800
|| (c&0xFFFFFFFE)==0xFFFE ){ c = 0xFFFD; }
}
*pzNext = zIn;
return c;
}
@@ -283,7 +281,6 @@ int sqlite3VdbeMemTranslate(Mem *pMem, u8 desiredEnc){
if( desiredEnc==SQLITE_UTF16LE ){
/* UTF-8 -> UTF-16 Little-endian */
while( zIn<zTerm ){
/* c = sqlite3Utf8Read(zIn, zTerm, (const u8**)&zIn); */
READ_UTF8(zIn, zTerm, c);
WRITE_UTF16LE(z, c);
}
@@ -291,7 +288,6 @@ int sqlite3VdbeMemTranslate(Mem *pMem, u8 desiredEnc){
assert( desiredEnc==SQLITE_UTF16BE );
/* UTF-8 -> UTF-16 Big-endian */
while( zIn<zTerm ){
/* c = sqlite3Utf8Read(zIn, zTerm, (const u8**)&zIn); */
READ_UTF8(zIn, zTerm, c);
WRITE_UTF16BE(z, c);
}
@@ -419,7 +415,7 @@ int sqlite3Utf8To8(unsigned char *zIn){
u32 c;
while( zIn[0] && zOut<=zIn ){
c = sqlite3Utf8Read(zIn, (const u8**)&zIn);
c = sqlite3Utf8Read((const u8**)&zIn);
if( c!=0xfffd ){
WRITE_UTF8(zOut, c);
}
@@ -524,7 +520,7 @@ void sqlite3UtfSelfTest(void){
assert( n>0 && n<=4 );
z[0] = 0;
z = zBuf;
c = sqlite3Utf8Read(z, (const u8**)&z);
c = sqlite3Utf8Read((const u8**)&z);
t = i;
if( i>=0xD800 && i<=0xDFFF ) t = 0xFFFD;
if( (i&0xFFFFFFFE)==0xFFFE ) t = 0xFFFD;
+50 -17
View File
@@ -956,23 +956,28 @@ case OP_String: { /* out2-prerelease */
break;
}
/* Opcode: Null * P2 P3 * *
/* Opcode: Null P1 P2 P3 * *
**
** Write a NULL into registers P2. If P3 greater than P2, then also write
** NULL into register P3 and ever register in between P2 and P3. If P3
** NULL into register P3 and every register in between P2 and P3. If P3
** is less than P2 (typically P3 is zero) then only register P2 is
** set to NULL
** set to NULL.
**
** If the P1 value is non-zero, then also set the MEM_Cleared flag so that
** NULL values will not compare equal even if SQLITE_NULLEQ is set on
** OP_Ne or OP_Eq.
*/
case OP_Null: { /* out2-prerelease */
int cnt;
u16 nullFlag;
cnt = pOp->p3-pOp->p2;
assert( pOp->p3<=p->nMem );
pOut->flags = MEM_Null;
pOut->flags = nullFlag = pOp->p1 ? (MEM_Null|MEM_Cleared) : MEM_Null;
while( cnt>0 ){
pOut++;
memAboutToChange(p, pOut);
VdbeMemRelease(pOut);
pOut->flags = MEM_Null;
pOut->flags = nullFlag;
cnt--;
}
break;
@@ -1015,10 +1020,10 @@ case OP_Variable: { /* out2-prerelease */
/* Opcode: Move P1 P2 P3 * *
**
** Move the values in register P1..P1+P3-1 over into
** registers P2..P2+P3-1. Registers P1..P1+P1-1 are
** Move the values in register P1..P1+P3 over into
** registers P2..P2+P3. Registers P1..P1+P3 are
** left holding a NULL. It is an error for register ranges
** P1..P1+P3-1 and P2..P2+P3-1 to overlap.
** P1..P1+P3 and P2..P2+P3 to overlap.
*/
case OP_Move: {
char *zMalloc; /* Holding variable for allocated memory */
@@ -1026,7 +1031,7 @@ case OP_Move: {
int p1; /* Register to copy from */
int p2; /* Register to copy to */
n = pOp->p3;
n = pOp->p3 + 1;
p1 = pOp->p1;
p2 = pOp->p2;
assert( n>0 && p1>0 && p2>0 );
@@ -1055,20 +1060,28 @@ case OP_Move: {
break;
}
/* Opcode: Copy P1 P2 * * *
/* Opcode: Copy P1 P2 P3 * *
**
** Make a copy of register P1 into register P2.
** Make a copy of registers P1..P1+P3 into registers P2..P2+P3.
**
** This instruction makes a deep copy of the value. A duplicate
** is made of any string or blob constant. See also OP_SCopy.
*/
case OP_Copy: { /* in1, out2 */
case OP_Copy: {
int n;
n = pOp->p3;
pIn1 = &aMem[pOp->p1];
pOut = &aMem[pOp->p2];
assert( pOut!=pIn1 );
sqlite3VdbeMemShallowCopy(pOut, pIn1, MEM_Ephem);
Deephemeralize(pOut);
REGISTER_TRACE(pOp->p2, pOut);
while( 1 ){
sqlite3VdbeMemShallowCopy(pOut, pIn1, MEM_Ephem);
Deephemeralize(pOut);
REGISTER_TRACE(pOp->p2+pOp->p3-n, pOut);
if( (n--)==0 ) break;
pOut++;
pIn1++;
}
break;
}
@@ -1737,6 +1750,10 @@ case OP_ToReal: { /* same as TK_TO_REAL, in1 */
**
** If the SQLITE_STOREP2 bit of P5 is set, then do not jump. Instead,
** store a boolean result (either 0, or 1, or NULL) in register P2.
**
** If the SQLITE_NULLEQ bit is set in P5, then NULL values are considered
** equal to one another, provided that they do not have their MEM_Cleared
** bit set.
*/
/* Opcode: Ne P1 P2 P3 P4 P5
**
@@ -1803,7 +1820,15 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
** or not both operands are null.
*/
assert( pOp->opcode==OP_Eq || pOp->opcode==OP_Ne );
res = (flags1 & flags3 & MEM_Null)==0;
assert( (flags1 & MEM_Cleared)==0 );
if( (flags1&MEM_Null)!=0
&& (flags3&MEM_Null)!=0
&& (flags3&MEM_Cleared)==0
){
res = 0; /* Results are equal */
}else{
res = 1; /* Results are not equal */
}
}else{
/* SQLITE_NULLEQ is clear and at least one operand is NULL,
** then the result is always NULL.
@@ -3278,6 +3303,7 @@ case OP_OpenEphemeral: {
*/
case OP_SorterOpen: {
VdbeCursor *pCx;
#ifndef SQLITE_OMIT_MERGE_SORT
pCx = allocateCursor(p, pOp->p1, pOp->p2, -1, 1);
if( pCx==0 ) goto no_mem;
@@ -4168,6 +4194,7 @@ case OP_SorterCompare: {
*/
case OP_SorterData: {
VdbeCursor *pC;
#ifndef SQLITE_OMIT_MERGE_SORT
pOut = &aMem[pOp->p2];
pC = p->apCsr[pOp->p1];
@@ -4706,6 +4733,7 @@ case OP_Destroy: { /* out2-prerelease */
int iCnt;
Vdbe *pVdbe;
int iDb;
#ifndef SQLITE_OMIT_VIRTUALTABLE
iCnt = 0;
for(pVdbe=db->pVdbe; pVdbe; pVdbe = pVdbe->pNext){
@@ -5495,7 +5523,9 @@ case OP_JournalMode: { /* out2-prerelease */
Pager *pPager; /* Pager associated with pBt */
int eNew; /* New journal mode */
int eOld; /* The old journal mode */
#ifndef SQLITE_OMIT_WAL
const char *zFilename; /* Name of database file for pPager */
#endif
eNew = pOp->p3;
assert( eNew==PAGER_JOURNALMODE_DELETE
@@ -6075,7 +6105,10 @@ case OP_Trace: {
char *zTrace;
char *z;
if( db->xTrace && (zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql))!=0 ){
if( db->xTrace
&& !p->doingRerun
&& (zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql))!=0
){
z = sqlite3VdbeExpandSql(p, zTrace);
db->xTrace(db->pTraceArg, z);
sqlite3DbFree(db, z);
+17 -9
View File
@@ -187,7 +187,9 @@ struct Mem {
#define MEM_RowSet 0x0020 /* Value is a RowSet object */
#define MEM_Frame 0x0040 /* Value is a VdbeFrame object */
#define MEM_Invalid 0x0080 /* Value is undefined */
#define MEM_TypeMask 0x00ff /* Mask of type bits */
#define MEM_Cleared 0x0100 /* NULL set by OP_Null, not from data */
#define MEM_TypeMask 0x01ff /* Mask of type bits */
/* Whenever Mem contains a valid string or blob representation, one of
** the following flags must be set to determine the memory management
@@ -273,6 +275,11 @@ struct Explain {
char zBase[100]; /* Initial space */
};
/* A bitfield type for use inside of structures. Always follow with :N where
** N is the number of bits.
*/
typedef unsigned bft; /* Bit Field Type */
/*
** An instance of the virtual machine. This structure contains the complete
** state of the virtual machine.
@@ -314,15 +321,16 @@ struct Vdbe {
int pc; /* The program counter */
int rc; /* Value to return */
u8 errorAction; /* Recovery action to do in case of an error */
u8 explain; /* True if EXPLAIN present on SQL command */
u8 changeCntOn; /* True to update the change-counter */
u8 expired; /* True if the VM needs to be recompiled */
u8 runOnlyOnce; /* Automatically expire on reset */
u8 minWriteFileFormat; /* Minimum file format for writable database files */
u8 inVtabMethod; /* See comments above */
u8 usesStmtJournal; /* True if uses a statement journal */
u8 readOnly; /* True for read-only statements */
u8 isPrepareV2; /* True if prepared with prepare_v2() */
bft explain:2; /* True if EXPLAIN present on SQL command */
bft inVtabMethod:2; /* See comments above */
bft changeCntOn:1; /* True to update the change-counter */
bft expired:1; /* True if the VM needs to be recompiled */
bft runOnlyOnce:1; /* Automatically expire on reset */
bft usesStmtJournal:1; /* True if uses a statement journal */
bft readOnly:1; /* True for read-only statements */
bft isPrepareV2:1; /* True if prepared with prepare_v2() */
bft doingRerun:1; /* True if rerunning after an auto-reprepare */
int nChange; /* Number of db changes made since last reset */
yDbMask btreeMask; /* Bitmask of db->aDb[] entries referenced */
yDbMask lockMask; /* Subset of btreeMask that requires a lock */
+2
View File
@@ -478,10 +478,12 @@ int sqlite3_step(sqlite3_stmt *pStmt){
}
db = v->db;
sqlite3_mutex_enter(db->mutex);
v->doingRerun = 0;
while( (rc = sqlite3Step(v))==SQLITE_SCHEMA
&& cnt++ < SQLITE_MAX_SCHEMA_RETRY
&& (rc2 = rc = sqlite3Reprepare(v))==SQLITE_OK ){
sqlite3_reset(pStmt);
v->doingRerun = 1;
assert( v->expired==0 );
}
if( rc2!=SQLITE_OK && ALWAYS(v->isPrepareV2) && ALWAYS(db->pErr) ){
+13 -10
View File
@@ -745,10 +745,9 @@ void sqlite3VdbeChangeP4(Vdbe *p, int addr, const char *zP4, int n){
u8 *aSortOrder;
memcpy((char*)pKeyInfo, zP4, nByte - nField);
aSortOrder = pKeyInfo->aSortOrder;
if( aSortOrder ){
pKeyInfo->aSortOrder = (unsigned char*)&pKeyInfo->aColl[nField];
memcpy(pKeyInfo->aSortOrder, aSortOrder, nField);
}
assert( aSortOrder!=0 );
pKeyInfo->aSortOrder = (unsigned char*)&pKeyInfo->aColl[nField];
memcpy(pKeyInfo->aSortOrder, aSortOrder, nField);
pOp->p4type = P4_KEYINFO;
}else{
p->db->mallocFailed = 1;
@@ -861,6 +860,7 @@ static char *displayP4(Op *pOp, char *zTemp, int nTemp){
case P4_KEYINFO: {
int i, j;
KeyInfo *pKeyInfo = pOp->p4.pKeyInfo;
assert( pKeyInfo->aSortOrder!=0 );
sqlite3_snprintf(nTemp, zTemp, "keyinfo(%d", pKeyInfo->nField);
i = sqlite3Strlen30(zTemp);
for(j=0; j<pKeyInfo->nField; j++){
@@ -872,7 +872,7 @@ static char *displayP4(Op *pOp, char *zTemp, int nTemp){
break;
}
zTemp[i++] = ',';
if( pKeyInfo->aSortOrder && pKeyInfo->aSortOrder[j] ){
if( pKeyInfo->aSortOrder[j] ){
zTemp[i++] = '-';
}
memcpy(&zTemp[i], pColl->zName,n+1);
@@ -1770,7 +1770,9 @@ static int vdbeCommit(sqlite3 *db, Vdbe *p){
if( sqlite3BtreeIsInTrans(pBt) ){
needXcommit = 1;
if( i!=1 ) nTrans++;
sqlite3BtreeEnter(pBt);
rc = sqlite3PagerExclusiveLock(sqlite3BtreePager(pBt));
sqlite3BtreeLeave(pBt);
}
}
if( rc!=SQLITE_OK ){
@@ -2583,9 +2585,6 @@ u32 sqlite3VdbeSerialType(Mem *pMem, int file_format){
# define MAX_6BYTE ((((i64)0x00008000)<<32)-1)
i64 i = pMem->u.i;
u64 u;
if( file_format>=4 && (i&1)==i ){
return 8+(u32)i;
}
if( i<0 ){
if( i<(-MAX_6BYTE) ) return 6;
/* Previous test prevents: u = -(-9223372036854775808) */
@@ -2593,7 +2592,9 @@ u32 sqlite3VdbeSerialType(Mem *pMem, int file_format){
}else{
u = i;
}
if( u<=127 ) return 1;
if( u<=127 ){
return ((i&1)==i && file_format>=4) ? 8+(u32)u : 1;
}
if( u<=32767 ) return 2;
if( u<=8388607 ) return 3;
if( u<=2147483647 ) return 4;
@@ -2878,6 +2879,7 @@ UnpackedRecord *sqlite3VdbeAllocUnpackedRecord(
}
p->aMem = (Mem*)&((char*)p)[ROUND8(sizeof(UnpackedRecord))];
assert( pKeyInfo->aSortOrder!=0 );
p->pKeyInfo = pKeyInfo;
p->nField = pKeyInfo->nField + 1;
return p;
@@ -2971,6 +2973,7 @@ int sqlite3VdbeRecordCompare(
idx1 = getVarint32(aKey1, szHdr1);
d1 = szHdr1;
nField = pKeyInfo->nField;
assert( pKeyInfo->aSortOrder!=0 );
while( idx1<szHdr1 && i<pPKey2->nField ){
u32 serial_type1;
@@ -2990,7 +2993,7 @@ int sqlite3VdbeRecordCompare(
assert( mem1.zMalloc==0 ); /* See comment below */
/* Invert the result if we are using DESC sort order. */
if( pKeyInfo->aSortOrder && i<nField && pKeyInfo->aSortOrder[i] ){
if( i<nField && pKeyInfo->aSortOrder[i] ){
rc = -rc;
}
+10 -3
View File
@@ -263,6 +263,7 @@ void sqlite3VtabClear(sqlite3 *db, Table *p){
if( !db || db->pnBytesFreed==0 ) vtabDisconnectAll(0, p);
if( p->azModuleArg ){
int i;
assert( p->nModuleArg<2 || p->azModuleArg[1]==0 );
for(i=0; i<p->nModuleArg; i++){
sqlite3DbFree(db, p->azModuleArg[i]);
}
@@ -324,7 +325,7 @@ void sqlite3VtabBeginParse(
pTable->tabFlags |= TF_Virtual;
pTable->nModuleArg = 0;
addModuleArgument(db, pTable, sqlite3NameFromToken(db, pModuleName));
addModuleArgument(db, pTable, sqlite3DbStrDup(db, db->aDb[iDb].zName));
addModuleArgument(db, pTable, 0);
addModuleArgument(db, pTable, sqlite3DbStrDup(db, pTable->zName));
pParse->sNameToken.n = (int)(&pModuleName->z[pModuleName->n] - pName1->z);
@@ -481,6 +482,7 @@ static int vtabCallConstructor(
int nArg = pTab->nModuleArg;
char *zErr = 0;
char *zModuleName = sqlite3MPrintf(db, "%s", pTab->zName);
int iDb;
if( !zModuleName ){
return SQLITE_NOMEM;
@@ -494,6 +496,10 @@ static int vtabCallConstructor(
pVTable->db = db;
pVTable->pMod = pMod;
assert( pTab->azModuleArg[1]==0 );
iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
pTab->azModuleArg[1] = db->aDb[iDb].zName;
/* Invoke the virtual table constructor */
assert( &db->pVtabCtx );
assert( xConstruct );
@@ -504,6 +510,7 @@ static int vtabCallConstructor(
rc = xConstruct(db, pMod->pAux, nArg, azArg, &pVTable->pVtab, &zErr);
db->pVtabCtx = pPriorCtx;
if( rc==SQLITE_NOMEM ) db->mallocFailed = 1;
pTab->azModuleArg[1] = 0;
if( SQLITE_OK!=rc ){
if( zErr==0 ){
@@ -528,7 +535,7 @@ static int vtabCallConstructor(
/* If everything went according to plan, link the new VTable structure
** into the linked list headed by pTab->pVTable. Then loop through the
** columns of the table to see if any of them contain the token "hidden".
** If so, set the Column.isHidden flag and remove the token from
** If so, set the Column COLFLAG_HIDDEN flag and remove the token from
** the type string. */
pVTable->pNext = pTab->pVTable;
pTab->pVTable = pVTable;
@@ -559,7 +566,7 @@ static int vtabCallConstructor(
assert(zType[i-1]==' ');
zType[i-1] = '\0';
}
pTab->aCol[iCol].isHidden = 1;
pTab->aCol[iCol].colFlags |= COLFLAG_HIDDEN;
}
}
}
+1 -1
View File
@@ -2828,7 +2828,7 @@ int sqlite3WalFrames(
*/
if( isCommit && (sync_flags & WAL_SYNC_TRANSACTIONS)!=0 ){
if( pWal->padToSectorBoundary ){
int sectorSize = sqlite3OsSectorSize(pWal->pWalFd);
int sectorSize = sqlite3SectorSize(pWal->pWalFd);
w.iSyncPoint = ((iOffset+sectorSize-1)/sectorSize)*sectorSize;
while( iOffset<w.iSyncPoint ){
rc = walWriteOneFrame(&w, pLast, nTruncate, iOffset);
+666 -496
View File
File diff suppressed because it is too large Load Diff
+2 -2
View File
@@ -61,14 +61,14 @@ do_test analyze6-1.0 {
#
do_test analyze6-1.1 {
eqp {SELECT count(*) FROM ev, cat WHERE x=y}
} {0 0 1 {SCAN TABLE cat (~16 rows)} 0 1 0 {SEARCH TABLE ev USING COVERING INDEX evy (y=?) (~32 rows)}}
} {0 0 1 {SCAN TABLE cat USING COVERING INDEX catx (~16 rows)} 0 1 0 {SEARCH TABLE ev USING COVERING INDEX evy (y=?) (~32 rows)}}
# The same plan is chosen regardless of the order of the tables in the
# FROM clause.
#
do_test analyze6-1.2 {
eqp {SELECT count(*) FROM cat, ev WHERE x=y}
} {0 0 0 {SCAN TABLE cat (~16 rows)} 0 1 1 {SEARCH TABLE ev USING COVERING INDEX evy (y=?) (~32 rows)}}
} {0 0 0 {SCAN TABLE cat USING COVERING INDEX catx (~16 rows)} 0 1 1 {SEARCH TABLE ev USING COVERING INDEX evy (y=?) (~32 rows)}}
# Ticket [83ea97620bd3101645138b7b0e71c12c5498fe3d] 2011-03-30
+1 -1
View File
@@ -114,7 +114,7 @@ foreach delete_order $delete_orders {
}
do_test autovacuum-1.$tn.($delete).3 {
execsql {
select a from av1
select a from av1 order by rowid
}
} $::tbl_data
}
+2
View File
@@ -213,7 +213,9 @@ unset ::incompatible
#
do_allbackcompat_test {
if {[code1 {sqlite3 -version}] >= "3.7.0"
&& [code1 {set ::sqlite_options(wal)}]
&& [code2 {sqlite3 -version}] >= "3.7.0"
&& [code2 {set ::sqlite_options(wal)}]
} {
do_test backcompat-2.1.1 { sql1 {
+1
View File
@@ -16,6 +16,7 @@
#
if {[file exists skip-big-file]} return
if {$tcl_platform(os)=="Darwin"} return
set testdir [file dirname $argv0]
source $testdir/tester.tcl
+1
View File
@@ -14,6 +14,7 @@
#
if {[file exists skip-big-file]} return
if {$tcl_platform(os)=="Darwin"} return
set testdir [file dirname $argv0]
source $testdir/tester.tcl
+14 -11
View File
@@ -94,7 +94,7 @@ do_test collate4-1.1.5 {
cksort {SELECT b FROM collate4t1 ORDER BY b COLLATE TEXT}
} {{} A B a b nosort}
do_test collate4-1.1.6 {
cksort {SELECT b FROM collate4t1 ORDER BY b COLLATE NOCASE}
cksort {SELECT b FROM collate4t1 ORDER BY b COLLATE NOCASE, rowid}
} {{} a A b B sort}
do_test collate4-1.1.7 {
@@ -171,13 +171,13 @@ do_test collate4-1.1.21 {
}
} {}
do_test collate4-1.1.22 {
cksort {SELECT a FROM collate4t4 ORDER BY a}
cksort {SELECT a FROM collate4t4 ORDER BY a, rowid}
} {{} a A b B sort}
do_test collate4-1.1.23 {
cksort {SELECT a FROM collate4t4 ORDER BY a COLLATE NOCASE}
cksort {SELECT a FROM collate4t4 ORDER BY a COLLATE NOCASE, rowid}
} {{} a A b B sort}
do_test collate4-1.1.24 {
cksort {SELECT a FROM collate4t4 ORDER BY a COLLATE TEXT}
cksort {SELECT a FROM collate4t4 ORDER BY a COLLATE TEXT, rowid}
} {{} A B a b nosort}
do_test collate4-1.1.25 {
cksort {SELECT b FROM collate4t4 ORDER BY b}
@@ -222,7 +222,7 @@ do_test collate4-1.2.4 {
cksort {SELECT a FROM collate4t1 ORDER BY a, b}
} {{} A a B b nosort}
do_test collate4-1.2.5 {
cksort {SELECT a FROM collate4t1 ORDER BY a, b COLLATE nocase}
cksort {SELECT a FROM collate4t1 ORDER BY a, b COLLATE nocase, rowid}
} {{} a A b B sort}
do_test collate4-1.2.6 {
cksort {SELECT a FROM collate4t1 ORDER BY a, b COLLATE text}
@@ -271,10 +271,10 @@ do_test collate4-1.2.14 {
}
} {}
do_test collate4-1.2.15 {
cksort {SELECT a FROM collate4t3 ORDER BY a}
cksort {SELECT a FROM collate4t3 ORDER BY a, rowid}
} {{} a A b B sort}
do_test collate4-1.2.16 {
cksort {SELECT a FROM collate4t3 ORDER BY a COLLATE nocase}
cksort {SELECT a FROM collate4t3 ORDER BY a COLLATE nocase, rowid}
} {{} a A b B sort}
do_test collate4-1.2.17 {
cksort {SELECT a FROM collate4t3 ORDER BY a COLLATE text}
@@ -364,7 +364,8 @@ do_test collate4-2.1.4 {
CREATE INDEX collate4i1 ON collate4t1(a COLLATE TEXT);
}
count {
SELECT * FROM collate4t2, collate4t1 WHERE a = b;
SELECT * FROM collate4t2, collate4t1 WHERE a = b
ORDER BY collate4t2.rowid, collate4t1.rowid
}
} {A a A A 19}
do_test collate4-2.1.5 {
@@ -375,7 +376,8 @@ do_test collate4-2.1.5 {
ifcapable subquery {
do_test collate4-2.1.6 {
count {
SELECT a FROM collate4t1 WHERE a IN (SELECT * FROM collate4t2);
SELECT a FROM collate4t1 WHERE a IN (SELECT * FROM collate4t2)
ORDER BY rowid
}
} {a A 10}
do_test collate4-2.1.7 {
@@ -384,7 +386,8 @@ ifcapable subquery {
CREATE INDEX collate4i1 ON collate4t1(a);
}
count {
SELECT a FROM collate4t1 WHERE a IN (SELECT * FROM collate4t2);
SELECT a FROM collate4t1 WHERE a IN (SELECT * FROM collate4t2)
ORDER BY rowid
}
} {a A 6}
do_test collate4-2.1.8 {
@@ -398,7 +401,7 @@ ifcapable subquery {
CREATE INDEX collate4i1 ON collate4t1(a COLLATE TEXT);
}
count {
SELECT a FROM collate4t1 WHERE a IN ('z', 'a');
SELECT a FROM collate4t1 WHERE a IN ('z', 'a') ORDER BY rowid;
}
} {a A 9}
}
+2 -2
View File
@@ -221,7 +221,7 @@ do_test collate5-3.0 {
execsql {
SELECT a FROM collate5t1 UNION ALL SELECT a FROM collate5t2 ORDER BY 1;
}
} {a A a A b B b B n N}
} {/[aA] [aA] [aA] [aA] [bB] [bB] [bB] [bB] [nN] [nN]/}
do_test collate5-3.1 {
execsql {
SELECT a FROM collate5t2 UNION ALL SELECT a FROM collate5t1 ORDER BY 1;
@@ -282,7 +282,7 @@ do_test collate5-4.2 {
execsql {
SELECT a, b, count(*) FROM collate5t1 GROUP BY a, b ORDER BY a, b;
}
} {A 1.0 2 b 2 1 B 3 1}
} {/[aA] 1(.0)? 2 [bB] 2 1 [bB] 3 1/}
do_test collate5-4.3 {
execsql {
DROP TABLE collate5t1;
+2 -2
View File
@@ -107,12 +107,12 @@ proc restore_file {} {
do_test corruptD-1.1.1 {
incr_change_counter
hexio_write test.db [expr 1024+1] FFFF
catchsql { SELECT * FROM t1 }
catchsql { SELECT * FROM t1 ORDER BY rowid }
} {1 {database disk image is malformed}}
do_test corruptD-1.1.2 {
incr_change_counter
hexio_write test.db [expr 1024+1] [hexio_render_int32 1021]
catchsql { SELECT * FROM t1 }
catchsql { SELECT * FROM t1 ORDER BY rowid }
} {1 {database disk image is malformed}}
#-------------------------------------------------------------------------
+1 -1
View File
@@ -49,7 +49,7 @@ do_test corruptE-1.1 {
INSERT OR IGNORE INTO t1 SELECT x*17,y FROM t1;
INSERT OR IGNORE INTO t1 SELECT x*19,y FROM t1;
CREATE INDEX t1i1 ON t1(x);
CREATE TABLE t2 AS SELECT x,2 as y FROM t1 WHERE rowid%5!=0;
CREATE TABLE t2 AS SELECT x,2 as y FROM t1 WHERE rowid%5!=0 ORDER BY rowid;
COMMIT;
}
} {}
+93
View File
@@ -0,0 +1,93 @@
# 2012 September 17
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
# May you find forgiveness for yourself and forgive others.
# May you share freely, never taking more than you give.
#
#***********************************************************************
#
# Tests for the optimization which attempts to use a covering index
# for a full-table scan (under the theory that the index will be smaller
# and require less I/O and hence will run faster.)
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix coveridxscan
do_test 1.1 {
db eval {
CREATE TABLE t1(a,b,c);
INSERT INTO t1 VALUES(5,4,3), (4,8,2), (3,2,1);
CREATE INDEX t1ab ON t1(a,b);
CREATE INDEX t1b ON t1(b);
SELECT a FROM t1;
}
# covering index used for the scan, hence values are increasing
} {3 4 5}
do_test 1.2 {
db eval {
SELECT a, c FROM t1;
}
# There is no covering index, hence the values are in rowid order
} {5 3 4 2 3 1}
do_test 1.3 {
db eval {
SELECT b FROM t1;
}
# Choice of two indices: use the one with fewest columns
} {2 4 8}
do_test 2.1 {
optimization_control db cover-idx-scan 0
db eval {SELECT a FROM t1}
# With the optimization turned off, output in rowid order
} {5 4 3}
do_test 2.2 {
db eval {SELECT a, c FROM t1}
} {5 3 4 2 3 1}
do_test 2.3 {
db eval {SELECT b FROM t1}
} {4 8 2}
db close
sqlite3_shutdown
sqlite3_config_cis 0
sqlite3 db test.db
do_test 3.1 {
db eval {SELECT a FROM t1}
# With the optimization configured off, output in rowid order
} {5 4 3}
do_test 3.2 {
db eval {SELECT a, c FROM t1}
} {5 3 4 2 3 1}
do_test 3.3 {
db eval {SELECT b FROM t1}
} {4 8 2}
db close
sqlite3_shutdown
sqlite3_config_cis 1
sqlite3 db test.db
# The CIS optimization is enabled again. Covering indices are once again
# used for all table scans.
do_test 4.1 {
db eval {SELECT a FROM t1}
} {3 4 5}
do_test 4.2 {
db eval {SELECT a, c FROM t1}
} {5 3 4 2 3 1}
do_test 4.3 {
db eval {SELECT b FROM t1}
} {2 4 8}
finish_test
+6 -4
View File
@@ -85,10 +85,12 @@ do_test 2.3 { db_write db 1 } {0 4 0}
do_test 2.4 { db_write db 0 } {0 0 0}
do_test 2.5 { db_write db 1 } {0 0 0}
do_test 2.6 {
execsql { PRAGMA journal_mode = WAL }
db_write db 1
} {0 1 0}
ifcapable wal {
do_test 2.6 {
execsql { PRAGMA journal_mode = WAL }
db_write db 1
} {0 1 0}
}
do_test 2.7 {
execsql { INSERT INTO t1 VALUES(5, randomblob(600)) }
db_write db
+19 -3
View File
@@ -175,10 +175,26 @@ foreach {tn sql temptables res} {
}
do_execsql_test 2.A {
SELECT (SELECT DISTINCT o.a FROM t1 AS i) FROM t1 AS o;
SELECT (SELECT DISTINCT o.a FROM t1 AS i) FROM t1 AS o ORDER BY rowid;
} {a A a A}
do_test 3.0 {
db eval {
CREATE TABLE t3(a INTEGER, b INTEGER, c, UNIQUE(a,b));
INSERT INTO t3 VALUES
(null, null, 1),
(null, null, 2),
(null, 3, 4),
(null, 3, 5),
(6, null, 7),
(6, null, 8);
SELECT DISTINCT a, b FROM t3 ORDER BY +a, +b;
}
} {{} {} {} 3 6 {}}
do_test 3.1 {
regexp {OpenEphemeral} [db eval {
EXPLAIN SELECT DISTINCT a, b FROM t3 ORDER BY +a, +b;
}]
} {0}
finish_test
+1 -1
View File
@@ -1591,7 +1591,7 @@ foreach {tn tbl res ac data} {
" $res
do_test e_createtable-4.17.$tn.3 { sqlite3_get_autocommit db } $ac
do_execsql_test 4.17.$tn.4 "SELECT * FROM $tbl" $data
do_execsql_test 4.17.$tn.4 "SELECT * FROM $tbl ORDER BY rowid" $data
}
catchsql COMMIT
+4 -4
View File
@@ -2060,7 +2060,7 @@ do_test e_fkey-45.1 {
do_test e_fkey-45.2 {
execsql {
DELETE FROM pA WHERE rowid = 3;
SELECT quote(x) FROM pA;
SELECT quote(x) FROM pA ORDER BY rowid;
}
} {X'0000' X'9999' X'1234'}
do_test e_fkey-45.3 {
@@ -2069,7 +2069,7 @@ do_test e_fkey-45.3 {
do_test e_fkey-45.4 {
execsql {
UPDATE pA SET x = X'8765' WHERE rowid = 4;
SELECT quote(x) FROM pA;
SELECT quote(x) FROM pA ORDER BY rowid;
}
} {X'0000' X'9999' X'8765'}
do_test e_fkey-45.5 {
@@ -2325,7 +2325,7 @@ do_test e_fkey-51.1 {
do_test e_fkey-51.2 {
execsql {
UPDATE parent SET x = 22;
SELECT * FROM parent ; SELECT 'xxx' ; SELECT a FROM child;
SELECT * FROM parent ORDER BY rowid; SELECT 'xxx' ; SELECT a FROM child;
}
} {22 21 23 xxx 22}
do_test e_fkey-51.3 {
@@ -2335,7 +2335,7 @@ do_test e_fkey-51.3 {
INSERT INTO parent VALUES(-1);
INSERT INTO child VALUES(-1);
UPDATE parent SET x = 22;
SELECT * FROM parent ; SELECT 'xxx' ; SELECT a FROM child;
SELECT * FROM parent ORDER BY rowid; SELECT 'xxx' ; SELECT a FROM child;
}
} {22 23 21 xxx 23}
+9 -9
View File
@@ -1023,10 +1023,10 @@ do_execsql_test e_select-4.9.0 {
#
do_select_tests e_select-4.9 {
1 "SELECT group_concat(one), two FROM b1 GROUP BY two" {
4,5 f 1 o 7,6 s 3,2 t
/#,# f 1 o #,# s #,# t/
}
2 "SELECT group_concat(one), sum(one) FROM b1 GROUP BY (one>4)" {
1,4,3,2 10 5,7,6 18
1,2,3,4 10 5,6,7 18
}
3 "SELECT group_concat(one) FROM b1 GROUP BY (two>'o'), one%2" {
4 1,5 2,6 3,7
@@ -1040,7 +1040,7 @@ do_select_tests e_select-4.9 {
# values are considered equal.
#
do_select_tests e_select-4.10 {
1 "SELECT group_concat(y) FROM b2 GROUP BY x" {0,1 3 2,4}
1 "SELECT group_concat(y) FROM b2 GROUP BY x" {/#,# 3 #,#/}
2 "SELECT count(*) FROM b2 GROUP BY CASE WHEN y<4 THEN NULL ELSE 0 END" {4 1}
}
@@ -1745,12 +1745,12 @@ do_select_tests e_select-8.4 {
1 2 7 1 2 8 1 4 93 1 5 -1
}
8 "SELECT z, x FROM d1 ORDER BY 2" {
3 1 8 1 7 1 -20 1
93 1 -1 1 -1 2 93 2
/# 1 # 1 # 1 # 1
# 1 # 1 # 2 # 2/
}
9 "SELECT z, x FROM d1 ORDER BY 1" {
-20 1 -1 2 -1 1 3 1
7 1 8 1 93 2 93 1
/-20 1 -1 # -1 # 3 1
7 1 8 1 93 # 93 #/
}
}
@@ -1766,10 +1766,10 @@ do_select_tests e_select-8.5 {
94 94 9 8 4 0 0 -19
}
3 "SELECT z AS x, x AS z FROM d1 ORDER BY z" {
3 1 8 1 7 1 -20 1 93 1 -1 1 -1 2 93 2
/# 1 # 1 # 1 # 1 # 1 # 1 # 2 # 2/
}
4 "SELECT z AS x, x AS z FROM d1 ORDER BY x" {
-20 1 -1 2 -1 1 3 1 7 1 8 1 93 2 93 1
/-20 1 -1 # -1 # 3 1 7 1 8 1 93 # 93 #/
}
}
+8 -8
View File
@@ -62,7 +62,7 @@ do_eqp_test 1.3 {
do_eqp_test 1.4 {
SELECT a FROM t1 ORDER BY +a
} {
0 0 0 {SCAN TABLE t1 (~1000000 rows)}
0 0 0 {SCAN TABLE t1 USING COVERING INDEX i1 (~1000000 rows)}
0 0 0 {USE TEMP B-TREE FOR ORDER BY}
}
do_eqp_test 1.5 {
@@ -166,7 +166,7 @@ det 2.3.2 "SELECT min(x) FROM t2" {
0 0 0 {SEARCH TABLE t2 USING COVERING INDEX t2i1 (~1 rows)}
}
det 2.3.3 "SELECT min(x), max(x) FROM t2" {
0 0 0 {SCAN TABLE t2 (~1000000 rows)}
0 0 0 {SCAN TABLE t2 USING COVERING INDEX t2i1 (~1000000 rows)}
}
det 2.4.1 "SELECT * FROM t1 WHERE rowid=?" {
@@ -339,7 +339,7 @@ do_eqp_test 4.3.1 {
SELECT x FROM t1 UNION SELECT x FROM t2
} {
1 0 0 {SCAN TABLE t1 (~1000000 rows)}
2 0 0 {SCAN TABLE t2 (~1000000 rows)}
2 0 0 {SCAN TABLE t2 USING COVERING INDEX t2i1 (~1000000 rows)}
0 0 0 {COMPOUND SUBQUERIES 1 AND 2 USING TEMP B-TREE (UNION)}
}
@@ -347,7 +347,7 @@ do_eqp_test 4.3.2 {
SELECT x FROM t1 UNION SELECT x FROM t2 UNION SELECT x FROM t1
} {
2 0 0 {SCAN TABLE t1 (~1000000 rows)}
3 0 0 {SCAN TABLE t2 (~1000000 rows)}
3 0 0 {SCAN TABLE t2 USING COVERING INDEX t2i1 (~1000000 rows)}
1 0 0 {COMPOUND SUBQUERIES 2 AND 3 USING TEMP B-TREE (UNION)}
4 0 0 {SCAN TABLE t1 (~1000000 rows)}
0 0 0 {COMPOUND SUBQUERIES 1 AND 4 USING TEMP B-TREE (UNION)}
@@ -447,7 +447,7 @@ det 5.8.1 "SELECT c, d FROM t2 ORDER BY c" {
det 5.9 {
SELECT (SELECT b FROM t1 WHERE a=0), (SELECT a FROM t1 WHERE b=t2.c) FROM t2
} {
0 0 0 {SCAN TABLE t2 (~1000000 rows)}
0 0 0 {SCAN TABLE t2 USING COVERING INDEX i4 (~1000000 rows)}
0 0 0 {EXECUTE SCALAR SUBQUERY 1}
1 0 0 {SEARCH TABLE t1 USING COVERING INDEX i2 (a=?) (~10 rows)}
0 0 0 {EXECUTE CORRELATED SCALAR SUBQUERY 2}
@@ -471,7 +471,7 @@ det 5.10 {
# (c=?) (~10 rows) 0|1|1|SCAN TABLE t1 (~1000000 rows)
det 5.11 "SELECT * FROM (SELECT * FROM t2 WHERE c=1), t1" {
0 0 0 {SEARCH TABLE t2 USING INDEX i4 (c=?) (~10 rows)}
0 1 1 {SCAN TABLE t1 (~1000000 rows)}
0 1 1 {SCAN TABLE t1 USING COVERING INDEX i2 (~1000000 rows)}
}
# EVIDENCE-OF: R-40701-42164 sqlite> EXPLAIN QUERY PLAN SELECT a FROM
@@ -479,8 +479,8 @@ det 5.11 "SELECT * FROM (SELECT * FROM t2 WHERE c=1), t1" {
# 2|0|0|SCAN TABLE t2 (~1000000 rows) 0|0|0|COMPOUND SUBQUERIES 1 AND 2
# USING TEMP B-TREE (UNION)
det 5.12 "SELECT a FROM t1 UNION SELECT c FROM t2" {
1 0 0 {SCAN TABLE t1 (~1000000 rows)}
2 0 0 {SCAN TABLE t2 (~1000000 rows)}
1 0 0 {SCAN TABLE t1 USING COVERING INDEX i1 (~1000000 rows)}
2 0 0 {SCAN TABLE t2 USING COVERING INDEX i4 (~1000000 rows)}
0 0 0 {COMPOUND SUBQUERIES 1 AND 2 USING TEMP B-TREE (UNION)}
}
+20
View File
@@ -0,0 +1,20 @@
# 2012 September 12
#
# 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 runs the "full" test suite. It is a peer of the quick.test
# and all.test scripts.
#
set testdir [file dirname $argv0]
source $testdir/permutations.test
run_test_suite full
finish_test
-2
View File
@@ -1864,5 +1864,3 @@ do_execsql_test 10.3 {
} {1 21 41 61 81}
finish_test
+138
View File
@@ -0,0 +1,138 @@
# 2012 September 18
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
# May you find forgiveness for yourself and forgive others.
# May you share freely, never taking more than you give.
#
#***********************************************************************
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
do_test in5-1.1 {
execsql {
CREATE TABLE t1x(x INTEGER PRIMARY KEY);
INSERT INTO t1x VALUES(1),(3),(5),(7),(9);
CREATE TABLE t1y(y INTEGER UNIQUE);
INSERT INTO t1y VALUES(2),(4),(6),(8);
CREATE TABLE t1z(z TEXT UNIQUE);
INSERT INTO t1z VALUES('a'),('c'),('e'),('g');
CREATE TABLE t2(a INTEGER, b INTEGER, c TEXT, d TEXT);
INSERT INTO t2 VALUES(1,2,'a','12a'),(1,2,'b','12b'),
(2,3,'g','23g'),(3,5,'c','35c'),
(4,6,'h','46h'),(5,6,'e','56e');
CREATE TABLE t3x AS SELECT x FROM t1x;
CREATE TABLE t3y AS SELECT y FROM t1y;
CREATE TABLE t3z AS SELECT z FROM t1z;
SELECT d FROM t2 WHERE a IN t1x AND b IN t1y AND c IN t1z ORDER BY c;
}
} {12a 56e}
do_test in5-1.2 {
execsql {
SELECT d FROM t2 WHERE a IN t1y AND b IN t1x AND c IN t1z ORDER BY d;
}
} {23g}
do_test in5-1.3 {
execsql {
SELECT d FROM t2 WHERE a IN t3x AND b IN t3y AND c IN t3z ORDER BY d;
}
} {12a 56e}
do_test in5-2.1 {
execsql {
CREATE INDEX t2abc ON t2(a,b,c);
SELECT d FROM t2 WHERE a IN t1x AND b IN t1y AND c IN t1z ORDER BY d;
}
} {12a 56e}
do_test in5-2.2 {
execsql {
SELECT d FROM t2 WHERE a IN t1y AND b IN t1x AND c IN t1z ORDER BY d;
}
} {23g}
do_test in5-2.3 {
regexp {OpenEphemeral} [db eval {
EXPLAIN SELECT d FROM t2 WHERE a IN t1x AND b IN t1y AND c IN t1z
}]
} {0}
do_test in5-2.4 {
execsql {
SELECT d FROM t2 WHERE a IN t3x AND b IN t3y AND c IN t3z ORDER BY d;
}
} {12a 56e}
do_test in5-2.5.1 {
regexp {OpenEphemeral} [db eval {
EXPLAIN SELECT d FROM t2 WHERE a IN t3x AND b IN t1y AND c IN t1z
}]
} {1}
do_test in5-2.5.2 {
regexp {OpenEphemeral} [db eval {
EXPLAIN SELECT d FROM t2 WHERE a IN t1x AND b IN t3y AND c IN t1z
}]
} {1}
do_test in5-2.5.3 {
regexp {OpenEphemeral} [db eval {
EXPLAIN SELECT d FROM t2 WHERE a IN t1x AND b IN t1y AND c IN t3z
}]
} {1}
do_test in5-3.1 {
execsql {
DROP INDEX t2abc;
CREATE INDEX t2ab ON t2(a,b);
SELECT d FROM t2 WHERE a IN t1x AND b IN t1y AND c IN t1z ORDER BY d;
}
} {12a 56e}
do_test in5-3.2 {
execsql {
SELECT d FROM t2 WHERE a IN t1y AND b IN t1x AND c IN t1z ORDER BY d;
}
} {23g}
do_test in5-3.3 {
regexp {OpenEphemeral} [db eval {
EXPLAIN SELECT d FROM t2 WHERE a IN t1x AND b IN t1y AND c IN t1z
}]
} {0}
do_test in5-4.1 {
execsql {
DROP INDEX t2ab;
CREATE INDEX t2abcd ON t2(a,b,c,d);
SELECT d FROM t2 WHERE a IN t1x AND b IN t1y AND c IN t1z ORDER BY d;
}
} {12a 56e}
do_test in5-4.2 {
execsql {
SELECT d FROM t2 WHERE a IN t1y AND b IN t1x AND c IN t1z ORDER BY d;
}
} {23g}
do_test in5-4.3 {
regexp {OpenEphemeral} [db eval {
EXPLAIN SELECT d FROM t2 WHERE a IN t1x AND b IN t1y AND c IN t1z
}]
} {0}
do_test in5-5.1 {
execsql {
DROP INDEX t2abcd;
CREATE INDEX t2cbad ON t2(c,b,a,d);
SELECT d FROM t2 WHERE a IN t1x AND b IN t1y AND c IN t1z ORDER BY d;
}
} {12a 56e}
do_test in5-5.2 {
execsql {
SELECT d FROM t2 WHERE a IN t1y AND b IN t1x AND c IN t1z ORDER BY d;
}
} {23g}
do_test in5-5.3 {
regexp {OpenEphemeral} [db eval {
EXPLAIN SELECT d FROM t2 WHERE a IN t1x AND b IN t1y AND c IN t1z
}]
} {0}
finish_test
+1 -1
View File
@@ -437,7 +437,7 @@ if {[permutation] != "memsubsys1"} {
} {}
do_test incrblob-6.2 {
execsql {
SELECT rowid FROM blobs
SELECT rowid FROM blobs ORDER BY rowid
}
} {1 2 3}
do_test incrblob-6.3 {
+1 -1
View File
@@ -376,7 +376,7 @@ do_test intpkey-5.1 {
} {0 zero entry 0}
do_test intpkey-5.2 {
execsql {
SELECT rowid, a FROM t1
SELECT rowid, a FROM t1 ORDER BY rowid
}
} {-4 -4 0 0 5 5 6 6 11 11}
+3 -3
View File
@@ -406,7 +406,7 @@ do_test like-5.2 {
do_test like-5.3 {
execsql {
CREATE TABLE t2(x TEXT COLLATE NOCASE);
INSERT INTO t2 SELECT * FROM t1;
INSERT INTO t2 SELECT * FROM t1 ORDER BY rowid;
CREATE INDEX i2 ON t2(x COLLATE NOCASE);
}
set sqlite_like_count 0
@@ -662,8 +662,8 @@ ifcapable like_opt&&!icu {
set res [sqlite3_exec_hex db {
EXPLAIN QUERY PLAN SELECT x FROM t2 WHERE x LIKE '%ff%25'
}]
regexp {INDEX i2} $res
} {0}
regexp {SCAN TABLE t2} $res
} {1}
}
do_test like-9.5.1 {
set res [sqlite3_exec_hex db {
+23
View File
@@ -247,11 +247,34 @@ do_test lock-2.8 {
execsql {UPDATE t1 SET a = 0 WHERE 0}
catchsql {BEGIN EXCLUSIVE;} db2
} {1 {database is locked}}
do_test lock-2.8b {
db2 eval {PRAGMA busy_timeout}
} {400}
do_test lock-2.9 {
db2 timeout 0
execsql COMMIT
} {}
do_test lock-2.9b {
db2 eval {PRAGMA busy_timeout}
} {0}
integrity_check lock-2.10
do_test lock-2.11 {
db2 eval {PRAGMA busy_timeout(400)}
execsql BEGIN
execsql {UPDATE t1 SET a = 0 WHERE 0}
catchsql {BEGIN EXCLUSIVE;} db2
} {1 {database is locked}}
do_test lock-2.11b {
db2 eval {PRAGMA busy_timeout}
} {400}
do_test lock-2.12 {
db2 eval {PRAGMA busy_timeout(0)}
execsql COMMIT
} {}
do_test lock-2.12b {
db2 eval {PRAGMA busy_timeout}
} {0}
integrity_check lock-2.13
# Try to start two transactions in a row
#
+438
View File
@@ -0,0 +1,438 @@
# 2012 Sept 27
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
# May you find forgiveness for yourself and forgive others.
# May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library. The
# focus of this file is testing that the optimizations that disable
# ORDER BY clauses when the natural order of a query is correct.
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
set ::testprefix orderby1
# Generate test data for a join. Verify that the join gets the
# correct answer.
#
do_test 1.0 {
db eval {
BEGIN;
CREATE TABLE album(
aid INTEGER PRIMARY KEY,
title TEXT UNIQUE NOT NULL
);
CREATE TABLE track(
tid INTEGER PRIMARY KEY,
aid INTEGER NOT NULL REFERENCES album,
tn INTEGER NOT NULL,
name TEXT,
UNIQUE(aid, tn)
);
INSERT INTO album VALUES(1, '1-one'), (2, '2-two'), (3, '3-three');
INSERT INTO track VALUES
(NULL, 1, 1, 'one-a'),
(NULL, 2, 2, 'two-b'),
(NULL, 3, 3, 'three-c'),
(NULL, 1, 3, 'one-c'),
(NULL, 2, 1, 'two-a'),
(NULL, 3, 1, 'three-a');
COMMIT;
}
} {}
do_test 1.1a {
db eval {
SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn
}
} {one-a one-c two-a two-b three-a three-c}
# Verify that the ORDER BY clause is optimized out
#
do_test 1.1b {
db eval {
EXPLAIN QUERY PLAN
SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn
}
} {~/ORDER BY/} ;# ORDER BY optimized out
# The same query with ORDER BY clause optimization disabled via + operators
# should give exactly the same answer.
#
do_test 1.2a {
db eval {
SELECT name FROM album JOIN track USING (aid) ORDER BY +title, +tn
}
} {one-a one-c two-a two-b three-a three-c}
# The output is sorted manually in this case.
#
do_test 1.2b {
db eval {
EXPLAIN QUERY PLAN
SELECT name FROM album JOIN track USING (aid) ORDER BY +title, +tn
}
} {/ORDER BY/} ;# separate sorting pass due to "+" on ORDER BY terms
# The same query with ORDER BY optimizations turned off via built-in test.
#
do_test 1.3a {
optimization_control db order-by-idx-join 0
db cache flush
db eval {
SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn
}
} {one-a one-c two-a two-b three-a three-c}
do_test 1.3b {
db eval {
EXPLAIN QUERY PLAN
SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn
}
} {/ORDER BY/} ;# separate sorting pass due to disabled optimization
optimization_control db all 1
db cache flush
# Reverse order sorts
#
do_test 1.4a {
db eval {
SELECT name FROM album JOIN track USING (aid) ORDER BY title DESC, tn
}
} {three-a three-c two-a two-b one-a one-c}
do_test 1.4b {
db eval {
SELECT name FROM album JOIN track USING (aid) ORDER BY +title DESC, +tn
}
} {three-a three-c two-a two-b one-a one-c} ;# verify same order after sorting
do_test 1.4c {
db eval {
EXPLAIN QUERY PLAN
SELECT name FROM album JOIN track USING (aid) ORDER BY title DESC, tn
}
} {/ORDER BY/} ;# separate sorting pass due to mixed DESC/ASC
do_test 1.5a {
db eval {
SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn DESC
}
} {one-c one-a two-b two-a three-c three-a}
do_test 1.5b {
db eval {
SELECT name FROM album JOIN track USING (aid) ORDER BY +title, +tn DESC
}
} {one-c one-a two-b two-a three-c three-a} ;# verify same order after sorting
do_test 1.5c {
db eval {
EXPLAIN QUERY PLAN
SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn DESC
}
} {/ORDER BY/} ;# separate sorting pass due to mixed DESC/ASC
do_test 1.6a {
db eval {
SELECT name FROM album JOIN track USING (aid) ORDER BY title DESC, tn DESC
}
} {three-c three-a two-b two-a one-c one-a}
do_test 1.6b {
db eval {
SELECT name FROM album JOIN track USING (aid) ORDER BY +title DESC, +tn DESC
}
} {three-c three-a two-b two-a one-c one-a} ;# verify same order after sorting
do_test 1.6c {
db eval {
EXPLAIN QUERY PLAN
SELECT name FROM album JOIN track USING (aid) ORDER BY title DESC, tn DESC
}
} {~/ORDER BY/} ;# ORDER BY optimized-out
# Reconstruct the test data to use indices rather than integer primary keys.
#
do_test 2.0 {
db eval {
BEGIN;
DROP TABLE album;
DROP TABLE track;
CREATE TABLE album(
aid INT PRIMARY KEY,
title TEXT NOT NULL
);
CREATE INDEX album_i1 ON album(title, aid);
CREATE TABLE track(
aid INTEGER NOT NULL REFERENCES album,
tn INTEGER NOT NULL,
name TEXT,
UNIQUE(aid, tn)
);
INSERT INTO album VALUES(1, '1-one'), (20, '2-two'), (3, '3-three');
INSERT INTO track VALUES
(1, 1, 'one-a'),
(20, 2, 'two-b'),
(3, 3, 'three-c'),
(1, 3, 'one-c'),
(20, 1, 'two-a'),
(3, 1, 'three-a');
COMMIT;
}
} {}
do_test 2.1a {
db eval {
SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn
}
} {one-a one-c two-a two-b three-a three-c}
# Verify that the ORDER BY clause is optimized out
#
do_test 2.1b {
db eval {
EXPLAIN QUERY PLAN
SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn
}
} {~/ORDER BY/} ;# ORDER BY optimized out
do_test 2.1c {
db eval {
SELECT name FROM album JOIN track USING (aid) ORDER BY title, aid, tn
}
} {one-a one-c two-a two-b three-a three-c}
do_test 2.1d {
db eval {
EXPLAIN QUERY PLAN
SELECT name FROM album JOIN track USING (aid) ORDER BY title, aid, tn
}
} {~/ORDER BY/} ;# ORDER BY optimized out
# The same query with ORDER BY clause optimization disabled via + operators
# should give exactly the same answer.
#
do_test 2.2a {
db eval {
SELECT name FROM album JOIN track USING (aid) ORDER BY +title, +tn
}
} {one-a one-c two-a two-b three-a three-c}
# The output is sorted manually in this case.
#
do_test 2.2b {
db eval {
EXPLAIN QUERY PLAN
SELECT name FROM album JOIN track USING (aid) ORDER BY +title, +tn
}
} {/ORDER BY/} ;# separate sorting pass due to "+" on ORDER BY terms
# The same query with ORDER BY optimizations turned off via built-in test.
#
do_test 2.3a {
optimization_control db order-by-idx-join 0
db cache flush
db eval {
SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn
}
} {one-a one-c two-a two-b three-a three-c}
do_test 2.3b {
db eval {
EXPLAIN QUERY PLAN
SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn
}
} {/ORDER BY/} ;# separate sorting pass due to disabled optimization
optimization_control db all 1
db cache flush
# Reverse order sorts
#
do_test 2.4a {
db eval {
SELECT name FROM album JOIN track USING (aid) ORDER BY title DESC, tn
}
} {three-a three-c two-a two-b one-a one-c}
do_test 2.4b {
db eval {
SELECT name FROM album JOIN track USING (aid) ORDER BY +title DESC, +tn
}
} {three-a three-c two-a two-b one-a one-c} ;# verify same order after sorting
do_test 2.4c {
db eval {
EXPLAIN QUERY PLAN
SELECT name FROM album JOIN track USING (aid) ORDER BY title DESC, tn
}
} {/ORDER BY/} ;# separate sorting pass due to mixed DESC/ASC
do_test 2.5a {
db eval {
SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn DESC
}
} {one-c one-a two-b two-a three-c three-a}
do_test 2.5b {
db eval {
SELECT name FROM album JOIN track USING (aid) ORDER BY +title, +tn DESC
}
} {one-c one-a two-b two-a three-c three-a} ;# verify same order after sorting
do_test 2.5c {
db eval {
EXPLAIN QUERY PLAN
SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn DESC
}
} {/ORDER BY/} ;# separate sorting pass due to mixed ASC/DESC
do_test 2.6a {
db eval {
SELECT name FROM album JOIN track USING (aid) ORDER BY title DESC, tn DESC
}
} {three-c three-a two-b two-a one-c one-a}
do_test 2.6b {
db eval {
SELECT name FROM album JOIN track USING (aid) ORDER BY +title DESC, +tn DESC
}
} {three-c three-a two-b two-a one-c one-a} ;# verify same order after sorting
do_test 2.6c {
db eval {
EXPLAIN QUERY PLAN
SELECT name FROM album JOIN track USING (aid) ORDER BY title DESC, tn DESC
}
} {~/ORDER BY/} ;# ORDER BY optimized out
# Generate another test dataset, but this time using mixed ASC/DESC indices.
#
do_test 3.0 {
db eval {
BEGIN;
DROP TABLE album;
DROP TABLE track;
CREATE TABLE album(
aid INTEGER PRIMARY KEY,
title TEXT UNIQUE NOT NULL
);
CREATE TABLE track(
tid INTEGER PRIMARY KEY,
aid INTEGER NOT NULL REFERENCES album,
tn INTEGER NOT NULL,
name TEXT,
UNIQUE(aid ASC, tn DESC)
);
INSERT INTO album VALUES(1, '1-one'), (2, '2-two'), (3, '3-three');
INSERT INTO track VALUES
(NULL, 1, 1, 'one-a'),
(NULL, 2, 2, 'two-b'),
(NULL, 3, 3, 'three-c'),
(NULL, 1, 3, 'one-c'),
(NULL, 2, 1, 'two-a'),
(NULL, 3, 1, 'three-a');
COMMIT;
}
} {}
do_test 3.1a {
db eval {
SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn DESC
}
} {one-c one-a two-b two-a three-c three-a}
# Verify that the ORDER BY clause is optimized out
#
do_test 3.1b {
db eval {
EXPLAIN QUERY PLAN
SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn DESC
}
} {~/ORDER BY/} ;# ORDER BY optimized out
# The same query with ORDER BY clause optimization disabled via + operators
# should give exactly the same answer.
#
do_test 3.2a {
db eval {
SELECT name FROM album JOIN track USING (aid) ORDER BY +title, +tn DESC
}
} {one-c one-a two-b two-a three-c three-a}
# The output is sorted manually in this case.
#
do_test 3.2b {
db eval {
EXPLAIN QUERY PLAN
SELECT name FROM album JOIN track USING (aid) ORDER BY +title, +tn DESC
}
} {/ORDER BY/} ;# separate sorting pass due to "+" on ORDER BY terms
# The same query with ORDER BY optimizations turned off via built-in test.
#
do_test 3.3a {
optimization_control db order-by-idx-join 0
db cache flush
db eval {
SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn DESC
}
} {one-c one-a two-b two-a three-c three-a}
do_test 3.3b {
db eval {
EXPLAIN QUERY PLAN
SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn DESC
}
} {/ORDER BY/} ;# separate sorting pass due to disabled optimization
optimization_control db all 1
db cache flush
# Without the mixed ASC/DESC on ORDER BY
#
do_test 3.4a {
db eval {
SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn
}
} {one-a one-c two-a two-b three-a three-c}
do_test 3.4b {
db eval {
SELECT name FROM album JOIN track USING (aid) ORDER BY +title, +tn
}
} {one-a one-c two-a two-b three-a three-c} ;# verify same order after sorting
do_test 3.4c {
db eval {
EXPLAIN QUERY PLAN
SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn
}
} {/ORDER BY/} ;# separate sorting pass due to mismatched DESC/ASC
do_test 3.5a {
db eval {
SELECT name FROM album JOIN track USING (aid) ORDER BY title DESC, tn DESC
}
} {three-c three-a two-b two-a one-c one-a}
do_test 3.5b {
db eval {
SELECT name FROM album JOIN track USING (aid) ORDER BY +title DESC, +tn DESC
}
} {three-c three-a two-b two-a one-c one-a} ;# verify same order after sorting
do_test 3.5c {
db eval {
EXPLAIN QUERY PLAN
SELECT name FROM album JOIN track USING (aid) ORDER BY title DESC, tn DESC
}
} {/ORDER BY/} ;# separate sorting pass due to mismatched ASC/DESC
do_test 3.6a {
db eval {
SELECT name FROM album JOIN track USING (aid) ORDER BY title DESC, tn
}
} {three-a three-c two-a two-b one-a one-c}
do_test 3.6b {
db eval {
SELECT name FROM album JOIN track USING (aid) ORDER BY +title DESC, +tn
}
} {three-a three-c two-a two-b one-a one-c} ;# verify same order after sorting
do_test 3.6c {
db eval {
EXPLAIN QUERY PLAN
SELECT name FROM album JOIN track USING (aid) ORDER BY title DESC, tn
}
} {~/ORDER BY/} ;# inverted ASC/DESC is optimized out
finish_test
+117
View File
@@ -0,0 +1,117 @@
# 2012 Sept 27
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
# May you find forgiveness for yourself and forgive others.
# May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library. The
# focus of this file is testing that the optimizations that disable
# ORDER BY clauses when the natural order of a query is correct.
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
set ::testprefix orderby2
# Generate test data for a join. Verify that the join gets the
# correct answer.
#
do_test 1.0 {
db eval {
CREATE TABLE t1(a INTEGER PRIMARY KEY, b);
INSERT INTO t1 VALUES(1,11), (2,22);
CREATE TABLE t2(d, e, UNIQUE(d,e));
INSERT INTO t2 VALUES(10, 'ten'), (11,'eleven'), (12,'twelve'),
(11, 'oneteen');
}
} {}
do_test 1.1a {
db eval {
SELECT e FROM t1, t2 WHERE a=1 AND d=b ORDER BY d, e;
}
} {eleven oneteen}
do_test 1.1b {
db eval {
EXPLAIN QUERY PLAN
SELECT e FROM t1, t2 WHERE a=1 AND d=b ORDER BY d, e;
}
} {~/ORDER BY/}
do_test 1.2a {
db eval {
SELECT e FROM t1, t2 WHERE a=1 AND d=b ORDER BY e;
}
} {eleven oneteen}
do_test 1.2b {
db eval {
EXPLAIN QUERY PLAN
SELECT e FROM t1, t2 WHERE a=1 AND d=b ORDER BY e;
}
} {~/ORDER BY/}
do_test 1.3a {
db eval {
SELECT e, b FROM t1, t2 WHERE a=1 ORDER BY d, e;
}
} {ten 11 eleven 11 oneteen 11 twelve 11}
do_test 1.3b {
db eval {
EXPLAIN QUERY PLAN
SELECT e, b FROM t1, t2 WHERE a=1 ORDER BY d, e;
}
} {~/ORDER BY/}
# The following tests derived from TH3 test module cov1/where34.test
#
do_test 2.0 {
db eval {
CREATE TABLE t31(a,b); CREATE INDEX t31ab ON t31(a,b);
CREATE TABLE t32(c,d); CREATE INDEX t32cd ON t32(c,d);
CREATE TABLE t33(e,f); CREATE INDEX t33ef ON t33(e,f);
CREATE TABLE t34(g,h); CREATE INDEX t34gh ON t34(g,h);
INSERT INTO t31 VALUES(1,4), (2,3), (1,3);
INSERT INTO t32 VALUES(4,5), (3,6), (3,7), (4,8);
INSERT INTO t33 VALUES(5,9), (7,10), (6,11), (8,12), (8,13), (7,14);
INSERT INTO t34 VALUES(11,20), (10,21), (12,22), (9,23), (13,24),
(14,25), (12,26);
SELECT a||','||c||','||e||','||g FROM t31, t32, t33, t34
WHERE c=b AND e=d AND g=f
ORDER BY a ASC, c ASC, e DESC, g ASC;
}
} {1,3,7,10 1,3,7,14 1,3,6,11 1,4,8,12 1,4,8,12 1,4,8,13 1,4,5,9 2,3,7,10 2,3,7,14 2,3,6,11}
do_test 2.1 {
db eval {
SELECT a||','||c||','||e||','||g FROM t31, t32, t33, t34
WHERE c=b AND e=d AND g=f
ORDER BY +a ASC, +c ASC, +e DESC, +g ASC;
}
} {1,3,7,10 1,3,7,14 1,3,6,11 1,4,8,12 1,4,8,12 1,4,8,13 1,4,5,9 2,3,7,10 2,3,7,14 2,3,6,11}
do_test 2.2 {
db eval {
SELECT a||','||c||','||e||','||g FROM t31, t32, t33, t34
WHERE c=b AND e=d AND g=f
ORDER BY a ASC, c ASC, e ASC, g ASC;
}
} {1,3,6,11 1,3,7,10 1,3,7,14 1,4,5,9 1,4,8,12 1,4,8,12 1,4,8,13 2,3,6,11 2,3,7,10 2,3,7,14}
do_test 2.3 {
optimization_control db cover-idx-scan off
db cache flush
db eval {
SELECT a||','||c||','||e||','||g FROM t31, t32, t33, t34
WHERE c=b AND e=d AND g=f
ORDER BY a ASC, c ASC, e ASC, g ASC;
}
} {1,3,6,11 1,3,7,10 1,3,7,14 1,4,5,9 1,4,8,12 1,4,8,12 1,4,8,13 2,3,6,11 2,3,7,10 2,3,7,14}
optimization_control db all on
db cache flush
finish_test
+1 -1
View File
@@ -96,7 +96,7 @@ if {$::tcl_platform(platform)!="unix"} {
set alltests [test_set $alltests -exclude {
all.test async.test quick.test veryquick.test
memleak.test permutations.test soak.test fts3.test
mallocAll.test rtree.test
mallocAll.test rtree.test full.test
}]
set allquicktests [test_set $alltests -exclude {
+207
View File
@@ -0,0 +1,207 @@
# 2012 October 5
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
# May you find forgiveness for yourself and forgive others.
# May you share freely, never taking more than you give.
#
#***********************************************************************
#
# The tests in this file are intended to show if two connections attach
# to the same shared cache using different database names, views and
# virtual tables may still be accessed.
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
source $testdir/lock_common.tcl
set testprefix shared9
ifcapable !view||!trigger {
finish_test
return
}
db close
set enable_shared_cache [sqlite3_enable_shared_cache 1]
sqlite3 db1 test.db
sqlite3 db2 test.db
forcedelete test.db2
do_test 1.1 {
db1 eval {
ATTACH 'test.db2' AS 'fred';
CREATE TABLE fred.t1(a, b, c);
CREATE VIEW fred.v1 AS SELECT * FROM t1;
CREATE TABLE fred.t2(a, b);
CREATE TABLE fred.t3(a, b);
CREATE TRIGGER fred.trig AFTER INSERT ON t2 BEGIN
DELETE FROM t3;
INSERT INTO t3 SELECT * FROM t2;
END;
INSERT INTO t2 VALUES(1, 2);
SELECT * FROM t3;
}
} {1 2}
do_test 1.2 { db2 eval "ATTACH 'test.db2' AS 'jones'" } {}
do_test 1.3 { db2 eval "SELECT * FROM v1" } {}
do_test 1.4 { db2 eval "INSERT INTO t2 VALUES(3, 4)" } {}
ifcapable fts3 {
do_test 1.5 {
db1 eval {
CREATE VIRTUAL TABLE fred.t4 USING fts4;
INSERT INTO t4 VALUES('hello world');
}
} {}
do_test 1.6 {
db2 eval {
INSERT INTO t4 VALUES('shared cache');
SELECT * FROM t4 WHERE t4 MATCH 'hello';
}
} {{hello world}}
do_test 1.7 {
db1 eval {
SELECT * FROM t4 WHERE t4 MATCH 'c*';
}
} {{shared cache}}
}
db1 close
db2 close
#-------------------------------------------------------------------------
# The following tests attempt to find a similar problem with collation
# sequence names - pointers to database handle specific allocations leaking
# into schema objects and being used after the original handle has been
# closed.
#
forcedelete test.db test.db2
sqlite3 db1 test.db
sqlite3 db2 test.db
foreach x {collate1 collate2 collate3} {
proc $x {a b} { string compare $a $b }
db1 collate $x $x
db2 collate $x $x
}
do_test 2.1 {
db1 eval {
CREATE TABLE t1(a, b, c COLLATE collate1);
CREATE INDEX i1 ON t1(a COLLATE collate2, c, b);
}
} {}
do_test 2.2 {
db1 close
db2 eval "INSERT INTO t1 VALUES('abc', 'def', 'ghi')"
} {}
db2 close
#-------------------------------------------------------------------------
# At one point, the following would cause a collation sequence belonging
# to connection [db1] to be invoked by a call to [db2 eval]. Which is a
# problem if [db1] has already been closed.
#
forcedelete test.db test.db2
sqlite3 db1 test.db
sqlite3 db2 test.db
proc mycollate_db1 {a b} {set ::invoked_mycollate_db1 1 ; string compare $a $b}
proc mycollate_db2 {a b} {string compare $a $b}
db1 collate mycollate mycollate_db1
db2 collate mycollate mycollate_db2
do_test 2.3 {
set ::invoked_mycollate_db1 0
db1 eval {
CREATE TABLE t1(a COLLATE mycollate, CHECK (a IN ('one', 'two', 'three')));
INSERT INTO t1 VALUES('one');
}
db1 close
set ::invoked_mycollate_db1
} {1}
do_test 2.4 {
set ::invoked_mycollate_db1 0
db2 eval {
INSERT INTO t1 VALUES('two');
}
db2 close
set ::invoked_mycollate_db1
} {0}
#-------------------------------------------------------------------------
# This test verifies that a bug causing a busy-handler belonging to one
# shared-cache connection to be executed as a result of an sqlite3_step()
# on another has been fixed.
#
forcedelete test.db test.db2
sqlite3 db1 test.db
sqlite3 db2 test.db
proc busyhandler {handle args} {
set ::busyhandler_invoked_for $handle
return 1
}
db1 busy [list busyhandler db1]
db2 busy [list busyhandler db2]
do_test 3.1 {
db1 eval {
BEGIN;
CREATE TABLE t1(a, b);
CREATE TABLE t2(a, b);
INSERT INTO t1 VALUES(1, 2);
INSERT INTO t2 VALUES(1, 2);
}
# Keep this next COMMIT as a separate statement. This ensures that COMMIT
# has already been compiled and loaded into the tcl interface statement
# cache when it is attempted below.
db1 eval COMMIT
db1 eval {
BEGIN;
INSERT INTO t1 VALUES(3, 4);
}
} {}
do_test 3.3 {
set ::tf [launch_testfixture]
testfixture $::tf {
sqlite3 db test.db
db eval {
BEGIN;
SELECT * FROM t1;
}
}
} {1 2}
do_test 3.2 {
db2 eval { SELECT * FROM t2 }
} {1 2}
do_test 3.3 {
list [catch { db1 eval COMMIT } msg] $msg
} {1 {database is locked}}
# At one point the following would fail, showing that the busy-handler
# belonging to [db2] was invoked instead.
do_test 3.4 {
set ::busyhandler_invoked_for
} {db1}
do_test 3.5 {
close $::tf
db1 eval COMMIT
} {}
db1 close
db2 close
sqlite3_enable_shared_cache $::enable_shared_cache
finish_test
+13
View File
@@ -680,6 +680,15 @@ do_test shell1-3.26.4 {
catchcmd "test.db" ".width 1 1"
# this should be treated the same as a '1' width for col 1 and 2
} {0 {}}
do_test shell1-3.26.5 {
catchcmd "test.db" ".mode column\n.width 10 -10\nSELECT 'abcdefg', 123456;"
# this should be treated the same as a '1' width for col 1 and 2
} {0 {abcdefg 123456}}
do_test shell1-3.26.6 {
catchcmd "test.db" ".mode column\n.width -10 10\nSELECT 'abcdefg', 123456;"
# this should be treated the same as a '1' width for col 1 and 2
} {0 { abcdefg 123456 }}
# .timer ON|OFF Turn the CPU timer measurement on or off
do_test shell1-3.27.1 {
@@ -701,6 +710,10 @@ do_test shell1-3-28.1 {
".log stdout\nSELECT coalesce(sqlite_log(123,'hello'),'456');"
} "0 {(123) hello\n456}"
do_test shell1-3-29.1 {
catchcmd "test.db" ".print this is a test"
} {0 {this is a test}}
# Test the output of the ".dump" command
#
do_test shell1-4.1 {
+10 -5
View File
@@ -76,11 +76,16 @@ do_test stat-1.4 {
do_execsql_test stat-2.1 {
CREATE TABLE t3(a PRIMARY KEY, b);
INSERT INTO t3(rowid, a, b) VALUES(2, a_string(111), a_string(222));
INSERT INTO t3 SELECT a_string(110+rowid), a_string(221+rowid) FROM t3;
INSERT INTO t3 SELECT a_string(110+rowid), a_string(221+rowid) FROM t3;
INSERT INTO t3 SELECT a_string(110+rowid), a_string(221+rowid) FROM t3;
INSERT INTO t3 SELECT a_string(110+rowid), a_string(221+rowid) FROM t3;
INSERT INTO t3 SELECT a_string(110+rowid), a_string(221+rowid) FROM t3;
INSERT INTO t3 SELECT a_string(110+rowid), a_string(221+rowid) FROM t3
ORDER BY rowid;
INSERT INTO t3 SELECT a_string(110+rowid), a_string(221+rowid) FROM t3
ORDER BY rowid;
INSERT INTO t3 SELECT a_string(110+rowid), a_string(221+rowid) FROM t3
ORDER BY rowid;
INSERT INTO t3 SELECT a_string(110+rowid), a_string(221+rowid) FROM t3
ORDER BY rowid;
INSERT INTO t3 SELECT a_string(110+rowid), a_string(221+rowid) FROM t3
ORDER BY rowid;
SELECT name, path, pageno, pagetype, ncell, payload, unused, mx_payload
FROM stat WHERE name != 'sqlite_master';
} [list \
+12 -3
View File
@@ -143,11 +143,11 @@ do_test tcl-1.21 {
set v [catch {db total_changes xyz} msg]
lappend v $msg
} {1 {wrong # args: should be "db total_changes "}}
do_test tcl-1.20 {
do_test tcl-1.22 {
set v [catch {db copy} msg]
lappend v $msg
} {1 {wrong # args: should be "db copy CONFLICT-ALGORITHM TABLE FILENAME ?SEPARATOR? ?NULLINDICATOR?"}}
do_test tcl-1.21 {
do_test tcl-1.23 {
set v [catch {sqlite3 db2 test.db -vfs nosuchvfs} msg]
lappend v $msg
} {1 {no such vfs: nosuchvfs}}
@@ -319,14 +319,23 @@ do_test tcl-8.1 {
execsql {INSERT INTO t1 VALUES(30,NULL)}
db eval {SELECT * FROM t1 WHERE b IS NULL}
} {30 NaN}
proc concatFunc args {return [join $args {}]}
do_test tcl-8.2 {
db function concat concatFunc
db eval {SELECT concat('a', b, 'z') FROM t1 WHERE b is NULL}
} {aNaNz}
do_test tcl-8.3 {
db nullvalue NULL
db nullvalue
} {NULL}
do_test tcl-8.3 {
do_test tcl-8.4 {
db nullvalue {}
db eval {SELECT * FROM t1 WHERE b IS NULL}
} {30 {}}
do_test tcl-8.5 {
db function concat concatFunc
db eval {SELECT concat('a', b, 'z') FROM t1 WHERE b is NULL}
} {az}
# Test the return type of user-defined functions
#
+13 -3
View File
@@ -31,6 +31,7 @@
# Test the capability of the SQLite version built into the interpreter to
# determine if a specific test can be run:
#
# capable EXPR
# ifcapable EXPR
#
# Calulate checksums based on database contents:
@@ -134,7 +135,7 @@ proc getFileRetries {} {
# NOTE: Return the default number of retries for [file] operations. A
# value of zero or less here means "disabled".
#
return [expr {$::tcl_platform(platform) eq "windows" ? 10 : 0}]
return [expr {$::tcl_platform(platform) eq "windows" ? 50 : 0}]
}
return $::G(file-retries)
}
@@ -537,16 +538,19 @@ proc do_test {name cmd expected} {
} else {
if {[regexp {^~?/.*/$} $expected]} {
if {[string index $expected 0]=="~"} {
set re [string range $expected 2 end-1]
set re [string map {# {[-0-9.]+}} [string range $expected 2 end-1]]
set ok [expr {![regexp $re $result]}]
} else {
set re [string range $expected 1 end-1]
set re [string map {# {[-0-9.]+}} [string range $expected 1 end-1]]
set ok [regexp $re $result]
}
} else {
set ok [expr {[string compare $result $expected]==0}]
}
if {!$ok} {
# if {![info exists ::testprefix] || $::testprefix eq ""} {
# error "no test prefix"
# }
puts "\nExpected: \[$expected\]\n Got: \[$result\]"
fail_test $name
} else {
@@ -994,6 +998,12 @@ proc fix_ifcapable_expr {expr} {
return $ret
}
# Returns non-zero if the capabilities are present; zero otherwise.
#
proc capable {expr} {
set e [fix_ifcapable_expr $expr]; return [expr ($e)]
}
# Evaluate a boolean expression of capabilities. If true, execute the
# code. Omit the code if false.
#
+1 -2
View File
@@ -39,7 +39,7 @@ do_eqp_test 2.1 { SELECT DISTINCT x FROM t2 } {
}
do_eqp_test 2.2 { SELECT DISTINCT y FROM t2 } {
0 0 0 {SCAN TABLE t2 (~1000000 rows)}
0 0 0 {SCAN TABLE t2 USING COVERING INDEX t2y (~1000000 rows)}
}
do_eqp_test 2.3 { SELECT DISTINCT x, y FROM t2 WHERE y=10 } {
@@ -51,4 +51,3 @@ do_eqp_test 2.4 { SELECT DISTINCT x, y FROM t2 WHERE x=10 } {
}
finish_test
+2
View File
@@ -17,6 +17,8 @@
set testdir [file dirname $argv0]
source $testdir/tester.tcl
source $testdir/lock_common.tcl
set ::testprefix tkt-5d863f876e
ifcapable !wal {finish_test ; return }
do_multiclient_test tn {
do_test $tn.1 {
+1 -1
View File
@@ -44,7 +44,7 @@ do_test tkt-78e04-1.4 {
execsql {
EXPLAIN QUERY PLAN SELECT * FROM "" WHERE "" LIKE 'abc%';
}
} {0 0 0 {SCAN TABLE (~500000 rows)}}
} {0 0 0 {SCAN TABLE USING COVERING INDEX i1 (~500000 rows)}}
do_test tkt-78e04-1.5 {
execsql {
DROP TABLE "";
+1 -1
View File
@@ -17,7 +17,7 @@
set testdir [file dirname $argv0]
source $testdir/tester.tcl
set ::testprefix tkt-80ba2
set ::testprefix tkt-80ba201079
do_test tkt-80ba2-100 {
db eval {
+2 -2
View File
@@ -50,7 +50,7 @@ do_test tkt-cbd05-1.3 {
WHERE idx = 't1_x'
GROUP BY tbl,idx
}
} {t1 t1_x { A B C D E F G H I}}
} {/t1 t1_x .[ ABCDEFGHI]{10}./}
do_test tkt-cbd05-2.1 {
db eval {
@@ -82,6 +82,6 @@ do_test tkt-cbd05-2.3 {
WHERE idx = 't1_x'
GROUP BY tbl,idx
}
} {t1 t1_x { A B C D E F G H I}}
} {/t1 t1_x .[ ABCDEFGHI]{10}./}
finish_test
+3 -3
View File
@@ -210,7 +210,7 @@ do_test trigger1-1.12 {
delete from t1 WHERE a=old.a+2;
end;
}
} {1 {cannot create INSTEAD OF trigger on table: main.t1}}
} {1 {cannot create INSTEAD OF trigger on table: t1}}
ifcapable view {
# Ensure that we cannot create BEFORE triggers on views
@@ -221,7 +221,7 @@ do_test trigger1-1.13 {
delete from t1 WHERE a=old.a+2;
end;
}
} {1 {cannot create BEFORE trigger on view: main.v1}}
} {1 {cannot create BEFORE trigger on view: v1}}
# Ensure that we cannot create AFTER triggers on views
do_test trigger1-1.14 {
catchsql {
@@ -231,7 +231,7 @@ do_test trigger1-1.14 {
delete from t1 WHERE a=old.a+2;
end;
}
} {1 {cannot create AFTER trigger on view: main.v1}}
} {1 {cannot create AFTER trigger on view: v1}}
} ;# ifcapable view
# Check for memory leaks in the trigger parser
+8 -8
View File
@@ -222,7 +222,7 @@ foreach {n tdefn rc} {
execsql $tdefn
catchsql {
INSERT INTO t2 VALUES(10);
SELECT * FROM t2;
SELECT * FROM t2 ORDER BY rowid;
}
} $rc
}
@@ -547,7 +547,7 @@ foreach {n insert log} {
eval concat [execsql "
DELETE FROM log;
$insert ;
SELECT * FROM log;
SELECT * FROM log ORDER BY rowid;
"]
} [join $log " "]
}
@@ -584,8 +584,8 @@ foreach {n dml t5g t5} {
execsql "
BEGIN;
$dml ;
SELECT * FROM t5g;
SELECT * FROM t5;
SELECT * FROM t5g ORDER BY rowid;
SELECT * FROM t5 ORDER BY rowid;
ROLLBACK;
"
} [concat $t5g $t5]
@@ -611,8 +611,8 @@ foreach {n dml t5g t5} {
execsql "
BEGIN;
$dml ;
SELECT * FROM t5g;
SELECT * FROM t5;
SELECT * FROM t5g ORDER BY rowid;
SELECT * FROM t5 ORDER BY rowid;
ROLLBACK;
"
} [concat $t5g $t5]
@@ -633,8 +633,8 @@ foreach {n dml t5g t5} {
execsql "
BEGIN;
$dml ;
SELECT * FROM t5g;
SELECT * FROM t5;
SELECT * FROM t5g ORDER BY rowid;
SELECT * FROM t5 ORDER BY rowid;
ROLLBACK;
"
} [concat $t5g $t5]
+1 -1
View File
@@ -51,7 +51,7 @@ foreach idxmode {ordered unordered} {
0 0 0 {USE TEMP B-TREE FOR ORDER BY}}
4 "SELECT max(a) FROM t1"
{0 0 0 {SEARCH TABLE t1 USING COVERING INDEX i1 (~1 rows)}}
{0 0 0 {SEARCH TABLE t1 (~1 rows)}}
{0 0 0 {SEARCH TABLE t1 USING COVERING INDEX i1 (~1 rows)}}
5 "SELECT group_concat(b) FROM t1 GROUP BY a"
{0 0 0 {SCAN TABLE t1 USING INDEX i1 (~128 rows)}}
{0 0 0 {SCAN TABLE t1 (~128 rows)} 0 0 0 {USE TEMP B-TREE FOR GROUP BY}}
+1
View File
@@ -26,6 +26,7 @@
set testdir [file dirname $argv0]
source $testdir/tester.tcl
set ::testprefix wal8
ifcapable !wal {finish_test ; return }
db close
forcedelete test.db test.db-wal
+7 -7
View File
@@ -1088,34 +1088,34 @@ do_test where-14.1 {
cksort {
SELECT x.a || '/' || y.a FROM t8 x, t8 y ORDER BY x.a, y.b
}
} {1/4 1/1 4/4 4/1 sort}
} {1/4 1/1 4/4 4/1 nosort}
do_test where-14.2 {
cksort {
SELECT x.a || '/' || y.a FROM t8 x, t8 y ORDER BY x.a, y.b DESC
}
} {1/1 1/4 4/1 4/4 sort}
} {1/1 1/4 4/1 4/4 nosort}
do_test where-14.3 {
cksort {
SELECT x.a || '/' || y.a FROM t8 x, t8 y ORDER BY x.a, x.b
}
} {1/1 1/4 4/1 4/4 nosort}
} {1/4 1/1 4/4 4/1 nosort}
do_test where-14.4 {
cksort {
SELECT x.a || '/' || y.a FROM t8 x, t8 y ORDER BY x.a, x.b DESC
}
} {1/1 1/4 4/1 4/4 nosort}
} {1/4 1/1 4/4 4/1 nosort}
do_test where-14.5 {
# This test case changed from "nosort" to "sort". See ticket 2a5629202f.
cksort {
SELECT x.a || '/' || y.a FROM t8 x, t8 y ORDER BY x.b, x.a||x.b
}
} {4/1 4/4 1/1 1/4 sort}
} {/4/[14] 4/[14] 1/[14] 1/[14] sort/}
do_test where-14.6 {
# This test case changed from "nosort" to "sort". See ticket 2a5629202f.
cksort {
SELECT x.a || '/' || y.a FROM t8 x, t8 y ORDER BY x.b, x.a||x.b DESC
}
} {4/1 4/4 1/1 1/4 sort}
} {/4/[14] 4/[14] 1/[14] 1/[14] sort/}
do_test where-14.7 {
cksort {
SELECT x.a || '/' || y.a FROM t8 x, t8 y ORDER BY x.b, y.a||y.b
@@ -1130,7 +1130,7 @@ do_test where-14.7.2 {
cksort {
SELECT x.a || '/' || y.a FROM t8 x, t8 y ORDER BY x.b, x.a, x.a||x.b
}
} {4/1 4/4 1/1 1/4 nosort}
} {4/4 4/1 1/4 1/1 nosort}
do_test where-14.8 {
cksort {
SELECT x.a || '/' || y.a FROM t8 x, t8 y ORDER BY x.b, y.a||y.b DESC
+1 -1
View File
@@ -692,7 +692,7 @@ do_test where9-6.5.3 {
do_test where9-6.5.4 {
db eval {
SELECT count(*) FROM t1 UNION ALL
SELECT a FROM t1 WHERE a%100 IN (5,31,57,82,83,84,85,86,87);
SELECT a FROM t1 WHERE a%100 IN (5,31,57,82,83,84,85,86,87) ORDER BY rowid;
ROLLBACK;
}
} {99 105 131 157 182 183 184 185 186 187}
+28 -26
View File
@@ -18,7 +18,7 @@
set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix wal5
set testprefix zerodamage
ifcapable !vtab {
finish_test
@@ -89,31 +89,33 @@ do_test zerodamage-2.1 {
concat [file_control_powersafe_overwrite db -1] [set ::max_journal_size]
} {0 0 24704}
# Run a WAL-mode transaction with POWERSAFE_OVERWRITE on to verify that the
# WAL file does not get too big.
#
do_test zerodamage-3.0 {
db eval {
PRAGMA journal_mode=WAL;
}
db close
sqlite3 db file:test.db?psow=TRUE -uri 1
db eval {
UPDATE t1 SET y=randomblob(50) WHERE x=124;
}
file size test.db-wal
} {1080}
ifcapable wal {
# Run a WAL-mode transaction with POWERSAFE_OVERWRITE on to verify that the
# WAL file does not get too big.
#
do_test zerodamage-3.0 {
db eval {
PRAGMA journal_mode=WAL;
}
db close
sqlite3 db file:test.db?psow=TRUE -uri 1
db eval {
UPDATE t1 SET y=randomblob(50) WHERE x=124;
}
file size test.db-wal
} {1080}
# Repeat the previous with POWERSAFE_OVERWRITE off. Verify that the WAL file
# is padded.
#
do_test zerodamage-3.1 {
db close
sqlite3 db file:test.db?psow=FALSE -uri 1
db eval {
UPDATE t1 SET y=randomblob(50) WHERE x=124;
}
file size test.db-wal
} {8416}
# Repeat the previous with POWERSAFE_OVERWRITE off. Verify that the WAL file
# is padded.
#
do_test zerodamage-3.1 {
db close
sqlite3 db file:test.db?psow=FALSE -uri 1
db eval {
UPDATE t1 SET y=randomblob(50) WHERE x=124;
}
file size test.db-wal
} {8416}
}
finish_test
+3 -3
View File
@@ -142,7 +142,7 @@ FOR %%P IN (%PLATFORMS%) DO (
REM be used for the name of the platform-specific binary directory via
REM the environment variables setup earlier.
REM
CALL :fn_SetVariable %%P_NAME PLATFORMNAME
CALL :fn_CopyVariable %%P_NAME PLATFORMNAME
REM
REM NOTE: This is the inner loop. There should be exactly one iteration.
@@ -230,7 +230,7 @@ FOR %%P IN (%PLATFORMS%) DO (
REM file used to setup the MSVC environment.
REM
IF DEFINED SET_NSDKLIBPATH (
CALL :fn_SetVariable WindowsSdkDir NSDKLIBPATH
CALL :fn_CopyVariable WindowsSdkDir NSDKLIBPATH
CALL :fn_AppendVariable NSDKLIBPATH \lib\win8\um\x86
)
@@ -339,7 +339,7 @@ GOTO no_errors
VERIFY MAYBE 2> NUL
GOTO :EOF
:fn_SetVariable
:fn_CopyVariable
SETLOCAL
IF NOT DEFINED %1 GOTO :EOF
IF "%2" == "" GOTO :EOF
+98
View File
@@ -0,0 +1,98 @@
#!/usr/bin/tclsh
#
# Parse the output of
#
# objdump -d sqlite3.o
#
# for x64 and generate a report showing:
#
# (1) Stack used by each function
# (2) Recursion paths and their aggregate stack depth
#
set getStack 0
while {![eof stdin]} {
set line [gets stdin]
if {[regexp {^[0-9a-f]+ <([^>]+)>:\s*$} $line all procname]} {
set curfunc $procname
set root($curfunc) 1
set calls($curfunc) {}
set calledby($curfunc) {}
set recursive($curfunc) {}
set stkdepth($curfunc) 0
set getStack 1
continue
}
if {[regexp {callq? +[0-9a-z]+ <([^>]+)>} $line all other]} {
set key [list $curfunc $other]
set callpair($key) 1
unset -nocomplain root($curfunc)
continue
}
if {[regexp {sub +\$(0x[0-9a-z]+),%[er]sp} $line all xdepth]} {
if {$getStack} {
scan $xdepth %x depth
set stkdepth($curfunc) $depth
set getStack 0
}
continue
}
}
puts "****************** Stack Usage By Function ********************"
set sdlist {}
foreach f [array names stkdepth] {
lappend sdlist [list $stkdepth($f) $f]
}
foreach sd [lsort -integer -decr -index 0 $sdlist] {
foreach {depth fname} $sd break
puts [format {%6d %s} $depth $fname]
}
puts "****************** Stack Usage By Recursion *******************"
foreach key [array names callpair] {
foreach {from to} $key break
lappend calls($from) $to
# lappend calledby($to) $from
}
proc all_descendents {root} {
global calls recursive
set todo($root) $root
set go 1
while {$go} {
set go 0
foreach f [array names todo] {
set path $todo($f)
unset todo($f)
if {![info exists calls($f)]} continue
foreach x $calls($f) {
if {$x==$root} {
lappend recursive($root) [concat $path $root]
} elseif {![info exists d($x)]} {
set go 1
set todo($x) [concat $path $x]
set d($x) 1
}
}
}
}
return [array names d]
}
set pathlist {}
foreach f [array names recursive] {
all_descendents $f
foreach m $recursive($f) {
set depth 0
foreach b [lrange $m 0 end-1] {
set depth [expr {$depth+$stkdepth($b)}]
}
lappend pathlist [list $depth $m]
}
}
foreach path [lsort -integer -decr -index 0 $pathlist] {
foreach {depth m} $path break
set first [lindex $m 0]
puts [format {%6d %s %d} $depth $first $stkdepth($first)]
foreach b [lrange $m 1 end] {
puts " $b $stkdepth($b)"
}
}
+3
View File
@@ -79,6 +79,9 @@ while {![eof stdin]} {
append unionDef " $line\n"
append afterUnion $line\n
lappend vlist $vname
} elseif {[regexp {^#(if|endif)} $line] && [llength $vlist]>0} {
append unionDef "$line\n"
append afterUnion $line\n
} else {
break
}