Compare commits

..

133 Commits

Author SHA1 Message Date
drh c0359f0490 If a subquery is used to drive an index, this change avoids making an extra
copy of the result of that subquery.  But, such situations are probably
sufficiently unusual that the added complexity of this enhancement is not
worth the performance gain.  So I'm going to park this check-in on a branch.
If we later find a use case to justify it, we can merge it to trunk then.
This is the "further change" that was promised by the prior check-in comment.

FossilOrigin-Name: 4488cb883e155a7466946d25569ab2816c4a8de9d4c7d540f5053ea5334e7ae5
2021-05-28 14:28:54 +00:00
drh e9de65201c Make a deep copy of the result of a subquery in case the subquery is
reused.  Fix for the problem reported by
[forum:/forumpost/28216b36ac|forum post 28216b36ac] and introduced by
check-in [f30fb19ff763a7cb].  Further changes to try to optimize the new
OP_Copy opcode back into either OP_SCopy or OP_Move will be attempted
separately.  A test case will be in TH3.

FossilOrigin-Name: c9f0b9cb0aef107265435e22c164dd3c974eadfd00abf7cfd4fc7ec95c0dd7d0
2021-05-28 12:48:31 +00:00
drh d2f55773f1 Fix a potential memory leak in json_group_object() following an error.
dbsqlfuzz cd32630de3ff039d97089592b63cb3616f8ec9dd

FossilOrigin-Name: 21676731cedae27d1ab9fe62b269001ae6e3eeb3caa87b4f5536f777631a8bbc
2021-05-28 12:15:19 +00:00
drh 48a296c589 Add the merge-test.tcl script to ease verification of LTS branches.
FossilOrigin-Name: f958ffbc61c693b71538cc3aa5f95ce0f0b5d4906efbb0c075f543e19883a669
2021-05-27 16:31:04 +00:00
drh 342cb33b23 Improved comment on the prpagateConstants() routine. No changes to executable
code.

FossilOrigin-Name: d61a875df48d8baab3ada0174c8e0312a9268bbd11bf104b4385eff9e2744266
2021-05-27 14:09:01 +00:00
drh 48f4f27cfb Remove a NEVER that is reachable following OOM in writable_schema=ON mode
with a corrupt schema.

FossilOrigin-Name: 4eb80b0cc61526c1ff7478b1b855b29fa4326daee61facd1d85e4297bb32ac9d
2021-05-27 10:23:16 +00:00
drh 7d11e647ad Improvements to the constant-propagation optimization in order to better
deal with unusual affinities.  See
[forum:/forumpost/6a06202608|forum post 6a06202608] for more detail.

FossilOrigin-Name: 9be208a6d70582c6808abe6e016ab9cd8d10f0deefb8c7a8c0543372cca15b12
2021-05-26 23:10:19 +00:00
drh a8ed515400 Minor optimization to opcode comparison logic in the fixes to
the constant-propagation optimization on this branch.

FossilOrigin-Name: f17dec40a0ccc044bd32e035fc10797552329af242408a45f36125ed8d2ef088
2021-05-26 19:52:21 +00:00
dan c3b48848b3 Add new test file whereM.test. Containing tests for the change on this branch.
FossilOrigin-Name: c4c76b824c41afb5b4d7b397c4d3142698aa303ea3a368c0cc7af4884e3a10bd
2021-05-26 19:37:27 +00:00
dan 40b82f9dc6 Avoid assuming that an expression like "x=10" in a WHERE clause implies that CASE(x AS TEXT)=='10'.
FossilOrigin-Name: 389ec669f416c74d651e25572f6e007c2a62ddd4027524f553107b06db5c55eb
2021-05-26 18:51:57 +00:00
drh 14c4d42874 Take care that the code is not generated for the same Select object more
than once, as transformations that apply during the first pass might
cause problems for the second pass.
dbsqlfuzz 836b625cd8a41809ef80fc7ebaa6554357bcb463.

FossilOrigin-Name: f30fb19ff763a7cbe768ea49954704e14d6400f69bb4257c9c890e1564e14835
2021-05-26 18:46:51 +00:00
dan 151446e793 Update an assert() in wherecode.c that might fail following an unrelated SQL error.
FossilOrigin-Name: 3e2c36a8272ab3c1777638c0ed8222e7ff04657fe1c40f74a63b99a5a90258cc
2021-05-26 14:32:33 +00:00
dan 137b8ebb2b Do not run sessionbig.test as part of the session_strm permutation. It is too slow.
FossilOrigin-Name: 708ce7ad8acee702d08d1987aa253b0bfc3fd97255d6e4153122b03eba337570
2021-05-25 16:10:12 +00:00
dan 4df68e0ae5 Update an allocation routine in the sessions module to allow it to allocate the maximum size permitted by sqlite3_realloc64().
FossilOrigin-Name: 0b45e821911e4a852edd6d9e9cfe5f9de33337edf76fb12b79adaf11a4b83e8a
2021-05-25 15:21:54 +00:00
dan 78a9d7551c Enhance the shell tool ".dump PATTERN" command so that it dumps the contents of shadow tables when a virtual table is identified by the PATTERN.
FossilOrigin-Name: b0bc5ab9ceec496ac260ccfd53b51a2b53a81576fbe04c97b99f6705b063c59f
2021-05-25 11:39:14 +00:00
dan c00727ab58 Fix a problem in the in-memory journal code that could occasionally lead to a segfault when a sub-transaction that modified zero pages was committed.
FossilOrigin-Name: 17960165f5840cab45b7a8bb02779ebfb321c68f33ec6da9ab14063ccd134fa4
2021-05-24 14:35:19 +00:00
drh 0fcf6f01e7 Minor comment improvements in fuzzcheck.c.
FossilOrigin-Name: 7aca8d52c16c2192d9c1ff03a976c482a60365cef8d2474b540ff4c84e8737b4
2021-05-24 12:28:13 +00:00
drh b6b06bb339 New dbsqlfuzz cases added to test/fuzzdata8.db.
FossilOrigin-Name: 5bb5c9ec049488f95e47bbd9f1db9038ffabad3cfafa613acdaa790ab4034eee
2021-05-24 12:13:10 +00:00
drh bf7f3a005e Fix the TreeView module so that it works with the TK_ERROR exprssion.
Also fix an assert() that was failing due to the recent TK_ERROR addition.

FossilOrigin-Name: dd56fbe0cfb0f7848190ce097b378321dd25ae509c7edf93682b091014824fc6
2021-05-24 11:35:16 +00:00
drh 0542812726 Additional defenses (above and beyond [b986600520696b0c]) to prevent an
invalid subquery from causing problems downstream.  If an error is found
while analyzing a subquery expression, change the expression to TK_ERROR
so inhibit further processing on that expression.
dbsqlfuzz cf624b8c0484c66e0f552bf6475e3e3f2c22b24e.

FossilOrigin-Name: 0be6b6c9f7c562e764792a4a5eb53ed11b230174b19361f7cd7778c743314bbd
2021-05-24 00:17:04 +00:00
drh 7cc73b399e Do not push a WITH clause onto the processing stack if prior errors have
occurred.  dbsqlfuzz 6b7a144674e215f06ddfeb9042c873d9ee956ac0.

FossilOrigin-Name: c2066dde53b9872dbb991e27419dd031791c942fe23826556f52efbd66c51662
2021-05-23 17:47:04 +00:00
drh 5e1a7ded4d Do not invoke sqlite3ExprAffinity() after a syntax error that might have
left the tree in an inconsistent state.  See also [e8a1515b44380cc5] and
[forum:/forumpost/7e484e225c|forum post 7e484e225c].

FossilOrigin-Name: b986600520696b0c91c4ccc6aff1b698391b4bcaf8a3ea436be1967883faa2fe
2021-05-22 11:23:20 +00:00
drh ff9186137d The fix in the previous check-in was only correct if the OOM occurs on
the initial allocation.  This changes should make it correct for a resize
as well.

FossilOrigin-Name: 57087ab2f297e4d96da5b9f3b89a26d8dd2bc4d22c2be8045b5d956d86282f39
2021-05-22 11:00:03 +00:00
drh d42dbd9dfe If an FTS5 Cursor fails to enlarge the space for the aInst array, set the
size of the aInst array to zero.
dbsqlfuzz 294254b8105cca409f27a711f1eb2e9e63cbcac5.

FossilOrigin-Name: 4ae5e5b5ecbce580d3f7f970076e828fc6fb5fbcdc3bbe8381ab38f52870a54f
2021-05-22 01:30:30 +00:00
drh 93c8139c1a If there are errors in a nested CTE, be sure to abandon processing. Do not
continue since the parse tree may have been left in a goofy state which could
cause use-after-free and segfaults.
See [forum:/forumpost/aa4a7a3980|forum post aa4a7a3980] for an example.

FossilOrigin-Name: 94225d693932eb0b5d7799d40513afbd31ed40e1e156675eb92ad7216f1ff20f
2021-05-21 21:49:07 +00:00
dan acef1abda2 Fix a problem with SQLITE_MAX_MEMORY in malloc.c.
FossilOrigin-Name: c18dbe2f389f4ba7b219b7995d4f7009d1bc249ef8f93a30b262c6d2c008319d
2021-05-21 16:41:22 +00:00
drh ec2f689b21 Fix a faulty assert() statement in sqlite3ExprListDup(). This is a continuation
of the fix at [59812e7ef705226c].

FossilOrigin-Name: 240f7494bfa3e0806ae2f971e78039c62a419de647cb9e807309f90e1d2a536d
2021-05-20 23:25:28 +00:00
drh a76b7f5296 Enhance one test case to use various alternative definitions of DUAL.
FossilOrigin-Name: 179dcb6ba771f0e94e06b5e3c5534d8005d27b2c9b4601be20fd68abfbc5dfd0
2021-05-20 18:11:45 +00:00
dan 90bc36fb30 Ensure that objects within view definitions are not incorrectly resolved to CTEs that are part of the statement using the view.
FossilOrigin-Name: f7dcc4b5197c6413be31384b390bb98a737d3f9edb7964433448c3b90b35a436
2021-05-20 17:15:06 +00:00
dan a8f249f1e7 Ensure the required b-tree mutexes are held for "CREATE TABLE IF NOT EXISTS" and "DROP TABLE IF EXISTS" statements on attached databases.
FossilOrigin-Name: 67bde01614edd944b769ab28488bac1dbbf17d88beee62ca7f1e45681aa3d402
2021-05-20 11:42:51 +00:00
drh cd1499f47b Replace [0f0959c6f95046e8] with a new and better solution that also fixes the
CTE name resolution problem described in
[forum:/forumpost/8590e3f6dc|forum post 8590e3f6dc].
Test cases for both problems added.

FossilOrigin-Name: 5614279daff5007d6e047c5c1b3cc82ba80a5c91c529525b0fe68b79ee82dd2c
2021-05-20 00:44:04 +00:00
drh 5da5b71435 Fixes and improvements to PRAGMA compile_options.
FossilOrigin-Name: 34579549a3bc1c2cfbf47a4770c1d7abc97869ba57bcd3ab1515765ca505ea05
2021-05-20 00:10:24 +00:00
drh 1168f81092 When constructing the synthensized SELECT statement that is used to choose
the rows in an UPDATE FROM, make sure the first table is really the table
being updated, and not some common-table expression that happens to have the
same name.  [forum:/forumpost/a274248080|forum post a274248080].  More
changes associated with CTE name resolution are pending.

FossilOrigin-Name: 0f0959c6f95046e8e7887716e0a7de95da18d1e926ab1f919527083a56541db5
2021-05-19 21:55:56 +00:00
larrybr 14e250ac16 Incorporate ..._DESERIALIZE revision.
FossilOrigin-Name: b70587cca9e4f0116621e27362186e9329bcea8016c6565cd3ec5a9bf4a99d46
2021-05-19 20:01:53 +00:00
larrybr 4f878f33a9 merge from trunk
FossilOrigin-Name: 19ffe3cfe278a4046f32df56f75080c2377e4c44ad40a02d39db8e7701526204
2021-05-19 19:55:10 +00:00
drh 1f4f7c7a41 Add a comment with useful information about SHM locking. No changes to
deliverable code.

FossilOrigin-Name: 4e81ea3b15fb3fce5f31b77273639e748a735ab0970620e564e9a5c977b24a1a
2021-05-19 19:28:48 +00:00
drh 04f4b6836b Fix a formatting error on the comment.
FossilOrigin-Name: 6f2fb60e499fc758bea6ffec030fef8ab5f97d08d31450f0b3ffafc20e652891
2021-05-19 19:27:42 +00:00
drh 187e2e48a8 Add a table of shared-memory lock offsets in a comment in the os_unix.c code.
Include some assert()s to help verify the numbers.

FossilOrigin-Name: b480aacb3430a789d98ffd81a1886bbbc3cda5b0e736ec9a3e2b463db2a3b3ad
2021-05-19 16:55:28 +00:00
dan 3d691fd9ff Allow aggregate sub-selects within ORDER BY and PARTITION BY clauses of window frame definitions.
FossilOrigin-Name: 3daab94977af5e8a95690acc555540311403d890a3261a9757c633fcaaf428a9
2021-05-19 14:49:51 +00:00
drh 9088186bfb Improved column name and column type determination for the RETURNING clause.
FossilOrigin-Name: 699c33990a9438f28673ecf34f1e521d1af0b01c6ee30a608c0c91d2d593590e
2021-05-19 12:17:03 +00:00
larrybr 99bd552503 Cure some TCL test failures and narrow an object scope.
FossilOrigin-Name: 1155696c700862de1a8b1318bc41cd5cd01dec1af2c7720d8ef1e5c3321c425d
2021-05-19 02:33:42 +00:00
drh 93ffb50fcd In the MULTI-INDEX OR query plan, code for sub-expressions can sometimes be
generated twice.  But for some subqueries, generating code off of the same
tree twice causes problems.  So now MULTI-INDEX OR makes a copy of the
sub-expressions it uses to avoid code-generating them more than once.
dbsqlfuzz 9ebd2140e7206ff724e665f172faea28af801635.

FossilOrigin-Name: 4a55f72542c8bcc80253aa77043314cecb29d73cb4f51aa80f7811e86cc8ef68
2021-05-18 19:10:10 +00:00
drh e74ca517b4 Improved comments on the generated opcodes.h file.
FossilOrigin-Name: f2a17f1fad08779486e4d50d0d9277c7f87a9558a53af1a68aa5fe2ec30e820e
2021-05-18 12:36:35 +00:00
drh 8ed1da195a Add a CORRUPT_DB term to an assert() added earlier today.
FossilOrigin-Name: 304739d2382446e7b698d67377679168e46f0a19bb0794fdf22d0a0a84a8cbcc
2021-05-18 00:52:06 +00:00
drh 904e48eb89 Fix harmless compiler warnings.
FossilOrigin-Name: ace12a3912a4fdc2f0e741361ec705652a11b6f5e3548d54bd6f273671ba1e09
2021-05-17 17:14:38 +00:00
drh 8546497383 Enhance the integer-comparison optimization on the OP_Eq and similar
opcodes so that it avoids a lot of useless work.

FossilOrigin-Name: 4221f41af9df90da4183d45d0edfae19b4f7095ec35a203c8dfd2712799e3839
2021-05-17 16:54:52 +00:00
dan be12083bc7 Fix problems with refering to CTEs from within sub-selects in PARTITION BY or ORDER BY clauses of window frame definitions. Also a problem with renaming a column when the schema contains a trigger containing a correlated sub-select within a window frames PARTITION BY or ORDER BY clause.
FossilOrigin-Name: 4c6cd54a8db78e5535912e76856bed4f797261aaca4248c69d2e2452194de297
2021-05-17 16:20:41 +00:00
drh ba39ca4058 When deleting an SQL function that does not exist, return without doing
anything at all rather than creating a tombstone function.  In this way,
function deletes that happen inside virtual-table destructors that are run
when a database connection is closing do not create new tombstones in the
function table after the function table has already been purged.
[forum:/forumpost/726219164b|forum post 726219164b].

FossilOrigin-Name: 391c73132c80df944fb49a17d8fe78203c54ac48f968ee9dd9dd8c769c0b4b10
2021-05-17 13:11:24 +00:00
drh 9430506df0 Performance improvement in sqlite3TableLock().
FossilOrigin-Name: 0d77e371c47107f67550e9bedfd26808fcfd84c7473f94b6053f75f0e3463c73
2021-05-17 11:19:32 +00:00
drh 2454e4a901 Performance optimization in the memory allocation of allocateCursor.
FossilOrigin-Name: 9d16323d14370b737399eb52b69b70cc614f78fb8a1e93f21a348c34a30dd456
2021-05-15 19:36:36 +00:00
drh 86c779fe42 Performance optimization to the clearCell() routine inside of btree.
FossilOrigin-Name: c4e02619a4dc8b07f658e7c88011991a086eb1e760d920b9024a11437daaabfd
2021-05-15 13:08:44 +00:00
drh 49bb56e9b0 Small performance improvement for sqlite3BtreeInsert().
FossilOrigin-Name: 4ae64484c57740333322cebd713b50b01a5a5838d41c65f67e26d65769770789
2021-05-14 20:01:36 +00:00
drh 6a9595a76b Avoid adding superfluous virtual WHERE clause terms that might arise due
to the constant propagation optimization.

FossilOrigin-Name: cf63abbe559d04f993f99a37d41ba4a97c0261094f1d4cc05cfa23b1e11731f5
2021-05-14 15:37:00 +00:00
drh b775c97682 Attempt the [/info/f4229707ac08d66c|constant propagation optimization] on any
WHERE clause that has a top-level AND operator, even if the query is not
a join.  This is an attempt to partially address the concern raised in
[forum:/forumpost/830d37b928|forum post 830d37b928].

FossilOrigin-Name: e994c9f29f7a561dd5f30573865b0f793fb1388af09a2afb9b1a5b037ea52f89
2021-05-14 14:26:57 +00:00
drh 11c87895e0 Fix an over-length source code comment in whereexpr.c. No logic changes.
FossilOrigin-Name: af5eb902e7b13f50a8890098b85ae64a9d2ff4f122f3ab46ddb2c048b5c846a0
2021-05-14 13:32:07 +00:00
drh 31da7be9f2 Modify the sqlite3_stmt_readonly() interface so that it returns false for
CREATE TABLE IF NOT EXISTS statements even if the table already exists and
the statement is really a read-only no-op.  Likewise for DROP TABLE, 
CREATE INDEX, and DROP INDEX.  Update the documentation for
sqlite3_stmt_readonly() to reflect this new behavior.

FossilOrigin-Name: cf8eb465974e596a13df56f3efbc98e098e7b74de9af4fde9ad58312db9750e4
2021-05-13 18:24:22 +00:00
drh 756748ea86 The content columns of the index-btree that implements a WITHOUT ROWID
table are not ordered and so the query planner should not assume they
are ordered.  Fix for the issue identified by
[forum:/forumpost/6c8960f545|forum post 6c8960f545].

FossilOrigin-Name: c21bc5a2353e660f2acf5ed916921a4ee416910d0b3f2deb512a05c54138d1c0
2021-05-13 13:43:40 +00:00
drh 7ffb16b495 Further simplification of the reverse-order scan logic of the previous
check-in.

FossilOrigin-Name: b2b0e23ba885f22c88b03492e42c3cd1cbd59289e452263951bb757a871699f0
2021-05-12 22:15:44 +00:00
drh 0564cc2601 Fix the query plan for an indexed lookup on a WITHOUT ROWID table with
a DESC primary key when the primary key is constrained by an inequality.
See [forum:/forumpost/8988341615|forum post 8988341615]. Test cases in TH3.

FossilOrigin-Name: f65c929bf189cf5ca5f1cacdbbb8eec014c9960f767b135023bd2323cd26f279
2021-05-12 22:02:14 +00:00
drh 52d1407891 Fix a race condition that can lead to deadlock in the memdb VFS if one
thread is trying to open an existing database at the same moment that
another thread that is the only prior user of that database is trying to
close it.

FossilOrigin-Name: b635375dbe22bd31c437ca574eb0c014c0b045de6cc0816c32d2ceceff9191fb
2021-05-12 15:39:02 +00:00
drh 85ffcae177 Add the new threadtest5 test program for stressing multiple database
connections in the same process hammering on a single database.
Primarily designed to test memdb, but works on any database.

FossilOrigin-Name: 8db1c06958b8e1691440d4fd392648b74a1940b721852dabd315005efad520fc
2021-05-12 14:17:20 +00:00
drh 277ae64103 Enhance the memdb VFS so that it is able to share databases among multiple
database connections in the same process, as long as the database filename
begins with "/".  This provides a way for threads to share an in-memory
database without the use of shared-cache mode.

FossilOrigin-Name: 533fffc4a39b01c3aba75bd3271fd6ccd9516d9681ed04adbe19bd7de03f4c16
2021-05-12 11:55:59 +00:00
drh 2d344f944e Respond correctly to OOM during mutex allocation.
FossilOrigin-Name: 98dae595d861941bb0bcd12126ee02492587c466e6da579a58b5dc4a4d655917
2021-05-12 02:52:20 +00:00
drh 483051c9b6 Mark an unreachable branch as NEVER().
FossilOrigin-Name: 6c20d9d4b7c7986e8404142974a91dce7514ca574ee52ed5d036367aad396689
2021-05-12 02:09:01 +00:00
drh f71d6fa9db Fix a NEVER() that can sometimes be true.
FossilOrigin-Name: 8f9f1cbc4468d07d693b418be4d89771fd240ee4af34395d7da5b7709fe88f37
2021-05-11 11:40:22 +00:00
drh ccb897c70a Fix a NEVER() that can sometimes be true.
dbsqlfuzz 9a86fb3830977e216fde061bfbe1c1e5c2e9bfc4

FossilOrigin-Name: f39666e64d6d32420170c54f874d8314eb8c6f91df625f7b28f9ccffb9474dc0
2021-05-11 10:47:41 +00:00
drh 2f4d0ec392 Enhance the memdb VFS to provide the ability to share a single database
among multiple database connections.

FossilOrigin-Name: 0617c66ac213d406a9a21580227a57542d7f21c8750c854f549ab818d7a936bc
2021-05-10 23:48:46 +00:00
drh 8d889afc0d Enable the sqlite3_serialize() and sqlite3_deserialize() interfaces by
default.  Omit the SQLITE_ENABLE_DESERIALIZE option and replace it with
the SQLITE_OMIT_DESERIALIZE option.

FossilOrigin-Name: 6df3b03e00b1143be8fed3a39a58ce81063020275aa1ac13d87c84f1ceda6e27
2021-05-08 17:18:23 +00:00
drh d10c3ca3f7 Fix help-text typo in the CLI.
FossilOrigin-Name: 560753148a16a0032477e379af6f62d9357f69847f351cc9db6021ce1b5594ea
2021-05-08 11:57:35 +00:00
drh 4752bbd872 Detect misuse of aggregate functions in the ORDER BY clause of a query
even if the query also contains window functions.

FossilOrigin-Name: 0d11d777c8d368f0b6e9faf3afccf7da1b041d303a68782e43aebd713aaecf51
2021-05-07 15:46:36 +00:00
dan 01ec691979 Fixes for cksmvfs and rbu so that they work together.
FossilOrigin-Name: f35f6972cdcf16915cc37908b65a3780742a1f75f65e974714b16e86f0c9e3f0
2021-05-06 20:47:49 +00:00
drh e31cba5675 Remove an assert() in FTS5 that can (rarely) be false in the event of an
OOM while processing a corrupt database file.

FossilOrigin-Name: 5f12f89154843e83b1d69ea1652e881d583aa329df732af72dd59029cd7eb577
2021-05-06 13:45:37 +00:00
drh c3c23f346c Improved detection of oversized cells in balance_nonroot(), especially in
index b-trees when a cell is being moved from a child page into the parent
page in order to become a new divider cell.

FossilOrigin-Name: 9080d3d5f5aaddbb3410158bcc446649651b7dce3940eb3491620ec9208914b4
2021-05-06 11:02:55 +00:00
drh 59df3e92db Provide the sqlite3PrintMem() routine on SQLITE_DEBUG builds, which can be
invoked from a debugger to get a summary of the status of an sqlite3_value
or Mem object.

FossilOrigin-Name: 5ac24179f5ef16dccc1b65248e33376c9748767b14c75c1056f3b0d08b7a89a7
2021-05-05 19:46:50 +00:00
dan 4fd82a2a78 Fix an undefined-integer-overflow problem in fts3.c.
FossilOrigin-Name: a0bf931bd712037e44e8d7cac3c00a6715c1b451f222bad3184d3ecab1a4c7f4
2021-05-05 11:47:34 +00:00
drh 67656ac78a When applying the optimization that disables WHERE clause terms that drive
indexes, make sure not to do so if the term being disabled is a transitive
constraint.  Fix for the problem identified by
[forum:forumpost/eb8613976a|forum post eb8613976a].

FossilOrigin-Name: f1f9b5de3c59489b94963685660b3ddc45eece5535b02fec399b6ece0e38563d
2021-05-04 23:21:35 +00:00
drh 23634898c5 Also for the 0x20000 bit of ".wheretrace", show when WHERE clause terms are
disabled.

FossilOrigin-Name: 625fb253eecd6c10fce5d0127d516361df0c1d1661502b396fc418dcdb4ae999
2021-05-04 18:24:56 +00:00
drh 6068b6b451 Additional debugging output for whereScanNext() showing equivalence classes
when the ".wheretrace" setting contains the 0x20000 bit.

FossilOrigin-Name: 9280e3d994656344d4feb346156df8a278da80181f6efe0ff8e0340b6f0f91cb
2021-05-04 16:51:52 +00:00
drh 433a3e935d Back out the EXISTS-to-IN optimization. It slows things down rather than
speeds them up depending on the query.  And (see
[forum:/forumpost/8692d94725|forum post 8692d94725]) it sometimes results in
an incorrect answer.  We may come back and revisit this optimization later,
but for now it seems best just to disable it.

FossilOrigin-Name: 16252d73fa73569fd7506676f6ffbbcd43addfb105384fb74449d30ca720904a
2021-05-04 12:07:16 +00:00
drh f83d501c6d Fix minor coverity warnings in the CLI.
FossilOrigin-Name: 204086a94202fc631371b75c7a8286df2f66116399628ac27ef54533641b8f20
2021-05-03 13:35:00 +00:00
drh e103a8de2d Fix a potential memory leak following OOM in the decimal extension.
FossilOrigin-Name: 5127f7376776e6220eb8f83a30aa6b823c23ae0ac76e7ae41b33ca4e03ce236a
2021-05-03 13:24:30 +00:00
drh 736d11ed21 Back out the NEVER() inserted by [c7309ed3c7588c7e] because it is reachable
after all.  dbsqlfuzz bc17a306a09329bba0ecc61547077f6178bcf321

FossilOrigin-Name: 20a4f3f12cdd8823d53d91025fa41e284c9f629b1d049eb486ff8dc4a1736e1f
2021-05-01 12:09:36 +00:00
drh 76baad95f4 Guard against a NULL-pointer dereference following OOM in the JSON extension.
FossilOrigin-Name: ea221f3c8e243a5dc4952e510cbe396614a24876bacdc04fb1ebd4127c7ef0d9
2021-04-30 16:12:40 +00:00
drh 0449f6561f Fix a harmless "unused variable" warning when compiling with
-DSQLITE_COVERAGE_TEST.

FossilOrigin-Name: 0bef3fb11fb95d7ede82b59aea26e99e2e23b3bce48009181e691ea17ae78a61
2021-04-30 12:30:35 +00:00
larrybr 5f5719bd07 Reduce API lifetime requirement for objects passed to sqlite3_bind_...() with SQLITE_STATIC.
Also fix broken session doc links (by zapping refs.)

FossilOrigin-Name: 327eb4792f9b98f6220fd35ba744002d36ed53f43a016924117b3cea32343947
2021-04-29 19:30:35 +00:00
drh 5960724789 Fix the operation of the "-" argument to --load-dbsql in the fuzzcheck program.
FossilOrigin-Name: 1f18b3cbee7e1342fdd66e45ef744fea3db2ba4513943c0582ff8ef98974865e
2021-04-29 18:03:42 +00:00
drh 81f5ef05a9 Fix the IN-early-out optimization so that it works even for the corner case
where the NULL bypass fires before the affinity of the LHS operator has been
set.  Fix for the problem described in
[forum:/forumpost/6a3ec138e9|forum post 6a3ec138e9].

FossilOrigin-Name: eb40248ce606b792a02e4e0b7dd826a82891c5f4c9793f3ca5d332e593109525
2021-04-29 15:49:34 +00:00
drh 7bfccfe73c Enhanced "PRAGMA vdbe_trace=on" output associated with the seekHit flag.
FossilOrigin-Name: 683950009300657b0321d7d3f77f2585a28696ff93cedef399d1cd4aa484b2d4
2021-04-29 13:58:28 +00:00
drh 5f086ddee0 Fix harmless compiler warnings.
See [forum:/forumpost/256140e470|forum post 256140e470].

FossilOrigin-Name: 1b8da7924cc78710ae4bbe12b57140fdaeae5efb0e6ac10073ae9c98b7f8d7a4
2021-04-29 13:37:36 +00:00
drh 5e26d07d62 Update test/fuzzdata8.db with recent dbsqlfuzz finds.
FossilOrigin-Name: bce2ea393a872b5b70ef3b9cedce3d406725dcc56d8800ee4f7ec29562cc3f9b
2021-04-29 10:48:50 +00:00
drh c645871123 Ignore the TEMP or TEMPORARY keyword on CREATE statements which parsing
the schema out of an existing database file.  Those keywords should never be
there.  This change simply adds robustness in case a legacy or damaged database
is seen.

FossilOrigin-Name: 65ec39f0f092fe29e1d4e9e96cf07a73d2ef7ce2c41b6f1cd3ab23546ada0e67
2021-04-28 17:37:26 +00:00
drh 79f313f13c Adjust a VDBE coverage macros due to the enhancement at [506333742103c1f4].
FossilOrigin-Name: daed59b4f96a6899d2404274ad985be3f22f407c1502b3f8ffd7977441a9fe9a
2021-04-28 15:43:36 +00:00
drh 3765c03243 Further improvements to the handling of RETURNING clauses on changes
to TEMP tables with triggers.
dbsqlfuzz 683913e98f54fe4f14e8dd11a48011f73bdca58d

FossilOrigin-Name: ff3538ae37a02f4f36a15cddd1245171e724aac9c84b2e576980fd3806302775
2021-04-27 17:18:10 +00:00
drh a476768340 RETURNING bug fix: Correctly deal with RETURNING statements on changes to
TEMP tables that also have triggers.
dbsqlfuzz 78b9400770ef8cc7d9427dfba26f4fcf46ea7dc2

FossilOrigin-Name: d0b15eccbfe1e50c3daf7b2fd4769a52bba35d553b07e462ca3f5f22df6742fd
2021-04-27 13:04:18 +00:00
dan a4cd0bbcb3 Fix a segfault that could occur when querying a corrupt data structures with an fts5token table.
FossilOrigin-Name: cbedfa05501f3eb9750fb21e2ab8516f8f14c479c847f454e52572af278aab71
2021-04-27 11:28:57 +00:00
larrybr 3ec4861c00 merge latest trunk
FossilOrigin-Name: 3ff228249adf2da345d3e19e9af3e23d1354f6b9a35ddbe9864e1a07716d871c
2021-04-27 04:47:27 +00:00
drh 2f40dc9884 Better error messages on showdb.
FossilOrigin-Name: 7e18e114b245d17aa259ea9ab42752ccc9ad5303bbac8d8e46928dd10319f545
2021-04-27 00:05:03 +00:00
drh 19a7f72ce2 Improved robustness of the "showdb" debugging program when it is parsing
corrupt database files.

FossilOrigin-Name: 3eabac2ee50fd70b22a927d3d2934718a15e1f666d8d271b854579156c8b01de
2021-04-26 23:57:02 +00:00
drh d8bc250b91 New dbsqlfuzz cases added to test/fuzzdata8.db.
FossilOrigin-Name: 88d20500c516fe89ad1cd42f7366ca190c3790f911f11ab332b86b675f5f69ba
2021-04-26 22:30:49 +00:00
drh c7f5077e88 Fix the [/info/df1d6482f9e92daf|UNION ALL flattener optimization] so that it
works better with recursive CTEs.
dbsqlfuzz 88ed5c66789fced139d148aed823cba7c0926dd7

FossilOrigin-Name: f80d7bb2c305c1dd4658767660b33259032c048a91f18c654a6bda7332c54a0c
2021-04-26 21:23:01 +00:00
drh feef447271 Add ALWAYS() to branches that are no longer reachable due to recent
enhancements.

FossilOrigin-Name: 63c50fbdeed831ba450d1dce67e968a7daa2b69ac1270eb271fb1e1873d4a07e
2021-04-26 21:00:51 +00:00
larrybr ada2323d95 refix altertab.test
FossilOrigin-Name: db032156932fb0dcae5ffb7cbdfb711079daa595713fcb254f09f8ef90c81d95
2021-04-26 20:18:08 +00:00
dan f0ac29090b Fix a problem that could cause a crash in sqlite3BtreeDelete() when operating on a corrupt database file.
FossilOrigin-Name: 6c6334660dfe81cc33a14b87b25d748b1c98b0702b7bc6db2e3ced16dc992740
2021-04-26 15:32:36 +00:00
drh 3c6edc8a11 More aggressive detection of OOM errors in resolveAlias().
dbsqlfuzz 7f96832c2ef7ee472022ed805b064e55e41094b2

FossilOrigin-Name: e99faf4f82746761c389e24db1b00ee94b9f849e7bcb29517fa0ca10290afc41
2021-04-26 15:28:06 +00:00
drh 8ed8ddf759 When doing the optimization that attempts to avoid sorting on a
GROUP BY, do not assume that the values in an index on an expression are
non-NULL.  Bug discovered by Wang Ke's fuzzer and reported at
[forum:/forumpost/74330094d8|forum post 74330094d8].

FossilOrigin-Name: 7178dc3a32c3a4a33e437fd5026f6f72e4809ceb7d2cd12a25a74b80d5c95d33
2021-04-26 14:32:48 +00:00
dan bb0eec438d Do not initialize eponymous virtual tables when parsing the schema. This can happen if the db is corrupt.
FossilOrigin-Name: cb8c41aa20bb351c4c712ed7a3617187ceeb0905ede1e6f561bc1d89f31c95ea
2021-04-26 14:09:48 +00:00
larrybr 3ff6a5edd9 Skip test when no JSON.
FossilOrigin-Name: 6fcb2438f88a70ed67e19103bfa263a6c98b06962207f153559c9516d8c7b5d5
2021-04-25 23:13:04 +00:00
drh 113a33c539 Make window range queries more robust against corrupt database files.
dbsqlfuzz f22df3a7b2aab0937a415484514fc2f68a293c99.

FossilOrigin-Name: 506333742103c1f440db5da819a36f3b518f7b49e94a7b74419b02bbcadc5a78
2021-04-24 23:40:05 +00:00
drh ba9ebc2d12 Treat byte-order marks (BOMs) at the start of a token as whitespace.
This enhancement is inspired by
[forum:/forumpost/ed8f696a20|forum post ed8f696a20].

FossilOrigin-Name: 3d55c21c167631f42d155aadec544e629bd078de9992aa5a74694d08bc52052b
2021-04-24 12:24:08 +00:00
drh 971ae9f66a Fix testcase altertab-25.1 due to check-in [c7909e8e0d0577c6] disallowing
ALTER TABLE on eponymous virtual tables.

FossilOrigin-Name: 32255e39cbde65492d88177464cee9e10cb20cf3105208416be131e2c89b63e1
2021-04-24 12:20:10 +00:00
drh 1521270010 Fix harmless compiler warnings in fuzzcheck.
FossilOrigin-Name: e7b4ffecc610c494ebd506977402ec48cc799780f96c6293c0ccf27697160aa1
2021-04-23 13:57:53 +00:00
drh ba6619d7be Enhance the --load-dbsql and related options of fuzzcheck so that if the
argument is a single - then filenames are read from standard input.

FossilOrigin-Name: e1548802b6de7037baf388d27a7f3658abafe07b6f48d5ec97e5f644303592d8
2021-04-23 12:58:16 +00:00
drh 292ed6decf Give a better final output line for the --spinner option on fuzzcheck.
FossilOrigin-Name: 93729614e21ee674b83b0d2babb71bb758f1a2ec55bf9bda057fb7739f2e14e0
2021-04-23 12:16:16 +00:00
drh d84f10ed13 New dbsqlfuzz cases added to test/fuzzdata8.db.
FossilOrigin-Name: 8da88508932e475c8c6af1553268ff02e3e013b78ccc94b14532ec928fc62537
2021-04-23 11:50:23 +00:00
dan f3d5a68461 Fix an assert() in fts5_index.c that may fail if the database records are corrupt.
FossilOrigin-Name: dfadb96edfef1d49e48a659264b9eb8d7f98d95d159d95c92c30dd4ba6c6e739
2021-04-23 11:37:01 +00:00
drh 7a04e296f3 Improved OOM detection in sqlite3ExprCheckIN().
dbsqlfuzz 46ae2d8f473ac672f3042cc14ab67aeab9ffa6c2

FossilOrigin-Name: fac12115a994a1b4347586e68faf38895ee9cb588eaa84c6f71cf9afd4c488b4
2021-04-23 00:59:38 +00:00
drh eca3c67b1c Change a memcpy() into a memmove() to prevent a warning about overlapping
regions passed to memcpy() in case of some obscure and unlikely database
corruption.

FossilOrigin-Name: bab132cbd18a529389a0315e60f30ccf1b565823116e0ec9b4f7684db1914c80
2021-04-22 20:01:02 +00:00
drh 214b50314a Fix harmless compiler warnings of unused function parameters in FTS5.
FossilOrigin-Name: 14273915979f8fbf80111e795b5511a6ee24638896b9d434d6ccf4bf7f7a7f62
2021-04-22 19:34:31 +00:00
dan 743b5fd589 Further tweaks for comments in sqlite3session.h.
FossilOrigin-Name: 553ada28f356d773c145b502163d766285e73fd4f64dc05f98e3e43ade806331
2021-04-22 18:52:36 +00:00
dan 9ad39a33ff Change to comments in sqlite3session.h. No changes to code.
FossilOrigin-Name: 353ebb71c4113a35a92011c72f9c1d6c56f3bf681d94426a6a73e40f219ff2f4
2021-04-22 18:39:02 +00:00
drh 3d8c92d041 Raise an error on an attempt to rename an eponymous virtual table.
FossilOrigin-Name: c7909e8e0d0577c6109f13c0b14fb565239aae8af8963d659f363e124f3437fc
2021-04-22 18:02:48 +00:00
dan a5b51b8715 Add the experimental sqlite3session_changeset_size() API.
FossilOrigin-Name: 3de544d495fee553d95fde3fb656745d633138115d25ed39760a1ea7c8c3fae6
2021-04-22 17:55:42 +00:00
drh 65b930553d Improved handling of errors in ALTER TABLE RENAME.
dbsqlfuzz 3e3e2e076e53d02288f80af41a11143a6ddf8c88

FossilOrigin-Name: 9c7a449f52a391506ebf4a8efa4ff27e6e97bd8da4b300a5c0dd942a209fe474
2021-04-22 16:54:34 +00:00
drh 68b63c0195 Fix the date/time translation logic in the zipfile extension so that it
works with boundary cases. See
[forum:/forumpost/d82289d69f|forum post d82289d69f] for the trouble report.

FossilOrigin-Name: c8de5f061359c174e143e5e81ade8aa9b7d71ba57287459cf0f4f2c94459c345
2021-04-22 14:43:16 +00:00
drh 1da9c97bc0 Ensure that the typedefs for specific-length integers in zipfile.c are
correct.

FossilOrigin-Name: f1f2a49007e938ea7a00dda6f8898b1cd38525c0de1e1cac00a7aebcd7b625f5
2021-04-22 13:59:54 +00:00
drh 824043150f In the whereLoopXfer() routine, ensure that the destination is fully
initialized even if an OOM error occurs.

FossilOrigin-Name: c4258708c08c5b1956052f9febbf22c1e94c8352a25059063746921d2cc373b7
2021-04-22 12:38:30 +00:00
drh 31536304a5 The new OP_Null opcode from check-in [8b54102a00852b72] was not coded
correctly.  This check-in attempts to fix that.

FossilOrigin-Name: 02af30aab24878c4382a8863512b816889400104549b51df6a632767fee48d04
2021-04-21 23:13:26 +00:00
larrybr 7d0a2f3fe3 Merge trunk bug/test fixes
FossilOrigin-Name: 830b0b1c49aaca53a40e5a4ca9a11351d697a980c7bf80379e32f0646738d566
2021-04-17 20:13:35 +00:00
larrybr c7a409e78e Merge from trunk.
FossilOrigin-Name: 43894f0b5b4f000a929052bc32822d704d25d139375362fad77f8824b5aad456
2021-04-16 23:53:07 +00:00
larrybr 89eab376da Merge from trunk.
FossilOrigin-Name: d762784a46946c5a5d565d7ef8ae243703eb38eb71d6101a7f2ed6d22eff1c53
2021-04-16 15:44:32 +00:00
larrybr 5ae13144ef Dial back assumptions on compile option defaults to reflect actual conditionals.
FossilOrigin-Name: cb3127725dbb9490f9bb3a95d7fd52acd78390981ee8b7c6da35bdfb84ad0359
2021-04-16 10:25:54 +00:00
larrybr cf5ad4210e Merge from (forked) trunk. Handle compile options that differ from default by being 0.
FossilOrigin-Name: 6eb83f83d280f82bd225972f52c52922257303740a968457ff0be08d43993d59
2021-04-15 23:43:25 +00:00
larrybr f8fb27f4a9 Bring pragma compile_options up to date. And make mkctimec.tcl help do so.
FossilOrigin-Name: 63ea3e298c575a408e5c5e12368292c966db6dcffcb6e1c770734f28b8757635
2021-04-15 00:26:34 +00:00
96 changed files with 3323 additions and 1236 deletions
+4 -4
View File
@@ -616,12 +616,10 @@ SHELL_OPT += -DSQLITE_ENABLE_DBPAGE_VTAB
SHELL_OPT += -DSQLITE_ENABLE_DBSTAT_VTAB
SHELL_OPT += -DSQLITE_ENABLE_BYTECODE_VTAB
SHELL_OPT += -DSQLITE_ENABLE_OFFSET_SQL_FUNC
SHELL_OPT += -DSQLITE_ENABLE_DESERIALIZE
FUZZERSHELL_OPT = -DSQLITE_ENABLE_JSON1
FUZZCHECK_OPT = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_MEMSYS5 -DSQLITE_OSS_FUZZ
FUZZCHECK_OPT += -DSQLITE_MAX_MEMORY=50000000
FUZZCHECK_OPT += -DSQLITE_PRINTF_PRECISION_LIMIT=1000
FUZZCHECK_OPT += -DSQLITE_ENABLE_DESERIALIZE
FUZZCHECK_OPT += -DSQLITE_ENABLE_FTS4
FUZZCHECK_OPT += -DSQLITE_ENABLE_FTS3_PARENTHESIS
#FUZZCHECK_OPT += -DSQLITE_ENABLE_FTS5
@@ -695,7 +693,6 @@ dbfuzz$(TEXE): $(TOP)/test/dbfuzz.c sqlite3.c sqlite3.h
DBFUZZ2_OPTS = \
-DSQLITE_THREADSAFE=0 \
-DSQLITE_OMIT_LOAD_EXTENSION \
-DSQLITE_ENABLE_DESERIALIZE \
-DSQLITE_DEBUG \
-DSQLITE_ENABLE_DBSTAT_VTAB \
-DSQLITE_ENABLE_BYTECODE_VTAB \
@@ -1235,7 +1232,6 @@ TESTFIXTURE_FLAGS += -DSQLITE_DEFAULT_PAGE_SIZE=1024
TESTFIXTURE_FLAGS += -DSQLITE_ENABLE_STMTVTAB
TESTFIXTURE_FLAGS += -DSQLITE_ENABLE_DBPAGE_VTAB
TESTFIXTURE_FLAGS += -DSQLITE_ENABLE_BYTECODE_VTAB
TESTFIXTURE_FLAGS += -DSQLITE_ENABLE_DESERIALIZE
TESTFIXTURE_FLAGS += -DSQLITE_CKSUMVFS_STATIC
TESTFIXTURE_SRC0 = $(TESTSRC2) libsqlite3.la
@@ -1431,6 +1427,9 @@ threadtest3$(TEXE): sqlite3.lo $(THREADTEST3_SRC)
threadtest: threadtest3$(TEXE)
./threadtest3$(TEXE)
threadtest5: sqlite3.c $(TOP)/test/threadtest5.c
$(LTLINK) $(TOP)/test/threadtest5.c sqlite3.c -o $@ $(TLIBS)
releasetest:
$(TCLSH_CMD) $(TOP)/test/releasetest.tcl
@@ -1484,6 +1483,7 @@ clean:
rm -f sqldiff sqldiff.exe
rm -f dbhash dbhash.exe
rm -f fts5.* fts5parse.*
rm -f threadtest5
distclean: clean
rm -f config.h config.log config.status libtool Makefile sqlite3.pc
-4
View File
@@ -367,7 +367,6 @@ OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_STMTVTAB=1
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_DBPAGE_VTAB=1
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_DBSTAT_VTAB=1
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_BYTECODE_VTAB=1
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_DESERIALIZE=1
!ENDIF
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_COLUMN_METADATA=1
!ENDIF
@@ -1689,7 +1688,6 @@ FUZZDATA = \
SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_FTS4=1
SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_EXPLAIN_COMMENTS=1
SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_OFFSET_SQL_FUNC=1
SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_DESERIALIZE=1
!ENDIF
# <<mark>>
@@ -1698,7 +1696,6 @@ SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_DESERIALIZE=1
MPTESTER_COMPILE_OPTS = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_FTS5
FUZZERSHELL_COMPILE_OPTS = -DSQLITE_ENABLE_JSON1
FUZZCHECK_OPTS = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_MEMSYS5 -DSQLITE_OSS_FUZZ -DSQLITE_MAX_MEMORY=50000000 -DSQLITE_PRINTF_PRECISION_LIMIT=1000
FUZZCHECK_OPTS = $(FUZZCHECK_OPTS) -DSQLITE_ENABLE_DESERIALIZE
FUZZCHECK_OPTS = $(FUZZCHECK_OPTS) -DSQLITE_ENABLE_FTS4
FUZZCHECK_OPTS = $(FUZZCHECK_OPTS) -DSQLITE_ENABLE_RTREE
FUZZCHECK_OPTS = $(FUZZCHECK_OPTS) -DSQLITE_ENABLE_GEOPOLY
@@ -2392,7 +2389,6 @@ TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_ENABLE_STMTVTAB=1
TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_ENABLE_DBPAGE_VTAB=1
TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_ENABLE_BYTECODE_VTAB=1
TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_ENABLE_JSON1=1
TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_ENABLE_DESERIALIZE=1
TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_CKSUMVFS_STATIC=1
TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) $(TEST_CCONV_OPTS)
-2
View File
@@ -290,7 +290,6 @@ OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_STMTVTAB=1
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_DBPAGE_VTAB=1
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_DBSTAT_VTAB=1
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_BYTECODE_VTAB=1
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_DESERIALIZE=1
!ENDIF
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_COLUMN_METADATA=1
!ENDIF
@@ -960,7 +959,6 @@ LIBRESOBJS =
SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_FTS4=1
SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_EXPLAIN_COMMENTS=1
SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_OFFSET_SQL_FUNC=1
SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_DESERIALIZE=1
!ENDIF
+7 -7
View File
@@ -1899,7 +1899,7 @@ static int fts3ScanInteriorNode(
char *zBuffer = 0; /* Buffer to load terms into */
i64 nAlloc = 0; /* Size of allocated buffer */
int isFirstTerm = 1; /* True when processing first term on page */
sqlite3_int64 iChild; /* Block id of child node to descend to */
u64 iChild; /* Block id of child node to descend to */
int nBuffer = 0; /* Total term size */
/* Skip over the 'height' varint that occurs at the start of every
@@ -1915,8 +1915,8 @@ static int fts3ScanInteriorNode(
** table, then there are always 20 bytes of zeroed padding following the
** nNode bytes of content (see sqlite3Fts3ReadBlock() for details).
*/
zCsr += sqlite3Fts3GetVarint(zCsr, &iChild);
zCsr += sqlite3Fts3GetVarint(zCsr, &iChild);
zCsr += sqlite3Fts3GetVarintU(zCsr, &iChild);
zCsr += sqlite3Fts3GetVarintU(zCsr, &iChild);
if( zCsr>zEnd ){
return FTS_CORRUPT_VTAB;
}
@@ -1969,20 +1969,20 @@ static int fts3ScanInteriorNode(
*/
cmp = memcmp(zTerm, zBuffer, (nBuffer>nTerm ? nTerm : nBuffer));
if( piFirst && (cmp<0 || (cmp==0 && nBuffer>nTerm)) ){
*piFirst = iChild;
*piFirst = (i64)iChild;
piFirst = 0;
}
if( piLast && cmp<0 ){
*piLast = iChild;
*piLast = (i64)iChild;
piLast = 0;
}
iChild++;
};
if( piFirst ) *piFirst = iChild;
if( piLast ) *piLast = iChild;
if( piFirst ) *piFirst = (i64)iChild;
if( piLast ) *piLast = (i64)iChild;
finish_scan:
sqlite3_free(zBuffer);
+1
View File
@@ -2806,6 +2806,7 @@ int sqlite3Fts5ExprInit(Fts5Global *pGlobal, sqlite3 *db){
}
#else
int rc = SQLITE_OK;
UNUSED_PARAM2(pGlobal,db);
#endif
/* Avoid warnings indicating that sqlite3Fts5ParserTrace() and
+6 -5
View File
@@ -431,7 +431,7 @@ struct Fts5SegIter {
int iLeafPgno; /* Current leaf page number */
Fts5Data *pLeaf; /* Current leaf data */
Fts5Data *pNextLeaf; /* Leaf page (iLeafPgno+1) */
int iLeafOffset; /* Byte offset within current leaf */
i64 iLeafOffset; /* Byte offset within current leaf */
/* Next method */
void (*xNext)(Fts5Index*, Fts5SegIter*, int*);
@@ -1611,7 +1611,7 @@ static void fts5SegIterLoadNPos(Fts5Index *p, Fts5SegIter *pIter){
static void fts5SegIterLoadRowid(Fts5Index *p, Fts5SegIter *pIter){
u8 *a = pIter->pLeaf->p; /* Buffer to read data from */
int iOff = pIter->iLeafOffset;
i64 iOff = pIter->iLeafOffset;
ASSERT_SZLEAF_OK(pIter->pLeaf);
if( iOff>=pIter->pLeaf->szLeaf ){
@@ -1644,7 +1644,7 @@ static void fts5SegIterLoadRowid(Fts5Index *p, Fts5SegIter *pIter){
*/
static void fts5SegIterLoadTerm(Fts5Index *p, Fts5SegIter *pIter, int nKeep){
u8 *a = pIter->pLeaf->p; /* Buffer to read data from */
int iOff = pIter->iLeafOffset; /* Offset to read at */
i64 iOff = pIter->iLeafOffset; /* Offset to read at */
int nNew; /* Bytes of new data */
iOff += fts5GetVarint32(&a[iOff], nNew);
@@ -2072,7 +2072,6 @@ static void fts5SegIterNext(
** this block is particularly performance critical, so equivalent
** code is inlined. */
int nSz;
assert( p->rc==SQLITE_OK );
assert_nc( pIter->iLeafOffset<=pIter->pLeaf->nn );
fts5FastGetVarint32(pIter->pLeaf->p, pIter->iLeafOffset, nSz);
pIter->bDel = (nSz & 0x0001);
@@ -5079,7 +5078,8 @@ static void fts5MergePrefixLists(
nTail = pHead->iter.nPoslist - pHead->iOff;
/* WRITEPOSLISTSIZE */
assert( tmp.n+nTail<=nTmp );
assert_nc( tmp.n+nTail<=nTmp );
assert( tmp.n+nTail<=nTmp+nMerge*10 );
if( tmp.n+nTail>nTmp-FTS5_DATA_ZERO_PADDING ){
if( p->rc==SQLITE_OK ) p->rc = FTS5_CORRUPT;
break;
@@ -6720,6 +6720,7 @@ int sqlite3Fts5IndexInit(sqlite3 *db){
return rc;
#else
return SQLITE_OK;
UNUSED_PARAM(db);
#endif
}
+4 -2
View File
@@ -1949,13 +1949,15 @@ static int fts5CacheInstArray(Fts5Cursor *pCsr){
nInst++;
if( nInst>=pCsr->nInstAlloc ){
pCsr->nInstAlloc = pCsr->nInstAlloc ? pCsr->nInstAlloc*2 : 32;
int nNewSize = pCsr->nInstAlloc ? pCsr->nInstAlloc*2 : 32;
aInst = (int*)sqlite3_realloc64(
pCsr->aInst, pCsr->nInstAlloc*sizeof(int)*3
pCsr->aInst, nNewSize*sizeof(int)*3
);
if( aInst ){
pCsr->aInst = aInst;
pCsr->nInstAlloc = nNewSize;
}else{
nInst--;
rc = SQLITE_NOMEM;
break;
}
+330
View File
@@ -14591,6 +14591,336 @@ do_catchsql_test 74.1 {
SELECT rowid, quote(matchinfo(t1,'pxyb<s')) FROM t1 WHERE t1 MATCH 'e*';
} {1 {unable to use function matchinfo in the requested context}}
#-------------------------------------------------------------------------
reset_db
do_test 75.0 {
sqlite3 db {}
db deserialize [decode_hexdb {
| size 32768 pagesize 4096 filename crash-033d665d5caa8d.db
| page 1 offset 0
| 0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00 SQLite format 3.
| 16: 10 00 01 01 00 40 20 20 00 00 00 00 00 00 00 00 .....@ ........
| 96: 00 00 00 00 0d 0f c7 00 07 0d 92 00 0f 8d 0f 36 ...............6
| 112: 0e cb 0e 6b 0e 0e 0d b6 0d 92 00 00 00 00 00 00 ...k............
| 3472: 00 00 22 08 06 17 11 11 01 31 74 61 62 6c 65 74 .........1tablet
| 3488: 32 74 32 08 43 52 45 41 54 45 20 54 41 42 4c 45 2t2.CREATE TABLE
| 3504: 20 74 32 28 78 29 56 07 06 17 1f 1f 01 7d 74 61 t2(x)V.......ta
| 3520: 62 6c 65 74 31 5f 63 6f 6e 66 69 67 74 31 5f 63 blet1_configt1_c
| 3536: 6f 6e 66 69 67 07 43 52 45 41 54 45 20 54 41 42 onfig.CREATE TAB
| 3552: 4c 45 20 27 74 31 5f 63 6f 6e 66 69 67 27 28 6b LE 't1_config'(k
| 3568: 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 76 29 PRIMARY KEY, v)
| 3584: 20 57 49 54 48 4f 55 54 20 52 4f 57 49 44 5b 06 WITHOUT ROWID[.
| 3600: 07 17 21 21 01 81 01 74 61 62 6c 65 74 31 5f 64 ..!!...tablet1_d
| 3616: 6f 63 73 69 7a 65 74 31 5f 64 6f 63 73 69 7a 65 ocsizet1_docsize
| 3632: 06 43 52 45 41 54 45 20 54 41 42 4c 45 20 27 74 .CREATE TABLE 't
| 3648: 31 5f 64 6f 63 73 69 7a 65 27 28 69 64 20 49 4e 1_docsize'(id IN
| 3664: 54 45 47 45 52 20 50 52 49 4d 54 52 59 20 4b 45 TEGER PRIMTRY KE
| 3680: 59 2c 20 73 7a 20 42 4c 4f 42 29 5e 05 07 17 21 Y, sz BLOB)^...!
| 3696: 21 01 81 07 74 61 62 6c 65 74 31 5f 63 6f 6e 74 !...tablet1_cont
| 3712: 65 6e 74 74 31 5f 63 6f 6e 74 65 6e 74 05 43 52 entt1_content.CR
| 3728: 45 41 54 45 20 54 41 42 4c 45 20 27 74 31 5f 63 EATE TABLE 't1_c
| 3744: 6f 6e 74 65 6e 74 27 28 69 64 20 49 4e 54 45 47 ontent'(id INTEG
| 3760: 45 52 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 ER PRIMARY KEY,
| 3776: 63 30 2c 20 63 31 2c d6 63 32 29 69 04 07 17 19 c0, c1,.c2)i....
| 3792: 19 01 81 2d 74 61 62 6c 65 74 31 5f 69 64 78 74 ...-tablet1_idxt
| 3808: 31 5f 69 64 78 04 43 52 45 41 54 45 20 54 41 42 1_idx.CREATE TAB
| 3824: 4c 45 20 27 74 31 5f 69 64 78 27 28 73 65 67 69 LE 't1_idx'(segi
| 3840: 64 2c 20 74 65 72 6d 2c 20 70 67 6e 6f 2c 20 50 d, term, pgno, P
| 3856: 52 49 4d 41 52 59 20 4b 45 59 28 73 65 67 69 64 RIMARY KEY(segid
| 3872: 2c 20 74 65 72 6d 29 29 20 57 49 54 48 4f 55 54 , term)) WITHOUT
| 3888: 20 52 4f 57 49 44 55 03 07 17 1b 1b 01 81 01 74 ROWIDU........t
| 3904: 61 62 6c 65 74 31 5f 64 61 74 61 74 31 5f 64 61 ablet1_datat1_da
| 3920: 74 61 03 43 52 45 41 54 45 20 54 41 42 4c 45 20 ta.CREATE TABLE
| 3936: 27 74 31 5f 64 61 74 61 27 28 69 64 20 49 4e 54 't1_data'(id INT
| 3952: 45 47 45 52 20 50 52 49 4d 41 52 59 20 4b 45 59 EGER PRIMARY KEY
| 3968: 2c 20 62 6c 6f 63 6b 20 42 4c 4f 42 29 38 02 06 , block BLOB)8..
| 3984: 17 11 11 08 5f 74 61 62 6c 65 74 31 74 31 43 52 ...._tablet1t1CR
| 4000: 45 41 54 45 20 56 49 52 54 55 41 4c 20 54 41 42 EATE VIRTUAL TAB
| 4016: 4c 45 20 74 31 20 55 53 49 4e 47 20 66 74 73 35 LE t1 USING fts5
| 4032: 28 61 2c 62 2c 63 29 00 00 00 00 00 00 00 00 00 (a,b,c).........
| page 3 offset 8192
| 0: 0d 00 00 00 03 0c 93 ff 0f e6 0f ef 0c 94 00 00 ................
| 3216: 00 00 00 00 86 4a 84 80 80 80 80 01 04 00 8d 18 .....J..........
| 3232: 00 00 03 2b 02 30 30 01 02 06 01 02 06 01 02 06 ...+.00.........
| 3248: 1f 02 03 01 02 03 01 02 03 01 08 32 31 31 36 30 ...........21160
| 3264: 36 30 39 01 02 07 01 02 07 01 02 07 01 01 33 f1 609...........3.
| 3280: 02 05 01 02 05 01 02 05 01 01 35 01 02 03 01 02 ..........5.....
| 3296: 04 01 02 04 02 07 30 30 30 30 30 30 30 1c 02 3d ......0000000..=
| 3312: 01 02 04 01 02 04 01 06 62 69 6e 61 72 79 03 06 ........binary..
| 3328: 01 02 02 03 06 01 01 f2 03 06 4e 02 02 03 06 01 ..........N.....
| 3344: 02 02 03 05 01 02 02 03 06 01 02 02 03 06 01 02 ................
| 3360: 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 02 ................
| 3376: 03 06 01 02 02 03 06 01 02 02 01 08 63 6f 6d 70 ............comp
| 3392: 69 6c 65 72 01 02 02 01 02 02 01 02 02 01 06 64 iler...........d
| 3408: 62 73 74 61 74 07 02 03 01 02 13 01 02 03 02 04 bstat...........
| 3424: 65 62 75 67 04 02 02 01 02 02 01 02 02 01 07 65 ebug...........e
| 3440: 6e 61 62 6c 65 07 02 02 01 02 02 01 02 02 01 02 nable...........
| 3456: 02 01 02 02 01 02 02 01 02 02 01 02 02 01 02 02 ................
| 3472: 01 02 02 01 02 02 01 02 01 f1 02 02 01 02 02 01 ................
| 3488: 02 02 01 02 02 01 02 02 01 02 02 01 02 02 01 02 ................
| 3504: 02 01 02 02 02 08 78 74 65 6e 73 69 6f 6e 1f 02 ......xtension..
| 3520: 04 01 02 04 01 02 04 01 04 66 74 73 34 0a 02 03 .........fts4...
| 3536: 01 02 03 01 02 03 04 01 25 0d 02 03 01 02 03 01 ........%.......
| 3552: 02 03 01 03 67 63 63 01 02 03 01 02 03 01 02 03 ....gcc.........
| 3568: 02 06 65 6f 70 6f 6c 79 0f f2 03 01 02 03 01 02 ..eopoly........
| 3584: 03 01 05 6a 73 6f 6e 31 13 02 03 01 02 03 01 02 ...json1........
| 3600: 03 01 04 6c 6f 61 64 1f 02 03 01 02 03 01 02 03 ...load.........
| 3616: 00 03 6d 61 78 1c 02 02 01 02 02 01 02 02 02 05 ..max...........
| 3632: 65 6d 6f 72 79 1c 02 03 01 02 03 01 02 03 04 04 emory...........
| 3648: 73 79 73 35 16 02 03 01 02 03 01 02 03 01 06 6e sys5...........n
| 3664: 6f 63 61 73 65 02 06 01 02 02 13 06 00 f2 02 03 ocase...........
| 3680: 06 01 02 02 13 06 01 02 02 03 06 01 02 02 03 06 ................
| 3696: 01 02 02 03 06 01 02 02 03 06 02 02 02 03 06 01 ................
| 3712: 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 ................
| 3728: 02 01 04 6f 6d 69 74 1f 02 02 01 02 02 01 02 b2 ...omit.........
| 3744: 01 0a 22 74 72 65 65 19 02 03 01 02 03 01 02 03 ...tree.........
| 3760: 04 02 69 6c f1 06 01 02 02 03 06 01 02 02 03 06 ..il............
| 3776: 01 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 ................
| 3792: 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 ................
| 3808: 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 02 ................
| 3824: 01 0a 74 68 72 65 61 64 73 61 66 65 22 02 02 01 ..threadsafe....
| 3840: 02 02 01 02 02 01 04 76 74 61 62 07 02 04 01 02 .......vtab.....
| 3856: 04 01 02 04 01 01 78 01 06 01 01 02 01 06 01 01 ......x.........
| 3872: 02 01 06 01 01 02 04 36 01 01 02 01 06 01 01 02 .......6........
| 3888: 01 06 01 11 02 01 06 01 01 02 01 06 01 01 02 01 ................
| 3904: 06 01 01 02 01 06 01 01 02 01 06 01 01 02 01 06 ................
| 3920: 01 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 ................
| 3936: 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 01 ................
| 3952: 02 01 06 01 01 01 f1 06 01 01 02 ad 06 01 01 02 ................
| 3968: 01 06 01 01 02 01 06 01 01 02 01 06 01 01 02 01 ................
| 3984: 06 01 01 01 01 06 01 01 02 01 06 01 01 02 01 06 ................
| 4000: 01 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 ................
| 4016: 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 01 ................
| 4032: 02 01 06 01 01 02 01 06 01 01 02 04 15 13 0c 0c ................
| 4048: 12 44 13 11 0f 47 13 0e fc 0e 11 10 0f 0e 10 0f .D...G..........
| 4064: 44 0f 10 40 15 0f 07 01 03 00 14 24 5a 24 24 0f D..@.......$Z$$.
| 4080: 0a 03 00 24 00 00 00 00 01 01 01 00 01 01 01 01 ...$............
| page 4 offset 12288
| 0: 0a 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
| 4080: 00 00 00 00 00 00 00 00 00 00 05 04 09 0c 01 02 ................
| page 5 offset 16384
| 0: 0d 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
| 3072: 00 00 00 00 00 00 00 00 00 00 18 24 05 00 25 0f ...........$..%.
| 3088: 19 54 48 52 45 41 44 53 41 46 45 3d 30 58 42 49 .THREADSAFE=0XBI
| 3104: 4e 41 52 59 18 23 05 00 25 0f 19 54 48 52 45 41 NARY.#..%..THREA
| 3120: 44 53 41 46 45 3d 30 58 4e 4f 43 41 53 45 17 8f DSAFE=0XNOCASE..
| 3136: 05 00 25 0f 17 54 48 52 45 41 44 53 41 46 45 3d ..%..THREADSAFE=
| 3152: 30 58 52 54 52 49 4d 1f 21 05 00 33 0f 19 45 ed 0XRTRIM.!..3..E.
| 3168: 49 54 20 4c 4f 41 44 21 45 58 54 45 4e 53 49 4f IT LOAD!EXTENSIO
| 3184: 4e 58 42 49 4e 41 52 59 1f 20 05 00 33 0f 19 4f NXBINARY. ..3..O
| 3200: 4d 49 54 20 4c 4f 41 44 20 45 58 54 45 4e 5a 29 MIT LOAD EXTENZ)
| 3216: 4f 4e 58 4e 4f 43 41 53 45 1e 1f 05 00 33 0f 17 ONXNOCASE....3..
| 3232: 4f 4d 59 54 20 4c 4f 41 44 20 45 58 54 45 4e 53 OMYT LOAD EXTENS
| 3248: 49 4f 4e 58 52 54 56 a9 4d 1f 1e 05 00 33 0f 19 IONXRTV.M....3..
| 3264: 4d 41 58 20 4d 45 4d 4f 52 59 3d 25 30 30 30 30 MAX MEMORY=%0000
| 3280: 30 30 30 57 42 49 4e 31 52 59 1f 1d 05 00 33 0f 000WBIN1RY....3.
| 3296: 19 4d 41 58 20 4d 45 4d 4f 52 59 3d 35 30 30 30 .MAX MEMORY=5000
| 3312: 30 30 30 30 58 4e 4f 43 41 53 45 1e 1c 05 00 32 0000XNOCASE....2
| 3328: 0e 17 4e 41 58 20 4d 45 4d 4f 52 59 2d 35 30 30 ..NAX MEMORY-500
| 3344: 30 30 30 30 30 58 52 54 52 49 4d 18 1b 05 00 25 00000XRTRIM....%
| 3360: 0f 19 45 4e 41 42 4c 45 20 52 54 52 45 45 58 42 ..ENABLE RTREEXB
| 3376: 49 4e 41 52 59 18 1a 05 00 25 0f 19 45 4e 41 42 INARY....%..ENAB
| 3392: 4c 45 20 52 54 52 45 45 59 4e 4f 43 41 53 45 17 LE RTREEYNOCASE.
| 3408: 19 66 00 25 0f 17 45 4e 41 42 4c 45 20 52 54 52 .f.%..ENABLE RTR
| 3424: 45 45 58 52 54 52 49 4d 1a 18 05 00 29 0f 19 45 EEXRTRIM....)..E
| 3440: 4e 41 42 4c 45 20 4d 45 4d 53 59 53 35 58 42 49 NABLE MEMSYS5XBI
| 3456: 4e 41 52 59 1a 17 05 00 29 0f 19 45 4e 41 42 4c NARY....)..ENABL
| 3472: 45 20 4d 45 4d 53 59 53 35 58 4e 4f 43 41 53 45 E MEMSYS5XNOCASE
| 3488: 19 16 05 00 29 0f 17 45 4e 41 42 4c 45 20 4d 45 ....)..ENABLE ME
| 3504: 4d 53 59 76 35 58 52 54 52 49 4d 18 15 05 10 25 MSYv5XRTRIM....%
| 3520: 0f 19 45 4e 40 42 4c 45 20 4a 53 4f 4e 31 58 42 ..EN@BLE JSON1XB
| 3536: 49 4e 41 52 59 18 14 05 00 25 0f 19 45 4e 41 42 INARY....%..ENAB
| 3552: 4c 45 20 4a 53 4f 4e 32 58 4e 4f 43 41 53 45 17 LE JSON2XNOCASE.
| 3568: 13 05 00 25 0f 17 45 4e 41 42 4c 45 20 4a 53 4f ...%..ENABLE JSO
| 3584: 4e 31 58 52 54 52 49 4d 1a 12 05 00 29 0f 19 45 N1XRTRIM....)..E
| 3600: 4e 41 42 4c 45 20 47 45 4f 50 4f 4c 59 58 42 49 NABLE GEOPOLYXBI
| 3616: 4e 41 52 59 1a 11 05 00 29 0f 19 45 5f 81 42 4c NARY....)..E_.BL
| 3632: 45 20 47 45 4f 50 4f 4c 59 58 4e 4f 43 51 53 45 E GEOPOLYXNOCQSE
| 3648: 19 10 05 00 29 0f 17 45 4e 41 42 4c 45 20 47 45 ....)..ENABLE GE
| 3664: 4f 50 4f 4c 59 58 52 54 52 49 4d 17 0f 05 00 23 OPOLYXRTRIM....#
| 3680: 0f 1a 45 4e 41 42 4c 45 20 56 54 43 35 58 42 49 ..ENABLE VTC5XBI
| 3696: 4e 41 52 59 17 0e 05 00 23 0f 19 45 4e 41 42 4c NARY....#..ENABL
| 3712: 45 20 46 54 53 35 48 4e 4f 43 41 53 45 16 1d 05 E FTS5HNOCASE...
| 3728: 00 23 0f a4 45 4e 41 42 4c 45 20 46 54 53 35 58 .#..ENABLE FTS5X
| 3744: 52 54 52 49 4d b7 0c 05 00 23 0f 19 45 4e 41 42 RTRIM....#..ENAB
| 3760: 4c 45 20 46 55 53 34 58 42 49 4e 41 52 59 17 0b LE FUS4XBINARY..
| 3776: 05 00 23 0f 19 45 4e 41 42 4c 45 20 46 54 53 34 ..#..ENABLE FTS4
| 3792: 57 4e 4f 43 41 53 45 16 0a 05 00 21 7f 17 45 4e WNOCASE....!..EN
| 3808: 41 42 4c 45 20 46 54 53 34 05 52 54 52 49 4d 1e ABLE FTS4.RTRIM.
| 3824: 09 05 00 31 0f 19 45 4e 41 42 4c 45 20 44 42 53 ...1..ENABLE DBS
| 3840: 54 41 54 20 56 54 41 42 58 42 49 4e 41 52 59 1e TAT VTABXBINARY.
| 3856: 08 05 00 31 0f 19 45 4e 41 42 4c 45 20 44 42 53 ...1..ENABLE DBS
| 3872: 54 41 54 20 56 54 41 42 58 4e 4f 43 41 53 45 1d TAT VTABXNOCASE.
| 3888: 07 05 00 31 0f 17 45 4e 41 42 4c 45 20 44 42 53 ...1..ENABLE DBS
| 3904: 54 41 54 20 56 54 41 42 58 52 54 52 49 4d 11 06 TAT VTABXRTRIM..
| 3920: 05 00 17 0f 19 44 45 42 55 47 58 42 49 4e 41 52 .....DEBUGXBINAR
| 3936: 59 11 05 05 00 17 0f 19 44 45 42 55 47 58 4e 4f Y.......DEBUGXNO
| 3952: 43 41 53 45 10 04 05 00 17 0f 17 44 45 42 55 47 CASE.......DEBUG
| 3968: 58 52 54 52 49 4d 27 03 05 00 43 0f 19 43 4f 4d XRTRIM'...C..COM
| 3984: 50 49 4c 45 52 3d 67 63 63 2d 35 2e 34 2e 30 20 PILER=gcc-5.4.0
| 4000: 32 30 31 36 30 36 30 39 58 42 49 4e 41 52 59 27 20160609XBINARY'
| 4016: 02 05 00 43 0f 19 43 4f 4d 50 49 4c 45 52 3f 87 ...C..COMPILER?.
| 4032: 63 63 2d 35 2e 34 2e 30 20 32 30 31 36 30 36 30 cc-5.4.0 2016060
| 4048: 39 58 4e 4f 43 41 53 45 26 01 05 00 43 0f 17 00 9XNOCASE&...C...
| page 6 offset 20480
| 3808: 06 24 03 00 12 02 01 01 06 23 03 00 12 02 01 01 .$.......#......
| 3824: 06 22 03 01 12 02 01 01 06 21 03 00 12 03 01 01 .........!......
| 3840: 06 20 03 00 12 03 01 01 06 1f 03 00 12 03 02 01 . ..............
| 3856: 06 1e 03 00 12 03 01 01 06 1d 03 00 12 03 01 01 ................
| 3872: 06 1c 03 00 12 03 01 01 06 1b 03 00 12 02 01 01 ................
| 3888: 06 1a 03 00 12 02 01 01 06 19 03 00 12 02 01 01 ................
| 3904: 06 18 03 00 12 02 01 01 06 17 03 00 12 02 01 01 ................
| 3920: 06 16 03 00 12 02 01 01 06 15 03 00 12 02 01 01 ................
| 3936: 06 14 03 00 12 02 01 01 06 13 03 00 12 02 01 01 ................
| 3952: 06 12 03 00 12 02 01 01 06 11 03 00 12 02 01 01 ................
| 3968: 06 00 03 00 12 02 01 01 06 0f 03 00 12 02 01 01 ................
| 3984: 06 0e 03 00 12 02 01 01 06 0d 03 00 12 02 01 01 ................
| 4000: 06 0c 03 00 12 02 01 01 06 0b 03 10 12 02 01 01 ................
| 4016: 06 0a 03 00 12 02 01 01 06 09 03 01 12 03 01 01 ................
| 4032: 06 08 03 00 12 03 01 01 06 07 03 00 12 03 01 01 ................
| 4048: 07 06 03 00 12 01 01 01 06 05 03 00 12 01 01 01 ................
| 4064: 06 04 03 00 12 01 01 01 06 03 03 00 12 06 01 01 ................
| 4080: 06 02 03 00 12 06 01 01 06 01 03 00 12 06 01 01 ................
| page 7 offset 24576
| 0: 0a 00 00 00 01 0f f4 00 0f f4 00 00 00 00 00 00 ................
| 4080: 00 00 00 00 0b 03 1b 01 76 65 72 73 69 6f 6e 04 ........version.
| page 8 offset 28672
| 4048: 00 00 00 00 00 00 5d 03 02 2b 69 6e 74 00 00 00 ......]..+int...
| end crash-033d665d5caa8d.db
}]} {}
do_catchsql_test 75.1 {
SELECT rowid, quote(matchinfo(t1,'pcxybs')) FROM t1 WHERE t1 MATCH 'e*';
} {1 {database disk image is malformed}}
#-------------------------------------------------------------------------
reset_db
do_test 76.0 {
sqlite3 db {}
db deserialize [decode_hexdb {
| size 40960 pagesize 4096 filename crash-03b68c01d30713.db
| page 1 offset 0
| 0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00 SQLite format 3.
| 16: 10 00 01 01 00 40 20 20 00 00 00 00 00 00 00 0a .....@ ........
| 32: 00 00 00 00 00 00 00 00 00 00 00 0d 00 00 00 04 ................
| 96: 00 00 00 00 0d 00 00 00 0d 0b 6e 00 0f a3 0f 4c ..........n....L
| 112: 0e e1 0e 81 0e 24 0d cc 0d 72 0d 1b 0c b0 0c 50 .....$...r.....P
| 128: 0b f8 0b b3 0b 6e 01 00 00 00 00 00 00 00 00 00 .....n..........
| 2912: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 43 0d ..............C.
| 2928: 06 17 11 11 08 75 74 61 62 6c 65 74 34 74 34 43 .....utablet4t4C
| 2944: 52 45 41 54 45 20 56 49 52 54 55 41 4c 20 54 41 REATE VIRTUAL TA
| 2960: 42 4c 45 20 74 34 20 55 53 49 4e 47 20 66 74 73 BLE t4 USING fts
| 2976: 35 76 6f 63 61 62 28 27 74 32 27 2c 20 27 72 6f 5vocab('t2', 'ro
| 2992: 77 27 29 43 0c 06 17 11 11 08 75 74 61 62 6c 65 w')C......utable
| 3008: 74 33 74 33 43 52 45 41 54 45 20 56 49 52 54 55 t3t3CREATE VIRTU
| 3024: 41 4c 20 54 41 42 4c 45 20 74 33 20 55 53 49 4e AL TABLE t3 USIN
| 3040: 47 20 66 74 73 35 76 6f 63 61 62 28 27 74 31 27 G fts5vocab('t1'
| 3056: 2c 20 27 72 6f 77 27 29 56 0b 06 17 1f 1f 01 7d , 'row')V.......
| 3072: 74 61 62 6c 65 74 32 5f 63 6f 6e 66 69 67 74 32 tablet2_configt2
| 3088: 5f 63 6f 6e 66 69 67 0a 43 52 45 41 54 45 20 54 _config.CREATE T
| 3104: 41 42 4c 45 20 27 74 32 5f 63 6f 6e 66 69 67 27 ABLE 't2_config'
| 3120: 28 6b 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 (k PRIMARY KEY,
| 3136: 76 29 20 57 49 54 48 4f 55 54 20 52 4f 57 49 44 v) WITHOUT ROWID
| 3152: 5e 0a 07 17 21 21 01 81 07 74 61 62 6c 65 74 32 ^...!!...tablet2
| 3168: 5f 63 6f 6e 74 65 6e 74 74 32 5f 63 6f 6e 74 65 _contentt2_conte
| 3184: 6e 74 09 43 52 45 41 54 45 20 54 41 42 4c 45 20 nt.CREATE TABLE
| 3200: 27 74 32 5f 63 6f 6e 74 65 6e 74 27 28 69 64 20 't2_content'(id
| 3216: 49 4e 54 45 47 45 52 20 50 52 49 4d 41 52 59 20 INTEGER PRIMARY
| 3232: 4b 45 59 2c 20 63 30 2c 20 63 31 2c 20 63 32 29 KEY, c0, c1, c2)
| 3248: 69 09 07 17 19 19 01 81 2d 74 61 62 6c 65 74 32 i.......-tablet2
| 3264: 5f 69 64 78 74 32 5f 69 64 78 08 43 52 45 41 54 _idxt2_idx.CREAT
| 3280: 45 20 54 41 42 4c 45 20 27 74 32 5f 69 64 78 27 E TABLE 't2_idx'
| 3296: 28 73 65 67 69 64 2c 20 74 65 72 6d 2c 20 70 67 (segid, term, pg
| 3312: 6e 6f 2c 20 50 52 49 4d 41 52 59 20 4b 45 59 28 no, PRIMARY KEY(
| 3328: 73 65 67 69 64 2c 20 74 65 72 6d 29 29 20 57 49 segid, term)) WI
| 3344: 54 48 4f 55 54 20 52 4f 57 49 44 55 08 07 17 1b THOUT ROWIDU....
| 3360: 1b 01 81 01 74 61 62 6c 65 74 32 5f 64 61 74 61 ....tablet2_data
| 3376: 74 32 5f 64 61 74 61 07 43 52 45 41 54 45 20 54 t2_data.CREATE T
| 3392: 41 42 4c 45 20 27 74 32 5f 64 61 74 61 27 28 69 ABLE 't2_data'(i
| 3408: 64 20 49 4e 54 45 47 45 52 20 50 52 49 4d 41 52 d INTEGER PRIMAR
| 3424: 59 20 4b 45 59 2c 20 62 6c 6f 63 6b 20 42 4c 4f Y KEY, block BLO
| 3440: 42 29 58 07 07 17 11 11 08 81 1d 74 61 62 6c 65 B)X........table
| 3456: 74 32 74 32 43 52 45 41 54 45 20 56 49 52 54 55 t2t2CREATE VIRTU
| 3472: 41 4c 20 54 41 42 4c 45 20 74 32 20 55 53 49 4e AL TABLE t2 USIN
| 3488: 47 20 66 74 73 35 28 27 61 27 2c 5b 62 5d 2c 22 G fts5('a',[b],.
| 3504: 63 22 2c 64 65 74 61 69 6c 3d 6e 6f 6e 65 2c 63 c.,detail=none,c
| 3520: 6f 6c 75 6d 6e 73 69 7a 65 3d 30 29 56 06 06 17 olumnsize=0)V...
| 3536: 1f 1f 01 7d 74 61 62 6c 65 74 31 5f 63 6f 6e 66 ....tablet1_conf
| 3552: 69 67 74 31 5f 63 6f 6e 66 69 67 06 43 52 45 41 igt1_config.CREA
| 3568: 54 45 20 54 41 42 4c 45 20 27 74 31 5f 63 6f 6e TE TABLE 't1_con
| 3584: 66 69 67 27 28 6b 20 50 52 49 4d 41 52 59 20 4b fig'(k PRIMARY K
| 3600: 45 59 2c 20 76 29 20 57 49 54 48 4f 55 54 20 52 EY, v) WITHOUT R
| 3616: 4f 57 49 44 5b 05 07 17 21 21 01 81 01 74 61 62 OWID[...!!...tab
| 3632: 6c 65 74 31 5f 64 6f 63 73 69 7a 65 74 31 5f 64 let1_docsizet1_d
| 3648: 6f 63 73 69 7a 65 05 43 52 45 41 54 45 20 54 41 ocsize.CREATE TA
| 3664: 42 4c 45 20 27 74 31 5f 64 6f 63 73 69 7a 65 27 BLE 't1_docsize'
| 3680: 28 69 64 20 49 4e 54 45 47 45 52 20 50 52 49 4d (id INTEGER PRIM
| 3696: 41 52 59 20 4b 45 59 2c 20 73 7a 20 42 4c 4f 42 ARY KEY, sz BLOB
| 3712: 29 5e 04 07 17 21 21 01 81 07 74 61 62 6c 65 74 )^...!!...tablet
| 3728: 31 5f 63 6f 6e 74 65 6e 74 74 31 5f 63 6f 6e 74 1_contentt1_cont
| 3744: 65 6e 74 04 43 52 45 41 54 45 20 54 41 42 4c 45 ent.CREATE TABLE
| 3760: 20 27 74 31 5f 63 6f 6e 74 65 6e 74 27 28 69 64 't1_content'(id
| 3776: 20 49 4e 54 45 47 45 52 20 50 52 49 4d 41 52 59 INTEGER PRIMARY
| 3792: 20 4b 45 59 2c 20 63 30 2c 20 63 31 2c 20 63 32 KEY, c0, c1, c2
| 3808: 29 69 03 07 17 19 19 01 81 2d 74 61 62 6c 65 74 )i.......-tablet
| 3824: 31 5f 69 64 78 74 31 5f 69 64 78 03 43 52 45 41 1_idxt1_idx.CREA
| 3840: 54 45 20 54 41 42 4c 45 20 27 74 31 5f 69 64 78 TE TABLE 't1_idx
| 3856: 27 28 73 65 67 69 64 2c 20 74 65 72 6d 2c 20 70 '(segid, term, p
| 3872: 67 6e 6f 2c 20 50 52 49 4d 41 52 59 20 4b 45 59 gno, PRIMARY KEY
| 3888: 28 73 65 67 69 64 2c 20 74 65 72 6d 29 29 20 57 (segid, term)) W
| 3904: 49 54 48 4f 55 54 20 52 4f 57 49 44 55 02 07 17 ITHOUT ROWIDU...
| 3920: 1b 1b 01 81 01 74 61 62 6c 65 74 31 5f 64 61 74 .....tablet1_dat
| 3936: 61 74 31 5f 64 61 74 61 02 43 52 45 41 54 45 20 at1_data.CREATE
| 3952: 54 41 42 4c 45 20 27 74 31 5f 64 61 74 61 27 28 TABLE 't1_data'(
| 3968: 69 64 20 49 4e 54 45 47 45 52 20 50 52 49 4d 41 id INTEGER PRIMA
| 3984: 52 59 20 4b 45 59 2c 20 62 6c 6f 63 6b 20 42 4c RY KEY, block BL
| 4000: 4f 42 29 5b 01 07 17 11 11 08 81 23 74 61 62 6c OB)[.......#tabl
| 4016: 65 74 31 74 31 43 52 45 41 54 45 20 56 49 52 54 et1t1CREATE VIRT
| 4032: 55 41 4c 20 54 41 42 4c 45 20 74 31 20 55 53 49 UAL TABLE t1 USI
| 4048: 4e 47 20 66 74 73 35 28 61 2c 62 20 75 6e 69 65 NG fts5(a,b unie
| 4064: 24 65 78 65 64 2c 63 2c 74 6f 6b 65 6e 69 7a 65 $exed,c,tokenize
| 4080: 3d 22 70 6f 72 74 65 72 20 61 73 63 69 69 22 29 =.porter ascii.)
| page 2 offset 4096
| 0: 0d 0f 68 00 05 0f 13 00 0f e6 0f 13 0f a8 00 00 ..h.............
| 3856: 00 00 00 15 0a 03 00 30 00 00 00 00 01 03 03 00 .......0........
| 3872: 03 01 01 01 02 01 01 03 01 01 37 8c 80 80 80 80 ..........7.....
| 3888: 01 03 00 74 00 20 68 20 69 0d 00 00 00 03 0f e8 ...t. h i.......
| page 5 offset 16384
| 4064: 00 00 00 00 00 00 00 00 06 03 03 00 12 03 00 00 ................
| 4080: 60 20 30 d6 20 30 00 30 60 10 30 01 20 30 00 30 ` 0. 0.0`.0. 0.0
| page 6 offset 20480
| 0: a0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
| 4080: 00 00 00 00 0b 03 1b 01 76 65 72 73 69 6f 6e 04 ........version.
| page 7 offset 24576
| 0: 0d 00 00 00 03 0f 9e 00 0f e6 0f ef 0f 9e 00 00 ................
| 16: 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 ................
| 3984: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 41 84 ..............A.
| 4000: 80 80 80 80 01 04 00 81 06 00 00 00 34 02 30 61 ............4.0a
| 4016: 01 00 ff ff ff ff ff ff ff ff ff 11 87 89 06 26 ...............&
| 4032: 01 64 01 01 01 65 01 01 01 66 01 01 01 66 01 01 .d...e...f...f..
| 4048: 01 01 01 68 01 01 01 01 01 69 01 01 01 04 01 56 ...h.....i.....V
| 4064: 06 04 44 00 06 06 07 01 03 00 14 03 09 09 09 0f ..D.............
| 4080: 0a 03 00 24 00 00 00 00 01 01 01 00 01 01 01 01 ...$............
| page 8 offset 28672
| 0: 0a 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 ................
| 4080: 00 00 00 00 00 00 00 00 00 00 05 04 09 1c 01 02 ................
| page 9 offset 32768
| 0: 0d 00 00 00 9d 0f be 00 0f ea 0f d4 0f be 00 00 ................
| 4016: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 14 03 ................
| 4032: 05 00 17 17 17 61 20 62 20 63 67 20 68 20 69 67 .....a b cg h ig
| 4048: 20 68 20 69 14 02 05 00 17 17 17 67 20 68 20 69 h i.......g h i
| 4064: 61 20 62 20 63 67 20 68 20 69 14 01 04 ff 17 17 a b cg h i......
| 4080: 17 61 20 62 20 63 64 20 65 20 66 67 20 68 20 69 .a b cd e fg h i
| page 10 offset 36864
| 0: 0a 00 00 00 01 0f f4 00 0f f4 00 00 00 00 00 01 ................
| 4080: 00 00 00 00 0b 03 1b 01 76 65 72 73 69 6f 6e 04 ........version.
| end crash-03b68c01d30713.db
}]} {}
do_catchsql_test 76.1 {
SELECT * FROM t4;
} {1 {database disk image is malformed}}
sqlite3_fts5_may_be_corrupt 0
+14
View File
@@ -579,6 +579,18 @@ static int cksmFileControl(sqlite3_file *pFile, int op, void *pArg){
}else if( op==SQLITE_FCNTL_CKPT_START || op==SQLITE_FCNTL_CKPT_DONE ){
p->inCkpt = op==SQLITE_FCNTL_CKPT_START;
if( p->pPartner ) p->pPartner->inCkpt = p->inCkpt;
}else if( op==SQLITE_FCNTL_CKSM_FILE ){
/* This VFS needs to obtain a pointer to the corresponding database
** file handle from within xOpen() calls to open wal files. To do this,
** it uses the sqlite3_database_file_object() API to obtain a pointer
** to the file-handle used by SQLite to access the db file. This is
** fine if cksmvfs happens to be the top-level VFS, but not if there
** are one or more wrapper VFS. To handle this case, this file-control
** is used to extract the cksmvfs file-handle from any wrapper file
** handle. */
sqlite3_file **ppFile = (sqlite3_file**)pArg;
*ppFile = (sqlite3_file*)p;
return SQLITE_OK;
}
rc = pFile->pMethods->xFileControl(pFile, op, pArg);
if( rc==SQLITE_OK && op==SQLITE_FCNTL_VFSNAME ){
@@ -688,6 +700,8 @@ static int cksmOpen(
if( rc ) goto cksm_open_done;
if( flags & SQLITE_OPEN_WAL ){
sqlite3_file *pDb = sqlite3_database_file_object(zName);
rc = pDb->pMethods->xFileControl(pDb, SQLITE_FCNTL_CKSM_FILE, (void*)&pDb);
assert( rc==SQLITE_OK );
p->pPartner = (CksmFile*)pDb;
assert( p->pPartner->pPartner==0 );
p->pPartner->pPartner = p;
+5 -4
View File
@@ -459,10 +459,11 @@ static void decimalSubFunc(
Decimal *pA = decimal_new(context, argv[0], 0, 0);
Decimal *pB = decimal_new(context, argv[1], 0, 0);
UNUSED_PARAMETER(argc);
if( pB==0 ) return;
pB->sign = !pB->sign;
decimal_add(pA, pB);
decimal_result(context, pA);
if( pB ){
pB->sign = !pB->sign;
decimal_add(pA, pB);
decimal_result(context, pA);
}
decimal_free(pA);
decimal_free(pB);
}
+2 -2
View File
@@ -299,7 +299,7 @@ static void jsonAppendSeparator(JsonString *p){
*/
static void jsonAppendString(JsonString *p, const char *zIn, u32 N){
u32 i;
if( (N+p->nUsed+2 >= p->nAlloc) && jsonGrow(p,N+2)!=0 ) return;
if( zIn==0 || ((N+p->nUsed+2 >= p->nAlloc) && jsonGrow(p,N+2)!=0) ) return;
p->zBuf[p->nUsed++] = '"';
for(i=0; i<N; i++){
unsigned char c = ((unsigned const char*)zIn)[i];
@@ -2003,8 +2003,8 @@ static void jsonObjectStep(
jsonAppendChar(pStr, '{');
}else if( pStr->nUsed>1 ){
jsonAppendChar(pStr, ',');
pStr->pCtx = ctx;
}
pStr->pCtx = ctx;
z = (const char*)sqlite3_value_text(argv[0]);
n = (u32)sqlite3_value_bytes(argv[0]);
jsonAppendString(pStr, z, n);
+37 -29
View File
@@ -36,10 +36,24 @@ SQLITE_EXTENSION_INIT1
#ifndef SQLITE_AMALGAMATION
#ifndef UINT32_TYPE
# ifdef HAVE_UINT32_T
# define UINT32_TYPE uint32_t
# else
# define UINT32_TYPE unsigned int
# endif
#endif
#ifndef UINT16_TYPE
# ifdef HAVE_UINT16_T
# define UINT16_TYPE uint16_t
# else
# define UINT16_TYPE unsigned short int
# endif
#endif
typedef sqlite3_int64 i64;
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned long u32;
typedef UINT32_TYPE u32; /* 4-byte unsigned integer */
typedef UINT16_TYPE u16; /* 2-byte unsigned integer */
#define MIN(a,b) ((a)<(b) ? (a) : (b))
#if defined(SQLITE_COVERAGE_TEST) || defined(SQLITE_MUTATION_TEST)
@@ -706,34 +720,24 @@ static int zipfileScanExtra(u8 *aExtra, int nExtra, u32 *pmTime){
** https://msdn.microsoft.com/en-us/library/9kkf9tah.aspx
*/
static u32 zipfileMtime(ZipfileCDS *pCDS){
int Y = (1980 + ((pCDS->mDate >> 9) & 0x7F));
int M = ((pCDS->mDate >> 5) & 0x0F);
int D = (pCDS->mDate & 0x1F);
int B = -13;
int sec = (pCDS->mTime & 0x1F)*2;
int min = (pCDS->mTime >> 5) & 0x3F;
int hr = (pCDS->mTime >> 11) & 0x1F;
i64 JD;
/* JD = INT(365.25 * (Y+4716)) + INT(30.6001 * (M+1)) + D + B - 1524.5 */
/* Calculate the JD in seconds for noon on the day in question */
if( M<3 ){
Y = Y-1;
M = M+12;
int Y,M,D,X1,X2,A,B,sec,min,hr;
i64 JDsec;
Y = (1980 + ((pCDS->mDate >> 9) & 0x7F));
M = ((pCDS->mDate >> 5) & 0x0F);
D = (pCDS->mDate & 0x1F);
sec = (pCDS->mTime & 0x1F)*2;
min = (pCDS->mTime >> 5) & 0x3F;
hr = (pCDS->mTime >> 11) & 0x1F;
if( M<=2 ){
Y--;
M += 12;
}
JD = (i64)(24*60*60) * (
(int)(365.25 * (Y + 4716))
+ (int)(30.6001 * (M + 1))
+ D + B - 1524
);
/* Correct the JD for the time within the day */
JD += (hr-12) * 3600 + min * 60 + sec;
/* Convert JD to unix timestamp (the JD epoch is 2440587.5) */
return (u32)(JD - (i64)(24405875) * 24*60*6);
X1 = 36525*(Y+4716)/100;
X2 = 306001*(M+1)/10000;
A = Y/100;
B = 2 - A + (A/4);
JDsec = (i64)((X1 + X2 + D + B - 1524.5)*86400) + hr*3600 + min*60 + sec;
return (u32)(JDsec - (i64)24405875*(i64)8640);
}
/*
@@ -2170,6 +2174,10 @@ static int zipfileRegister(sqlite3 *db){
zipfileStep, zipfileFinal
);
}
assert( sizeof(i64)==8 );
assert( sizeof(u32)==4 );
assert( sizeof(u16)==2 );
assert( sizeof(u8)==1 );
return rc;
}
#else /* SQLITE_OMIT_VIRTUALTABLE */
+5
View File
@@ -132,6 +132,11 @@ foreach {tn3 create_vfs destroy_vfs} {
} {
sqlite3rbu_destroy_vfs myrbu
}
3 {
sqlite3_register_cksumvfs
} {
sqlite3_unregister_cksumvfs
}
} {
eval $create_vfs
+9 -21
View File
@@ -1620,7 +1620,9 @@ char *rbuVacuumIndexStart(
zSep = "";
for(iCol=0; iCol<pIter->nCol; iCol++){
const char *zQuoted = (const char*)sqlite3_column_text(pSel, iCol);
if( zQuoted[0]=='N' ){
if( zQuoted==0 ){
p->rc = SQLITE_NOMEM;
}else if( zQuoted[0]=='N' ){
bFailed = 1;
break;
}
@@ -4992,28 +4994,14 @@ static int rbuVfsOpen(
rbu_file *pDb = rbuFindMaindb(pRbuVfs, zName, 0);
if( pDb ){
if( pDb->pRbu && pDb->pRbu->eStage==RBU_STAGE_OAL ){
/* This call is to open a *-wal file. Intead, open the *-oal. This
** code ensures that the string passed to xOpen() is terminated by a
** pair of '\0' bytes in case the VFS attempts to extract a URI
** parameter from it. */
const char *zBase = zName;
size_t nCopy;
char *zCopy;
/* This call is to open a *-wal file. Intead, open the *-oal. */
size_t nOpen;
if( rbuIsVacuum(pDb->pRbu) ){
zBase = sqlite3_db_filename(pDb->pRbu->dbRbu, "main");
zBase = sqlite3_filename_wal(zBase);
}
nCopy = strlen(zBase);
zCopy = sqlite3_malloc64(nCopy+2);
if( zCopy ){
memcpy(zCopy, zBase, nCopy);
zCopy[nCopy-3] = 'o';
zCopy[nCopy] = '\0';
zCopy[nCopy+1] = '\0';
zOpen = (const char*)(pFd->zDel = zCopy);
}else{
rc = SQLITE_NOMEM;
zOpen = sqlite3_db_filename(pDb->pRbu->dbRbu, "main");
zOpen = sqlite3_filename_wal(zOpen);
}
nOpen = strlen(zOpen);
((char*)zOpen)[nOpen-3] = 'o';
pFd->pRbu = pDb->pRbu;
}
pDb->pWalFd = pFd;
+103
View File
@@ -0,0 +1,103 @@
# 2014 August 16
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
# May you find forgiveness for yourself and forgive others.
# May you share freely, never taking more than you give.
#
#***********************************************************************
#
# This file implements regression tests for sessions SQLite extension.
# Specifically, this file contains tests for "patchset" changes.
#
if {![info exists testdir]} {
set testdir [file join [file dirname [info script]] .. .. test]
}
source [file join [file dirname [info script]] session_common.tcl]
source $testdir/tester.tcl
ifcapable !session {finish_test; return}
if {[permutation]=="session_strm" || [permutation]=="session_eec"} {
finish_test
return
}
set testprefix sessionbig
forcedelete test.db2
sqlite3 db2 test.db2
do_execsql_test 1.0 {
CREATE TABLE t1(a INTEGER PRIMARY KEY, b);
}
do_execsql_test -db db2 1.1 {
CREATE TABLE t1(a INTEGER PRIMARY KEY, b);
}
do_test 1.2 {
do_then_apply_sql {
INSERT INTO t1(b) VALUES( zeroblob(100*1000*1000) );
INSERT INTO t1(b) VALUES( zeroblob(100*1000*1000) );
INSERT INTO t1(b) VALUES( zeroblob(100*1000*1000) );
INSERT INTO t1(b) VALUES( zeroblob(100*1000*1000) );
INSERT INTO t1(b) VALUES( zeroblob(100*1000*1000) );
INSERT INTO t1(b) VALUES( zeroblob(100*1000*1000) );
INSERT INTO t1(b) VALUES( zeroblob(100*1000*1000) );
INSERT INTO t1(b) VALUES( zeroblob(100*1000*1000) );
INSERT INTO t1(b) VALUES( zeroblob(100*1000*1000) );
INSERT INTO t1(b) VALUES( zeroblob(100*1000*1000) );
INSERT INTO t1(b) VALUES( zeroblob(100*1000*1000) );
INSERT INTO t1(b) VALUES( zeroblob(100*1000*1000) );
INSERT INTO t1(b) VALUES( zeroblob(100*1000*1000) );
INSERT INTO t1(b) VALUES( zeroblob(100*1000*1000) );
INSERT INTO t1(b) VALUES( zeroblob(100*1000*1000) );
}
} {}
do_test 1.3 {
execsql { DELETE FROM t1 }
execsql2 { DELETE FROM t1 }
} {}
do_test 1.4 {
set rc [catch {
do_then_apply_sql {
INSERT INTO t1(b) VALUES( zeroblob(100*1000*1000) );
INSERT INTO t1(b) VALUES( zeroblob(100*1000*1000) );
INSERT INTO t1(b) VALUES( zeroblob(100*1000*1000) );
INSERT INTO t1(b) VALUES( zeroblob(100*1000*1000) );
INSERT INTO t1(b) VALUES( zeroblob(100*1000*1000) );
INSERT INTO t1(b) VALUES( zeroblob(100*1000*1000) );
INSERT INTO t1(b) VALUES( zeroblob(100*1000*1000) );
INSERT INTO t1(b) VALUES( zeroblob(100*1000*1000) );
INSERT INTO t1(b) VALUES( zeroblob(100*1000*1000) );
INSERT INTO t1(b) VALUES( zeroblob(100*1000*1000) );
INSERT INTO t1(b) VALUES( zeroblob(100*1000*1000) );
INSERT INTO t1(b) VALUES( zeroblob(100*1000*1000) );
INSERT INTO t1(b) VALUES( zeroblob(100*1000*1000) );
INSERT INTO t1(b) VALUES( zeroblob(100*1000*1000) );
INSERT INTO t1(b) VALUES( zeroblob(100*1000*1000) );
INSERT INTO t1(b) VALUES( zeroblob(100*1000*1000) );
INSERT INTO t1(b) VALUES( zeroblob(100*1000*1000) );
INSERT INTO t1(b) VALUES( zeroblob(100*1000*1000) );
INSERT INTO t1(b) VALUES( zeroblob(100*1000*1000) );
INSERT INTO t1(b) VALUES( zeroblob(100*1000*1000) );
INSERT INTO t1(b) VALUES( zeroblob(100*1000*1000) );
INSERT INTO t1(b) VALUES( zeroblob(100*1000*1000) );
}
} msg]
list $rc $msg
} {1 SQLITE_NOMEM}
finish_test
+19 -3
View File
@@ -1974,13 +1974,29 @@ int sqlite3session_attach(
** If successful, return zero. Otherwise, if an OOM condition is encountered,
** set *pRc to SQLITE_NOMEM and return non-zero.
*/
static int sessionBufferGrow(SessionBuffer *p, size_t nByte, int *pRc){
if( *pRc==SQLITE_OK && (size_t)(p->nAlloc-p->nBuf)<nByte ){
static int sessionBufferGrow(SessionBuffer *p, i64 nByte, int *pRc){
#define SESSION_MAX_BUFFER_SZ (0x7FFFFF00 - 1)
i64 nReq = p->nBuf + nByte;
if( *pRc==SQLITE_OK && nReq>p->nAlloc ){
u8 *aNew;
i64 nNew = p->nAlloc ? p->nAlloc : 128;
do {
nNew = nNew*2;
}while( (size_t)(nNew-p->nBuf)<nByte );
}while( nNew<nReq );
/* The value of SESSION_MAX_BUFFER_SZ is copied from the implementation
** of sqlite3_realloc64(). Allocations greater than this size in bytes
** always fail. It is used here to ensure that this routine can always
** allocate up to this limit - instead of up to the largest power of
** two smaller than the limit. */
if( nNew>SESSION_MAX_BUFFER_SZ ){
nNew = SESSION_MAX_BUFFER_SZ;
if( nNew<nReq ){
*pRc = SQLITE_NOMEM;
return 1;
}
}
aNew = (u8 *)sqlite3_realloc64(p->aBuf, nNew);
if( 0==aNew ){
+22 -12
View File
@@ -82,14 +82,15 @@ void sqlite3session_delete(sqlite3_session *pSession);
/*
** CAPIREF: Conigure a Session Object
** METHOD: sqlite3_session
*/
int sqlite3session_object_config(sqlite3_session*, int op, void *pArg);
/*
** CAPI3REF: Arguments for sqlite3session_object_config()
**
** This method is used to configure a session object after it has been
** created. At present the only valid value for the second parameter is
** [SQLITE_SESSION_OBJCONFIG_SIZE].
**
** Arguments for sqlite3session_object_config()
**
** The following values may passed as the the 4th parameter to
** [sqlite3session_object_config].
** sqlite3session_object_config().
**
** <dt>SQLITE_SESSION_OBJCONFIG_SIZE <dd>
** This option is used to set, clear or query the flag that enables
@@ -105,6 +106,10 @@ int sqlite3session_object_config(sqlite3_session*, int op, void *pArg);
** It is an error (SQLITE_MISUSE) to attempt to modify this setting after
** the first table has been attached to the session object.
*/
int sqlite3session_object_config(sqlite3_session*, int op, void *pArg);
/*
*/
#define SQLITE_SESSION_OBJCONFIG_SIZE 1
/*
@@ -351,13 +356,18 @@ int sqlite3session_changeset(
);
/*
** CAPI3REF: Load The Difference Between Tables Into A Session
** METHOD: sqlite3session_changeset_size()
** CAPI3REF: Return An Upper-limit For The Size Of The Changeset
** METHOD: sqlite3_session
**
** This function returns an upper limit, in bytes, of the size of the
** changeset that might be produced if sqlite3session_changeset() were
** called. The final changeset size might be equal to or smaller than
** the size in bytes returned by this function.
** By default, this function always returns 0. For it to return
** a useful result, the sqlite3_session object must have been configured
** to enable this API using sqlite3session_object_config() with the
** SQLITE_SESSION_OBJCONFIG_SIZE verb.
**
** When enabled, this function returns an upper limit, in bytes, for the size
** of the changeset that might be produced if sqlite3session_changeset() were
** called. The final changeset size might be equal to or smaller than the
** size in bytes returned by this function.
*/
sqlite3_int64 sqlite3session_changeset_size(sqlite3_session *pSession);
+4 -2
View File
@@ -539,7 +539,6 @@ FUZZERSHELL_OPT = -DSQLITE_ENABLE_JSON1
FUZZCHECK_OPT = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_MEMSYS5
FUZZCHECK_OPT += -DSQLITE_MAX_MEMORY=50000000
FUZZCHECK_OPT += -DSQLITE_PRINTF_PRECISION_LIMIT=1000
FUZZCHECK_OPT += -DSQLITE_ENABLE_DESERIALIZE
FUZZCHECK_OPT += -DSQLITE_ENABLE_FTS4
FUZZCHECK_OPT += -DSQLITE_ENABLE_RTREE
FUZZCHECK_OPT += -DSQLITE_ENABLE_GEOPOLY
@@ -592,7 +591,6 @@ dbfuzz$(EXE): $(TOP)/test/dbfuzz.c sqlite3.c sqlite3.h
DBFUZZ2_OPTS = \
-DSQLITE_THREADSAFE=0 \
-DSQLITE_OMIT_LOAD_EXTENSION \
-DSQLITE_ENABLE_DESERIALIZE \
-DSQLITE_DEBUG \
-DSQLITE_ENABLE_DBSTAT_VTAB \
-DSQLITE_ENABLE_BYTECODE_VTAB \
@@ -1081,6 +1079,9 @@ rbu$(EXE): $(TOP)/ext/rbu/rbu.c $(TOP)/ext/rbu/sqlite3rbu.c sqlite3.o
loadfts: $(TOP)/tool/loadfts.c libsqlite3.a
$(TCC) $(TOP)/tool/loadfts.c libsqlite3.a -o loadfts $(THREADLIB)
threadtest5: $(TOP)/test/threadtest5.c libsqlite3.a
$(TCC) $(TOP)/test/threadtest5.c libsqlite3.a -o threadtest5 $(THREADLIB)
# This target will fail if the SQLite amalgamation contains any exported
# symbols that do not begin with "sqlite3_". It is run as part of the
# releasetest.tcl script.
@@ -1143,3 +1144,4 @@ clean:
rm -f sqldiff sqldiff.exe
rm -f fts5.* fts5parse.*
rm -f lsm.h lsm1.c
rm -f threadtest5
+101 -94
View File
@@ -1,11 +1,11 @@
C Add\sthe\ssqlite3session_object_config()\sAPI.\sCurrent\sused\sto\senable/disable\scollecting\sdata\sfor\ssqlite3session_changeset_size().
D 2021-04-22T17:40:28.167
C If\sa\ssubquery\sis\sused\sto\sdrive\san\sindex,\sthis\schange\savoids\smaking\san\sextra\ncopy\sof\sthe\sresult\sof\sthat\ssubquery.\s\sBut,\ssuch\ssituations\sare\sprobably\nsufficiently\sunusual\sthat\sthe\sadded\scomplexity\sof\sthis\senhancement\sis\snot\nworth\sthe\sperformance\sgain.\s\sSo\sI'm\sgoing\sto\spark\sthis\scheck-in\son\sa\sbranch.\nIf\swe\slater\sfind\sa\suse\scase\sto\sjustify\sit,\swe\scan\smerge\sit\sto\strunk\sthen.\nThis\sis\sthe\s"further\schange"\sthat\swas\spromised\sby\sthe\sprior\scheck-in\scomment.
D 2021-05-28T14:28:54.261
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
F Makefile.in 3f76d8a9b0e78aa7b627ad56cab35908d99909de51dcb90b1e6a29eb4fd4394a
F Makefile.in 30c6d39386246695e951a676973e0bf57aabbd1e37024c07e657af89dd332555
F Makefile.linux-gcc f609543700659711fbd230eced1f01353117621dccae7b9fb70daa64236c5241
F Makefile.msc 231cf3fbc7bab3cc1801b3bf6a006098e9dfeca00d4d0910aad74795d0f94d5f
F Makefile.msc 6443729ba6a013a0fea4f999b22e54760f36e73c2e691554f0c4bfa1dbe4d070
F README.md 2a71913f398ecac5f3e10945fcf438aed425c2e9ed9874de561156ba77fb7023
F VERSION 8c392f6d70d82e513a0eac622bdf23c43df3e084cb630288beba8cef3012c812
F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50
@@ -15,7 +15,7 @@ F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2
F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903
F autoconf/Makefile.am a8d1d24affe52ebf8d7ddcf91aa973fa0316618ab95bb68c87cabf8faf527dc8
F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac
F autoconf/Makefile.msc ebe7e66edbb2f453593cbde186d1a0fa0dcd8cae9977febcae27aef1dab5678d
F autoconf/Makefile.msc d146a08ebbdf7f881ba600a49cd8dce40c4c807addcdb4b9b6a507e4b40ce837
F autoconf/README.first 6c4f34fe115ff55d4e8dbfa3cecf04a0188292f7
F autoconf/README.txt 4f04b0819303aabaa35fff5f7b257fb0c1ef95f1
F autoconf/configure.ac a8ba2a9e61216f5093d44f3b7d2cb8fe1890d6b7dc330a02f802d8efaa1fdc79
@@ -84,7 +84,7 @@ F ext/fts3/README.content b9078d0843a094d86af0d48dffbff13c906702b4c3558012e67b9c
F ext/fts3/README.syntax a19711dc5458c20734b8e485e75fb1981ec2427a
F ext/fts3/README.tokenizers b92bdeb8b46503f0dd301d364efc5ef59ef9fa8e2758b8e742f39fa93a2e422d
F ext/fts3/README.txt 8c18f41574404623b76917b9da66fcb0ab38328d
F ext/fts3/fts3.c 1d80d0a1e53ce5e7316e1379969c842079c46237369e131fd378288e64ebbf5f
F ext/fts3/fts3.c 95f55e24550c01c2a325d09c9ea8fdff61e923a4675f8545b28bf3c470e57dfb
F ext/fts3/fts3.h 3a10a0af180d502cecc50df77b1b22df142817fe
F ext/fts3/fts3Int.h bde280294d56ff50ee29d03e5140f0b6953b44d1c969bb5831e8ae85e3e76715
F ext/fts3/fts3_aux.c 1af58af8f2b00a49f4fb1c2602f8da2054ad60076f46c8ebf85c5410eccccb65
@@ -117,10 +117,10 @@ F ext/fts5/fts5Int.h 26c74dd5776f798436fbf604a0bf0e8de263b35b5060b05c15f9085845d
F ext/fts5/fts5_aux.c f558e1fb9f0f86a4f7489e258c162e1f947de5ff2709087fbb465fddb7092f98
F ext/fts5/fts5_buffer.c 5a5fe0159752c0fb0a5a93c722e9db2662822709490769d482b76a6dc8aaca70
F ext/fts5/fts5_config.c 8336d0ff6db0933f63cfec8ae0ab76e68393259cbccc0b46e1f79f7fa1842ff3
F ext/fts5/fts5_expr.c 5d0ab73f08af31837b1a4cbcaf571e74d7bb87f4f15bf79709de1b67ff4bfc05
F ext/fts5/fts5_expr.c 9462249a3bb82d0e49b163500f9d2197c2e4cd95bf440a9bbfc3906b22ea1e1b
F ext/fts5/fts5_hash.c 1aa93c9b5f461afba66701ee226297dc78402b3bdde81e90a10de5fe3df14959
F ext/fts5/fts5_index.c a2ee22478318ad2c176fb06b0a7a752b770056cde6a0a8d8a50968f3afcc306e
F ext/fts5/fts5_main.c f497ca97cb2802311ec93733b595762dc5b044ce3c6c8ce5fb3e871dd3fccd5d
F ext/fts5/fts5_index.c 222b5e56f51139ca5400985e26ea9971165901c7a45a2c17499bd2be3695c697
F ext/fts5/fts5_main.c 35ebbcae681a4a40027c47bc2e94d7e7c81e331dc406bb9b23c546454ee8f98a
F ext/fts5/fts5_storage.c 58ba71e6cd3d43a5735815e7956ee167babb4d2cbfe206905174792af4d09d75
F ext/fts5/fts5_tcl.c b1445cbe69908c411df8084a10b2485500ac70a9c747cdc8cda175a3da59d8ae
F ext/fts5/fts5_test_mi.c 08c11ec968148d4cb4119d96d819f8c1f329812c568bac3684f5464be177d3ee
@@ -160,7 +160,7 @@ F ext/fts5/test/fts5connect.test 08030168fc96fc278fa81f28654fb7e90566f33aff269c0
F ext/fts5/test/fts5content.test 213506436fb2c87567b8e31f6d43ab30aab99354cec74ed679f22aad0cdbf283
F ext/fts5/test/fts5corrupt.test 77ae6f41a7eba10620efb921cf7dbe218b0ef232b04519deb43581cb17a57ebe
F ext/fts5/test/fts5corrupt2.test 7453752ba12ce91690c469a6449d412561cc604b1dec994e16ab132952e7805f
F ext/fts5/test/fts5corrupt3.test 1cad09897fc69084a904c921dee7f777e1c866964ee2ec2cc7a8a69cc3f1ab68
F ext/fts5/test/fts5corrupt3.test 7748c28d0a0c8f00e7741a097df7c76eed207b5443908621dd1ce1dd23b84a07
F ext/fts5/test/fts5corrupt4.test f4c08e2182a48d8b70975fd869ee5391855c06d8a0ff87b6a2529e7c5a88a1d3
F ext/fts5/test/fts5delete.test 619295b20dbc1d840b403ee07c878f52378849c3c02e44f2ee143b3e978a0aa7
F ext/fts5/test/fts5detail.test 31b240dbf6d44ac3507e2f8b65f29fdc12465ffd531212378c7ce1066766f54e
@@ -291,21 +291,21 @@ F ext/misc/blobio.c a867c4c4617f6ec223a307ebfe0eabb45e0992f74dd47722b96f3e631c0e
F ext/misc/btreeinfo.c d28ce349b40054eaa9473e835837bad7a71deec33ba13e39f963d50933bfa0f9
F ext/misc/carray.c b75a0f207391038bf1540d3372f482a95c3613511c7c474db51ede1196321c7c
F ext/misc/carray.h de74ac70b2338f416723f7d538026e8ec0b7f1d388319f8f140c9a4d7677f02e
F ext/misc/cksumvfs.c 8dc4e1b718e374bed3a9b5c0a08da2922438002e33267311697768e06217b983
F ext/misc/cksumvfs.c 2c6b07714f3be6c1200671c53aa781a86d2c472c0fcb2fff520375362eb94303
F ext/misc/closure.c dbfd8543b2a017ae6b1a5843986b22ddf99ff126ec9634a2f4047cd14c85c243
F ext/misc/completion.c 6dafd7f4348eecc7be9e920d4b419d1fb2af75d938cd9c59a20cfe8beb2f22b9
F ext/misc/compress.c 3354c77a7c8e86e07d849916000cdac451ed96500bfb5bd83b20eb61eee012c9
F ext/misc/csv.c 53b3338d4fa812eda51a2637df30233a4dae16b964ee5666e2051b9672ed8bb4
F ext/misc/dbdata.c e316fba936571584e55abd5b974a32a191727a6b746053a0c9d439bd2cf93940
F ext/misc/dbdump.c b8592f6f2da292c62991a13864a60d6c573c47a9cc58362131b9e6a64f823e01
F ext/misc/decimal.c 3ddbf8162015be4d5ec2395dee4538f1e638bb517174bb148274b132df6e1d08
F ext/misc/decimal.c 09f967dcf4a1ee35a76309829308ec278d3648168733f4a1147820e11ebefd12
F ext/misc/eval.c 04bc9aada78c888394204b4ed996ab834b99726fb59603b0ee3ed6e049755dc1
F ext/misc/explain.c 0086fab288d4352ea638cf40ac382aad3b0dc5e845a1ea829a694c015fd970fe
F ext/misc/fileio.c 9b69e25da3b51d4a1d905a464ccb96709792ad627a742ba09215bc0d1447e7bd
F ext/misc/fossildelta.c 1240b2d3e52eab1d50c160c7fe1902a9bd210e052dc209200a750bbf885402d5
F ext/misc/fuzzer.c eae560134f66333e9e1ca4c8ffea75df42056e2ce8456734565dbe1c2a92bf3d
F ext/misc/ieee754.c cd6ab89f85fda8a020559b3f4d03001a8a62dd856beda5af3f558621d12be913
F ext/misc/json1.c 332c285db81a3757c278d725e5dafd7afeab6232240c679fbdc087683923eb85
F ext/misc/json1.c 76c5d9e0960fd15b4be79dacb76d872b4d0d983ce13e72ebfe9481d82cb9345d
F ext/misc/memstat.c 3017a0832c645c0f8c773435620d663855f04690172316bd127270d1a7523d4d
F ext/misc/memtrace.c 7c0d115d2ef716ad0ba632c91e05bd119cb16c1aedf3bec9f06196ead2d5537b
F ext/misc/memvfs.c ab36f49e02ebcdf85a1e08dc4d8599ea8f343e073ac9e0bca18a98b7e1ec9567
@@ -337,10 +337,10 @@ F ext/misc/vfsstat.c 389ea13983d3af926504c314f06a83cc858d5adc24b40af74aaed1fece0
F ext/misc/vtablog.c 5538acd0c8ddaae372331bee11608d76973436b77d6a91e8635cfc9432fba5ae
F ext/misc/vtshim.c 1976e6dd68dd0d64508c91a6dfab8e75f8aaf6cd
F ext/misc/wholenumber.c a838d1bea913c514ff316c69695efbb49ea3b8cb37d22afc57f73b6b010b4546
F ext/misc/zipfile.c e35e035bc2765b1ccdcb15f9815c2112843fcbc8f36aa071f0e5935df7072228
F ext/misc/zipfile.c acbad31bd9c9ec3540fa72b2e3fcd6f757eb33117d51528c0e13d0da5c836908
F ext/misc/zorder.c b0ff58fa643afa1d846786d51ea8d5c4b6b35aa0254ab5a82617db92f3adda64
F ext/rbu/rbu.c b880ca5cb857d6d6f52e72eb7397813058ef48c78c5402cd04ff2b6b5437f622
F ext/rbu/rbu1.test 221d9c18a5e600ac9ac6b1810d99d9f99163a7909ba61597876ab6e4d4beb3d6
F ext/rbu/rbu1.test c62904bd9526dcdc3496a21199aaf14ae191bbadbf67f076bf16be6b3f2115c2
F ext/rbu/rbu10.test 0a201c32202143f23c81c0144503da339786fc20acb7a2fda11601b65659f314
F ext/rbu/rbu11.test 5c834cf491086b45e071eabf71f708febc143e86a384a92de69e0b1a4cace144
F ext/rbu/rbu12.test 29f8b2118f6c96fac3755bd6d2b55c2db24f878b1f11fbfbe294f3a230a3dcdc
@@ -379,7 +379,7 @@ F ext/rbu/rbuvacuum.test 55e101e90168c2b31df6c9638fe73dc7f7cc666b6142266d1563697
F ext/rbu/rbuvacuum2.test b8e5b51dc8b2c0153373d024c0936be3f66f9234acbd6d0baab0869d56b14e6b
F ext/rbu/rbuvacuum3.test 8addd82e4b83b4c93fa47428eae4fd0dbf410f8512c186f38e348feb49ba03dc
F ext/rbu/rbuvacuum4.test a78898e438a44803eb2bc897ba3323373c9f277418e2d6d76e90f2f1dbccfd10
F ext/rbu/sqlite3rbu.c e6531884442b72f9e0ba47036fb5c4641ea817ff659a642b3984c10b8535b0fd
F ext/rbu/sqlite3rbu.c badb52388467f58e67ef104c5276d1ac68b316a30f8ccb2f74eac733625ae236
F ext/rbu/sqlite3rbu.h 1dc88ab7bd32d0f15890ea08d23476c4198d3da3056985403991f8c9cd389812
F ext/rbu/test_rbu.c 03f6f177096a5f822d68d8e4069ad8907fe572c62ff2d19b141f59742821828a
F ext/repair/README.md 92f5e8aae749a4dae14f02eea8e1bb42d4db2b6ce5e83dbcdd6b1446997e0c15
@@ -446,6 +446,7 @@ F ext/session/sessionH.test b17afdbd3b8f17e9bab91e235acf167cf35485db2ab2df0ea889
F ext/session/session_common.tcl f613174665456b2d916ae8df3e5735092a1c1712f36f46840172e9a01e8cc53e
F ext/session/session_speed_test.c dcf0ef58d76b70c8fbd9eab3be77cf9deb8bc1638fed8be518b62d6cbdef88b3
F ext/session/sessionat.test efe88965e74ff1bc2af9c310b28358c02d420c1fb2705cc7a28f0c1cc142c3ec
F ext/session/sessionbig.test 5851fc7f9981e2ccf1c7d9e7cb239dc530db07d5e878ebbb2f6d993d27872a43
F ext/session/sessiondiff.test ad13dd65664bae26744e1f18eb3cbd5588349b7e9118851d8f9364248d67bcec
F ext/session/sessionfault.test da273f2712b6411e85e71465a1733b8501dbf6f7
F ext/session/sessionfault2.test dd593f80b6b4786f7adfe83c5939620bc505559770cc181332da26f29cddd7bb
@@ -456,8 +457,8 @@ F ext/session/sessionrebase.test ccfa716b23bd1d3b03217ee58cfd90c78d4b99f53e6a9a2
F ext/session/sessionsize.test 6f644aff31c7f1e4871e9ff3542766e18da68fc7e587b83a347ea9820a002dd8
F ext/session/sessionstat1.test 218d351cf9fcd6648f125a26b607b140310160184723c2666091b54450a68fb5
F ext/session/sessionwor.test 6fd9a2256442cebde5b2284936ae9e0d54bde692d0f5fd009ecef8511f4cf3fc
F ext/session/sqlite3session.c 703634ca25b4b903ae8ec25045802a8c8deca36a65d2b993c4bc8888f6d6c7ee
F ext/session/sqlite3session.h 874b084ea97252a57ff1b79bb5da172ab4156f6302a8d3e3f5c88ce2748480d8
F ext/session/sqlite3session.c af0cb1163e224b286a9cba3c1ad877d927821e6a0e317c29b289a16e5da378a8
F ext/session/sqlite3session.h 0907de79bc13a2e3af30a6dc29acc60792a3eaf7d33d44cf52500d0f3c2b2171
F ext/session/test_session.c f433f68a8a8c64b0f5bc74dc725078f12483301ad4ae8375205eef790274a787
F ext/userauth/sqlite3userauth.h 7f3ea8c4686db8e40b0a0e7a8e0b00fac13aa7a3
F ext/userauth/user-auth.txt e6641021a9210364665fe625d067617d03f27b04
@@ -465,7 +466,7 @@ F ext/userauth/userauth.c 7f00cded7dcaa5d47f54539b290a43d2e59f4b1eb5f447545fa865
F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x
F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8
F magic.txt 8273bf49ba3b0c8559cb2774495390c31fd61c60
F main.mk 71abdbb39dbc530f436f7095d2c0504140d513142a6a552602fb55c8156fd854
F main.mk d1654e2923a7195603a7d6564dabe037a3a20ea5b3817002db534ffc4ad8cecf
F mkso.sh fd21c06b063bb16a5d25deea1752c2da6ac3ed83
F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271
F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504
@@ -477,29 +478,29 @@ F spec.template 86a4a43b99ebb3e75e6b9a735d5fd293a24e90ca
F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b
F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786
F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a
F src/alter.c e7caf3eefce268250dc1d10322eec637319de486aa1bae7f48c606259455537e
F src/alter.c e2e0e6be8a53cc5c145d9ff4f82a2c8d6851468a366ac8b5bd7306c792e37619
F src/analyze.c 01c6c6765cb4d40b473b71d85535093730770bb186f2f473abac25f07fcdee5c
F src/attach.c a7d1a7df69f053951ec1665e5894c61184fda3f677323762f1c3679ebd27d5c7
F src/attach.c a514e81758ba7b3a3a0501faf70af6cfc509de8810235db726cfc9f25165e929
F src/auth.c 08954fdc4cc2da5264ba5b75cfd90b67a6fc7d1710a02ccf917c38eadec77853
F src/backup.c 3014889fa06e20e6adfa0d07b60097eec1f6e5b06671625f476a714d2356513d
F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33
F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6
F src/btree.c c747dca6b20dbc6f4de8aad99ac6deae153a099af95718de366c602bb9121a63
F src/btree.c 51ba86095316fceb3e25bc61617d673d84627e79f4ace83f8722910f33eedef3
F src/btree.h 096cc53baa58be22b02c896d1cf933c38cfc6d65f9253c1367ece8cc88a24de5
F src/btreeInt.h 7bc15a24a02662409ebcd6aeaa1065522d14b7fda71573a2b0568b458f514ae0
F src/build.c 45889a1ac425eb7d60113ce65a519c55c5d5d01f2a9e978ab1467f8653bb57eb
F src/build.c daeb1beb04e3729456f095686bc26bb0cde026263fc281257d431ba22c2e7f21
F src/callback.c d0b853dd413255d2e337b34545e54d888ea02f20da5ad0e63585b389624c4a6c
F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e
F src/ctime.c 2a322b9a3d75771fb4d99e0702851f4f68dda982507a0f798eefb0712969a410
F src/ctime.c 3052b6b05ed9ef547a3dd66b8e01bfa9d582e78752ad6ed327da84652641e038
F src/date.c e0632f335952b32401482d099321bbf12716b29d6e72836b53ae49683ebae4bf
F src/dbpage.c 8a01e865bf8bc6d7b1844b4314443a6436c07c3efe1d488ed89e81719047833a
F src/dbstat.c 3aa79fc3aed7ce906e4ea6c10e85d657299e304f6049861fe300053ac57de36c
F src/delete.c 73f57a9a183532c344a3135cf8f2a5589376e39183e0b5f562d6b61b2af0f4d8
F src/expr.c 2b79c16f167b7ec74dfbd325b6f9cd9ff026908017f6804a5af6ba451c13b5b1
F src/expr.c 09f8ae1421d09802b4ac4b05c507761ecd142fa32cc0b1e33b9bd07fba10d34a
F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007
F src/fkey.c e9063648396c58778f77583a678342fe4a9bc82436bf23c5f9f444f2df0fdaa4
F src/func.c 88fd711754a7241cb9f8eb1391370fd0c0cea756b3358efa274c5d1efd59af93
F src/global.c 56d6762a3a44495ab035e2d3185eeccbc98579e18c06038e1bb9af346105bc84
F src/global.c 25ba4d58476f6be29bba9d9d14f7f146b78476d3a4d75ebb8c3b736328afe0f9
F src/hash.c 8d7dda241d0ebdafb6ffdeda3149a412d7df75102cecfc1021c98d6219823b19
F src/hash.h 9d56a9079d523b648774c1784b74b89bd93fac7b365210157482e4319a468f38
F src/hwtime.h cb1d7e3e1ed94b7aa6fde95ae2c2daccc3df826be26fc9ed7fd90d1750ae6144
@@ -507,15 +508,15 @@ F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71
F src/insert.c 2189e0e596010a0dc5405d9f14f78db1ee2fa71138c931f5b6ea96610b95bfc1
F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa
F src/loadext.c 8c9c8cd2bd8eecdb06d9b6e89de7e9e65bae45cc8fc33609cc74023a5c296067
F src/main.c 7db30c6293bb86c45c11638b1de38419e663623b549c74959be6981e7731eb5e
F src/malloc.c c1af4ac5a463648cd2953fd4ac679b3ba9022ce5ec794a60806150ad69dfd33a
F src/main.c 2b2044221a10e7c5f49a98f50563ce9a944511241ba5946d1754dcc2a7437a07
F src/malloc.c cbc93cdd429c4594912017d92ab656e2579aca64dbd1c6888551275bed46f25b
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
F src/mem1.c c12a42539b1ba105e3707d0e628ad70e611040d8f5e38cf942cee30c867083de
F src/mem2.c b93b8762ab999a29ae7751532dadf0a1ac78040308a5fb1d17fcc365171d67eb
F src/mem3.c 30301196cace2a085cbedee1326a49f4b26deff0af68774ca82c1f7c06fda4f6
F src/mem5.c 9bf955937b07f8c32541c8a9991f33ce3173d944
F src/memdb.c eab3c87582a99de1589703e393b0238881c9a16511dc5a29009e84042a5e9f25
F src/memjournal.c 431c70a111223a8a6e2e7e9f014afc6c88d818d357d866afc563195f2277d50e
F src/memdb.c f6ce717b26cd51a24cda62fce611b4b72b3db367113374aa498e489a69470715
F src/memjournal.c a85f0dc5c02a42453d0bc3819ecfb5666cb6433e5deefcd93ccbe05c9f088b83
F src/msvc.h 3a15918220367a8876be3fa4f2abe423a861491e84b864fb2b7426bf022a28f8
F src/mutex.c 5e3409715552348732e97b9194abe92fdfcd934cfb681df4ba0ab87ac6c18d25
F src/mutex.h a7b2293c48db5f27007c3bdb21d438873637d12658f5a0bf8ad025bb96803c4a
@@ -527,12 +528,12 @@ F src/os.c 6e94cd64b134c9317e52ad534117578e3df66ec180d70dbf4b1d7eb1db8e5a5d
F src/os.h 48388821692e87da174ea198bf96b1b2d9d83be5dfc908f673ee21fafbe0d432
F src/os_common.h b2f4707a603e36811d9b1a13278bffd757857b85
F src/os_setup.h 0dbaea40a7d36bf311613d31342e0b99e2536586
F src/os_unix.c b5b7475bd1a8f1b83b6173a81f4fe50f9e077ccbacb62ce2fe7a5cb89916bce1
F src/os_unix.c efa60c1cb54dba767abbba3c6dd67d3df5ef8aa26e2e499c37f055f56a374068
F src/os_win.c 77d39873836f1831a9b0b91894fec45ab0e9ca8e067dc8c549e1d1eca1566fe9
F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a
F src/pager.c 0c84ba222cc58825098ae7d693db85c69f1700ba2a74d9d395033337a511b4e6
F src/pager.c 95c255256b13827caf038c8f963d334784073f38ab6ef9d70371d9d04f3c43e0
F src/pager.h 4bf9b3213a4b2bebbced5eaa8b219cf25d4a82f385d093cd64b7e93e5285f66f
F src/parse.y 77039cf996d9cde8ee1e947ad9284566c30e48cc227766a7be1d475ec7aed9dd
F src/parse.y 8920f4444957d7827ca458029b2e41ffa32dd3b72917be0b52cae0aace3eadb5
F src/pcache.c 385ff064bca69789d199a98e2169445dc16e4291fa807babd61d4890c3b34177
F src/pcache.h 4f87acd914cef5016fae3030343540d75f5b85a1877eed1a2a19b9f284248586
F src/pcache1.c 388304fd2d91c39591080b5e0f3c62cfba87db20370e7e0554062bfb29740e9f
@@ -541,18 +542,18 @@ F src/pragma.h 8dc78ab7e9ec6ce3ded8332810a2066f1ef6267e2e03cd7356ee00276125c6cf
F src/prepare.c d778af9986f3b0107c5b255dcfe2696e8e99e00fb77c5115bbfea4e92c3302e7
F src/printf.c 78fabb49b9ac9a12dd1c89d744abdc9b67fd3205e62967e158f78b965a29ec4b
F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384
F src/resolve.c e299d53c4077fc32bc63741b5b27fdf8a1328cb8e812b9fafb55441c4c73a80a
F src/resolve.c 40e216d9a72e52841a9c8e0aec7d367bade8e2df17b804653b539b20c1ab5660
F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92
F src/select.c bc08a79364ad2056b1b3b83142b1cc4eacabf850603166f3a72581d56c320d9c
F src/shell.c.in 9320b476fde0f7c46700e5695b69b435f1e46843a1513cdd187ac426cdbee016
F src/sqlite.h.in 372554fcd1e1ed25ba44a316e8abdaad712470b7dcfa185ece54f51b10fbde10
F src/select.c 2f4429e0b0ca031e360489c45dca5dfa06cd85480e12c0d1360b91e1c8e7f7a2
F src/shell.c.in 2a2b06d463933ee3a5bb0242d5d2200ca36769493fd6f4d939a0574113f3d6d8
F src/sqlite.h.in 5c950066775ca9efdaa49077c05d38d0bef6418f3bd07d2dce0210f1d2f3c326
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
F src/sqlite3ext.h 61b38c073d5e1e96a3d45271b257aef27d0d13da2bea5347692ae579475cd95e
F src/sqliteInt.h 234ab17b1797cbc2adb7741a15786edf72bc96d40b4de68795e91926cfd46eba
F src/sqliteInt.h 6d0c49ed218f9f6ffabfdc8bed1a5de89f61e70c96a62156aeebeb20c1be9bf0
F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657
F src/status.c 4b8bc2a6905163a38b739854a35b826c737333fab5b1f8e03fa7eb9a4799c4c1
F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1
F src/tclsqlite.c 986b6391f02cd9b53c1d688be55899f6ffddeb8e8014cd83c1b73ff912579a71
F src/tclsqlite.c 97645e4a15dde6a6ad6de8d81057ff9869413b866015a89e208fedacd709493e
F src/test1.c 2100f4c28bae21ce83a9a0c5ec6827efd0e15d11b93b569b614daa5654b3fcf6
F src/test2.c 3efb99ab7f1fc8d154933e02ae1378bac9637da5
F src/test3.c 61798bb0d38b915067a8c8e03f5a534b431181f802659a6616f9b4ff7d872644
@@ -560,7 +561,7 @@ F src/test4.c 7c4420e01c577b5c4add2cb03119743b1a357543d347773b9e717195ea967159
F src/test5.c 328aae2c010c57a9829d255dc099d6899311672d
F src/test6.c ae73a3a42bbc982fb9e301b84d30bda65a307be48c6dff20aba1461e17a9b0ce
F src/test7.c 5612e9aecf934d6df7bba6ce861fdf5ba5456010
F src/test8.c 7fb971777c2c79c734bb52757191d68d4af659b8de9b4a071be3f527a9d19a02
F src/test8.c 0c856d6ff6b0d2ff6696addc467a15ed17c6910f14475302cd5b3b4e54406161
F src/test9.c 12e5ba554d2d1cbe0158f6ab3f7ffcd7a86ee4e5
F src/test_async.c 195ab49da082053fdb0f949c114b806a49ca770a
F src/test_autoext.c 915d245e736652a219a907909bb6710f0d587871
@@ -568,7 +569,7 @@ F src/test_backup.c bf5da90c9926df0a4b941f2d92825a01bbe090a0
F src/test_bestindex.c 78809f11026f18a93fcfd798d9479cba37e1201c830260bf1edc674b2fa9b857
F src/test_blob.c ae4a0620b478548afb67963095a7417cd06a4ec0a56adb453542203bfdcb31ce
F src/test_btree.c 8b2dc8b8848cf3a4db93f11578f075e82252a274
F src/test_config.c 842ddde1f1d32c12f1651a77e51d6ccdb84697d5023be352c54683db930e9702
F src/test_config.c 9c8e12823c46082a01765addf43be9309889f4e9dfb5a512a6c974e1c4efb413
F src/test_delete.c e2fe07646dff6300b48d49b2fee2fe192ed389e834dd635e3b3bac0ce0bf9f8f
F src/test_demovfs.c 86142ba864d4297d54c5b2e972e74f3141ae4b30f05b3a95824184ed2d3d7f91
F src/test_devsym.c aff2255ea290d7718da08af30cdf18e470ff7325a5eff63e0057b1496ed66593
@@ -607,34 +608,34 @@ F src/test_windirent.h 90dfbe95442c9762357fe128dc7ae3dc199d006de93eb33ba3972e0a9
F src/test_window.c cdae419fdcea5bad6dcd9368c685abdad6deb59e9fc8b84b153de513d394ba3f
F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9
F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c
F src/tokenize.c 0b9c82fa628b5adce93e2bcaf935a24d43eb83344fb51551f7835526d0693fc4
F src/treeview.c e483aeedf6f207000db1f90eb6abd816350493314c30e8749d319bdb9ab3b08c
F src/trigger.c f8493674f5c8f103c1a2cd0616af9dca85c7058450f9fe47cacd15cf5d512d52
F src/update.c b3abdaf4a314bbed238da69a6ca54c0f21262119389b412ee5778fffe62dd3cc
F src/tokenize.c bae853ad129d1129c063de8630a3e99e306283bc40146f359b1bb91be2c08f1e
F src/treeview.c 21449a944d5abd3ac07b7eab76f7221e20c9480d06f01798f8dc66d9bc361769
F src/trigger.c e0fd347b2571a2d956318cdc6d011ccca7ce862d10a0ca04188a37920ef5440c
F src/update.c 56fa0458b1ffc1042629f926443e8ed44203983df3ab2b0db2ba556e6ceed68c
F src/upsert.c df8f1727d62b5987c4fd302cd4d7c0c84ae57cd65683c5a34a740dfe24039235
F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0
F src/util.c 41c7a72da1df47864faa378a1c720b38adb288c6838cb6be5594511b6287a048
F src/vacuum.c 492422c1463c076473bae1858799c7a0a5fe87a133d1223239447c422cd26286
F src/vdbe.c ff3ccdd969774e6ce821b54d076286c84137e2f0e6387b1133bafbaa7470f749
F src/vdbe.c 73e5a8b64a77359f4287d76f168e89d12ba967cbb72a3d7619650568e9c1d66c
F src/vdbe.h 25dabb25c7e157b84e59260cfb5b466c3ac103ede9f36f4db371332c47601abe
F src/vdbeInt.h 58980223a32495ad059d10581b83e133abdc77248b1bab85c080cab8a13bd819
F src/vdbeapi.c d9e99daf59fec928986838b3389a7337e82fec6b3b5de30206cb99fb4661b94e
F src/vdbeaux.c 065a10392378109f08435bd50d03dff315e384cde2831d6b8dbaec05f33b10af
F src/vdbeblob.c c6b8db50b227f66fb404215732068df76485b5b433e5f9d4d9ac27410b218193
F src/vdbemem.c 947f2a65910edb4014dc981d33e414a68c51f169f9df8c4c493a0ba840b6eb1f
F src/vdbemem.c 175c73ced03edbb0f6567a41c8032afaeb83372090fa7bddfc88a67e28da2b8a
F src/vdbesort.c f5b5e473a7cee44e47a94817b042fd7172cf3aa2c0a7928a8339d612bcfdec5a
F src/vdbetrace.c 666c6fd9f1b62be6999e072a45b913e3c2c3518bc60dfd4d54fe304130acb724
F src/vdbevtab.c f99b275366c5fc5e2d99f734729880994ab9500bdafde7fae3b02d562b9d323c
F src/vtab.c 032a0165c147fda16927e6a3230e90c068d4af93f887ce94e26f678fe48e5e4c
F src/vtab.c b928405ccb66040fc6c3a11eaa93ddb02cbf20f9ab6860b301b222b9b50dc089
F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9
F src/wal.c 69e770e96fd56cc21608992bf2c6f1f3dc5cf2572d0495c6a643b06c3a679f14
F src/wal.c c8ec20a1ca161d5635a4f19c2a4efec2e006e19a8a61f272bf6bce1c80ab7436
F src/wal.h c3aa7825bfa2fe0d85bef2db94655f99870a285778baa36307c0a16da32b226a
F src/walker.c 6e540867a30d81e00205995fa2dc0e3d25365a7402251c9fd5d19aa4ff5e60b6
F src/where.c 1c305bab0996a63219a6cb3d4718587f3a5dc5608120c4448985aa2bef88b7f5
F src/whereInt.h 446e5e8018f83358ef917cf32d8e6a86dc8430113d0b17e720f1839d3faa44c4
F src/wherecode.c b4f24544fbaf5ecf0d060d9581e14df7c0de51b5e6c37af5b98048a9ba551b72
F src/whereexpr.c d8cafcf6781cf871082f04d7540862cf0fe30cb381dd1b2145a380376364fe8e
F src/window.c ae9fbd0cbaa39e1b384c13289ed769f9981383bde7b2f262c70ad6c42e5ab226
F src/walker.c 7342becedf3f8a26f9817f08436bdf8b56ad69af83705f6b9320a0ad3092c2ac
F src/where.c 32f41c3c93c6785e0077e3a2cdc669c3ccfe70173787847be77f294c18fc7dc3
F src/whereInt.h 9248161dd004f625ce5d3841ca9b99fed3fc8d61522cf76340fc5217dbe1375b
F src/wherecode.c bcfee3789a7d3da1f3f8a76c1b20c95d6c0fc4ea93c5d9b03206a432ac8b1cc4
F src/whereexpr.c 5a9c9f5d2dac4bcdcaae3035034b4667523f731df228e0bb1d4efc669efa9da5
F src/window.c a6d624d83b2d5b3cfb82bb437a2fbae759c928d47dc9ad1338a9419269181bb2
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
F test/affinity2.test ce1aafc86e110685b324e9a763eab4f2a73f737842ec3b687bd965867de90627
F test/affinity3.test eecb0dabee4b7765a8465439d5e99429279ffba23ca74a7eae270a452799f9e7
@@ -645,7 +646,7 @@ F test/all.test 2ecb8bbd52416642e41c9081182a8df05d42c75637afd4488aace78cc4b69e13
F test/alter.test f53d8a4ecd35f051c07e54a36beec5d0a30d30a9d98bc723f6cde6afbfb3c5ca
F test/alter2.test a966ccfcddf9ce0a4e0e6ff1aca9e6e7948e0e242cd7e43fc091948521807687
F test/alter3.test e487958dec7932453e0b83baf21d6b1e71d5e7d9a55bc20eadfa62a51ddffc29
F test/alter4.test dfd6086faf461b27ca2d2999848dcd207edf23352fc1592d0005c0844f3f08cf
F test/alter4.test 716caa071dd8a3c6d57225778d15d3c3cbf5e34b2e84ae44199aeb2bbf50a707
F test/alterauth.test 63442ba61ceb0c1eeb63aac1f4f5cebfa509d352276059d27106ae256bafc959
F test/alterauth2.test 381b1ab603c9ef96314a3158528ea17f7964449385a28eeaf8191120b2e24a8d
F test/altercol.test b11fa1b131e80ab5b6ecfb3b725fb0419c14ca6efba5adb57aeabfc9baa0c8f3
@@ -657,7 +658,7 @@ F test/altermalloc.test 167a47de41b5c638f5f5c6efb59784002b196fff70f98d9b4ed3cd74
F test/altermalloc2.test fa7b1c1139ea39b8dec407cf1feb032ca8e0076bd429574969b619175ad0174b
F test/altermalloc3.test 059841a3de6b6780efd9f0b30bf1d9b4443c555f68d39975cbcac2583167b239
F test/alterqf.test 67568ad152db8c1187b15633b801242cf960f1beafc51261a3d1725d910baeb2
F test/altertab.test d15362de3d487368e1f64d600fdfc1976033aecf8394c0a88454a5c63b357209
F test/altertab.test c7966d92e4da535050b911e1e9972ecb3a5befb0b2d22026b132cf5003d43dec
F test/altertab2.test b0d62f323ca5dab42b0bc028c52e310ebdd13e655e8fac070fe622bad7852c2b
F test/altertab3.test 2b82fa2236a3a91553d53ae5555d8e723c7eec174c41f1fa62ff497355398479
F test/amatch1.test b5ae7065f042b7f4c1c922933f4700add50cdb9f
@@ -782,7 +783,7 @@ F test/contrib01.test 2a1cbc0f2f48955d7d073f725765da6fbceda6b4
F test/corrupt.test d7cb0300e4a297147b6a05e92a1684bc8973635c3bcaa3d66e983c9cbdbf47a3
F test/corrupt2.test bb50042cf9a1f1023d73af325d47eb02a6bb11e3c52f8812644b220c5d4bca35
F test/corrupt3.test 2520432b1fbf99994841e69804a3c59fb828183f4d09b85a1631bc7adca17e31
F test/corrupt4.test 04965221ecd005901923fdc57f26811fa07178074b0672e50ea424c21638c708
F test/corrupt4.test b5ae41607e8d17d9c1f3e94fdb572ce061ed3beeebdb46fb3a348181b8c8a097
F test/corrupt5.test 387be3250795e2a86e6234745558b80efb248a357d0cd8e53bce75c7463f545d
F test/corrupt6.test fc6a891716139665dae0073b6945e3670bf92568
F test/corrupt7.test b036f94bda4b0b23a2919bf717046ce9ecca4543
@@ -801,7 +802,7 @@ F test/corruptJ.test 4d5ccc4bf959464229a836d60142831ef76a5aa4
F test/corruptK.test 5b4212fe346699831c5ad559a62c54e11c0611bdde1ea8423a091f9c01aa32af
F test/corruptL.test df132ba9ffd6fa15038380b4154998b9904ab8f1ea78400d7da53c920cb3b13d
F test/corruptM.test 7d574320e08c1b36caa3e47262061f186367d593a7e305d35f15289cc2c3e067
F test/corruptN.test 352c8f006b46130c27c06d4894c0919123308440473d699ec796b9c04f828ad8
F test/corruptN.test f56e3417fe9a444efd765ae55acbe65595d7b8f747785fe0fd785dbdc424932a
F test/cost.test b11cdbf9f11ffe8ef99c9881bf390e61fe92baf2182bad1dbe6de59a7295c576
F test/count.test 5364003488249957750a5f15ee42ca1cd7b100b1131c2dc71fff266a1250bf55
F test/countofview.test e17d6e6688cf74f22783c9ec6e788c0790ee4fbbaee713affd00b1ac0bb39b86
@@ -829,7 +830,7 @@ F test/dbdata.test 042f49acff3438f940eeba5868d3af080ae64ddf26ae78f80c92bec3ca7d8
F test/dbfuzz.c 73047c920d6210e5912c87cdffd9a1c281d4252e
F test/dbfuzz001.test 55e1a3504f8dea84155e09912fe3b1c3ad77e0b1a938ec42ca03b8e51b321e30
F test/dbfuzz2-seed1.db e6225c6f3d7b63f9c5b6867146a5f329d997ab105bee64644dc2b3a2f2aebaee
F test/dbfuzz2.c db2a1710c0d30d38e1352ee1b52b717fcb224c8caacc6f10909ef540f73cc9e8
F test/dbfuzz2.c 4b3c12de4d98b1b2d908ab03d217d4619e47c8b23d5e67f8a6f2b1bdee7cae23
F test/dbpage.test 650234ba683b9d82b899c6c51439819787e7609f17a0cc40e0080a7b6443bc38
F test/dbstatus.test 4a4221a883025ffd39696b3d1b3910b928fb097d77e671351acb35f3aed42759
F test/dbstatus2.test f5fe0afed3fa45e57cfa70d1147606c20d2ba23feac78e9a172f2fe8ab5b78ef
@@ -884,8 +885,6 @@ F test/exclusive.test 7ff63be7503990921838d5c9f77f6e33e68e48ed1a9d48cd28745bf650
F test/exclusive2.test 984090e8e9d1b331d2e8111daf6e5d61dda0bef7
F test/exec.test e949714dc127eaa5ecc7d723efec1ec27118fdd7
F test/exists.test 79a75323c78f02bbe9c251ea502a092f9ef63dac
F test/exists2.test 92d563a97019a70f7adcbe3cbaab16f9fc696affbf0f9ede1796ea5f7cc5a3ac
F test/existsfault.test 72a0036c1424d9204d49f4d976c3277a1b8bb2eed3c67aa124ba2df2f1331c7c
F test/expr.test 26cd01e8485bc48c8aa6a1add598e9ce1e706b4eb4f3f554e0b0223022e8c2cf
F test/expr2.test c27327ae9c017a7ff6280123f67aff496f912da74d78c888926d68b46ec75fd8
F test/exprfault.test 497cc0b8fe6a677f49b55cb485e040f709ec2834b84f25912fe9c2dfeeda33db
@@ -1049,7 +1048,7 @@ F test/fuzz3.test 9c813e6613b837cb7a277b0383cd66bfa07042b4cf0317157c35852f30043c
F test/fuzz4.test c229bcdb45518a89e1d208a21343e061503460ac69fae1539320a89f572eb634
F test/fuzz_common.tcl b7197de6ed1ee8250a4f82d67876f4561b42ee8cbbfc6160dcb66331bad3f830
F test/fuzz_malloc.test f348276e732e814802e39f042b1f6da6362a610af73a528d8f76898fde6b22f2
F test/fuzzcheck.c 74a457891ba166e7f4121eaaae81f4dbceb053b65ddee47db3eccd2ba59cd67d
F test/fuzzcheck.c 37f09efcd982048694d8b06fa3ef817df17f2a82e90af85cb3fb8eddd0f57ec4
F test/fuzzdata1.db d36e88741b4f23bcbaaf55b006290669d03c6c891cf13c7b3a53bc1b097b693f
F test/fuzzdata2.db 128b3feeb78918d075c9b14b48610145a0dd4c8d6f1ca7c2870c7e425f5bf31f
F test/fuzzdata3.db c6586d3e3cef0fbc18108f9bb649aa77bfc38aba
@@ -1057,7 +1056,7 @@ F test/fuzzdata4.db b502c7d5498261715812dd8b3c2005bad08b3a26e6489414bd13926cd3e4
F test/fuzzdata5.db e35f64af17ec48926481cfaf3b3855e436bd40d1cfe2d59a9474cb4b748a52a5
F test/fuzzdata6.db 92a80e4afc172c24f662a10a612d188fb272de4a9bd19e017927c95f737de6d7
F test/fuzzdata7.db 0166b56fd7a6b9636a1d60ef0a060f86ddaecf99400a666bb6e5bbd7199ad1f2
F test/fuzzdata8.db a5f04edee03f0446759272e976f7e68568201077b8adf5c769f5b2a8ddc3e10d
F test/fuzzdata8.db 29ca3c47821abb626309e0d182b0f00ad3b49638370daee855641b9abc36dfa2
F test/fuzzer1.test 3d4c4b7e547aba5e5511a2991e3e3d07166cfbb8
F test/fuzzer2.test a85ef814ce071293bce1ad8dffa217cbbaad4c14
F test/fuzzerfault.test f64c4aef4c9e9edf1d6dc0d3f1e65dcc81e67c996403c88d14f09b74807a42bc
@@ -1077,7 +1076,7 @@ F test/in2.test 5d4c61d17493c832f7d2d32bef785119e87bde75
F test/in3.test 3cbf58c87f4052cee3a58b37b6389777505aa0c0
F test/in4.test cd08375ba470b248c3dc4ab30fd5dbcb682deafe3862d8249ba0ad6a11dd25ea
F test/in5.test b32ce7f4a93f44c5dee94af16886d922cc16ebe33c8e1765c73d4049d0f4b40f
F test/in6.test 8562d0945195cab3cc4ab3794e9118e72cb44c43f785c2b04d48a9d06ca6b4ec
F test/in6.test f5f40d6816a8bb7c784424b58a10ac38efb76ab29127a2c17399e0cbeeda0e4b
F test/incrblob.test c9b96afc292aeff43d6687bcb09b0280aa599822
F test/incrblob2.test a494c9e848560039a23974b9119cfc2cf3ad3bd15cc2694ee6367ae537ef8f1f
F test/incrblob3.test d8d036fde015d4a159cd3cbae9d29003b37227a4
@@ -1192,6 +1191,7 @@ F test/manydb.test 28385ae2087967aa05c38624cec7d96ec74feb3e
F test/mem5.test c6460fba403c5703141348cd90de1c294188c68f
F test/memdb.test c1f2a343ad14398d5d6debda6ea33e80d0dafcc7
F test/memdb1.test 7b76c3262d63c46dd6b408d18f5721071776f2df4ffeb11e668824e427127594
F test/memjournal.test 70f3a00c7f84ee2978ad14e831231caa1e7f23915a2c54b4f775a021d5740c6c
F test/memleak.test 10b9c6c57e19fc68c32941495e9ba1c50123f6e2
F test/memsubsys1.test 9e7555a22173b8f1c96c281ce289b338fcba2abe8b157f8798ca195bbf1d347e
F test/memsubsys2.test 3e4a8d0c05fd3e5fa92017c64666730a520c7e08
@@ -1239,7 +1239,7 @@ F test/offset1.test f06b83657bcf26f9ce805e67450e189e282143b2
F test/openv2.test 0d3040974bf402e19b7df4b783e447289d7ab394
F test/optfuzz-db01.c 9f2fa80b8f84ebbf1f2e8b13421a4e0477fe300f6686fbd76cac1d2db66e0fdc
F test/optfuzz-db01.txt 21f6bdeadc701cf11528276e2a55c70bfcb846ba42df327f979bd9e7b6ce7041
F test/optfuzz.c 50e330304eb1992e15ddd11f3daaad9bcc0d9aaad09cb2bcc77f9515df2e88b1
F test/optfuzz.c 690430a0bf0ad047d5a168bf52b05b2ee97aedaad8c14337e9eb5050faa64994
F test/orderby1.test a4bba04b9c60a21e53486fbc173a596b29641a3b3a57a0f26a1cbef1360358e9
F test/orderby2.test bc11009f7cd99d96b1b11e57b199b00633eb5b04
F test/orderby3.test 8619d06a3debdcd80a27c0fdea5c40b468854b99
@@ -1267,7 +1267,7 @@ F test/parser1.test 6ccdf5e459a5dc4673d3273dc311a7e9742ca952dd0551a6a6320d27035c
F test/pcache.test c8acbedd3b6fd0f9a7ca887a83b11d24a007972b
F test/pcache2.test af7f3deb1a819f77a6d0d81534e97d1cf62cd442
F test/percentile.test 4243af26b8f3f4555abe166f723715a1f74c77ff
F test/permutations.test 9bb03106a024e9938d329a33380ea7fd91b6e45516881db68663505c444b3242
F test/permutations.test 63da39a4234eed2ccd10bf7872de58e24d53a50d11014dc8a8ab9f252368e880
F test/pg_common.tcl 3b27542224db1e713ae387459b5d117c836a5f6e328846922993b6d2b7640d9f
F test/pragma.test 50b91bedea9324d3ab48e793f908ee7d2c7dcf84bfa2281e792838be59641ec8
F test/pragma2.test e5d5c176360c321344249354c0c16aec46214c9f
@@ -1295,11 +1295,11 @@ F test/recover.test ccb8c2623902a92ebb76770edd075cb4f75a4760bb7afde38026572c6e79
F test/regexp1.test 497ea812f264d12b6198d6e50a76be4a1973a9d8
F test/regexp2.test 40e894223b3d6672655481493f1be12012f2b33c
F test/reindex.test cd9d6021729910ece82267b4f5e1b5ac2911a7566c43b43c176a6a4732e2118d
F test/releasetest.tcl 8dcfc21d6b4a4a1d9a8503de0a94800d129ec8f03ef53d6e68b79ef78a786acd x
F test/releasetest_data.tcl a864d27370e812c34a05224d6144ca082463906d5a4651782ad3b43712ab166a
F test/releasetest.tcl 6f803ef0b896f8f3f4c26eb072c0399963a5987a509a64d45f5dfbc1ebae2951 x
F test/releasetest_data.tcl f88ed29aa18366ed3956ace36c96ec6868ef5b9ee04cc05d32f4d81031e19e28
F test/resetdb.test 8062cf10a09d8c048f8de7711e94571c38b38168db0e5877ba7561789e5eeb2b
F test/resolver01.test f4022acafda7f4d40eca94dbf16bc5fc4ac30ceb
F test/returning1.test 99012dc464860e1502153276d5e5c2bee32c53d3a866dcfc09b39932048e2276
F test/returning1.test 52b4ed60f104a4ce85b38417e5319b2078b2b908c71a768d539cee3c0ce8bdc9
F test/rollback.test 06680159bc6746d0f26276e339e3ae2f951c64812468308838e0a3362d911eaa
F test/rollback2.test 3f3a4e20401825017df7e7671e9f31b6de5fae5620c2b9b49917f52f8c160a8f
F test/rollbackfault.test 0e646aeab8840c399cfbfa43daab46fd609cf04a
@@ -1315,7 +1315,7 @@ F test/rowvalue5.test c81c7d8cf36711ab37675ad7376084ae2a359cb6
F test/rowvalue6.test d19b54feb604d5601f8614b15e214e0774c01087
F test/rowvalue7.test c1cbdbf407029db01f87764097c6ac02a1c5a37efd2776eff32a9cdfdf6f2dba
F test/rowvalue8.test 5900eddad9e2c3c2e26f1a95f74aafc1232ee5e0
F test/rowvalue9.test d8dd2c6ecac432dadaa79e41dc2434f007be1b6b
F test/rowvalue9.test cb5380df82dca9db463081e26952c1e097b34fc2c2ac87453970c048d97df687
F test/rowvaluefault.test 7cd9ccc6c2fbdd881672984087aad0491bb75504
F test/rowvaluevtab.test cd9747bb3f308086944c07968f547ad6b05022e698d80b9ffbdfe09ce0b8da6f
F test/rtree.test 0c8d9dd458d6824e59683c19ab2ffa9ef946f798
@@ -1341,7 +1341,7 @@ F test/select1.test 3d23f66bf9ba77570acfe2ca5f1540ece17037cc64ab1a00efec9758ac29
F test/select2.test 352480e0e9c66eda9c3044e412abdf5be0215b56
F test/select3.test c49fbb758903f3718e2de5aa4655eda4838131cbea24a86db908f8b6889aa68c
F test/select4.test f0684d3da3bccacbe2a1ebadf6fb49d9df6f53acb4c6ebc228a88d0d6054cc7b
F test/select5.test df9ec0d218cedceb4fe7b63262025b547b50a55e59148c6f40b60ca25f1d4546
F test/select5.test 8afc5e5dcdebc2be54472e73ebd9cd1adef1225fd15d37a1c62f969159f390ae
F test/select6.test 319d45e414cdd321bf17cfacedaf19e3935ad64dac357c53f1492338c6e9b801
F test/select7.test f659f231489349e8c5734e610803d7654207318f
F test/select8.test 8c8f5ae43894c891efc5755ed905467d1d67ad5d
@@ -1440,7 +1440,7 @@ F test/sync.test 89539f4973c010eda5638407e71ca7fddbcd8e0594f4c9980229f804d433309
F test/sync2.test 8f9f7d4f6d5be8ca8941a8dadcc4299e558cb6a1ff653a9469146c7a76ef2039
F test/syscall.test a39d9a36f852ae6e4800f861bc2f2e83f68bbc2112d9399931ecfadeabd2d69d
F test/sysfault.test c9f2b0d8d677558f74de750c75e12a5454719d04
F test/tabfunc01.test 5ca6d004157a3e886a55a9387b960cc0db41acd88753eb597ff409ec6cfb1be0
F test/tabfunc01.test acb5be558868c65d8cf3495539fff23093d77139eb1e4e8c4580568099f98645
F test/table.test eb3463b7add9f16a5bb836badf118cf391b809d09fdccd1f79684600d07ec132
F test/tableapi.test ecbcc29c4ab62c1912c3717c48ea5c5e59f7d64e4a91034e6148bd2b82f177f4
F test/tableopts.test dba698ba97251017b7c80d738c198d39ab747930
@@ -1465,6 +1465,7 @@ F test/threadtest1.c 6029d9c5567db28e6dc908a0c63099c3ba6c383b
F test/threadtest2.c a70a8e94bef23339d34226eb9521015ef99f4df8
F test/threadtest3.c e63013af10cf236c7610eb06d33bde08c861806dc64be811940ff4d9ddd34a4f
F test/threadtest4.c c1e67136ceb6c7ec8184e56ac61db28f96bd2925
F test/threadtest5.c 9b4d782c58d8915d7e955ff8051f3d03628bda0d33b82971ea8c0f2f2808c421
F test/time-wordcount.sh 8e0b0f8109367827ad5d58f5cc849705731e4b90
F test/tkt-02a8e81d44.test 6c80d9c7514e2a42d4918bf87bf6bc54f379110c
F test/tkt-18458b1a.test 6a62cb1ee50fa3c620da59e3a6f531eb38fceaf7e2166203816b724524e6f1d6
@@ -1617,7 +1618,7 @@ F test/trace3.test ae2004df24b585fed9046cc0bae4601762bc6fc4aa321d475f1350bba5047
F test/trans.test 45f6f9ab6f66a7b5744f1caac06b558f95da62501916906cf55586a896f9f439
F test/trans2.test 62bd045bfc7a1c14c5ba83ba64d21ade31583f76
F test/trans3.test 91a100e5412b488e22a655fe423a14c26403ab94
F test/transitive1.test 239eec5343388983f112c16d666aa89960cd85302b6af6cd8408ce8edb7b3316
F test/transitive1.test 06bcfeeb2ed719abf6ae582f9f65a6b07642dd1363fa648ae9a74a35e83a825c
F test/trigger1.test d30cd09ae8ac365a088f09daba583cc5c0b8fc7d4e1d70809d0b4be3bf6ae2ab
F test/trigger2.test 6e35bd7321c49e63d540aee980eb95dec63e1d1caca175224101045bcc80871f
F test/trigger3.test aa640bb2bbb03edd5ff69c055117ea088f121945
@@ -1645,7 +1646,7 @@ F test/tt3_vacuum.c 1753f45917699c9c1f66b64c717a717c9379f776
F test/types.test bf816ce73c7dfcfe26b700c19f97ef4050d194ff
F test/types2.test 1aeb81976841a91eef292723649b5c4fe3bc3cac
F test/types3.test 99e009491a54f4dc02c06bdbc0c5eea56ae3e25a
F test/unionall.test 369dac51f4e7b94442b054d3d7f2e6755cd6994274718228878e3bd47c425f6d
F test/unionall.test fee6e6adebe5446938475432ae8b042835a286c7e2efdc1b186d2182dfb93ffb
F test/unionall2.test 71e8fa08d5699d50dc9f9dc0c9799c2e7a6bb7931a330d369307a4df7f157fa1
F test/unionallfault.test 652bfbb630e6c43135965dc1e8f0a9a791da83aec885d626a632fe1909c56f73
F test/unionvtab.test e1704ab1b4c1bb3ffc9da4681f8e85a0b909fd80b937984fc94b27415ac8e5a4
@@ -1657,7 +1658,7 @@ F test/unordered.test 0edaf3411d300693bca595897c5201421c6c5ec787990a1dfe2f7f60ae
F test/update.test e906ca7cb1dc6f52af1ea243e08f727edfa79f924c2691f2f9e72481f847310d
F test/update2.test 67455bc61fcbcf96923c45b3bc4f87bc72be7d67575ad35f134906148c7b06d3
F test/upfrom1.tcl 8859d9d437f03b44174c4524a7a734a391fd4526fcff65be08285dafc9dc9041
F test/upfrom1.test d18f69f7c691bc791e7f31bf0e354eeff04cf2f44edc32d6b1928bad71697073
F test/upfrom1.test 8cb06689e99cd707d884faa16da0e8eb26ff658bb01c47ddf72fadade666e6e1
F test/upfrom2.test f92e47bfc35e9410d3e8716ee626384e89ad026c55fd6148508ca9d707521673
F test/upfrom3.test 6130f24ebf97f5ea865e5d2a14a2d543fe5428a62e87cc60f62d875e45c1f5f0
F test/upfromfault.test 3a10075a0043f0c4fad6614b2c371f88a8ba5a4acab68b907438413865d6a8d6
@@ -1682,7 +1683,8 @@ F test/vacuummem.test 7b42abb3208bd82dd23a7536588396f295a314f2
F test/varint.test bbce22cda8fc4d135bcc2b589574be8410614e62
F test/veryquick.test 57ab846bacf7b90cf4e9a672721ea5c5b669b661
F test/view.test ea88361d5e9bc8eabf9f573185a16aea73a885be9b6c6a95ae84908913416a80
F test/vtab1.test c5d9e90ed02bcacd776dcbb7360199d290f7f53c26b484ddece543060c54319f
F test/view2.test db32c8138b5b556f610b35dfddd38c5a58a292f07fda5281eedb0851b2672679
F test/vtab1.test 99c0c13b5336ca7f87f137459de144b2f396bb8563fbd602e46bfaa425e3d8cc
F test/vtab2.test 14d4ab26cee13ba6cf5c5601b158e4f57552d3b055cdd9406cf7f711e9c84082
F test/vtab3.test b45f47d20f225ccc9c28dc915d92740c2dee311e
F test/vtab4.test 8e73ed268f3d596bc3590f45fc948fb40f28e9c3
@@ -1750,7 +1752,7 @@ F test/where5.test fdf66f96d29a064b63eb543e28da4dfdccd81ad2
F test/where6.test 5da5a98cec820d488e82708301b96cb8c18a258b
F test/where7.test ab41d53ce8f2a6919ea3d5b13cd1153c1375a8e3ddaa129b81781f9033981383
F test/where8.test 461ca40265ed996a6305da99bb024b0e41602bb586acf544c08f95922358e49f
F test/where9.test b1942ed1d4c4632ea99e135691371f33803428ee4092a462280338ab3347f916
F test/where9.test 1ffb75edc50a8faa6e7bd77f8221d783febb00b44b0bdb32fb48cec6e38eca95
F test/whereA.test 9d1077b117f1b68d5f739d94f36956c36cf995eb87bb19b77b2e81af020edd20
F test/whereB.test 0def95db3bdec220a731c7e4bec5930327c1d8c5
F test/whereC.test cae295158703cb3fc23bf1a108a9ab730efff0f6
@@ -1762,7 +1764,8 @@ F test/whereH.test e4b07f7a3c2f5d31195cd33710054c78667573b2
F test/whereI.test c4bb7e2ca56d49bd8ab5c7bd085b8b83e353922b46904d68aefb3c7468643581
F test/whereJ.test fc05e374cc9f2dc204148d6c06822c380ad388895fe97a6d335b94a26a08aecf
F test/whereK.test 0270ab7f04ba5436fb9156d31d642a1c82727f4c4bfe5ba90d435c78cf44684a
F test/whereL.test 7717caf61ff4b09d05ddd2978701c4cf5661408bd4dce31d38eff482f60f44f3
F test/whereL.test 50171e3ec00b4c8ad5ec773119a35d9e9642cec45154b44c366d628326479f4d
F test/whereM.test 0dbc9998783458ddcf3cc078ca7c2951d8b2677d472ecf0028f449ed327c0250
F test/wherefault.test 6cf2a9c5712952d463d3f45ebee7f6caf400984df51a195d884cfb7eb0e837a7
F test/wherelfault.test 9012e4ef5259058b771606616bd007af5d154e64cc25fa9fd4170f6411db44e3
F test/wherelimit.test afb46397c6d7e964e6e294ba3569864a0c570fe3807afc634236c2b752372f31
@@ -1771,7 +1774,7 @@ F test/win32heap.test 10fd891266bd00af68671e702317726375e5407561d859be1aa04696f2
F test/win32lock.test fbf107c91d8f5512be5a5b87c4c42ab9fdd54972
F test/win32longpath.test 4baffc3acb2e5188a5e3a895b2b543ed09e62f7c72d713c1feebf76222fe9976
F test/win32nolock.test ac4f08811a562e45a5755e661f45ca85892bdbbc
F test/window1.test 54e160bdeb8b06fb3b97993e0eec45ee4c3294f39ad63007c921c40961298815
F test/window1.test 49eadb28b0bae0f916518c9983b1fb7450c198915664f323b2bfc480cc98c431
F test/window2.tcl 492c125fa550cda1dd3555768a2303b3effbeceee215293adf8871efc25f1476
F test/window2.test e466a88bd626d66edc3d352d7d7e1d5531e0079b549ba44efb029d1fbff9fd3c
F test/window3.tcl acea6e86a4324a210fd608d06741010ca83ded9fde438341cb978c49928faf03
@@ -1782,8 +1785,8 @@ F test/window5.test d328dd18221217c49c144181975eea17339eaeaf0e9aa558cee3afb84652
F test/window6.test f8d674254b23289cc17c84d79dec7eda7caa1dfb7836c43122cfdf3640d1df32
F test/window7.tcl 6a1210f05d40ec89c22960213a22cd3f98d4e2f2eb20646c83c8c30d4d76108f
F test/window7.test 1d31276961ae7801edc72173edaf7593e3cbc79c06d1f1f09e20d8418af403cd
F test/window8.tcl f2711aa3571e4e6b0dad98db8d95fd6cb8d9db0c92bbdf535f153b07606a1ce2
F test/window8.test c4331b27a6f66d69fa8f8bab10cc731db1a81d293ae108a68f7c3487fa94e65b
F test/window8.tcl 5e02e41d9d9a80f597063aed1a381eb19d1d0ef677a4f0df352c5365cf23f79c
F test/window8.test 4ab16817414af0c904abe2ebdf88eb6c2b00058b84f9748c6174ff11fc45f1ed
F test/window9.test 349c71eab4288a1ffc19e2f65872ec2c37e6cf8a1dda2ad300364b7450ae4836
F test/windowA.test 6d63dc1260daa17141a55007600581778523a8b420629f1282d2acfc36af23be
F test/windowB.test 6e601f8178ba8ba28b2f19e74fe613815084bb4a8d2ad942defc7d42e191e521
@@ -1791,14 +1794,14 @@ F test/windowerr.tcl f5acd6fbc210d7b5546c0e879d157888455cd4a17a1d3f28f07c1c8a387
F test/windowerr.test a8b752402109c15aa1c5efe1b93ccb0ce1ef84fa964ae1cd6684dd0b3cc1819b
F test/windowfault.test 21919e601f20b976ea2a73aa401220c89ed0e8d203c4f69476ea55bce3726496
F test/windowpushd.test d8895d08870b7226f7693665bd292eb177e62ca06799184957b3ca7dc03067df
F test/with1.test b231edbf0f7c1d94bc14365cd9f33e197b2f0aa16add927ee121649fce014c15
F test/with2.test 000fb95f1f29dae868cea0f41505eb5126077d49eb967ff88f9ee46212ad8863
F test/with1.test 7bc5abfe4c80c0cef8a90f5a66d60b9982e8ccd7350c8eb70611323a3b8e07ba
F test/with2.test bbf82609bbacc0a7a01d822022aed7b2fa702436dd3d0ecf942023564d2bba13
F test/with3.test ad32d13ad50661e6fa305f62a0717649c348792e7b658bf2644976227a9e0373
F test/with4.test 257be66c0c67fee1defbbac0f685c3465e2cad037f21ce65f23f86084f198205
F test/with5.test 6248213c41fab36290b5b73aa3f937309dfba337004d9d8434c3fabc8c7d4be8
F test/with6.test 661d7e416bef6c0a2556b2c9f0c8178a5b15932bed65246abed99723a8d4e7c0
F test/withM.test 693b61765f2b387b5e3e24a4536e2e82de15ff64
F test/without_rowid1.test e4034c0849ccc2e8bb749c69f15bd69bb9fcf8fe77e8d17ce02369604242fe83
F test/without_rowid1.test 6abc5d497f634520944dac0a89a6c240a48d2ee0f8353356a750eb70dc1db41a
F test/without_rowid2.test af260339f79d13cb220288b67cd287fbcf81ad99
F test/without_rowid3.test 39ab0dd773eaa62e59b17093f875327630f54c4145458f6d2b053d68d4b2f67b
F test/without_rowid4.test 4e08bcbaee0399f35d58b5581881e7a6243d458a
@@ -1809,7 +1812,7 @@ F test/wordcount.c d721a4b6fae93e6e33449700bce1686bc23257c27425bc3ef1599dc912ade
F test/writecrash.test f1da7f7adfe8d7f09ea79b42e5ca6dcc41102f27f8e334ad71539501ddd910cc
F test/zeroblob.test 07a5b11ab591d1f26c626945fb7f228f68b993533b2ada77273edf6ee29db174
F test/zerodamage.test 9c41628db7e8d9e8a0181e59ea5f189df311a9f6ce99cc376dc461f66db6f8dc
F test/zipfile.test 429cb81c518487fa1b644b6b04b6e9af704a4fa767bd1a110204c5f03b2e8616
F test/zipfile.test 0d8758d8c0d63f16644f959689f78969d223789d998964276554039f067b4548
F test/zipfile2.test 9903388a602a3834189857a985106ff95c3bba6a3969e0134127df991889db5d
F test/zipfilefault.test 44d4d7a7f7cca7521d569d7f71026b241d65a6b1757aa409c1a168827edbbc2c
F tool/GetFile.cs 47852aa0d806fe47ed1ac5138bdce7f000fe87aaa7f28107d0cb1e26682aeb44
@@ -1839,13 +1842,14 @@ F tool/libvers.c caafc3b689638a1d88d44bc5f526c2278760d9b9
F tool/loadfts.c c3c64e4d5e90e8ba41159232c2189dba4be7b862
F tool/logest.c 11346aa019e2e77a00902aa7d0cabd27bd2e8cca
F tool/max-limits.c cbb635fbb37ae4d05f240bfb5b5270bb63c54439
F tool/merge-test.tcl de76b62f2de2a92d4c1ca4f976bce0aea6899e0229e250479b229b2a1914b176
F tool/mkautoconfamal.sh f62353eb6c06ab264da027fd4507d09914433dbdcab9cb011cdc18016f1ab3b8
F tool/mkccode.tcl 86463e68ce9c15d3041610fedd285ce32a5cf7a58fc88b3202b8b76837650dbe x
F tool/mkctimec.tcl dd183b73ae1c28249669741c250525f0407e579a70482371668fd5f130d9feb3
F tool/mkctimec.tcl 06b0d503ee0e6c2d4abe83563b43d4925a12e31ec9fb3249ce39661f53fbd1ce
F tool/mkkeywordhash.c 08b6e4d7a482a7f37a9a0032e7ba968e26624a027b6b2e9ba589be6f5e3d8c2c
F tool/mkmsvcmin.tcl 6ecab9fe22c2c8de4d82d4c46797bda3d2deac8e763885f5a38d0c44a895ab33
F tool/mkopcodec.tcl d1b6362bd3aa80d5520d4d6f3765badf01f6c43c
F tool/mkopcodeh.tcl 352a4319c0ad869eb26442bf7c3b015aa15594c21f1cce5a6420dbe999367c21
F tool/mkopcodeh.tcl acc798757e2c60e4b6e16745505b9595fca76c206815c8ada576a136cf3608ed
F tool/mkopts.tcl 680f785fdb09729fd9ac50632413da4eadbdf9071535e3f26d03795828ab07fa
F tool/mkpragmatab.tcl ae5585ae76ca26e4d6ccd5ea9cdebaf5efefb318bf989497a0e846cd711d9ab1
F tool/mkshellc.tcl 70a9978e363b0f3280ca9ce1c46d72563ff479c1930a12a7375e3881b7325712
@@ -1857,14 +1861,14 @@ F tool/mksqlite3h.tcl 1f5e4a1dbbbc43c83cc6e74fe32c6c620502240b66c7c0f33a51378e78
F tool/mksqlite3internalh.tcl eb994013e833359137eb53a55acdad0b5ae1049b
F tool/mkvsix.tcl b9e0777a213c23156b6542842c238479e496ebf5
F tool/offsets.c 8ed2b344d33f06e71366a9b93ccedaa38c096cc1dbd4c3c26ad08c6115285845
F tool/omittest.tcl 38c3e409ae0070df177ca49164f5ed19ad4f3d5b574ee3272d521a94b59bdb84
F tool/omittest.tcl 3d222272b1d840b4e3d67bff0cb743ce3f633faddadb3702b2056b726775db8f
F tool/opcodesum.tcl 740ed206ba8c5040018988129abbf3089a0ccf4a
F tool/pagesig.c ff0ca355fd3c2398e933da5e22439bbff89b803b
F tool/replace.tcl 60f91e8dd06ab81f74d213ecbd9c9945f32ac048
F tool/restore_jrnl.tcl 6957a34f8f1f0f8285e07536225ec3b292a9024a
F tool/rollback-test.c 9fc98427d1e23e84429d7e6d07d9094fbdec65a5
F tool/run-speed-test.sh f95d19fd669b68c4c38b6b475242841d47c66076
F tool/showdb.c 49e810f5c414c792b5bf38cd5557ca9639713ebfef32aaff32faf7cb7ccce513
F tool/showdb.c 8c6b1cbb86ee25ca2173497183f8fcd444d4e26923e4cf57ddabe66c633b4dab
F tool/showjournal.c 5bad7ae8784a43d2b270d953060423b8bd480818
F tool/showlocks.c 9cc5e66d4ebbf2d194f39db2527ece92077e86ae627ddd233ee48e16e8142564
F tool/showshm.c a0ab6ec32dd1f11218ca2a4018f8fb875b59414801ab8ceed8b2e69b7b45a809
@@ -1914,7 +1918,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
P b5564a6fd54875db1de884fdc0e5eeabcd6aa5595ad03a8a60843503e830a2d8
R fa53b8d1cc3def8dc3ef8249968de9f0
U dan
Z 5eb2943cb766ada953003dbe5c9f5486
P c9f0b9cb0aef107265435e22c164dd3c974eadfd00abf7cfd4fc7ec95c0dd7d0
R c044497982752ba303617f7de106b59c
T *branch * copy-optimization
T *sym-copy-optimization *
T -sym-trunk *
U drh
Z 0c06d6f1ffda88b03d3d1e66ad233058
+1 -1
View File
@@ -1 +1 @@
4d5fd2151e024d11289b6c4fbce2996d8d07b2b5a1c953ef895c237e79d3aa55
4488cb883e155a7466946d25569ab2816c4a8de9d4c7d540f5053ea5334e7ae5
+6 -3
View File
@@ -29,8 +29,9 @@
** Or, if zName is not a system table, zero is returned.
*/
static int isAlterableTable(Parse *pParse, Table *pTab){
if( 0==sqlite3StrNICmp(pTab->zName, "sqlite_", 7)
if( 0==sqlite3StrNICmp(pTab->zName, "sqlite_", 7)
#ifndef SQLITE_OMIT_VIRTUALTABLE
|| (pTab->tabFlags & TF_Eponymous)!=0
|| ( (pTab->tabFlags & TF_Shadow)!=0
&& sqlite3ReadOnlyShadowTables(pParse->db)
)
@@ -834,7 +835,7 @@ static int renameUnmapSelectCb(Walker *pWalker, Select *p){
Parse *pParse = pWalker->pParse;
int i;
if( pParse->nErr ) return WRC_Abort;
if( NEVER(p->selFlags & SF_View) ) return WRC_Prune;
if( p->selFlags & SF_View ) return WRC_Prune;
if( ALWAYS(p->pEList) ){
ExprList *pList = p->pEList;
for(i=0; i<pList->nExpr; i++){
@@ -918,7 +919,9 @@ static RenameToken *renameTokenFind(
void *pPtr
){
RenameToken **pp;
assert( pPtr!=0 );
if( pPtr==0 ){
return 0;
}
for(pp=&pParse->pRename; (*pp); pp=&(*pp)->pNext){
if( (*pp)->p==pPtr ){
RenameToken *pToken = *pp;
+11 -8
View File
@@ -95,7 +95,7 @@ static void attachFunc(
if( zFile==0 ) zFile = "";
if( zName==0 ) zName = "";
#ifdef SQLITE_ENABLE_DESERIALIZE
#ifndef SQLITE_OMIT_DESERIALIZE
# define REOPEN_AS_MEMDB(db) (db->init.reopenMemdb)
#else
# define REOPEN_AS_MEMDB(db) (0)
@@ -464,14 +464,17 @@ static int fixSelectCb(Walker *p, Select *pSelect){
if( NEVER(pList==0) ) return WRC_Continue;
for(i=0, pItem=pList->a; i<pList->nSrc; i++, pItem++){
if( pFix->bTemp==0 ){
if( pItem->zDatabase && iDb!=sqlite3FindDbName(db, pItem->zDatabase) ){
sqlite3ErrorMsg(pFix->pParse,
"%s %T cannot reference objects in database %s",
pFix->zType, pFix->pName, pItem->zDatabase);
return WRC_Abort;
if( pItem->zDatabase ){
if( iDb!=sqlite3FindDbName(db, pItem->zDatabase) ){
sqlite3ErrorMsg(pFix->pParse,
"%s %T cannot reference objects in database %s",
pFix->zType, pFix->pName, pItem->zDatabase);
return WRC_Abort;
}
sqlite3DbFree(db, pItem->zDatabase);
pItem->zDatabase = 0;
pItem->fg.notCte = 1;
}
sqlite3DbFree(db, pItem->zDatabase);
pItem->zDatabase = 0;
pItem->pSchema = pFix->pSchema;
pItem->fg.fromDDL = 1;
}
+42 -17
View File
@@ -547,7 +547,7 @@ static void invalidateIncrblobCursors(
int isClearTable /* True if all rows are being deleted */
){
BtCursor *p;
if( pBtree->hasIncrblobCur==0 ) return;
assert( pBtree->hasIncrblobCur );
assert( sqlite3BtreeHoldsMutex(pBtree) );
pBtree->hasIncrblobCur = 0;
for(p=pBtree->pBt->pCursor; p; p=p->pNext){
@@ -6419,10 +6419,9 @@ static void freePage(MemPage *pPage, int *pRC){
}
/*
** Free any overflow pages associated with the given Cell. Store
** size information about the cell in pInfo.
** Free the overflow pages associated with the given Cell.
*/
static int clearCell(
static SQLITE_NOINLINE int clearCellOverflow(
MemPage *pPage, /* The page that contains the Cell */
unsigned char *pCell, /* First byte of the Cell */
CellInfo *pInfo /* Size information about the cell */
@@ -6434,10 +6433,7 @@ static int clearCell(
u32 ovflPageSize;
assert( sqlite3_mutex_held(pPage->pBt->mutex) );
pPage->xParseCell(pPage, pCell, pInfo);
if( pInfo->nLocal==pInfo->nPayload ){
return SQLITE_OK; /* No overflow pages. Return without doing anything */
}
assert( pInfo->nLocal!=pInfo->nPayload );
testcase( pCell + pInfo->nSize == pPage->aDataEnd );
testcase( pCell + (pInfo->nSize-1) == pPage->aDataEnd );
if( pCell + pInfo->nSize > pPage->aDataEnd ){
@@ -6493,6 +6489,21 @@ static int clearCell(
return SQLITE_OK;
}
/* Call xParseCell to compute the size of a cell. If the cell contains
** overflow, then invoke cellClearOverflow to clear out that overflow.
** STore the result code (SQLITE_OK or some error code) in rc.
**
** Implemented as macro to force inlining for performance.
*/
#define BTREE_CLEAR_CELL(rc, pPage, pCell, sInfo) \
pPage->xParseCell(pPage, pCell, &sInfo); \
if( sInfo.nLocal!=sInfo.nPayload ){ \
rc = clearCellOverflow(pPage, pCell, &sInfo); \
}else{ \
rc = SQLITE_OK; \
}
/*
** Create the byte sequence used to represent a cell on page pPage
** and write that byte sequence into pCell[]. Overflow pages are
@@ -7028,7 +7039,7 @@ static int rebuildPage(
put2byte(pCellptr, (pData - aData));
pCellptr += 2;
if( pData < pCellptr ) return SQLITE_CORRUPT_BKPT;
memcpy(pData, pCell, sz);
memmove(pData, pCell, sz);
assert( sz==pPg->xCellSize(pPg, pCell) || CORRUPT_DB );
i++;
if( i>=iEnd ) break;
@@ -7168,7 +7179,9 @@ static int pageFreeArray(
}
pFree = pCell;
szFree = sz;
if( pFree+sz>pEnd ) return 0;
if( pFree+sz>pEnd ){
return 0;
}
}else{
pFree = pCell;
szFree += sz;
@@ -8144,6 +8157,7 @@ static int balance_nonroot(
u8 *pCell;
u8 *pTemp;
int sz;
u8 *pSrcEnd;
MemPage *pNew = apNew[i];
j = cntNew[i];
@@ -8187,6 +8201,12 @@ static int balance_nonroot(
iOvflSpace += sz;
assert( sz<=pBt->maxLocal+23 );
assert( iOvflSpace <= (int)pBt->pageSize );
for(k=0; b.ixNx[k]<=i && ALWAYS(k<NB*2); k++){}
pSrcEnd = b.apEnd[k];
if( SQLITE_WITHIN(pSrcEnd, pCell, pCell+sz) ){
rc = SQLITE_CORRUPT_BKPT;
goto balance_cleanup;
}
insertCell(pParent, nxDiv+i, pCell, sz, pTemp, pNew->pgno, &rc);
if( rc!=SQLITE_OK ) goto balance_cleanup;
assert( sqlite3PagerIswriteable(pParent->pDbPage) );
@@ -8743,7 +8763,9 @@ int sqlite3BtreeInsert(
assert( pX->pKey==0 );
/* If this is an insert into a table b-tree, invalidate any incrblob
** cursors open on the row being replaced */
invalidateIncrblobCursors(p, pCur->pgnoRoot, pX->nKey, 0);
if( p->hasIncrblobCur ){
invalidateIncrblobCursors(p, pCur->pgnoRoot, pX->nKey, 0);
}
/* If BTREE_SAVEPOSITION is set, the cursor must already be pointing
** to a row with the same key as the new entry being inserted.
@@ -8877,7 +8899,7 @@ int sqlite3BtreeInsert(
if( !pPage->leaf ){
memcpy(newCell, oldCell, 4);
}
rc = clearCell(pPage, oldCell, &info);
BTREE_CLEAR_CELL(rc, pPage, oldCell, info);
testcase( pCur->curFlags & BTCF_ValidOvfl );
invalidateOverflowCache(pCur);
if( info.nSize==szNew && info.nLocal==info.nPayload
@@ -9114,7 +9136,8 @@ int sqlite3BtreeDelete(BtCursor *pCur, u8 flags){
assert( (flags & ~(BTREE_SAVEPOSITION | BTREE_AUXDELETE))==0 );
if( pCur->eState==CURSOR_REQUIRESEEK ){
rc = btreeRestoreCursorPosition(pCur);
if( rc ) return rc;
assert( rc!=SQLITE_OK || CORRUPT_DB || pCur->eState==CURSOR_VALID );
if( rc || pCur->eState!=CURSOR_VALID ) return rc;
}
assert( CORRUPT_DB || pCur->eState==CURSOR_VALID );
@@ -9169,7 +9192,7 @@ int sqlite3BtreeDelete(BtCursor *pCur, u8 flags){
/* If this is a delete operation to remove a row from a table b-tree,
** invalidate any incrblob cursors open on the row being deleted. */
if( pCur->pKeyInfo==0 ){
if( pCur->pKeyInfo==0 && p->hasIncrblobCur ){
invalidateIncrblobCursors(p, pCur->pgnoRoot, pCur->info.nKey, 0);
}
@@ -9178,7 +9201,7 @@ int sqlite3BtreeDelete(BtCursor *pCur, u8 flags){
** itself from within the page. */
rc = sqlite3PagerWrite(pPage->pDbPage);
if( rc ) return rc;
rc = clearCell(pPage, pCell, &info);
BTREE_CLEAR_CELL(rc, pPage, pCell, info);
dropCell(pPage, iCellIdx, info.nSize, &rc);
if( rc ) return rc;
@@ -9465,7 +9488,7 @@ static int clearDatabasePage(
rc = clearDatabasePage(pBt, get4byte(pCell), 1, pnChange);
if( rc ) goto cleardatabasepage_out;
}
rc = clearCell(pPage, pCell, &info);
BTREE_CLEAR_CELL(rc, pPage, pCell, info);
if( rc ) goto cleardatabasepage_out;
}
if( !pPage->leaf ){
@@ -9513,7 +9536,9 @@ int sqlite3BtreeClearTable(Btree *p, int iTable, int *pnChange){
/* Invalidate all incrblob cursors open on table iTable (assuming iTable
** is the root of a table b-tree - if it is not, the following call is
** a no-op). */
invalidateIncrblobCursors(p, (Pgno)iTable, 0, 1);
if( p->hasIncrblobCur ){
invalidateIncrblobCursors(p, (Pgno)iTable, 0, 1);
}
rc = clearDatabasePage(pBt, (Pgno)iTable, 0, pnChange);
}
sqlite3BtreeLeave(p);
+39 -6
View File
@@ -46,7 +46,7 @@ struct TableLock {
** code to make the lock occur is generated by a later call to
** codeTableLocks() which occurs during sqlite3FinishCoding().
*/
void sqlite3TableLock(
static SQLITE_NOINLINE void lockTable(
Parse *pParse, /* Parsing context */
int iDb, /* Index of the database containing the table to lock */
Pgno iTab, /* Root page number of the table to be locked */
@@ -59,8 +59,6 @@ void sqlite3TableLock(
TableLock *p;
assert( iDb>=0 );
if( iDb==1 ) return;
if( !sqlite3BtreeSharable(pParse->db->aDb[iDb].pBt) ) return;
pToplevel = sqlite3ParseToplevel(pParse);
for(i=0; i<pToplevel->nTableLock; i++){
p = &pToplevel->aTableLock[i];
@@ -84,6 +82,17 @@ void sqlite3TableLock(
sqlite3OomFault(pToplevel->db);
}
}
void sqlite3TableLock(
Parse *pParse, /* Parsing context */
int iDb, /* Index of the database containing the table to lock */
Pgno iTab, /* Root page number of the table to be locked */
u8 isWriteLock, /* True for a write lock */
const char *zName /* Name of the table to be locked */
){
if( iDb==1 ) return;
if( !sqlite3BtreeSharable(pParse->db->aDb[iDb].pBt) ) return;
lockTable(pParse, iDb, iTab, isWriteLock, zName);
}
/*
** Code an OP_TableLock instruction for each table locked by the
@@ -438,7 +447,7 @@ Table *sqlite3LocateTable(
/* If zName is the not the name of a table in the schema created using
** CREATE, then check to see if it is the name of an virtual table that
** can be an eponymous virtual table. */
if( pParse->disableVtab==0 ){
if( pParse->disableVtab==0 && db->init.busy==0 ){
Module *pMod = (Module*)sqlite3HashFind(&db->aModule, zName);
if( pMod==0 && sqlite3_strnicmp(zName, "pragma_", 7)==0 ){
pMod = sqlite3PragmaVtabRegister(db, zName);
@@ -1048,6 +1057,23 @@ i16 sqlite3TableColumnToStorage(Table *pTab, i16 iCol){
}
#endif
/*
** Insert a single OP_JournalMode query opcode in order to force the
** prepared statement to return false for sqlite3_stmt_readonly(). This
** is used by CREATE TABLE IF NOT EXISTS and similar if the table already
** exists, so that the prepared statement for CREATE TABLE IF NOT EXISTS
** will return false for sqlite3_stmt_readonly() even if that statement
** is a read-only no-op.
*/
static void sqlite3ForceNotReadOnly(Parse *pParse){
int iReg = ++pParse->nMem;
Vdbe *v = sqlite3GetVdbe(pParse);
if( v ){
sqlite3VdbeAddOp3(v, OP_JournalMode, 0, iReg, PAGER_JOURNALMODE_QUERY);
sqlite3VdbeUsesBtree(v, 0);
}
}
/*
** Begin constructing a new table representation in memory. This is
** the first of several action routines that get called in response
@@ -1147,6 +1173,7 @@ void sqlite3StartTable(
}else{
assert( !db->init.busy || CORRUPT_DB );
sqlite3CodeVerifySchema(pParse, iDb);
sqlite3ForceNotReadOnly(pParse);
}
goto begin_table_error;
}
@@ -1323,6 +1350,7 @@ void sqlite3AddReturning(Parse *pParse, ExprList *pList){
pRet->retTrig.tr_tm = TRIGGER_AFTER;
pRet->retTrig.bReturning = 1;
pRet->retTrig.pSchema = db->aDb[1].pSchema;
pRet->retTrig.pTabSchema = db->aDb[1].pSchema;
pRet->retTrig.step_list = &pRet->retTStep;
pRet->retTStep.op = TK_RETURNING;
pRet->retTStep.pTrig = &pRet->retTrig;
@@ -3196,7 +3224,10 @@ void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView, int noErr){
if( noErr ) db->suppressErr--;
if( pTab==0 ){
if( noErr ) sqlite3CodeVerifyNamedSchema(pParse, pName->a[0].zDatabase);
if( noErr ){
sqlite3CodeVerifyNamedSchema(pParse, pName->a[0].zDatabase);
sqlite3ForceNotReadOnly(pParse);
}
goto exit_drop_table;
}
iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
@@ -3766,6 +3797,7 @@ void sqlite3CreateIndex(
}else{
assert( !db->init.busy );
sqlite3CodeVerifySchema(pParse, iDb);
sqlite3ForceNotReadOnly(pParse);
}
goto exit_create_index;
}
@@ -4246,7 +4278,7 @@ void sqlite3DefaultRowEst(Index *pIdx){
if( x<99 ){
pIdx->pTable->nRowLogEst = x = 99;
}
if( pIdx->pPartIdxWhere!=0 ) x -= 10; assert( 10==sqlite3LogEst(2) );
if( pIdx->pPartIdxWhere!=0 ){ x -= 10; assert( 10==sqlite3LogEst(2) ); }
a[0] = x;
/* Estimate that a[1] is 10, a[2] is 9, a[3] is 8, a[4] is 7, a[5] is
@@ -4284,6 +4316,7 @@ void sqlite3DropIndex(Parse *pParse, SrcList *pName, int ifExists){
sqlite3ErrorMsg(pParse, "no such index: %S", pName->a);
}else{
sqlite3CodeVerifyNamedSchema(pParse, pName->a[0].zDatabase);
sqlite3ForceNotReadOnly(pParse);
}
pParse->checkSchema = 1;
goto exit_drop_index;
+41 -22
View File
@@ -58,8 +58,10 @@ static const char * const sqlite3azCompileOpt[] = {
#if SQLITE_64BIT_STATS
"64BIT_STATS",
#endif
#if SQLITE_ALLOW_COVERING_INDEX_SCAN
"ALLOW_COVERING_INDEX_SCAN",
#ifdef SQLITE_ALLOW_COVERING_INDEX_SCAN
# if SQLITE_ALLOW_COVERING_INDEX_SCAN != 1
"ALLOW_COVERING_INDEX_SCAN=" CTIMEOPT_VAL(SQLITE_ALLOW_COVERING_INDEX_SCAN),
# endif
#endif
#if SQLITE_ALLOW_URI_AUTHORITY
"ALLOW_URI_AUTHORITY",
@@ -121,8 +123,10 @@ static const char * const sqlite3azCompileOpt[] = {
#ifdef SQLITE_DEFAULT_LOOKASIDE
"DEFAULT_LOOKASIDE=" CTIMEOPT_VAL2(SQLITE_DEFAULT_LOOKASIDE),
#endif
#if SQLITE_DEFAULT_MEMSTATUS
"DEFAULT_MEMSTATUS",
#ifdef SQLITE_DEFAULT_MEMSTATUS
# if SQLITE_DEFAULT_MEMSTATUS != 1
"DEFAULT_MEMSTATUS=" CTIMEOPT_VAL(SQLITE_DEFAULT_MEMSTATUS),
# endif
#endif
#ifdef SQLITE_DEFAULT_MMAP_SIZE
"DEFAULT_MMAP_SIZE=" CTIMEOPT_VAL(SQLITE_DEFAULT_MMAP_SIZE),
@@ -196,7 +200,7 @@ static const char * const sqlite3azCompileOpt[] = {
#if SQLITE_ENABLE_BYTECODE_VTAB
"ENABLE_BYTECODE_VTAB",
#endif
#if SQLITE_ENABLE_CEROD
#ifdef SQLITE_ENABLE_CEROD
"ENABLE_CEROD=" CTIMEOPT_VAL(SQLITE_ENABLE_CEROD),
#endif
#if SQLITE_ENABLE_COLUMN_METADATA
@@ -211,17 +215,17 @@ static const char * const sqlite3azCompileOpt[] = {
#if SQLITE_ENABLE_CURSOR_HINTS
"ENABLE_CURSOR_HINTS",
#endif
#if SQLITE_ENABLE_DBPAGE_VTAB
"ENABLE_DBPAGE_VTAB",
#endif
#if SQLITE_ENABLE_DBSTAT_VTAB
"ENABLE_DBSTAT_VTAB",
#endif
#if SQLITE_ENABLE_EXPENSIVE_ASSERT
"ENABLE_EXPENSIVE_ASSERT",
#endif
#if SQLITE_ENABLE_FTS1
"ENABLE_FTS1",
#endif
#if SQLITE_ENABLE_FTS2
"ENABLE_FTS2",
#if SQLITE_ENABLE_EXPLAIN_COMMENTS
"ENABLE_EXPLAIN_COMMENTS",
#endif
#if SQLITE_ENABLE_FTS3
"ENABLE_FTS3",
@@ -280,6 +284,9 @@ static const char * const sqlite3azCompileOpt[] = {
#if SQLITE_ENABLE_NULL_TRIM
"ENABLE_NULL_TRIM",
#endif
#if SQLITE_ENABLE_OFFSET_SQL_FUNC
"ENABLE_OFFSET_SQL_FUNC",
#endif
#if SQLITE_ENABLE_OVERSIZE_CELL_CHECK
"ENABLE_OVERSIZE_CELL_CHECK",
#endif
@@ -310,7 +317,7 @@ static const char * const sqlite3azCompileOpt[] = {
#if SQLITE_ENABLE_SQLLOG
"ENABLE_SQLLOG",
#endif
#if defined(SQLITE_ENABLE_STAT4)
#if SQLITE_ENABLE_STAT4
"ENABLE_STAT4",
#endif
#if SQLITE_ENABLE_STMTVTAB
@@ -364,8 +371,10 @@ static const char * const sqlite3azCompileOpt[] = {
#if HAVE_ISNAN || SQLITE_HAVE_ISNAN
"HAVE_ISNAN",
#endif
#if SQLITE_HOMEGROWN_RECURSIVE_MUTEX
"HOMEGROWN_RECURSIVE_MUTEX",
#ifdef SQLITE_HOMEGROWN_RECURSIVE_MUTEX
# if SQLITE_HOMEGROWN_RECURSIVE_MUTEX != 1
"HOMEGROWN_RECURSIVE_MUTEX=" CTIMEOPT_VAL(SQLITE_HOMEGROWN_RECURSIVE_MUTEX),
# endif
#endif
#if SQLITE_IGNORE_AFP_LOCK_ERRORS
"IGNORE_AFP_LOCK_ERRORS",
@@ -463,9 +472,6 @@ static const char * const sqlite3azCompileOpt[] = {
#if SQLITE_MUTEX_NOOP
"MUTEX_NOOP",
#endif
#if SQLITE_MUTEX_NREF
"MUTEX_NREF",
#endif
#if SQLITE_MUTEX_OMIT
"MUTEX_OMIT",
#endif
@@ -535,7 +541,7 @@ static const char * const sqlite3azCompileOpt[] = {
#if SQLITE_OMIT_CTE
"OMIT_CTE",
#endif
#if SQLITE_OMIT_DATETIME_FUNCS
#if defined(SQLITE_OMIT_DATETIME_FUNCS) || defined(SQLITE_OMIT_FLOATING_POINT)
"OMIT_DATETIME_FUNCS",
#endif
#if SQLITE_OMIT_DECLTYPE
@@ -544,6 +550,9 @@ static const char * const sqlite3azCompileOpt[] = {
#if SQLITE_OMIT_DEPRECATED
"OMIT_DEPRECATED",
#endif
#if SQLITE_OMIT_DESERIALIZE
"OMIT_DESERIALIZE",
#endif
#if SQLITE_OMIT_DISKIO
"OMIT_DISKIO",
#endif
@@ -571,6 +580,9 @@ static const char * const sqlite3azCompileOpt[] = {
#if SQLITE_OMIT_INTEGRITY_CHECK
"OMIT_INTEGRITY_CHECK",
#endif
#if SQLITE_OMIT_INTROSPECTION_PRAGMAS
"OMIT_INTROSPECTION_PRAGMAS",
#endif
#if SQLITE_OMIT_LIKE_OPTIMIZATION
"OMIT_LIKE_OPTIMIZATION",
#endif
@@ -634,8 +646,10 @@ static const char * const sqlite3azCompileOpt[] = {
#if SQLITE_OMIT_TEST_CONTROL
"OMIT_TEST_CONTROL",
#endif
#if SQLITE_OMIT_TRACE
"OMIT_TRACE",
#ifdef SQLITE_OMIT_TRACE
# if SQLITE_OMIT_TRACE != 1
"OMIT_TRACE=" CTIMEOPT_VAL(SQLITE_OMIT_TRACE),
# endif
#endif
#if SQLITE_OMIT_TRIGGER
"OMIT_TRIGGER",
@@ -670,8 +684,10 @@ static const char * const sqlite3azCompileOpt[] = {
#if SQLITE_PERFORMANCE_TRACE
"PERFORMANCE_TRACE",
#endif
#if SQLITE_POWERSAFE_OVERWRITE
"POWERSAFE_OVERWRITE",
#ifdef SQLITE_POWERSAFE_OVERWRITE
# if SQLITE_POWERSAFE_OVERWRITE != 1
"POWERSAFE_OVERWRITE=" CTIMEOPT_VAL(SQLITE_POWERSAFE_OVERWRITE),
# endif
#endif
#if SQLITE_PREFER_PROXY_LOCKING
"PREFER_PROXY_LOCKING",
@@ -706,7 +722,10 @@ static const char * const sqlite3azCompileOpt[] = {
#if SQLITE_SUBSTR_COMPATIBILITY
"SUBSTR_COMPATIBILITY",
#endif
#if SQLITE_SYSTEM_MALLOC
#if (!defined(SQLITE_WIN32_MALLOC) \
&& !defined(SQLITE_ZERO_MALLOC) \
&& !defined(SQLITE_MEMDEBUG) \
) || defined(SQLITE_SYSTEM_MALLOC)
"SYSTEM_MALLOC",
#endif
#if SQLITE_TCL
+51 -45
View File
@@ -95,18 +95,7 @@ Expr *sqlite3ExprAddCollateToken(
const Token *pCollName, /* Name of collating sequence */
int dequote /* True to dequote pCollName */
){
assert( pExpr!=0 || pParse->db->mallocFailed );
if( pExpr==0 ) return 0;
if( pExpr->op==TK_VECTOR ){
ExprList *pList = pExpr->x.pList;
if( pList!=0 ){
int i;
for(i=0; i<pList->nExpr; i++){
pList->a[i].pExpr = sqlite3ExprAddCollateToken(pParse,pList->a[i].pExpr,
pCollName, dequote);
}
}
}else if( pCollName->n>0 ){
if( pCollName->n>0 ){
Expr *pNew = sqlite3ExprAlloc(pParse->db, TK_COLLATE, pCollName, dequote);
if( pNew ){
pNew->pLeft = pExpr;
@@ -456,7 +445,7 @@ int sqlite3ExprVectorSize(Expr *pExpr){
** been positioned.
*/
Expr *sqlite3VectorFieldSubexpr(Expr *pVector, int i){
assert( i<sqlite3ExprVectorSize(pVector) );
assert( i<sqlite3ExprVectorSize(pVector) || pVector->op==TK_ERROR );
if( sqlite3ExprIsVector(pVector) ){
assert( pVector->op2==0 || pVector->op==TK_REGISTER );
if( pVector->op==TK_SELECT || pVector->op2==TK_SELECT ){
@@ -572,7 +561,7 @@ static int exprVectorRegister(
int *pRegFree /* OUT: Temp register to free */
){
u8 op = pVector->op;
assert( op==TK_VECTOR || op==TK_REGISTER || op==TK_SELECT );
assert( op==TK_VECTOR || op==TK_REGISTER || op==TK_SELECT || op==TK_ERROR );
if( op==TK_REGISTER ){
*ppExpr = sqlite3VectorFieldSubexpr(pVector, iField);
return pVector->iTable+iField;
@@ -581,8 +570,11 @@ static int exprVectorRegister(
*ppExpr = pVector->x.pSelect->pEList->a[iField].pExpr;
return regSelect+iField;
}
*ppExpr = pVector->x.pList->a[iField].pExpr;
return sqlite3ExprCodeTemp(pParse, *ppExpr, pRegFree);
if( op==TK_VECTOR ){
*ppExpr = pVector->x.pList->a[iField].pExpr;
return sqlite3ExprCodeTemp(pParse, *ppExpr, pRegFree);
}
return 0;
}
/*
@@ -1324,6 +1316,7 @@ static Expr *exprDup(sqlite3 *db, Expr *p, int dupFlags, u8 **pzBuffer){
if( pzBuffer ){
zAlloc = *pzBuffer;
staticFlag = EP_Static;
assert( zAlloc!=0 );
}else{
zAlloc = sqlite3DbMallocRawNN(db, dupedExprSize(p, dupFlags));
staticFlag = 0;
@@ -1518,7 +1511,8 @@ ExprList *sqlite3ExprListDup(sqlite3 *db, ExprList *p, int flags){
){
assert( pNewExpr->iColumn==0 || i>0 );
if( pNewExpr->iColumn==0 ){
assert( pOldExpr->pLeft==pOldExpr->pRight );
assert( pOldExpr->pLeft==pOldExpr->pRight
|| ExprHasProperty(pOldExpr->pLeft, EP_Subquery) );
pPriorSelectCol = pNewExpr->pLeft = pNewExpr->pRight;
}else{
assert( i>0 );
@@ -2356,8 +2350,10 @@ int sqlite3ExprIsInteger(Expr *p, int *pValue){
*/
int sqlite3ExprCanBeNull(const Expr *p){
u8 op;
assert( p!=0 );
while( p->op==TK_UPLUS || p->op==TK_UMINUS ){
p = p->pLeft;
assert( p!=0 );
}
op = p->op;
if( op==TK_REGISTER ) op = p->op2;
@@ -2989,19 +2985,23 @@ void sqlite3CodeRhsOfIN(
/* If the LHS and RHS of the IN operator do not match, that
** error will have been caught long before we reach this point. */
if( ALWAYS(pEList->nExpr==nVal) ){
Select *pCopy;
SelectDest dest;
int i;
int rc;
sqlite3SelectDestInit(&dest, SRT_Set, iTab);
dest.zAffSdst = exprINAffinity(pParse, pExpr);
pSelect->iLimit = 0;
testcase( pSelect->selFlags & SF_Distinct );
testcase( pKeyInfo==0 ); /* Caused by OOM in sqlite3KeyInfoAlloc() */
if( sqlite3Select(pParse, pSelect, &dest) ){
sqlite3DbFree(pParse->db, dest.zAffSdst);
pCopy = sqlite3SelectDup(pParse->db, pSelect, 0);
rc = pParse->db->mallocFailed ? 1 :sqlite3Select(pParse, pCopy, &dest);
sqlite3SelectDelete(pParse->db, pCopy);
sqlite3DbFree(pParse->db, dest.zAffSdst);
if( rc ){
sqlite3KeyInfoUnref(pKeyInfo);
return;
}
sqlite3DbFree(pParse->db, dest.zAffSdst);
}
assert( pKeyInfo!=0 ); /* OOM will cause exit after sqlite3Select() */
assert( pEList!=0 );
assert( pEList->nExpr>0 );
@@ -3100,12 +3100,30 @@ int sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){
Vdbe *v = pParse->pVdbe;
assert( v!=0 );
if( pParse->nErr ) return 0;
testcase( pExpr->op==TK_EXISTS );
testcase( pExpr->op==TK_SELECT );
assert( pExpr->op==TK_EXISTS || pExpr->op==TK_SELECT );
assert( ExprHasProperty(pExpr, EP_xIsSelect) );
pSel = pExpr->x.pSelect;
/* If this routine has already been coded, then invoke it as a
** subroutine. */
if( ExprHasProperty(pExpr, EP_Subrtn) ){
ExplainQueryPlan((pParse, 0, "REUSE SUBQUERY %d", pSel->selId));
sqlite3VdbeAddOp2(v, OP_Gosub, pExpr->y.sub.regReturn,
pExpr->y.sub.iAddr);
return pExpr->iTable;
}
/* Begin coding the subroutine */
ExprSetProperty(pExpr, EP_Subrtn);
pExpr->y.sub.regReturn = ++pParse->nMem;
pExpr->y.sub.iAddr =
sqlite3VdbeAddOp2(v, OP_Integer, 0, pExpr->y.sub.regReturn) + 1;
VdbeComment((v, "return address"));
/* The evaluation of the EXISTS/SELECT must be repeated every time it
** is encountered if any of the following is true:
**
@@ -3117,22 +3135,6 @@ int sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){
** save the results, and reuse the same result on subsequent invocations.
*/
if( !ExprHasProperty(pExpr, EP_VarSelect) ){
/* If this routine has already been coded, then invoke it as a
** subroutine. */
if( ExprHasProperty(pExpr, EP_Subrtn) ){
ExplainQueryPlan((pParse, 0, "REUSE SUBQUERY %d", pSel->selId));
sqlite3VdbeAddOp2(v, OP_Gosub, pExpr->y.sub.regReturn,
pExpr->y.sub.iAddr);
return pExpr->iTable;
}
/* Begin coding the subroutine */
ExprSetProperty(pExpr, EP_Subrtn);
pExpr->y.sub.regReturn = ++pParse->nMem;
pExpr->y.sub.iAddr =
sqlite3VdbeAddOp2(v, OP_Integer, 0, pExpr->y.sub.regReturn) + 1;
VdbeComment((v, "return address"));
addrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v);
}
@@ -3181,19 +3183,22 @@ int sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){
}
pSel->iLimit = 0;
if( sqlite3Select(pParse, pSel, &dest) ){
if( pParse->nErr ){
pExpr->op2 = pExpr->op;
pExpr->op = TK_ERROR;
}
return 0;
}
pExpr->iTable = rReg = dest.iSDParm;
ExprSetVVAProperty(pExpr, EP_NoReduce);
if( addrOnce ){
sqlite3VdbeJumpHere(v, addrOnce);
/* Subroutine return */
sqlite3VdbeAddOp1(v, OP_Return, pExpr->y.sub.regReturn);
sqlite3VdbeChangeP1(v, pExpr->y.sub.iAddr-1, sqlite3VdbeCurrentAddr(v)-1);
sqlite3ClearTempRegCache(pParse);
}
/* Subroutine return */
sqlite3VdbeAddOp1(v, OP_Return, pExpr->y.sub.regReturn);
sqlite3VdbeChangeP1(v, pExpr->y.sub.iAddr-1, sqlite3VdbeCurrentAddr(v)-1);
sqlite3ClearTempRegCache(pParse);
return rReg;
}
#endif /* SQLITE_OMIT_SUBQUERY */
@@ -3207,7 +3212,7 @@ int sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){
*/
int sqlite3ExprCheckIN(Parse *pParse, Expr *pIn){
int nVector = sqlite3ExprVectorSize(pIn->pLeft);
if( (pIn->flags & EP_xIsSelect) ){
if( (pIn->flags & EP_xIsSelect)!=0 && !pParse->db->mallocFailed ){
if( nVector!=pIn->x.pSelect->pEList->nExpr ){
sqlite3SubselectError(pParse, pIn->x.pSelect->pEList->nExpr, nVector);
return 1;
@@ -4024,7 +4029,7 @@ expr_code_doover:
** Expr node to be passed into this function, it will be handled
** sanely and not crash. But keep the assert() to bring the problem
** to the attention of the developers. */
assert( op==TK_NULL || pParse->db->mallocFailed );
assert( op==TK_NULL || op==TK_ERROR || pParse->db->mallocFailed );
sqlite3VdbeAddOp2(v, OP_Null, 0, target);
return target;
}
@@ -4367,7 +4372,8 @@ expr_code_doover:
if( pExpr->pLeft->iTable==0 ){
pExpr->pLeft->iTable = sqlite3CodeSubselect(pParse, pExpr->pLeft);
}
assert( pExpr->iTable==0 || pExpr->pLeft->op==TK_SELECT );
assert( pExpr->iTable==0 || pExpr->pLeft->op==TK_SELECT
|| pExpr->pLeft->op==TK_ERROR );
if( pExpr->iTable!=0
&& pExpr->iTable!=(n = sqlite3ExprVectorSize(pExpr->pLeft))
){
+1 -1
View File
@@ -279,7 +279,7 @@ SQLITE_WSD struct Sqlite3Config sqlite3Config = {
0, /* xVdbeBranch */
0, /* pVbeBranchArg */
#endif
#ifdef SQLITE_ENABLE_DESERIALIZE
#ifndef SQLITE_OMIT_DESERIALIZE
SQLITE_MEMDB_DEFAULT_MAXSIZE, /* mxMemdbSize */
#endif
#ifndef SQLITE_UNTESTABLE
+7 -3
View File
@@ -305,7 +305,7 @@ int sqlite3_initialize(void){
sqlite3GlobalConfig.isPCacheInit = 1;
rc = sqlite3OsInit();
}
#ifdef SQLITE_ENABLE_DESERIALIZE
#ifndef SQLITE_OMIT_DESERIALIZE
if( rc==SQLITE_OK ){
rc = sqlite3MemdbInit();
}
@@ -720,12 +720,12 @@ int sqlite3_config(int op, ...){
}
#endif /* SQLITE_ENABLE_SORTER_REFERENCES */
#ifdef SQLITE_ENABLE_DESERIALIZE
#ifndef SQLITE_OMIT_DESERIALIZE
case SQLITE_CONFIG_MEMDB_MAXSIZE: {
sqlite3GlobalConfig.mxMemdbSize = va_arg(ap, sqlite3_int64);
break;
}
#endif /* SQLITE_ENABLE_DESERIALIZE */
#endif /* SQLITE_OMIT_DESERIALIZE */
default: {
rc = SQLITE_ERROR;
@@ -1884,6 +1884,10 @@ int sqlite3CreateFunc(
}else{
sqlite3ExpirePreparedStatements(db, 0);
}
}else if( xSFunc==0 && xFinal==0 ){
/* Trying to delete a function that does not exist. This is a no-op.
** https://sqlite.org/forum/forumpost/726219164b */
return SQLITE_OK;
}
p = sqlite3FindFunction(db, zFunctionName, nArg, (u8)enc, 1);
-1
View File
@@ -161,7 +161,6 @@ int sqlite3MallocInit(void){
if( sqlite3GlobalConfig.m.xMalloc==0 ){
sqlite3MemSetDefault();
}
memset(&mem0, 0, sizeof(mem0));
mem0.mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MEM);
if( sqlite3GlobalConfig.pPage==0 || sqlite3GlobalConfig.szPage<512
|| sqlite3GlobalConfig.nPage<=0 ){
+292 -53
View File
@@ -17,31 +17,88 @@
** sqlite3_deserialize().
*/
#include "sqliteInt.h"
#ifdef SQLITE_ENABLE_DESERIALIZE
#ifndef SQLITE_OMIT_DESERIALIZE
/*
** Forward declaration of objects used by this utility
*/
typedef struct sqlite3_vfs MemVfs;
typedef struct MemFile MemFile;
typedef struct MemStore MemStore;
/* Access to a lower-level VFS that (might) implement dynamic loading,
** access to randomness, etc.
*/
#define ORIGVFS(p) ((sqlite3_vfs*)((p)->pAppData))
/* An open file */
struct MemFile {
sqlite3_file base; /* IO methods */
/* Storage for a memdb file.
**
** An memdb object can be shared or separate. Shared memdb objects can be
** used by more than one database connection. Mutexes are used by shared
** memdb objects to coordinate access. Separate memdb objects are only
** connected to a single database connection and do not require additional
** mutexes.
**
** Shared memdb objects have .zFName!=0 and .pMutex!=0. They are created
** using "file:/name?vfs=memdb". The first character of the name must be
** "/" or else the object will be a separate memdb object. All shared
** memdb objects are stored in memdb_g.apMemStore[] in an arbitrary order.
**
** Separate memdb objects are created using a name that does not begin
** with "/" or using sqlite3_deserialize().
**
** Access rules for shared MemStore objects:
**
** * .zFName is initialized when the object is created and afterwards
** is unchanged until the object is destroyed. So it can be accessed
** at any time as long as we know the object is not being destroyed,
** which means while either the SQLITE_MUTEX_STATIC_VFS1 or
** .pMutex is held or the object is not part of memdb_g.apMemStore[].
**
** * Can .pMutex can only be changed while holding the
** SQLITE_MUTEX_STATIC_VFS1 mutex or while the object is not part
** of memdb_g.apMemStore[].
**
** * Other fields can only be changed while holding the .pMutex mutex
** or when the .nRef is less than zero and the object is not part of
** memdb_g.apMemStore[].
**
** * The .aData pointer has the added requirement that it can can only
** be changed (for resizing) when nMmap is zero.
**
*/
struct MemStore {
sqlite3_int64 sz; /* Size of the file */
sqlite3_int64 szAlloc; /* Space allocated to aData */
sqlite3_int64 szMax; /* Maximum allowed size of the file */
unsigned char *aData; /* content of the file */
sqlite3_mutex *pMutex; /* Used by shared stores only */
int nMmap; /* Number of memory mapped pages */
unsigned mFlags; /* Flags */
int nRdLock; /* Number of readers */
int nWrLock; /* Number of writers. (Always 0 or 1) */
int nRef; /* Number of users of this MemStore */
char *zFName; /* The filename for shared stores */
};
/* An open file */
struct MemFile {
sqlite3_file base; /* IO methods */
MemStore *pStore; /* The storage */
int eLock; /* Most recent lock against this file */
};
/*
** File-scope variables for holding the memdb files that are accessible
** to multiple database connections in separate threads.
**
** Must hold SQLITE_MUTEX_STATIC_VFS1 to access any part of this object.
*/
static struct MemFS {
int nMemStore; /* Number of shared MemStore objects */
MemStore **apMemStore; /* Array of all shared MemStore objects */
} memdb_g;
/*
** Methods for MemFile
*/
@@ -95,7 +152,10 @@ static sqlite3_vfs memdb_vfs = {
memdbSleep, /* xSleep */
0, /* memdbCurrentTime, */ /* xCurrentTime */
memdbGetLastError, /* xGetLastError */
memdbCurrentTimeInt64 /* xCurrentTimeInt64 */
memdbCurrentTimeInt64, /* xCurrentTimeInt64 */
0, /* xSetSystemCall */
0, /* xGetSystemCall */
0, /* xNextSystemCall */
};
static const sqlite3_io_methods memdb_io_methods = {
@@ -120,19 +180,67 @@ static const sqlite3_io_methods memdb_io_methods = {
memdbUnfetch /* xUnfetch */
};
/*
** Enter/leave the mutex on a MemStore
*/
#if defined(SQLITE_THREADSAFE) && SQLITE_THREADSAFE==0
static void memdbEnter(MemStore *p){
UNUSED_PARAMETER(p);
}
static void memdbLeave(MemStore *p){
UNUSED_PARAMETER(p);
}
#else
static void memdbEnter(MemStore *p){
sqlite3_mutex_enter(p->pMutex);
}
static void memdbLeave(MemStore *p){
sqlite3_mutex_leave(p->pMutex);
}
#endif
/*
** Close an memdb-file.
**
** The pData pointer is owned by the application, so there is nothing
** to free. Unless the SQLITE_DESERIALIZE_FREEONCLOSE flag is set,
** in which case we own the pData pointer and need to free it.
** Free the underlying MemStore object when its refcount drops to zero
** or less.
*/
static int memdbClose(sqlite3_file *pFile){
MemFile *p = (MemFile *)pFile;
if( p->mFlags & SQLITE_DESERIALIZE_FREEONCLOSE ){
sqlite3_free(p->aData);
MemStore *p = ((MemFile*)pFile)->pStore;
if( p->zFName ){
int i;
#ifndef SQLITE_MUTEX_OMIT
sqlite3_mutex *pVfsMutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_VFS1);
#endif
sqlite3_mutex_enter(pVfsMutex);
for(i=0; ALWAYS(i<memdb_g.nMemStore); i++){
if( memdb_g.apMemStore[i]==p ){
memdbEnter(p);
if( p->nRef==1 ){
memdb_g.apMemStore[i] = memdb_g.apMemStore[--memdb_g.nMemStore];
if( memdb_g.nMemStore==0 ){
sqlite3_free(memdb_g.apMemStore);
memdb_g.apMemStore = 0;
}
}
break;
}
}
sqlite3_mutex_leave(pVfsMutex);
}else{
memdbEnter(p);
}
p->nRef--;
if( p->nRef<=0 ){
if( p->mFlags & SQLITE_DESERIALIZE_FREEONCLOSE ){
sqlite3_free(p->aData);
}
memdbLeave(p);
sqlite3_mutex_free(p->pMutex);
sqlite3_free(p);
}else{
memdbLeave(p);
}
return SQLITE_OK;
}
@@ -146,20 +254,23 @@ static int memdbRead(
int iAmt,
sqlite_int64 iOfst
){
MemFile *p = (MemFile *)pFile;
MemStore *p = ((MemFile*)pFile)->pStore;
memdbEnter(p);
if( iOfst+iAmt>p->sz ){
memset(zBuf, 0, iAmt);
if( iOfst<p->sz ) memcpy(zBuf, p->aData+iOfst, p->sz - iOfst);
memdbLeave(p);
return SQLITE_IOERR_SHORT_READ;
}
memcpy(zBuf, p->aData+iOfst, iAmt);
memdbLeave(p);
return SQLITE_OK;
}
/*
** Try to enlarge the memory allocation to hold at least sz bytes
*/
static int memdbEnlarge(MemFile *p, sqlite3_int64 newSz){
static int memdbEnlarge(MemStore *p, sqlite3_int64 newSz){
unsigned char *pNew;
if( (p->mFlags & SQLITE_DESERIALIZE_RESIZEABLE)==0 || p->nMmap>0 ){
return SQLITE_FULL;
@@ -185,19 +296,27 @@ static int memdbWrite(
int iAmt,
sqlite_int64 iOfst
){
MemFile *p = (MemFile *)pFile;
if( NEVER(p->mFlags & SQLITE_DESERIALIZE_READONLY) ) return SQLITE_READONLY;
MemStore *p = ((MemFile*)pFile)->pStore;
memdbEnter(p);
if( NEVER(p->mFlags & SQLITE_DESERIALIZE_READONLY) ){
/* Can't happen: memdbLock() will return SQLITE_READONLY before
** reaching this point */
memdbLeave(p);
return SQLITE_IOERR_WRITE;
}
if( iOfst+iAmt>p->sz ){
int rc;
if( iOfst+iAmt>p->szAlloc
&& (rc = memdbEnlarge(p, iOfst+iAmt))!=SQLITE_OK
){
memdbLeave(p);
return rc;
}
if( iOfst>p->sz ) memset(p->aData+p->sz, 0, iOfst-p->sz);
p->sz = iOfst+iAmt;
}
memcpy(p->aData+iOfst, z, iAmt);
memdbLeave(p);
return SQLITE_OK;
}
@@ -209,16 +328,24 @@ static int memdbWrite(
** the size of a file, never to increase the size.
*/
static int memdbTruncate(sqlite3_file *pFile, sqlite_int64 size){
MemFile *p = (MemFile *)pFile;
if( NEVER(size>p->sz) ) return SQLITE_FULL;
p->sz = size;
return SQLITE_OK;
MemStore *p = ((MemFile*)pFile)->pStore;
int rc = SQLITE_OK;
memdbEnter(p);
if( NEVER(size>p->sz) ){
rc = SQLITE_FULL;
}else{
p->sz = size;
}
memdbLeave(p);
return rc;
}
/*
** Sync an memdb-file.
*/
static int memdbSync(sqlite3_file *pFile, int flags){
UNUSED_PARAMETER(pFile);
UNUSED_PARAMETER(flags);
return SQLITE_OK;
}
@@ -226,8 +353,10 @@ static int memdbSync(sqlite3_file *pFile, int flags){
** Return the current file-size of an memdb-file.
*/
static int memdbFileSize(sqlite3_file *pFile, sqlite_int64 *pSize){
MemFile *p = (MemFile *)pFile;
MemStore *p = ((MemFile*)pFile)->pStore;
memdbEnter(p);
*pSize = p->sz;
memdbLeave(p);
return SQLITE_OK;
}
@@ -235,19 +364,48 @@ static int memdbFileSize(sqlite3_file *pFile, sqlite_int64 *pSize){
** Lock an memdb-file.
*/
static int memdbLock(sqlite3_file *pFile, int eLock){
MemFile *p = (MemFile *)pFile;
if( eLock>SQLITE_LOCK_SHARED
&& (p->mFlags & SQLITE_DESERIALIZE_READONLY)!=0
){
return SQLITE_READONLY;
MemFile *pThis = (MemFile*)pFile;
MemStore *p = pThis->pStore;
int rc = SQLITE_OK;
if( eLock==pThis->eLock ) return SQLITE_OK;
memdbEnter(p);
if( eLock>SQLITE_LOCK_SHARED ){
if( p->mFlags & SQLITE_DESERIALIZE_READONLY ){
rc = SQLITE_READONLY;
}else if( pThis->eLock<=SQLITE_LOCK_SHARED ){
if( p->nWrLock ){
rc = SQLITE_BUSY;
}else{
p->nWrLock = 1;
}
}
}else if( eLock==SQLITE_LOCK_SHARED ){
if( pThis->eLock > SQLITE_LOCK_SHARED ){
assert( p->nWrLock==1 );
p->nWrLock = 0;
}else if( p->nWrLock ){
rc = SQLITE_BUSY;
}else{
p->nRdLock++;
}
}else{
assert( eLock==SQLITE_LOCK_NONE );
if( pThis->eLock>SQLITE_LOCK_SHARED ){
assert( p->nWrLock==1 );
p->nWrLock = 0;
}
assert( p->nRdLock>0 );
p->nRdLock--;
}
p->eLock = eLock;
return SQLITE_OK;
if( rc==SQLITE_OK ) pThis->eLock = eLock;
memdbLeave(p);
return rc;
}
#if 0 /* Never used because memdbAccess() always returns false */
#if 0
/*
** Check if another file-handle holds a RESERVED lock on an memdb-file.
** This interface is only used for crash recovery, which does not
** occur on an in-memory database.
*/
static int memdbCheckReservedLock(sqlite3_file *pFile, int *pResOut){
*pResOut = 0;
@@ -255,12 +413,14 @@ static int memdbCheckReservedLock(sqlite3_file *pFile, int *pResOut){
}
#endif
/*
** File control method. For custom operations on an memdb-file.
*/
static int memdbFileControl(sqlite3_file *pFile, int op, void *pArg){
MemFile *p = (MemFile *)pFile;
MemStore *p = ((MemFile*)pFile)->pStore;
int rc = SQLITE_NOTFOUND;
memdbEnter(p);
if( op==SQLITE_FCNTL_VFSNAME ){
*(char**)pArg = sqlite3_mprintf("memdb(%p,%lld)", p->aData, p->sz);
rc = SQLITE_OK;
@@ -278,6 +438,7 @@ static int memdbFileControl(sqlite3_file *pFile, int op, void *pArg){
*(sqlite3_int64*)pArg = iLimit;
rc = SQLITE_OK;
}
memdbLeave(p);
return rc;
}
@@ -294,6 +455,7 @@ static int memdbSectorSize(sqlite3_file *pFile){
** Return the device characteristic flags supported by an memdb-file.
*/
static int memdbDeviceCharacteristics(sqlite3_file *pFile){
UNUSED_PARAMETER(pFile);
return SQLITE_IOCAP_ATOMIC |
SQLITE_IOCAP_POWERSAFE_OVERWRITE |
SQLITE_IOCAP_SAFE_APPEND |
@@ -307,20 +469,26 @@ static int memdbFetch(
int iAmt,
void **pp
){
MemFile *p = (MemFile *)pFile;
MemStore *p = ((MemFile*)pFile)->pStore;
memdbEnter(p);
if( iOfst+iAmt>p->sz ){
*pp = 0;
}else{
p->nMmap++;
*pp = (void*)(p->aData + iOfst);
}
memdbLeave(p);
return SQLITE_OK;
}
/* Release a memory-mapped page */
static int memdbUnfetch(sqlite3_file *pFile, sqlite3_int64 iOfst, void *pPage){
MemFile *p = (MemFile *)pFile;
MemStore *p = ((MemFile*)pFile)->pStore;
UNUSED_PARAMETER(iOfst);
UNUSED_PARAMETER(pPage);
memdbEnter(p);
p->nMmap--;
memdbLeave(p);
return SQLITE_OK;
}
@@ -330,20 +498,79 @@ static int memdbUnfetch(sqlite3_file *pFile, sqlite3_int64 iOfst, void *pPage){
static int memdbOpen(
sqlite3_vfs *pVfs,
const char *zName,
sqlite3_file *pFile,
sqlite3_file *pFd,
int flags,
int *pOutFlags
){
MemFile *p = (MemFile*)pFile;
MemFile *pFile = (MemFile*)pFd;
MemStore *p = 0;
int szName;
if( (flags & SQLITE_OPEN_MAIN_DB)==0 ){
return ORIGVFS(pVfs)->xOpen(ORIGVFS(pVfs), zName, pFile, flags, pOutFlags);
return ORIGVFS(pVfs)->xOpen(ORIGVFS(pVfs), zName, pFd, flags, pOutFlags);
}
memset(p, 0, sizeof(*p));
p->mFlags = SQLITE_DESERIALIZE_RESIZEABLE | SQLITE_DESERIALIZE_FREEONCLOSE;
memset(pFile, 0, sizeof(*p));
szName = sqlite3Strlen30(zName);
if( szName>1 && zName[0]=='/' ){
int i;
#ifndef SQLITE_MUTEX_OMIT
sqlite3_mutex *pVfsMutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_VFS1);
#endif
sqlite3_mutex_enter(pVfsMutex);
for(i=0; i<memdb_g.nMemStore; i++){
if( strcmp(memdb_g.apMemStore[i]->zFName,zName)==0 ){
p = memdb_g.apMemStore[i];
break;
}
}
if( p==0 ){
MemStore **apNew;
p = sqlite3Malloc( sizeof(*p) + szName + 3 );
if( p==0 ){
sqlite3_mutex_leave(pVfsMutex);
return SQLITE_NOMEM;
}
apNew = sqlite3Realloc(memdb_g.apMemStore,
sizeof(apNew[0])*(memdb_g.nMemStore+1) );
if( apNew==0 ){
sqlite3_free(p);
sqlite3_mutex_leave(pVfsMutex);
return SQLITE_NOMEM;
}
apNew[memdb_g.nMemStore++] = p;
memdb_g.apMemStore = apNew;
memset(p, 0, sizeof(*p));
p->mFlags = SQLITE_DESERIALIZE_RESIZEABLE|SQLITE_DESERIALIZE_FREEONCLOSE;
p->szMax = sqlite3GlobalConfig.mxMemdbSize;
p->zFName = (char*)&p[1];
memcpy(p->zFName, zName, szName+1);
p->pMutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
if( p->pMutex==0 ){
memdb_g.nMemStore--;
sqlite3_free(p);
sqlite3_mutex_leave(pVfsMutex);
return SQLITE_NOMEM;
}
p->nRef = 1;
memdbEnter(p);
}else{
memdbEnter(p);
p->nRef++;
}
sqlite3_mutex_leave(pVfsMutex);
}else{
p = sqlite3Malloc( sizeof(*p) );
if( p==0 ){
return SQLITE_NOMEM;
}
memset(p, 0, sizeof(*p));
p->mFlags = SQLITE_DESERIALIZE_RESIZEABLE | SQLITE_DESERIALIZE_FREEONCLOSE;
p->szMax = sqlite3GlobalConfig.mxMemdbSize;
}
pFile->pStore = p;
assert( pOutFlags!=0 ); /* True because flags==SQLITE_OPEN_MAIN_DB */
*pOutFlags = flags | SQLITE_OPEN_MEMORY;
pFile->pMethods = &memdb_io_methods;
p->szMax = sqlite3GlobalConfig.mxMemdbSize;
pFd->pMethods = &memdb_io_methods;
memdbLeave(p);
return SQLITE_OK;
}
@@ -371,6 +598,9 @@ static int memdbAccess(
int flags,
int *pResOut
){
UNUSED_PARAMETER(pVfs);
UNUSED_PARAMETER(zPath);
UNUSED_PARAMETER(flags);
*pResOut = 0;
return SQLITE_OK;
}
@@ -386,6 +616,7 @@ static int memdbFullPathname(
int nOut,
char *zOut
){
UNUSED_PARAMETER(pVfs);
sqlite3_snprintf(nOut, zOut, "%s", zPath);
return SQLITE_OK;
}
@@ -458,9 +689,14 @@ static int memdbCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *p){
*/
static MemFile *memdbFromDbSchema(sqlite3 *db, const char *zSchema){
MemFile *p = 0;
MemStore *pStore;
int rc = sqlite3_file_control(db, zSchema, SQLITE_FCNTL_FILE_POINTER, &p);
if( rc ) return 0;
if( p->base.pMethods!=&memdb_io_methods ) return 0;
pStore = p->pStore;
memdbEnter(pStore);
if( pStore->zFName!=0 ) p = 0;
memdbLeave(pStore);
return p;
}
@@ -496,12 +732,14 @@ unsigned char *sqlite3_serialize(
if( piSize ) *piSize = -1;
if( iDb<0 ) return 0;
if( p ){
if( piSize ) *piSize = p->sz;
MemStore *pStore = p->pStore;
assert( pStore->pMutex==0 );
if( piSize ) *piSize = pStore->sz;
if( mFlags & SQLITE_SERIALIZE_NOCOPY ){
pOut = p->aData;
pOut = pStore->aData;
}else{
pOut = sqlite3_malloc64( p->sz );
if( pOut ) memcpy(pOut, p->aData, p->sz);
pOut = sqlite3_malloc64( pStore->sz );
if( pOut ) memcpy(pOut, pStore->aData, pStore->sz);
}
return pOut;
}
@@ -595,15 +833,16 @@ int sqlite3_deserialize(
if( p==0 ){
rc = SQLITE_ERROR;
}else{
p->aData = pData;
MemStore *pStore = p->pStore;
pStore->aData = pData;
pData = 0;
p->sz = szDb;
p->szAlloc = szBuf;
p->szMax = szBuf;
if( p->szMax<sqlite3GlobalConfig.mxMemdbSize ){
p->szMax = sqlite3GlobalConfig.mxMemdbSize;
pStore->sz = szDb;
pStore->szAlloc = szBuf;
pStore->szMax = szBuf;
if( pStore->szMax<sqlite3GlobalConfig.mxMemdbSize ){
pStore->szMax = sqlite3GlobalConfig.mxMemdbSize;
}
p->mFlags = mFlags;
pStore->mFlags = mFlags;
rc = SQLITE_OK;
}
@@ -622,7 +861,7 @@ end_deserialize:
*/
int sqlite3MemdbInit(void){
sqlite3_vfs *pLower = sqlite3_vfs_find(0);
int sz = pLower->szOsFile;
unsigned int sz = pLower->szOsFile;
memdb_vfs.pAppData = pLower;
/* The following conditional can only be true when compiled for
** Windows x86 and SQLITE_MAX_MMAP_SIZE=0. We always leave
@@ -632,4 +871,4 @@ int sqlite3MemdbInit(void){
memdb_vfs.szOsFile = sz;
return sqlite3_vfs_register(&memdb_vfs, 0);
}
#endif /* SQLITE_ENABLE_DESERIALIZE */
#endif /* SQLITE_OMIT_DESERIALIZE */
+20 -18
View File
@@ -257,26 +257,28 @@ static int memjrnlWrite(
*/
static int memjrnlTruncate(sqlite3_file *pJfd, sqlite_int64 size){
MemJournal *p = (MemJournal *)pJfd;
FileChunk *pIter = 0;
assert( p->endpoint.pChunk==0 || p->endpoint.pChunk->pNext==0 );
if( size<p->endpoint.iOffset ){
FileChunk *pIter = 0;
if( size==0 ){
memjrnlFreeChunks(p->pFirst);
p->pFirst = 0;
}else{
i64 iOff = p->nChunkSize;
for(pIter=p->pFirst; ALWAYS(pIter) && iOff<=size; pIter=pIter->pNext){
iOff += p->nChunkSize;
}
if( ALWAYS(pIter) ){
memjrnlFreeChunks(pIter->pNext);
pIter->pNext = 0;
}
}
if( size==0 ){
memjrnlFreeChunks(p->pFirst);
p->pFirst = 0;
}else{
i64 iOff = p->nChunkSize;
for(pIter=p->pFirst; ALWAYS(pIter) && iOff<=size; pIter=pIter->pNext){
iOff += p->nChunkSize;
}
if( ALWAYS(pIter) ){
memjrnlFreeChunks(pIter->pNext);
pIter->pNext = 0;
}
p->endpoint.pChunk = pIter;
p->endpoint.iOffset = size;
p->readpoint.pChunk = 0;
p->readpoint.iOffset = 0;
}
p->endpoint.pChunk = pIter;
p->endpoint.iOffset = size;
p->readpoint.pChunk = 0;
p->readpoint.iOffset = 0;
return SQLITE_OK;
}
+16
View File
@@ -8067,6 +8067,22 @@ int sqlite3_os_init(void){
sqlite3_vfs_register(&aVfs[i], i==0);
}
unixBigLock = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_VFS1);
/* Validate lock assumptions */
assert( SQLITE_SHM_NLOCK==8 ); /* Number of available locks */
assert( UNIX_SHM_BASE==120 ); /* Start of locking area */
/* Locks:
** WRITE UNIX_SHM_BASE 120
** CKPT UNIX_SHM_BASE+1 121
** RECOVER UNIX_SHM_BASE+2 122
** READ-0 UNIX_SHM_BASE+3 123
** READ-1 UNIX_SHM_BASE+4 124
** READ-2 UNIX_SHM_BASE+5 125
** READ-3 UNIX_SHM_BASE+6 126
** READ-4 UNIX_SHM_BASE+7 127
** DMS UNIX_SHM_BASE+8 128
*/
assert( UNIX_SHM_DMS==128 ); /* Byte offset of the deadman-switch */
return SQLITE_OK;
}
+2 -2
View File
@@ -4665,7 +4665,7 @@ int sqlite3PagerOpen(
int rc = SQLITE_OK; /* Return code */
int tempFile = 0; /* True for temp files (incl. in-memory files) */
int memDb = 0; /* True if this is an in-memory file */
#ifdef SQLITE_ENABLE_DESERIALIZE
#ifndef SQLITE_OMIT_DESERIALIZE
int memJM = 0; /* Memory journal mode */
#else
# define memJM 0
@@ -4869,7 +4869,7 @@ int sqlite3PagerOpen(
int fout = 0; /* VFS flags returned by xOpen() */
rc = sqlite3OsOpen(pVfs, pPager->zFilename, pPager->fd, vfsFlags, &fout);
assert( !memDb );
#ifdef SQLITE_ENABLE_DESERIALIZE
#ifndef SQLITE_OMIT_DESERIALIZE
memJM = (fout&SQLITE_OPEN_MEMORY)!=0;
#endif
readOnly = (fout&SQLITE_OPEN_READONLY)!=0;
+2 -1
View File
@@ -193,7 +193,7 @@ ifnotexists(A) ::= . {A = 0;}
ifnotexists(A) ::= IF NOT EXISTS. {A = 1;}
%type temp {int}
%ifndef SQLITE_OMIT_TEMPDB
temp(A) ::= TEMP. {A = 1;}
temp(A) ::= TEMP. {A = pParse->db->init.busy==0;}
%endif SQLITE_OMIT_TEMPDB
temp(A) ::= . {A = 0;}
create_table_args ::= LP columnlist conslist_opt(X) RP(E) table_options(F). {
@@ -1855,6 +1855,7 @@ filter_clause(A) ::= FILTER LP WHERE expr(X) RP. { A = X; }
IF_NULL_ROW /* the if-null-row operator */
ASTERISK /* The "*" in count(*) and similar */
SPAN /* The span operator */
ERROR /* An expression containing an error */
.
/* There must be no more than 255 tokens defined above. If this grammar
** is extended with new rules and tokens, they must either be so few in
+18 -17
View File
@@ -81,7 +81,10 @@ static void resolveAlias(
assert( pOrig!=0 );
db = pParse->db;
pDup = sqlite3ExprDup(db, pOrig, 0);
if( pDup!=0 ){
if( db->mallocFailed ){
sqlite3ExprDelete(db, pDup);
pDup = 0;
}else{
incrAggFunctionDepth(pDup, nSubquery);
if( pExpr->op==TK_COLLATE ){
pDup = sqlite3ExprAddCollateString(pParse, pDup, pExpr->u.zToken);
@@ -103,10 +106,8 @@ static void resolveAlias(
pExpr->flags |= EP_MemToken;
}
if( ExprHasProperty(pExpr, EP_WinFunc) ){
if( pExpr->y.pWin!=0 ){
if( ALWAYS(pExpr->y.pWin!=0) ){
pExpr->y.pWin->pOwner = pExpr;
}else{
assert( db->mallocFailed );
}
}
sqlite3DbFree(db, pDup);
@@ -1714,6 +1715,19 @@ static int resolveSelectStep(Walker *pWalker, Select *p){
}
}
#ifndef SQLITE_OMIT_WINDOWFUNC
if( IN_RENAME_OBJECT ){
Window *pWin;
for(pWin=p->pWinDefn; pWin; pWin=pWin->pNextWin){
if( sqlite3ResolveExprListNames(&sNC, pWin->pOrderBy)
|| sqlite3ResolveExprListNames(&sNC, pWin->pPartition)
){
return WRC_Abort;
}
}
}
#endif
/* The ORDER BY and GROUP BY clauses may not refer to terms in
** outer queries
*/
@@ -1770,19 +1784,6 @@ static int resolveSelectStep(Walker *pWalker, Select *p){
}
}
#ifndef SQLITE_OMIT_WINDOWFUNC
if( IN_RENAME_OBJECT ){
Window *pWin;
for(pWin=p->pWinDefn; pWin; pWin=pWin->pNextWin){
if( sqlite3ResolveExprListNames(&sNC, pWin->pOrderBy)
|| sqlite3ResolveExprListNames(&sNC, pWin->pPartition)
){
return WRC_Abort;
}
}
}
#endif
/* If this is part of a compound SELECT, check that it has the right
** number of expressions in the select list. */
if( p->pNext && p->pEList->nExpr!=p->pNext->pEList->nExpr ){
+121 -37
View File
@@ -1955,7 +1955,7 @@ static void generateColumnTypes(
** then the result column name with the table name
** prefix, ex: TABLE.COLUMN. Otherwise use zSpan.
*/
static void generateColumnNames(
void sqlite3GenerateColumnNames(
Parse *pParse, /* Parser context */
Select *pSelect /* Generate column names for this SELECT statement */
){
@@ -2045,7 +2045,7 @@ static void generateColumnNames(
** and will break if those assumptions changes. Hence, use extreme caution
** when modifying this routine to avoid breaking legacy.
**
** See Also: generateColumnNames()
** See Also: sqlite3GenerateColumnNames()
*/
int sqlite3ColumnsFromExprList(
Parse *pParse, /* Parsing context */
@@ -2748,6 +2748,7 @@ static int multiSelect(
pPrior->iLimit = p->iLimit;
pPrior->iOffset = p->iOffset;
pPrior->pLimit = p->pLimit;
SELECTTRACE(1, pParse, p, ("multiSelect UNION ALL left...\n"));
rc = sqlite3Select(pParse, pPrior, &dest);
pPrior->pLimit = 0;
if( rc ){
@@ -2765,6 +2766,7 @@ static int multiSelect(
}
}
ExplainQueryPlan((pParse, 1, "UNION ALL"));
SELECTTRACE(1, pParse, p, ("multiSelect UNION ALL right...\n"));
rc = sqlite3Select(pParse, p, &dest);
testcase( rc!=SQLITE_OK );
pDelete = p->pPrior;
@@ -2817,6 +2819,7 @@ static int multiSelect(
*/
assert( !pPrior->pOrderBy );
sqlite3SelectDestInit(&uniondest, priorOp, unionTab);
SELECTTRACE(1, pParse, p, ("multiSelect EXCEPT/UNION left...\n"));
rc = sqlite3Select(pParse, pPrior, &uniondest);
if( rc ){
goto multi_select_end;
@@ -2836,6 +2839,7 @@ static int multiSelect(
uniondest.eDest = op;
ExplainQueryPlan((pParse, 1, "%s USING TEMP B-TREE",
sqlite3SelectOpName(p->op)));
SELECTTRACE(1, pParse, p, ("multiSelect EXCEPT/UNION right...\n"));
rc = sqlite3Select(pParse, p, &uniondest);
testcase( rc!=SQLITE_OK );
assert( p->pOrderBy==0 );
@@ -2896,6 +2900,7 @@ static int multiSelect(
/* Code the SELECTs to our left into temporary table "tab1".
*/
sqlite3SelectDestInit(&intersectdest, SRT_Union, tab1);
SELECTTRACE(1, pParse, p, ("multiSelect INTERSECT left...\n"));
rc = sqlite3Select(pParse, pPrior, &intersectdest);
if( rc ){
goto multi_select_end;
@@ -2912,6 +2917,7 @@ static int multiSelect(
intersectdest.iSDParm = tab2;
ExplainQueryPlan((pParse, 1, "%s USING TEMP B-TREE",
sqlite3SelectOpName(p->op)));
SELECTTRACE(1, pParse, p, ("multiSelect INTERSECT right...\n"));
rc = sqlite3Select(pParse, p, &intersectdest);
testcase( rc!=SQLITE_OK );
pDelete = p->pPrior;
@@ -3767,7 +3773,10 @@ static void srclistRenumberCursors(
for(i=0, pItem=pSrc->a; i<pSrc->nSrc; i++, pItem++){
if( i!=iExcept ){
Select *p;
pItem->iCursor = aCsrMap[pItem->iCursor] = pParse->nTab++;
if( !pItem->fg.isRecursive || aCsrMap[pItem->iCursor]==0 ){
aCsrMap[pItem->iCursor] = pParse->nTab++;
}
pItem->iCursor = aCsrMap[pItem->iCursor];
for(p=pItem->pSelect; p; p=p->pPrior){
srclistRenumberCursors(pParse, aCsrMap, p->pSrc, -1);
}
@@ -4408,6 +4417,7 @@ struct WhereConst {
Parse *pParse; /* Parsing context */
int nConst; /* Number for COLUMN=CONSTANT terms */
int nChng; /* Number of times a constant is propagated */
int bHasAffBlob; /* At least one column in apExpr[] as affinity BLOB */
Expr **apExpr; /* [i*2] is COLUMN and [i*2+1] is VALUE */
};
@@ -4446,6 +4456,9 @@ static void constInsert(
return; /* Already present. Return without doing anything. */
}
}
if( sqlite3ExprAffinity(pColumn)==SQLITE_AFF_BLOB ){
pConst->bHasAffBlob = 1;
}
pConst->nConst++;
pConst->apExpr = sqlite3DbReallocOrFree(pConst->pParse->db, pConst->apExpr,
@@ -4466,7 +4479,7 @@ static void constInsert(
*/
static void findConstInWhere(WhereConst *pConst, Expr *pExpr){
Expr *pRight, *pLeft;
if( pExpr==0 ) return;
if( NEVER(pExpr==0) ) return;
if( ExprHasProperty(pExpr, EP_FromJoin) ) return;
if( pExpr->op==TK_AND ){
findConstInWhere(pConst, pExpr->pRight);
@@ -4487,26 +4500,34 @@ static void findConstInWhere(WhereConst *pConst, Expr *pExpr){
}
/*
** This is a Walker expression callback. pExpr is a candidate expression
** to be replaced by a value. If pExpr is equivalent to one of the
** columns named in pWalker->u.pConst, then overwrite it with its
** corresponding value.
** This is a helper function for Walker callback propagateConstantExprRewrite().
**
** Argument pExpr is a candidate expression to be replaced by a value. If
** pExpr is equivalent to one of the columns named in pWalker->u.pConst,
** then overwrite it with the corresponding value. Except, do not do so
** if argument bIgnoreAffBlob is non-zero and the affinity of pExpr
** is SQLITE_AFF_BLOB.
*/
static int propagateConstantExprRewrite(Walker *pWalker, Expr *pExpr){
static int propagateConstantExprRewriteOne(
WhereConst *pConst,
Expr *pExpr,
int bIgnoreAffBlob
){
int i;
WhereConst *pConst;
if( pExpr->op!=TK_COLUMN ) return WRC_Continue;
if( ExprHasProperty(pExpr, EP_FixedCol|EP_FromJoin) ){
testcase( ExprHasProperty(pExpr, EP_FixedCol) );
testcase( ExprHasProperty(pExpr, EP_FromJoin) );
return WRC_Continue;
}
pConst = pWalker->u.pConst;
for(i=0; i<pConst->nConst; i++){
Expr *pColumn = pConst->apExpr[i*2];
if( pColumn==pExpr ) continue;
if( pColumn->iTable!=pExpr->iTable ) continue;
if( pColumn->iColumn!=pExpr->iColumn ) continue;
if( bIgnoreAffBlob && sqlite3ExprAffinity(pColumn)==SQLITE_AFF_BLOB ){
break;
}
/* A match is found. Add the EP_FixedCol property */
pConst->nChng++;
ExprClearProperty(pExpr, EP_Leaf);
@@ -4518,6 +4539,41 @@ static int propagateConstantExprRewrite(Walker *pWalker, Expr *pExpr){
return WRC_Prune;
}
/*
** This is a Walker expression callback. pExpr is a node from the WHERE
** clause of a SELECT statement. This function examines pExpr to see if
** any substitutions based on the contents of pWalker->u.pConst should
** be made to pExpr or its immediate children.
**
** A substitution is made if:
**
** + pExpr is a column with an affinity other than BLOB that matches
** one of the columns in pWalker->u.pConst, or
**
** + pExpr is a binary comparison operator (=, <=, >=, <, >) that
** uses an affinity other than TEXT and one of its immediate
** children is a column that matches one of the columns in
** pWalker->u.pConst.
*/
static int propagateConstantExprRewrite(Walker *pWalker, Expr *pExpr){
WhereConst *pConst = pWalker->u.pConst;
assert( TK_GT==TK_EQ+1 );
assert( TK_LE==TK_EQ+2 );
assert( TK_LT==TK_EQ+3 );
assert( TK_GE==TK_EQ+4 );
if( pConst->bHasAffBlob ){
if( (pExpr->op>=TK_EQ && pExpr->op<=TK_GE)
|| pExpr->op==TK_IS
){
propagateConstantExprRewriteOne(pConst, pExpr->pLeft, 0);
if( sqlite3ExprAffinity(pExpr->pLeft)!=SQLITE_AFF_TEXT ){
propagateConstantExprRewriteOne(pConst, pExpr->pRight, 0);
}
}
}
return propagateConstantExprRewriteOne(pConst, pExpr, pConst->bHasAffBlob);
}
/*
** The WHERE-clause constant propagation optimization.
**
@@ -4553,6 +4609,21 @@ static int propagateConstantExprRewrite(Walker *pWalker, Expr *pExpr){
** routines know to generate the constant "123" instead of looking up the
** column value. Also, to avoid collation problems, this optimization is
** only attempted if the "a=123" term uses the default BINARY collation.
**
** 2021-05-25 forum post 6a06202608: Another troublesome case is...
**
** CREATE TABLE t1(x);
** INSERT INTO t1 VALUES(10.0);
** SELECT 1 FROM t1 WHERE x=10 AND x LIKE 10;
**
** The query should return no rows, because the t1.x value is '10.0' not '10'
** and '10.0' is not LIKE '10'. But if we are not careful, the first WHERE
** term "x=10" will cause the second WHERE term to become "10 LIKE 10",
** resulting in a false positive. To avoid this, constant propagation for
** columns with BLOB affinity is only allowed if the constant is used with
** operators ==, <=, <, >=, >, or IS in a way that will cause the correct
** type conversions to occur. See logic associated with the bHasAffBlob flag
** for details.
*/
static int propagateConstants(
Parse *pParse, /* The parsing context */
@@ -4566,6 +4637,7 @@ static int propagateConstants(
x.nConst = 0;
x.nChng = 0;
x.apExpr = 0;
x.bHasAffBlob = 0;
findConstInWhere(&x, p->pWhere);
if( x.nConst ){
memset(&w, 0, sizeof(w));
@@ -5002,6 +5074,7 @@ static struct Cte *searchWith(
return &p->a[i];
}
}
if( p->bView ) break;
}
return 0;
}
@@ -5011,16 +5084,18 @@ static struct Cte *searchWith(
**
** This routine pushes the WITH clause passed as the second argument
** onto the top of the stack. If argument bFree is true, then this
** WITH clause will never be popped from the stack. In this case it
** should be freed along with the Parse object. In other cases, when
** WITH clause will never be popped from the stack but should instead
** be freed along with the Parse object. In other cases, when
** bFree==0, the With object will be freed along with the SELECT
** statement with which it is associated.
*/
void sqlite3WithPush(Parse *pParse, With *pWith, u8 bFree){
if( pWith ){
assert( pParse->pWith!=pWith );
pWith->pOuter = pParse->pWith;
pParse->pWith = pWith;
if( pParse->nErr==0 ){
assert( pParse->pWith!=pWith );
pWith->pOuter = pParse->pWith;
pParse->pWith = pWith;
}
if( bFree ){
sqlite3ParserAddCleanup(pParse,
(void(*)(sqlite3*,void*))sqlite3WithDelete,
@@ -5057,11 +5132,24 @@ static int resolveFromTermToCte(
/* There are no WITH clauses in the stack. No match is possible */
return 0;
}
if( pParse->nErr ){
/* Prior errors might have left pParse->pWith in a goofy state, so
** go no further. */
return 0;
}
if( pFrom->zDatabase!=0 ){
/* The FROM term contains a schema qualifier (ex: main.t1) and so
** it cannot possibly be a CTE reference. */
return 0;
}
if( pFrom->fg.notCte ){
/* The FROM term is specifically excluded from matching a CTE.
** (1) It is part of a trigger that used to have zDatabase but had
** zDatabase removed by sqlite3FixTriggerStep().
** (2) This is the first term in the FROM clause of an UPDATE.
*/
return 0;
}
pCte = searchWith(pParse->pWith, pFrom, &pWith);
if( pCte ){
sqlite3 *db = pParse->db;
@@ -5210,7 +5298,7 @@ static int resolveFromTermToCte(
** sqlite3SelectExpand() when walking a SELECT tree to resolve table
** names and other FROM clause elements.
*/
static void selectPopWith(Walker *pWalker, Select *p){
void sqlite3SelectPopWith(Walker *pWalker, Select *p){
Parse *pParse = pWalker->pParse;
if( OK_IF_ALWAYS_TRUE(pParse->pWith) && p->pPrior==0 ){
With *pWith = findRightmost(p)->pWith;
@@ -5220,8 +5308,6 @@ static void selectPopWith(Walker *pWalker, Select *p){
}
}
}
#else
#define selectPopWith 0
#endif
/*
@@ -5308,6 +5394,15 @@ static int selectExpander(Walker *pWalker, Select *p){
}
pTabList = p->pSrc;
pEList = p->pEList;
if( pParse->pWith && (p->selFlags & SF_View) ){
if( p->pWith==0 ){
p->pWith = (With*)sqlite3DbMallocZero(db, sizeof(With));
if( p->pWith==0 ){
return WRC_Abort;
}
}
p->pWith->bView = 1;
}
sqlite3WithPush(pParse, p->pWith, 0);
/* Make sure cursor numbers have been assigned to all entries in
@@ -5608,7 +5703,7 @@ static void sqlite3SelectExpand(Parse *pParse, Select *pSelect){
sqlite3WalkSelect(&w, pSelect);
}
w.xSelectCallback = selectExpander;
w.xSelectCallback2 = selectPopWith;
w.xSelectCallback2 = sqlite3SelectPopWith;
w.eCode = 0;
sqlite3WalkSelect(&w, pSelect);
}
@@ -6195,7 +6290,7 @@ int sqlite3Select(
}
if( pDest->eDest==SRT_Output ){
generateColumnNames(pParse, p);
sqlite3GenerateColumnNames(pParse, p);
}
#ifndef SQLITE_OMIT_WINDOWFUNC
@@ -6325,7 +6420,8 @@ int sqlite3Select(
** as the equivalent optimization will be handled by query planner in
** sqlite3WhereBegin().
*/
if( pTabList->nSrc>1
if( p->pWhere!=0
&& p->pWhere->op==TK_AND
&& OptimizationEnabled(db, SQLITE_PropagateConst)
&& propagateConstants(pParse, p)
){
@@ -6388,19 +6484,8 @@ int sqlite3Select(
pSub = pItem->pSelect;
if( pSub==0 ) continue;
/* The code for a subquery should only be generated once, though it is
** technically harmless for it to be generated multiple times. The
** following assert() will detect if something changes to cause
** the same subquery to be coded multiple times, as a signal to the
** developers to try to optimize the situation.
**
** Update 2019-07-24:
** See ticket https://sqlite.org/src/tktview/c52b09c7f38903b1311cec40.
** The dbsqlfuzz fuzzer found a case where the same subquery gets
** coded twice. So this assert() now becomes a testcase(). It should
** be very rare, though.
*/
testcase( pItem->addrFillSub!=0 );
/* The code for a subquery should only be generated once. */
assert( pItem->addrFillSub==0 );
/* Increment Parse.nHeight by the height of the largest expression
** tree referred to by this, the parent select. The child select
@@ -6487,14 +6572,13 @@ int sqlite3Select(
sqlite3VdbeAddOp2(v, OP_OpenDup, pItem->iCursor, pPrior->iCursor);
pSub->nSelectRow = pPrior->pSelect->nSelectRow;
}else{
/* Materalize the view. If the view is not correlated, generate a
/* Materialize the view. If the view is not correlated, generate a
** subroutine to do the materialization so that subsequent uses of
** the same view can reuse the materialization. */
int topAddr;
int onceAddr = 0;
int retAddr;
testcase( pItem->addrFillSub==0 ); /* Ticket c52b09c7f38903b1311 */
pItem->regReturn = ++pParse->nMem;
topAddr = sqlite3VdbeAddOp2(v, OP_Integer, 0, pItem->regReturn);
pItem->addrFillSub = topAddr+1;
+37 -22
View File
@@ -3978,8 +3978,8 @@ static const char *(azHelp[]) = {
".open ?OPTIONS? ?FILE? Close existing database and reopen FILE",
" Options:",
" --append Use appendvfs to append database to the end of FILE",
#ifdef SQLITE_ENABLE_DESERIALIZE
" --deserialize Load into memory useing sqlite3_deserialize()",
#ifndef SQLITE_OMIT_DESERIALIZE
" --deserialize Load into memory using sqlite3_deserialize()",
" --hexdb Load the output of \"dbtotxt\" as an in-memory db",
" --maxsize N Maximum size for --hexdb or --deserialized database",
#endif
@@ -4300,7 +4300,7 @@ int deduceDatabaseType(const char *zName, int dfltZip){
return rc;
}
#ifdef SQLITE_ENABLE_DESERIALIZE
#ifndef SQLITE_OMIT_DESERIALIZE
/*
** Reconstruct an in-memory database using the output from the "dbtotxt"
** program. Read content from the file in p->zDbFilename. If p->zDbFilename
@@ -4389,7 +4389,7 @@ readHexDb_error:
utf8_printf(stderr,"Error on line %d of --hexdb input\n", nLine);
return 0;
}
#endif /* SQLITE_ENABLE_DESERIALIZE */
#endif /* SQLITE_OMIT_DESERIALIZE */
/*
** Scalar function "shell_int32". The first argument to this function
@@ -4650,7 +4650,7 @@ static void open_db(ShellState *p, int openFlags){
sqlite3_exec(p->db, zSql, 0, 0, 0);
sqlite3_free(zSql);
}
#ifdef SQLITE_ENABLE_DESERIALIZE
#ifndef SQLITE_OMIT_DESERIALIZE
else
if( p->openMode==SHELL_OPEN_DESERIALIZE || p->openMode==SHELL_OPEN_HEXDB ){
int rc;
@@ -6717,6 +6717,7 @@ static void shellExec(sqlite3 *db, int *pRc, const char *zSql){
if( rc!=SQLITE_OK ){
raw_printf(stderr, "SQL error: %s\n", zErr);
}
sqlite3_free(zErr);
*pRc = rc;
}
}
@@ -7738,11 +7739,26 @@ static int do_meta_command(char *zLine, ShellState *p){
sqlite3_free(zLike);
goto meta_command_exit;
}
}else if( zLike ){
zLike = sqlite3_mprintf("%z OR name LIKE %Q ESCAPE '\\'",
zLike, azArg[i]);
}else{
zLike = sqlite3_mprintf("name LIKE %Q ESCAPE '\\'", azArg[i]);
/* azArg[i] contains a LIKE pattern. This ".dump" request should
** only dump data for tables for which either the table name matches
** the LIKE pattern, or the table appears to be a shadow table of
** a virtual table for which the name matches the LIKE pattern.
*/
char *zExpr = sqlite3_mprintf(
"name LIKE %Q ESCAPE '\\' OR EXISTS ("
" SELECT 1 FROM sqlite_schema WHERE "
" name LIKE %Q ESCAPE '\\' AND"
" sql LIKE 'CREATE VIRTUAL TABLE%%' AND"
" substr(o.name, 1, length(name)+1) == (name||'_')"
")", azArg[i], azArg[i]
);
if( zLike ){
zLike = sqlite3_mprintf("%z OR %z", zLike, zExpr);
}else{
zLike = zExpr;
}
}
}
@@ -7764,7 +7780,7 @@ static int do_meta_command(char *zLine, ShellState *p){
p->nErr = 0;
if( zLike==0 ) zLike = sqlite3_mprintf("true");
zSql = sqlite3_mprintf(
"SELECT name, type, sql FROM sqlite_schema "
"SELECT name, type, sql FROM sqlite_schema AS o "
"WHERE (%s) AND type=='table'"
" AND sql NOT NULL"
" ORDER BY tbl_name='sqlite_sequence', rowid",
@@ -7774,7 +7790,7 @@ static int do_meta_command(char *zLine, ShellState *p){
sqlite3_free(zSql);
if( (p->shellFlgs & SHFLG_DumpDataOnly)==0 ){
zSql = sqlite3_mprintf(
"SELECT sql FROM sqlite_schema "
"SELECT sql FROM sqlite_schema AS o "
"WHERE (%s) AND sql NOT NULL"
" AND type IN ('index','trigger','view')",
zLike
@@ -8021,7 +8037,6 @@ static int do_meta_command(char *zLine, ShellState *p){
if( c=='f' && strncmp(azArg[0], "fullschema", n)==0 ){
ShellState data;
char *zErrMsg = 0;
int doStats = 0;
memcpy(&data, p, sizeof(data));
data.showHeader = 0;
@@ -8043,7 +8058,7 @@ static int do_meta_command(char *zLine, ShellState *p){
" SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_schema) "
"WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%' "
"ORDER BY rowid",
callback, &data, &zErrMsg
callback, &data, 0
);
if( rc==SQLITE_OK ){
sqlite3_stmt *pStmt;
@@ -8059,12 +8074,12 @@ static int do_meta_command(char *zLine, ShellState *p){
}else{
raw_printf(p->out, "ANALYZE sqlite_schema;\n");
sqlite3_exec(p->db, "SELECT 'ANALYZE sqlite_schema'",
callback, &data, &zErrMsg);
callback, &data, 0);
data.cMode = data.mode = MODE_Insert;
data.zDestTable = "sqlite_stat1";
shell_exec(&data, "SELECT * FROM sqlite_stat1", &zErrMsg);
shell_exec(&data, "SELECT * FROM sqlite_stat1", 0);
data.zDestTable = "sqlite_stat4";
shell_exec(&data, "SELECT * FROM sqlite_stat4", &zErrMsg);
shell_exec(&data, "SELECT * FROM sqlite_stat4", 0);
raw_printf(p->out, "ANALYZE sqlite_schema;\n");
}
}else
@@ -8712,14 +8727,14 @@ static int do_meta_command(char *zLine, ShellState *p){
p->openMode = SHELL_OPEN_READONLY;
}else if( optionMatch(z, "nofollow") ){
p->openFlags |= SQLITE_OPEN_NOFOLLOW;
#ifdef SQLITE_ENABLE_DESERIALIZE
#ifndef SQLITE_OMIT_DESERIALIZE
}else if( optionMatch(z, "deserialize") ){
p->openMode = SHELL_OPEN_DESERIALIZE;
}else if( optionMatch(z, "hexdb") ){
p->openMode = SHELL_OPEN_HEXDB;
}else if( optionMatch(z, "maxsize") && iName+1<nArg ){
p->szMax = integerValue(azArg[++iName]);
#endif /* SQLITE_ENABLE_DESERIALIZE */
#endif /* SQLITE_OMIT_DESERIALIZE */
}else if( z[0]=='-' ){
utf8_printf(stderr, "unknown option: %s\n", z);
rc = 1;
@@ -10703,7 +10718,7 @@ static const char zOptions[] =
" -column set output mode to 'column'\n"
" -cmd COMMAND run \"COMMAND\" before reading stdin\n"
" -csv set output mode to 'csv'\n"
#if defined(SQLITE_ENABLE_DESERIALIZE)
#if !defined(SQLITE_OMIT_DESERIALIZE)
" -deserialize open the database using sqlite3_deserialize()\n"
#endif
" -echo print commands before execution\n"
@@ -10720,7 +10735,7 @@ static const char zOptions[] =
" -list set output mode to 'list'\n"
" -lookaside SIZE N use N entries of SZ bytes for lookaside memory\n"
" -markdown set output mode to 'markdown'\n"
#if defined(SQLITE_ENABLE_DESERIALIZE)
#if !defined(SQLITE_OMIT_DESERIALIZE)
" -maxsize N maximum size for a --deserialize database\n"
#endif
" -memtrace trace all memory allocations and deallocations\n"
@@ -11050,7 +11065,7 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
#endif
}else if( strcmp(z,"-append")==0 ){
data.openMode = SHELL_OPEN_APPENDVFS;
#ifdef SQLITE_ENABLE_DESERIALIZE
#ifndef SQLITE_OMIT_DESERIALIZE
}else if( strcmp(z,"-deserialize")==0 ){
data.openMode = SHELL_OPEN_DESERIALIZE;
}else if( strcmp(z,"-maxsize")==0 && i+1<argc ){
@@ -11167,7 +11182,7 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
#endif
}else if( strcmp(z,"-append")==0 ){
data.openMode = SHELL_OPEN_APPENDVFS;
#ifdef SQLITE_ENABLE_DESERIALIZE
#ifndef SQLITE_OMIT_DESERIALIZE
}else if( strcmp(z,"-deserialize")==0 ){
data.openMode = SHELL_OPEN_DESERIALIZE;
}else if( strcmp(z,"-maxsize")==0 && i+1<argc ){
+34 -17
View File
@@ -1141,6 +1141,10 @@ struct sqlite3_io_methods {
** other process. This opcode cannot be used to detect transactions opened
** by clients within the current process, only within other processes.
** </ul>
**
** <li>[[SQLITE_FCNTL_CKSM_FILE]]
** Used by the cksmvfs VFS module only.
** </ul>
*/
#define SQLITE_FCNTL_LOCKSTATE 1
#define SQLITE_FCNTL_GET_LOCKPROXYFILE 2
@@ -1180,8 +1184,8 @@ struct sqlite3_io_methods {
#define SQLITE_FCNTL_CKPT_DONE 37
#define SQLITE_FCNTL_RESERVE_BYTES 38
#define SQLITE_FCNTL_CKPT_START 39
#define SQLITE_FCNTL_EXTERNAL_READER 40
#define SQLITE_FCNTL_CKSM_FILE 41
/* deprecated names */
#define SQLITE_GET_LOCKPROXYFILE SQLITE_FCNTL_GET_LOCKPROXYFILE
@@ -4194,6 +4198,15 @@ const char *sqlite3_normalized_sql(sqlite3_stmt *pStmt);
** [BEGIN] merely sets internal flags, but the [BEGIN|BEGIN IMMEDIATE] and
** [BEGIN|BEGIN EXCLUSIVE] commands do touch the database and so
** sqlite3_stmt_readonly() returns false for those commands.
**
** ^This routine returns false if there is any possibility that the
** statement might change the database file. ^A false return does
** not guarantee that the statement will change the database file.
** ^For example, an UPDATE statement might have a WHERE clause that
** makes it a no-op, but the sqlite3_stmt_readonly() result would still
** be false. ^Similarly, a CREATE TABLE IF NOT EXISTS statement is a
** read-only no-op if the table already exists, but
** sqlite3_stmt_readonly() still returns false for such a statement.
*/
int sqlite3_stmt_readonly(sqlite3_stmt *pStmt);
@@ -4363,18 +4376,22 @@ typedef struct sqlite3_context sqlite3_context;
** contain embedded NULs. The result of expressions involving strings
** with embedded NULs is undefined.
**
** ^The fifth argument to the BLOB and string binding interfaces
** is a destructor used to dispose of the BLOB or
** string after SQLite has finished with it. ^The destructor is called
** to dispose of the BLOB or string even if the call to the bind API fails,
** except the destructor is not called if the third parameter is a NULL
** pointer or the fourth parameter is negative.
** ^If the fifth argument is
** the special value [SQLITE_STATIC], then SQLite assumes that the
** information is in static, unmanaged space and does not need to be freed.
** ^If the fifth argument has the value [SQLITE_TRANSIENT], then
** SQLite makes its own private copy of the data immediately, before
** the sqlite3_bind_*() routine returns.
** ^The fifth argument to the BLOB and string binding interfaces controls
** or indicates the lifetime of the object referenced by the third parameter.
** ^These three options exist:
** ^(1) A destructor to dispose of the BLOB or string after SQLite has finished
** with it may be passed. ^It is called to dispose of the BLOB or string even
** if the call to the bind API fails, except the destructor is not called if
** the third parameter is a NULL pointer or the fourth parameter is negative.
** ^(2) The special constant, [SQLITE_STATIC], may be passsed to indicate that
** the application remains responsible for disposing of the object. ^In this
** case, the object and the provided pointer to it must remain valid until
** either the prepared statement is finalized or the same SQL parameter is
** bound to something else, whichever occurs sooner.
** ^(3) The constant, [SQLITE_TRANSIENT], may be passed to indicate that the
** object is to be copied prior to the return from sqlite3_bind_*(). ^The
** object and pointer to it must remain valid until then. ^SQLite will then
** manage the lifetime of its private copy.
**
** ^The sixth argument to sqlite3_bind_text64() must be one of
** [SQLITE_UTF8], [SQLITE_UTF16], [SQLITE_UTF16BE], or [SQLITE_UTF16LE]
@@ -9814,8 +9831,8 @@ SQLITE_EXPERIMENTAL int sqlite3_snapshot_recover(sqlite3 *db, const char *zDb);
** SQLITE_SERIALIZE_NOCOPY bit is omitted from argument F if a memory
** allocation error occurs.
**
** This interface is only available if SQLite is compiled with the
** [SQLITE_ENABLE_DESERIALIZE] option.
** This interface is omitted if SQLite is compiled with the
** [SQLITE_OMIT_DESERIALIZE] option.
*/
unsigned char *sqlite3_serialize(
sqlite3 *db, /* The database connection */
@@ -9866,8 +9883,8 @@ unsigned char *sqlite3_serialize(
** SQLITE_DESERIALIZE_FREEONCLOSE bit is set in argument F, then
** [sqlite3_free()] is invoked on argument P prior to returning.
**
** This interface is only available if SQLite is compiled with the
** [SQLITE_ENABLE_DESERIALIZE] option.
** This interface is omitted if SQLite is compiled with the
** [SQLITE_OMIT_DESERIALIZE] option.
*/
int sqlite3_deserialize(
sqlite3 *db, /* The database connection */
+12 -3
View File
@@ -1731,7 +1731,6 @@ struct sqlite3 {
#define SQLITE_SkipScan 0x00004000 /* Skip-scans */
#define SQLITE_PropagateConst 0x00008000 /* The constant propagation opt */
#define SQLITE_MinMaxOpt 0x00010000 /* The min/max optimization */
#define SQLITE_ExistsToIN 0x00020000 /* The EXISTS-to-IN optimization */
#define SQLITE_AllOpts 0xffffffff /* All optimizations */
/*
@@ -2236,6 +2235,7 @@ struct Table {
#define TF_Shadow 0x1000 /* True for a shadow table */
#define TF_HasStat4 0x2000 /* STAT4 info available for this table */
#define TF_Ephemeral 0x4000 /* An ephemeral table */
#define TF_Eponymous 0x8000 /* An eponymous virtual table */
/*
** Test to see whether or not a table is a virtual table. This is
@@ -2948,6 +2948,7 @@ struct SrcItem {
unsigned isRecursive :1; /* True for recursive reference in WITH */
unsigned fromDDL :1; /* Comes from sqlite_schema */
unsigned isCte :1; /* This is a CTE */
unsigned notCte :1; /* This item may not match a CTE */
} fg;
int iCursor; /* The VDBE cursor number used to access this table */
Expr *pOn; /* The ON clause of a join */
@@ -3793,7 +3794,7 @@ struct Sqlite3Config {
void (*xVdbeBranch)(void*,unsigned iSrcLine,u8 eThis,u8 eMx); /* Callback */
void *pVdbeBranchArg; /* 1st argument */
#endif
#ifdef SQLITE_ENABLE_DESERIALIZE
#ifndef SQLITE_OMIT_DESERIALIZE
sqlite3_int64 mxMemdbSize; /* Default max memdb size */
#endif
#ifndef SQLITE_UNTESTABLE
@@ -3886,6 +3887,12 @@ void sqlite3WalkWinDefnDummyCallback(Walker*,Select*);
void sqlite3SelectWalkAssert2(Walker*, Select*);
#endif
#ifndef SQLITE_OMIT_CTE
void sqlite3SelectPopWith(Walker*, Select*);
#else
# define sqlite3SelectPopWith 0
#endif
/*
** Return code from the parse-tree walking primitives and their
** callbacks.
@@ -3919,6 +3926,7 @@ struct Cte {
*/
struct With {
int nCte; /* Number of CTEs in the WITH clause */
int bView; /* Belongs to the outermost Select of a view */
With *pOuter; /* Containing WITH clause, or NULL */
Cte a[1]; /* For each CTE in the WITH clause.... */
};
@@ -4311,6 +4319,7 @@ void sqlite3ResetOneSchema(sqlite3*,int);
void sqlite3CollapseDatabaseArray(sqlite3*);
void sqlite3CommitInternalChanges(sqlite3*);
void sqlite3DeleteColumnNames(sqlite3*,Table*);
void sqlite3GenerateColumnNames(Parse *pParse, Select *pSelect);
int sqlite3ColumnsFromExprList(Parse*,ExprList*,i16*,Column**);
void sqlite3SelectAddColumnTypeAndCollation(Parse*,Table*,Select*,char);
Table *sqlite3ResultSetOfSelect(Parse*,Select*,char);
@@ -4689,7 +4698,7 @@ int sqlite3TwoPartName(Parse *, Token *, Token *, Token **);
const char *sqlite3ErrName(int);
#endif
#ifdef SQLITE_ENABLE_DESERIALIZE
#ifndef SQLITE_OMIT_DESERIALIZE
int sqlite3MemdbInit(void);
#endif
+2 -2
View File
@@ -2600,7 +2600,7 @@ static int SQLITE_TCLAPI DbObjCmd(
** Reopen DATABASE (default "main") using the content in $VALUE
*/
case DB_DESERIALIZE: {
#ifndef SQLITE_ENABLE_DESERIALIZE
#ifdef SQLITE_OMIT_DESERIALIZE
Tcl_AppendResult(interp, "MEMDB not available in this build",
(char*)0);
rc = TCL_ERROR;
@@ -3167,7 +3167,7 @@ deserialize_error:
** Return a serialization of a database.
*/
case DB_SERIALIZE: {
#ifndef SQLITE_ENABLE_DESERIALIZE
#ifdef SQLITE_OMIT_DESERIALIZE
Tcl_AppendResult(interp, "MEMDB not available in this build",
(char*)0);
rc = TCL_ERROR;
+6
View File
@@ -389,6 +389,7 @@ static int echoDestructor(sqlite3_vtab *pVtab){
typedef struct EchoModule EchoModule;
struct EchoModule {
Tcl_Interp *interp;
sqlite3 *db;
};
/*
@@ -1352,6 +1353,9 @@ extern int getDbPointer(Tcl_Interp *interp, const char *zA, sqlite3 **ppDb);
extern const char *sqlite3ErrName(int);
static void moduleDestroy(void *p){
EchoModule *pMod = (EchoModule*)p;
sqlite3_create_function(pMod->db, "function_that_does_not_exist_0982ma98",
SQLITE_ANY, 1, 0, 0, 0, 0);
sqlite3_free(p);
}
@@ -1376,6 +1380,7 @@ static int SQLITE_TCLAPI register_echo_module(
/* Virtual table module "echo" */
pMod = sqlite3_malloc(sizeof(EchoModule));
pMod->interp = interp;
pMod->db = db;
rc = sqlite3_create_module_v2(
db, "echo", &echoModule, (void*)pMod, moduleDestroy
);
@@ -1384,6 +1389,7 @@ static int SQLITE_TCLAPI register_echo_module(
if( rc==SQLITE_OK ){
pMod = sqlite3_malloc(sizeof(EchoModule));
pMod->interp = interp;
pMod->db = db;
rc = sqlite3_create_module_v2(db, "echo_v2",
&echoModuleV2, (void*)pMod, moduleDestroy
);
+1 -1
View File
@@ -155,7 +155,7 @@ static void set_options(Tcl_Interp *interp){
Tcl_SetVar2(interp, "sqlite_options", "hiddencolumns", "0", TCL_GLOBAL_ONLY);
#endif
#ifdef SQLITE_ENABLE_DESERIALIZE
#ifndef SQLITE_OMIT_DESERIALIZE
Tcl_SetVar2(interp, "sqlite_options", "deserialize", "1", TCL_GLOBAL_ONLY);
#else
Tcl_SetVar2(interp, "sqlite_options", "deserialize", "0", TCL_GLOBAL_ONLY);
+17 -8
View File
@@ -56,6 +56,7 @@
#define CC_ID 27 /* unicode characters usable in IDs */
#define CC_ILLEGAL 28 /* Illegal character */
#define CC_NUL 29 /* 0x00 */
#define CC_BOM 30 /* First byte of UTF8 BOM: 0xEF 0xBB 0xBF */
static const unsigned char aiClass[] = {
#ifdef SQLITE_ASCII
@@ -68,14 +69,14 @@ static const unsigned char aiClass[] = {
/* 5x */ 1, 1, 1, 1, 1, 1, 1, 1, 0, 2, 2, 9, 28, 28, 28, 2,
/* 6x */ 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
/* 7x */ 1, 1, 1, 1, 1, 1, 1, 1, 0, 2, 2, 28, 10, 28, 25, 28,
/* 8x */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
/* 9x */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
/* Ax */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
/* Bx */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
/* Cx */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
/* Dx */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
/* Ex */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
/* Fx */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2
/* 8x */ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
/* 9x */ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
/* Ax */ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
/* Bx */ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
/* Cx */ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
/* Dx */ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
/* Ex */ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 30,
/* Fx */ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27
#endif
#ifdef SQLITE_EBCDIC
/* x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xa xb xc xd xe xf */
@@ -535,6 +536,14 @@ int sqlite3GetToken(const unsigned char *z, int *tokenType){
i = 1;
break;
}
case CC_BOM: {
if( z[1]==0xbb && z[2]==0xbf ){
*tokenType = TK_SPACE;
return 3;
}
i = 1;
break;
}
case CC_NUL: {
*tokenType = TK_ILLEGAL;
return 0;
+8
View File
@@ -706,6 +706,14 @@ void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 moreToFollow){
sqlite3TreeViewExpr(pView, pExpr->pLeft, 0);
break;
}
case TK_ERROR: {
Expr tmp;
sqlite3TreeViewLine(pView, "ERROR");
tmp = *pExpr;
tmp.op = pExpr->op2;
sqlite3TreeViewExpr(pView, &tmp, 0);
break;
}
default: {
sqlite3TreeViewLine(pView, "op=%d", pExpr->op);
break;
+48 -34
View File
@@ -57,33 +57,41 @@ Trigger *sqlite3TriggerList(Parse *pParse, Table *pTab){
}
pTmpSchema = pParse->db->aDb[1].pSchema;
p = sqliteHashFirst(&pTmpSchema->trigHash);
if( p==0 ){
return pTab->pTrigger;
}
pList = pTab->pTrigger;
if( pTmpSchema!=pTab->pSchema ){
while( p ){
Trigger *pTrig = (Trigger *)sqliteHashData(p);
if( pTrig->pTabSchema==pTab->pSchema
&& 0==sqlite3StrICmp(pTrig->table, pTab->zName)
){
pTrig->pNext = pList;
pList = pTrig;
}else if( pTrig->op==TK_RETURNING
while( p ){
Trigger *pTrig = (Trigger *)sqliteHashData(p);
if( pTrig->pTabSchema==pTab->pSchema
&& pTrig->table
&& 0==sqlite3StrICmp(pTrig->table, pTab->zName)
&& pTrig->pTabSchema!=pTmpSchema
){
pTrig->pNext = pList;
pList = pTrig;
}else if( pTrig->op==TK_RETURNING
#ifndef SQLITE_OMIT_VIRTUALTABLE
&& pParse->db->pVtabCtx==0
&& pParse->db->pVtabCtx==0
#endif
){
assert( pParse->bReturning );
assert( &(pParse->u1.pReturning->retTrig) == pTrig );
pTrig->table = pTab->zName;
pTrig->pTabSchema = pTab->pSchema;
pTrig->pNext = pList;
pList = pTrig;
}
p = sqliteHashNext(p);
}
){
assert( pParse->bReturning );
assert( &(pParse->u1.pReturning->retTrig) == pTrig );
pTrig->table = pTab->zName;
pTrig->pTabSchema = pTab->pSchema;
pTrig->pNext = pList;
pList = pTrig;
}
p = sqliteHashNext(p);
}
#if 0
if( pList ){
Trigger *pX;
printf("Triggers for %s:", pTab->zName);
for(pX=pList; pX; pX=pX->pNext){
printf(" %s", pX->zName);
}
printf("\n");
fflush(stdout);
}
#endif
return pList;
}
@@ -887,15 +895,6 @@ static ExprList *sqlite3ExpandReturning(
}
}
}
if( !db->mallocFailed ){
Vdbe *v = pParse->pVdbe;
assert( v!=0 );
sqlite3VdbeSetNumCols(v, pNew->nExpr);
for(i=0; i<pNew->nExpr; i++){
sqlite3VdbeSetColName(v, i, COLNAME_NAME, pNew->a[i].zEName,
SQLITE_TRANSIENT);
}
}
return pNew;
}
@@ -911,13 +910,27 @@ static void codeReturningTrigger(
int regIn /* The first in an array of registers */
){
Vdbe *v = pParse->pVdbe;
sqlite3 *db = pParse->db;
ExprList *pNew;
Returning *pReturning;
Select sSelect;
SrcList sFrom;
assert( v!=0 );
assert( pParse->bReturning );
pReturning = pParse->u1.pReturning;
assert( pTrigger == &(pReturning->retTrig) );
memset(&sSelect, 0, sizeof(sSelect));
memset(&sFrom, 0, sizeof(sFrom));
sSelect.pEList = sqlite3ExprListDup(db, pReturning->pReturnEL, 0);
sSelect.pSrc = &sFrom;
sFrom.nSrc = 1;
sFrom.a[0].pTab = pTab;
sqlite3SelectPrep(pParse, &sSelect, 0);
if( db->mallocFailed==0 && pParse->nErr==0 ){
sqlite3GenerateColumnNames(pParse, &sSelect);
}
sqlite3ExprListDelete(db, sSelect.pEList);
pNew = sqlite3ExpandReturning(pParse, pReturning->pReturnEL, pTab);
if( pNew ){
NameContext sNC;
@@ -938,13 +951,14 @@ static void codeReturningTrigger(
pParse->nMem += nCol+2;
pReturning->iRetReg = reg;
for(i=0; i<nCol; i++){
sqlite3ExprCodeFactorable(pParse, pNew->a[i].pExpr, reg+i);
Expr *pCol = pNew->a[i].pExpr;
sqlite3ExprCodeFactorable(pParse, pCol, reg+i);
}
sqlite3VdbeAddOp3(v, OP_MakeRecord, reg, i, reg+i);
sqlite3VdbeAddOp2(v, OP_NewRowid, pReturning->iRetCur, reg+i+1);
sqlite3VdbeAddOp3(v, OP_Insert, pReturning->iRetCur, reg+i, reg+i+1);
}
sqlite3ExprListDelete(pParse->db, pNew);
sqlite3ExprListDelete(db, pNew);
pParse->eTriggerOp = 0;
pParse->pTriggerTab = 0;
}
+1
View File
@@ -220,6 +220,7 @@ static void updateFromSelect(
assert( pTabList->nSrc>1 );
if( pSrc ){
pSrc->a[0].fg.notCte = 1;
pSrc->a[0].iCursor = -1;
pSrc->a[0].pTab->nTabRef--;
pSrc->a[0].pTab = 0;
+78 -21
View File
@@ -275,18 +275,36 @@ static VdbeCursor *allocateCursor(
sqlite3VdbeFreeCursor(p, p->apCsr[iCur]);
p->apCsr[iCur] = 0;
}
if( SQLITE_OK==sqlite3VdbeMemClearAndResize(pMem, nByte) ){
p->apCsr[iCur] = pCx = (VdbeCursor*)pMem->z;
memset(pCx, 0, offsetof(VdbeCursor,pAltCursor));
pCx->eCurType = eCurType;
pCx->iDb = iDb;
pCx->nField = nField;
pCx->aOffset = &pCx->aType[nField];
if( eCurType==CURTYPE_BTREE ){
pCx->uc.pCursor = (BtCursor*)
&pMem->z[ROUND8(sizeof(VdbeCursor))+2*sizeof(u32)*nField];
sqlite3BtreeCursorZero(pCx->uc.pCursor);
/* There used to be a call to sqlite3VdbeMemClearAndResize() to make sure
** the pMem used to hold space for the cursor has enough storage available
** in pMem->zMalloc. But for the special case of the aMem[] entries used
** to hold cursors, it is faster to in-line the logic. */
assert( pMem->flags==MEM_Undefined );
assert( (pMem->flags & MEM_Dyn)==0 );
assert( pMem->szMalloc==0 || pMem->z==pMem->zMalloc );
if( pMem->szMalloc<nByte ){
if( pMem->szMalloc>0 ){
sqlite3DbFreeNN(pMem->db, pMem->zMalloc);
}
pMem->z = pMem->zMalloc = sqlite3DbMallocRaw(pMem->db, nByte);
if( pMem->zMalloc==0 ){
pMem->szMalloc = 0;
return 0;
}
pMem->szMalloc = nByte;
}
p->apCsr[iCur] = pCx = (VdbeCursor*)pMem->zMalloc;
memset(pCx, 0, offsetof(VdbeCursor,pAltCursor));
pCx->eCurType = eCurType;
pCx->iDb = iDb;
pCx->nField = nField;
pCx->aOffset = &pCx->aType[nField];
if( eCurType==CURTYPE_BTREE ){
pCx->uc.pCursor = (BtCursor*)
&pMem->z[ROUND8(sizeof(VdbeCursor))+2*sizeof(u32)*nField];
sqlite3BtreeCursorZero(pCx->uc.pCursor);
}
return pCx;
}
@@ -574,6 +592,11 @@ static void registerTrace(int iReg, Mem *p){
printf("\n");
sqlite3VdbeCheckMemInvariants(p);
}
/**/ void sqlite3PrintMem(Mem *pMem){
memTracePrint(pMem);
printf("\n");
fflush(stdout);
}
#endif
#ifdef SQLITE_DEBUG
@@ -2021,6 +2044,31 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
pIn3 = &aMem[pOp->p3];
flags1 = pIn1->flags;
flags3 = pIn3->flags;
if( (flags1 & flags3 & MEM_Int)!=0 ){
assert( (pOp->p5 & SQLITE_AFF_MASK)!=SQLITE_AFF_TEXT || CORRUPT_DB );
/* Common case of comparison of two integers */
if( pIn3->u.i > pIn1->u.i ){
iCompare = +1;
if( sqlite3aGTb[pOp->opcode] ){
VdbeBranchTaken(1, (pOp->p5 & SQLITE_NULLEQ)?2:3);
goto jump_to_p2;
}
}else if( pIn3->u.i < pIn1->u.i ){
iCompare = -1;
if( sqlite3aLTb[pOp->opcode] ){
VdbeBranchTaken(1, (pOp->p5 & SQLITE_NULLEQ)?2:3);
goto jump_to_p2;
}
}else{
iCompare = 0;
if( sqlite3aEQb[pOp->opcode] ){
VdbeBranchTaken(1, (pOp->p5 & SQLITE_NULLEQ)?2:3);
goto jump_to_p2;
}
}
VdbeBranchTaken(0, (pOp->p5 & SQLITE_NULLEQ)?2:3);
break;
}
if( (flags1 | flags3)&MEM_Null ){
/* One or both operands are NULL */
if( pOp->p5 & SQLITE_NULLEQ ){
@@ -2051,7 +2099,8 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
break;
}
}else{
/* Neither operand is NULL. Do a comparison. */
/* Neither operand is NULL and we couldn't do the special high-speed
** integer comparison case. So do a general-case comparison. */
affinity = pOp->p5 & SQLITE_AFF_MASK;
if( affinity>=SQLITE_AFF_NUMERIC ){
if( (flags1 | flags3)&MEM_Str ){
@@ -2064,14 +2113,6 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
applyNumericAffinity(pIn3,0);
}
}
/* Handle the common case of integer comparison here, as an
** optimization, to avoid a call to sqlite3MemCompare() */
if( (pIn1->flags & pIn3->flags & MEM_Int)!=0 ){
if( pIn3->u.i > pIn1->u.i ){ res = +1; goto compare_op; }
if( pIn3->u.i < pIn1->u.i ){ res = -1; goto compare_op; }
res = 0;
goto compare_op;
}
}else if( affinity==SQLITE_AFF_TEXT ){
if( (flags1 & MEM_Str)==0 && (flags1&(MEM_Int|MEM_Real|MEM_IntReal))!=0 ){
testcase( pIn1->flags & MEM_Int );
@@ -2094,7 +2135,7 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
assert( pOp->p4type==P4_COLLSEQ || pOp->p4.pColl==0 );
res = sqlite3MemCompare(pIn3, pIn1, pOp->p4.pColl);
}
compare_op:
/* At this point, res is negative, zero, or positive if reg[P1] is
** less than, equal to, or greater than reg[P3], respectively. Compute
** the answer to this operator in res2, depending on what the comparison
@@ -4535,8 +4576,18 @@ case OP_SeekHit: {
assert( pC!=0 );
assert( pOp->p3>=pOp->p2 );
if( pC->seekHit<pOp->p2 ){
#ifdef SQLITE_DEBUG
if( db->flags&SQLITE_VdbeTrace ){
printf("seekHit changes from %d to %d\n", pC->seekHit, pOp->p2);
}
#endif
pC->seekHit = pOp->p2;
}else if( pC->seekHit>pOp->p3 ){
#ifdef SQLITE_DEBUG
if( db->flags&SQLITE_VdbeTrace ){
printf("seekHit changes from %d to %d\n", pC->seekHit, pOp->p3);
}
#endif
pC->seekHit = pOp->p3;
}
break;
@@ -4651,6 +4702,11 @@ case OP_IfNoHope: { /* jump, in3 */
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
pC = p->apCsr[pOp->p1];
assert( pC!=0 );
#ifdef SQLITE_DEBUG
if( db->flags&SQLITE_VdbeTrace ){
printf("seekHit is %d\n", pC->seekHit);
}
#endif
if( pC->seekHit>=pOp->p4.i ) break;
/* Fall through into OP_NotFound */
/* no break */ deliberate_fall_through
@@ -7191,6 +7247,7 @@ case OP_JournalMode: { /* out2 */
pPager = sqlite3BtreePager(pBt);
eOld = sqlite3PagerGetJournalMode(pPager);
if( eNew==PAGER_JOURNALMODE_QUERY ) eNew = eOld;
assert( sqlite3BtreeHoldsMutex(pBt) );
if( !sqlite3PagerOkToChangeJournalMode(pPager) ) eNew = eOld;
#ifndef SQLITE_OMIT_WAL
+6 -2
View File
@@ -75,7 +75,9 @@ int sqlite3VdbeCheckMemInvariants(Mem *p){
/* The szMalloc field holds the correct memory allocation size */
assert( p->szMalloc==0
|| p->szMalloc==sqlite3DbMallocSize(p->db,p->zMalloc) );
|| (p->flags==MEM_Undefined
&& p->szMalloc<=sqlite3DbMallocSize(p->db,p->zMalloc))
|| p->szMalloc==sqlite3DbMallocSize(p->db,p->zMalloc));
/* If p holds a string or blob, the Mem.z must point to exactly
** one of the following:
@@ -239,7 +241,9 @@ SQLITE_NOINLINE int sqlite3VdbeMemGrow(Mem *pMem, int n, int bPreserve){
testcase( bPreserve && pMem->z==0 );
assert( pMem->szMalloc==0
|| pMem->szMalloc==sqlite3DbMallocSize(pMem->db, pMem->zMalloc) );
|| (pMem->flags==MEM_Undefined
&& pMem->szMalloc<=sqlite3DbMallocSize(pMem->db,pMem->zMalloc))
|| pMem->szMalloc==sqlite3DbMallocSize(pMem->db,pMem->zMalloc));
if( pMem->szMalloc>0 && bPreserve && pMem->z==pMem->zMalloc ){
if( pMem->db ){
pMem->z = pMem->zMalloc = sqlite3DbReallocOrFree(pMem->db, pMem->z, n);
+1
View File
@@ -1221,6 +1221,7 @@ int sqlite3VtabEponymousTableInit(Parse *pParse, Module *pMod){
pTab->pSchema = db->aDb[0].pSchema;
assert( pTab->nModuleArg==0 );
pTab->iPKey = -1;
pTab->tabFlags |= TF_Eponymous;
addModuleArgument(pParse, pTab, sqlite3DbStrDup(db, pTab->zName));
addModuleArgument(pParse, pTab, 0);
addModuleArgument(pParse, pTab, sqlite3DbStrDup(db, pTab->zName));
+2 -3
View File
@@ -999,7 +999,6 @@ static void walCleanupHash(Wal *pWal){
int iLimit = 0; /* Zero values greater than this */
int nByte; /* Number of bytes to zero in aPgno[] */
int i; /* Used to iterate through aHash[] */
int rc; /* Return code form walHashGet() */
assert( pWal->writeLock );
testcase( pWal->hdr.mxFrame==HASHTABLE_NPAGE_ONE-1 );
@@ -1014,8 +1013,8 @@ static void walCleanupHash(Wal *pWal){
*/
assert( pWal->nWiData>walFramePage(pWal->hdr.mxFrame) );
assert( pWal->apWiData[walFramePage(pWal->hdr.mxFrame)] );
rc = walHashGet(pWal, walFramePage(pWal->hdr.mxFrame), &sLoc);
if( NEVER(rc) ) return; /* Defense-in-depth, in case (1) above is wrong */
i = walHashGet(pWal, walFramePage(pWal->hdr.mxFrame), &sLoc);
if( NEVER(i) ) return; /* Defense-in-depth, in case (1) above is wrong */
/* Zero all hash-table entries that correspond to frame numbers greater
** than pWal->hdr.mxFrame.
+3
View File
@@ -140,6 +140,9 @@ int sqlite3WalkSelectExpr(Walker *pWalker, Select *p){
Parse *pParse;
if( pWalker->xSelectCallback2==sqlite3WalkWinDefnDummyCallback
|| ((pParse = pWalker->pParse)!=0 && IN_RENAME_OBJECT)
#ifndef SQLITE_OMIT_CTE
|| pWalker->xSelectCallback2==sqlite3SelectPopWith
#endif
){
/* The following may return WRC_Abort if there are unresolvable
** symbols (e.g. a table that does not exist) in a window definition. */
+42 -10
View File
@@ -338,6 +338,18 @@ static WhereTerm *whereScanNext(WhereScan *pScan){
}
pScan->pWC = pWC;
pScan->k = k+1;
#ifdef WHERETRACE_ENABLED
if( sqlite3WhereTrace & 0x20000 ){
int ii;
sqlite3DebugPrintf("SCAN-TERM %p: nEquiv=%d",
pTerm, pScan->nEquiv);
for(ii=0; ii<pScan->nEquiv; ii++){
sqlite3DebugPrintf(" {%d:%d}",
pScan->aiCur[ii], pScan->aiColumn[ii]);
}
sqlite3DebugPrintf("\n");
}
#endif
return pTerm;
}
}
@@ -1942,7 +1954,7 @@ static int whereLoopResize(sqlite3 *db, WhereLoop *p, int n){
static int whereLoopXfer(sqlite3 *db, WhereLoop *pTo, WhereLoop *pFrom){
whereLoopClearUnion(db, pTo);
if( whereLoopResize(db, pTo, pFrom->nLTerm) ){
memset(&pTo->u, 0, sizeof(pTo->u));
memset(pTo, 0, WHERE_LOOP_XFER_SZ);
return SQLITE_NOMEM_BKPT;
}
memcpy(pTo, pFrom, WHERE_LOOP_XFER_SZ);
@@ -2501,6 +2513,8 @@ static int whereLoopAddBtreeIndex(
if( pProbe->bUnordered ) opMask &= ~(WO_GT|WO_GE|WO_LT|WO_LE);
assert( pNew->u.btree.nEq<pProbe->nColumn );
assert( pNew->u.btree.nEq<pProbe->nKeyCol
|| pProbe->idxType!=SQLITE_IDXTYPE_PRIMARYKEY );
saved_nEq = pNew->u.btree.nEq;
saved_nBtm = pNew->u.btree.nBtm;
@@ -2634,6 +2648,7 @@ static int whereLoopAddBtreeIndex(
pNew->wsFlags |= WHERE_UNQ_WANTED;
}
}
if( scan.iEquiv>1 ) pNew->wsFlags |= WHERE_TRANSCONS;
}else if( eOp & WO_ISNULL ){
pNew->wsFlags |= WHERE_COLUMN_NULL;
}else if( eOp & (WO_GT|WO_GE) ){
@@ -2777,6 +2792,8 @@ static int whereLoopAddBtreeIndex(
if( (pNew->wsFlags & WHERE_TOP_LIMIT)==0
&& pNew->u.btree.nEq<pProbe->nColumn
&& (pNew->u.btree.nEq<pProbe->nKeyCol ||
pProbe->idxType!=SQLITE_IDXTYPE_PRIMARYKEY)
){
whereLoopAddBtreeIndex(pBuilder, pSrc, pProbe, nInMul+nIn);
}
@@ -3879,6 +3896,10 @@ static i8 wherePathSatisfiesOrderBy(
assert( nColumn==nKeyCol+1 || !HasRowid(pIndex->pTable) );
assert( pIndex->aiColumn[nColumn-1]==XN_ROWID
|| !HasRowid(pIndex->pTable));
/* All relevant terms of the index must also be non-NULL in order
** for isOrderDistinct to be true. So the isOrderDistint value
** computed here might be a false positive. Corrections will be
** made at tag-20210426-1 below */
isOrderDistinct = IsUniqueIndex(pIndex)
&& (pLoop->wsFlags & WHERE_SKIPSCAN)==0;
}
@@ -3946,15 +3967,19 @@ static i8 wherePathSatisfiesOrderBy(
}
/* An unconstrained column that might be NULL means that this
** WhereLoop is not well-ordered
** WhereLoop is not well-ordered. tag-20210426-1
*/
if( isOrderDistinct
&& iColumn>=0
&& j>=pLoop->u.btree.nEq
&& pIndex->pTable->aCol[iColumn].notNull==0
){
isOrderDistinct = 0;
}
if( isOrderDistinct ){
if( iColumn>=0
&& j>=pLoop->u.btree.nEq
&& pIndex->pTable->aCol[iColumn].notNull==0
){
isOrderDistinct = 0;
}
if( iColumn==XN_EXPR ){
isOrderDistinct = 0;
}
}
/* Find the ORDER BY term that corresponds to the j-th column
** of the index and mark that ORDER BY term off
@@ -4137,7 +4162,7 @@ static LogEst whereSortingCost(
}else if( (pWInfo->wctrlFlags & WHERE_WANT_DISTINCT) ){
/* TUNING: In the sort for a DISTINCT operator, assume that the DISTINCT
** reduces the number of output rows by a factor of 2 */
if( nRow>10 ) nRow -= 10; assert( 10==sqlite3LogEst(2) );
if( nRow>10 ){ nRow -= 10; assert( 10==sqlite3LogEst(2) ); }
}
rSortCost += estLog(nRow);
return rSortCost;
@@ -5427,6 +5452,8 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){
int j;
sqlite3VdbeResolveLabel(v, pLevel->addrNxt);
for(j=pLevel->u.in.nIn, pIn=&pLevel->u.in.aInLoop[j-1]; j>0; j--, pIn--){
assert( sqlite3VdbeGetOp(v, pIn->addrInTop+1)->opcode==OP_IsNull
|| pParse->db->mallocFailed );
sqlite3VdbeJumpHere(v, pIn->addrInTop+1);
if( pIn->eEndLoopOp!=OP_Noop ){
if( pIn->nPrefix ){
@@ -5451,6 +5478,11 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){
sqlite3VdbeCurrentAddr(v)+2,
pIn->iBase, pIn->nPrefix);
VdbeCoverage(v);
/* Retarget the OP_IsNull against the left operand of IN so
** it jumps past the OP_IfNoHope. This is because the
** OP_IsNull also bypasses the OP_Affinity opcode that is
** required by OP_IfNoHope. */
sqlite3VdbeJumpHere(v, pIn->addrInTop+1);
}
}
sqlite3VdbeAddOp2(v, pIn->eEndLoopOp, pIn->iCur, pIn->addrInTop);
+3 -2
View File
@@ -293,8 +293,8 @@ struct WhereScan {
const char *zCollName; /* Required collating sequence, if not NULL */
Expr *pIdxExpr; /* Search for this index expression */
char idxaff; /* Must match this affinity, if zCollName!=NULL */
unsigned char nEquiv; /* Number of entries in aEquiv[] */
unsigned char iEquiv; /* Next unused slot in aEquiv[] */
unsigned char nEquiv; /* Number of entries in aiCur[] and aiColumn[] */
unsigned char iEquiv; /* Next unused slot in aiCur[] and aiColumn[] */
u32 opMask; /* Acceptable operators */
int k; /* Resume scanning at this->pWC->a[this->k] */
int aiCur[11]; /* Cursors in the equivalence class */
@@ -603,5 +603,6 @@ void sqlite3WhereTabFuncArgs(Parse*, SrcItem*, WhereClause*);
#define WHERE_IN_EARLYOUT 0x00040000 /* Perhaps quit IN loops early */
#define WHERE_BIGNULL_SORT 0x00080000 /* Column nEq of index is BIGNULL */
#define WHERE_IN_SEEKSCAN 0x00100000 /* Seek-scan optimization for IN */
#define WHERE_TRANSCONS 0x00200000 /* Uses a transitive constraint */
#endif /* !defined(SQLITE_WHEREINT_H) */
+40 -9
View File
@@ -297,6 +297,12 @@ static void disableTerm(WhereLevel *pLevel, WhereTerm *pTerm){
}else{
pTerm->wtFlags |= TERM_CODED;
}
#ifdef WHERETRACE_ENABLED
if( sqlite3WhereTrace & 0x20000 ){
sqlite3DebugPrintf("DISABLE-");
sqlite3WhereTermPrint(pTerm, (int)(pTerm - (pTerm->pWC->a)));
}
#endif
if( pTerm->iParent<0 ) break;
pTerm = &pTerm->pWC->a[pTerm->iParent];
assert( pTerm!=0 );
@@ -614,7 +620,22 @@ static int codeEqualityTerm(
sqlite3DbFree(pParse->db, aiMap);
#endif
}
disableTerm(pLevel, pTerm);
/* As an optimization, try to disable the WHERE clause term that is
** driving the index as it will always be true. The correct answer is
** obtained regardless, but we might get the answer with fewer CPU cycles
** by omitting the term.
**
** But do not disable the term unless we are certain that the term is
** not a transitive constraint. For an example of where that does not
** work, see https://sqlite.org/forum/forumpost/eb8613976a (2021-05-04)
*/
if( (pLevel->pWLoop->wsFlags & WHERE_TRANSCONS)==0
|| (pTerm->eOperator & WO_EQUIV)==0
){
disableTerm(pLevel, pTerm);
}
return iReg;
}
@@ -700,7 +721,7 @@ static int codeAllEqualityTerms(
if( nSkip ){
int iIdxCur = pLevel->iIdxCur;
sqlite3VdbeAddOp3(v, OP_Null, 0, regBase, nSkip);
sqlite3VdbeAddOp3(v, OP_Null, 0, regBase, regBase+nSkip-1);
sqlite3VdbeAddOp1(v, (bRev?OP_Last:OP_Rewind), iIdxCur);
VdbeCoverageIf(v, bRev==0);
VdbeCoverageIf(v, bRev!=0);
@@ -731,11 +752,16 @@ static int codeAllEqualityTerms(
testcase( pTerm->wtFlags & TERM_VIRTUAL );
r1 = codeEqualityTerm(pParse, pTerm, pLevel, j, bRev, regBase+j);
if( r1!=regBase+j ){
assert( pTerm->pExpr->op==TK_EQ || pTerm->pExpr->op==TK_IS );
if( nReg==1 ){
sqlite3ReleaseTempReg(pParse, regBase);
regBase = r1;
}else{
sqlite3VdbeAddOp2(v, OP_SCopy, r1, regBase+j);
if( ExprHasProperty(pTerm->pExpr->pRight, EP_VarSelect) ){
sqlite3VdbeAddOp3(v, OP_Move, r1, regBase+j, 1);
}else{
sqlite3VdbeAddOp2(v, OP_SCopy, r1, regBase+j);
}
}
}
if( pTerm->eOperator & WO_IN ){
@@ -752,7 +778,7 @@ static int codeAllEqualityTerms(
sqlite3VdbeAddOp2(v, OP_IsNull, regBase+j, pLevel->addrBrk);
VdbeCoverage(v);
}
if( pParse->db->mallocFailed==0 ){
if( pParse->db->mallocFailed==0 && pParse->nErr==0 ){
if( sqlite3CompareAffinity(pRight, zAff[j])==SQLITE_AFF_BLOB ){
zAff[j] = SQLITE_AFF_BLOB;
}
@@ -1101,7 +1127,7 @@ static void codeExprOrVector(Parse *pParse, Expr *p, int iReg, int nReg){
}
}
}else{
assert( nReg==1 );
assert( nReg==1 || pParse->nErr );
sqlite3ExprCode(pParse, p, iReg);
}
}
@@ -1728,9 +1754,7 @@ Bitmask sqlite3WhereCodeOneLoopStart(
** a forward order scan on a descending index, interchange the
** start and end terms (pRangeStart and pRangeEnd).
*/
if( (nEq<pIdx->nKeyCol && bRev==(pIdx->aSortOrder[nEq]==SQLITE_SO_ASC))
|| (bRev && pIdx->nKeyCol==nEq)
){
if( (nEq<pIdx->nColumn && bRev==(pIdx->aSortOrder[nEq]==SQLITE_SO_ASC)) ){
SWAP(WhereTerm *, pRangeEnd, pRangeStart);
SWAP(u8, bSeekPastNull, bStopAtNull);
SWAP(u8, nBtm, nTop);
@@ -2151,7 +2175,7 @@ Bitmask sqlite3WhereCodeOneLoopStart(
/* The extra 0x10000 bit on the opcode is masked off and does not
** become part of the new Expr.op. However, it does make the
** op==TK_AND comparison inside of sqlite3PExpr() false, and this
** prevents sqlite3PExpr() from implementing AND short-circuit
** prevents sqlite3PExpr() from applying the AND short-circuit
** optimization, which we do not want here. */
pAndExpr = sqlite3PExpr(pParse, TK_AND|0x10000, 0, pAndExpr);
}
@@ -2167,10 +2191,16 @@ Bitmask sqlite3WhereCodeOneLoopStart(
if( pOrTerm->leftCursor==iCur || (pOrTerm->eOperator & WO_AND)!=0 ){
WhereInfo *pSubWInfo; /* Info for single OR-term scan */
Expr *pOrExpr = pOrTerm->pExpr; /* Current OR clause term */
Expr *pDelete; /* Local copy of OR clause term */
int jmp1 = 0; /* Address of jump operation */
testcase( (pTabItem[0].fg.jointype & JT_LEFT)!=0
&& !ExprHasProperty(pOrExpr, EP_FromJoin)
); /* See TH3 vtab25.400 and ticket 614b25314c766238 */
pDelete = pOrExpr = sqlite3ExprDup(db, pOrExpr, 0);
if( db->mallocFailed ){
sqlite3ExprDelete(db, pDelete);
continue;
}
if( pAndExpr ){
pAndExpr->pLeft = pOrExpr;
pOrExpr = pAndExpr;
@@ -2285,6 +2315,7 @@ Bitmask sqlite3WhereCodeOneLoopStart(
sqlite3WhereEnd(pSubWInfo);
ExplainQueryPlanPop(pParse);
}
sqlite3ExprDelete(db, pDelete);
}
}
ExplainQueryPlanPop(pParse);
+3 -281
View File
@@ -872,7 +872,7 @@ static void exprAnalyzeOrTerm(
idxNew = whereClauseInsert(pWC, pNew, TERM_VIRTUAL|TERM_DYNAMIC);
testcase( idxNew==0 );
exprAnalyze(pSrc, pWC, idxNew);
/* pTerm = &pWC->a[idxTerm]; // would be needed if pTerm where used again */
/* pTerm = &pWC->a[idxTerm]; // would be needed if pTerm where reused */
markTermAsChild(pWC, idxNew, idxTerm);
}else{
sqlite3ExprListDelete(db, pList);
@@ -996,6 +996,7 @@ static int exprMightBeIndexed(
assert( op<=TK_GE );
if( pExpr->op==TK_VECTOR && (op>=TK_GT && ALWAYS(op<=TK_GE)) ){
pExpr = pExpr->x.pList->a[0].pExpr;
}
if( pExpr->op==TK_COLUMN ){
@@ -1008,276 +1009,6 @@ static int exprMightBeIndexed(
return exprMightBeIndexed2(pFrom,mPrereq,aiCurCol,pExpr);
}
/*
** Expression callback for exprUsesSrclist().
*/
static int exprUsesSrclistCb(Walker *p, Expr *pExpr){
if( pExpr->op==TK_COLUMN ){
SrcList *pSrc = p->u.pSrcList;
int iCsr = pExpr->iTable;
int ii;
for(ii=0; ii<pSrc->nSrc; ii++){
if( pSrc->a[ii].iCursor==iCsr ){
return p->eCode ? WRC_Abort : WRC_Continue;
}
}
return p->eCode ? WRC_Continue : WRC_Abort;
}
return WRC_Continue;
}
/*
** Select callback for exprUsesSrclist().
*/
static int exprUsesSrclistSelectCb(Walker *NotUsed1, Select *NotUsed2){
UNUSED_PARAMETER(NotUsed1);
UNUSED_PARAMETER(NotUsed2);
return WRC_Abort;
}
/*
** This function always returns true if expression pExpr contains
** a sub-select.
**
** If there is no sub-select in pExpr, then return true if pExpr
** contains a TK_COLUMN node for a table that is (bUses==1)
** or is not (bUses==0) in pSrc.
**
** Said another way:
**
** bUses Return Meaning
** -------- ------ ------------------------------------------------
**
** bUses==1 true pExpr contains either a sub-select or a
** TK_COLUMN referencing pSrc.
**
** bUses==1 false pExpr contains no sub-selects and all TK_COLUMN
** nodes reference tables not found in pSrc
**
** bUses==0 true pExpr contains either a sub-select or a TK_COLUMN
** that references a table not in pSrc.
**
** bUses==0 false pExpr contains no sub-selects and all TK_COLUMN
** nodes reference pSrc
*/
static int exprUsesSrclist(SrcList *pSrc, Expr *pExpr, int bUses){
Walker sWalker;
memset(&sWalker, 0, sizeof(Walker));
sWalker.eCode = bUses;
sWalker.u.pSrcList = pSrc;
sWalker.xExprCallback = exprUsesSrclistCb;
sWalker.xSelectCallback = exprUsesSrclistSelectCb;
return (sqlite3WalkExpr(&sWalker, pExpr)==WRC_Abort);
}
/*
** Context object used by exprExistsToInIter() as it iterates through an
** expression tree.
*/
struct ExistsToInCtx {
SrcList *pSrc; /* The tables in an EXISTS(SELECT ... FROM <here> ...) */
Expr *pInLhs; /* OUT: Use this as the LHS of the IN operator */
Expr *pEq; /* OUT: The == term that include pInLhs */
Expr **ppAnd; /* OUT: The AND operator that includes pEq as a child */
Expr **ppParent; /* The AND operator currently being examined */
};
/*
** Iterate through all AND connected nodes in the expression tree
** headed by (*ppExpr), populating the structure passed as the first
** argument with the values required by exprAnalyzeExistsFindEq().
**
** This function returns non-zero if the expression tree does not meet
** the two conditions described by the header comment for
** exprAnalyzeExistsFindEq(), or zero if it does.
*/
static int exprExistsToInIter(struct ExistsToInCtx *p, Expr **ppExpr){
Expr *pExpr = *ppExpr;
switch( pExpr->op ){
case TK_AND:
p->ppParent = ppExpr;
if( exprExistsToInIter(p, &pExpr->pLeft) ) return 1;
p->ppParent = ppExpr;
if( exprExistsToInIter(p, &pExpr->pRight) ) return 1;
break;
case TK_EQ: {
int bLeft = exprUsesSrclist(p->pSrc, pExpr->pLeft, 0);
int bRight = exprUsesSrclist(p->pSrc, pExpr->pRight, 0);
if( bLeft || bRight ){
if( (bLeft && bRight) || p->pInLhs ) return 1;
p->pInLhs = bLeft ? pExpr->pLeft : pExpr->pRight;
if( exprUsesSrclist(p->pSrc, p->pInLhs, 1) ) return 1;
p->pEq = pExpr;
p->ppAnd = p->ppParent;
}
break;
}
default:
if( exprUsesSrclist(p->pSrc, pExpr, 0) ){
return 1;
}
break;
}
return 0;
}
/*
** This function is used by exprAnalyzeExists() when creating virtual IN(...)
** terms equivalent to user-supplied EXIST(...) clauses. It splits the WHERE
** clause of the Select object passed as the first argument into one or more
** expressions joined by AND operators, and then tests if the following are
** true:
**
** 1. Exactly one of the AND separated terms refers to the outer
** query, and it is an == (TK_EQ) expression.
**
** 2. Only one side of the == expression refers to the outer query, and
** it does not refer to any columns from the inner query.
**
** If both these conditions are true, then a pointer to the side of the ==
** expression that refers to the outer query is returned. The caller will
** use this expression as the LHS of the IN(...) virtual term. Or, if one
** or both of the above conditions are not true, NULL is returned.
**
** If non-NULL is returned and ppEq is non-NULL, *ppEq is set to point
** to the == expression node before returning. If pppAnd is non-NULL and
** the == node is not the root of the WHERE clause, then *pppAnd is set
** to point to the pointer to the AND node that is the parent of the ==
** node within the WHERE expression tree.
*/
static Expr *exprAnalyzeExistsFindEq(
Select *pSel, /* The SELECT of the EXISTS */
Expr **ppEq, /* OUT: == node from WHERE clause */
Expr ***pppAnd /* OUT: Pointer to parent of ==, if any */
){
struct ExistsToInCtx ctx;
memset(&ctx, 0, sizeof(ctx));
ctx.pSrc = pSel->pSrc;
if( exprExistsToInIter(&ctx, &pSel->pWhere) ){
return 0;
}
if( ppEq ) *ppEq = ctx.pEq;
if( pppAnd ) *pppAnd = ctx.ppAnd;
return ctx.pInLhs;
}
/*
** Term idxTerm of the WHERE clause passed as the second argument is an
** EXISTS expression with a correlated SELECT statement on the RHS.
** This function analyzes the SELECT statement, and if possible adds an
** equivalent "? IN(SELECT...)" virtual term to the WHERE clause.
**
** For an EXISTS term such as the following:
**
** EXISTS (SELECT ... FROM <srclist> WHERE <e1> = <e2> AND <e3>)
**
** The virtual IN() term added is:
**
** <e1> IN (SELECT <e2> FROM <srclist> WHERE <e3>)
**
** The virtual term is only added if the following conditions are met:
**
** 1. The sub-select must not be an aggregate or use window functions,
**
** 2. The sub-select must not be a compound SELECT,
**
** 3. Expression <e1> must refer to at least one column from the outer
** query, and must not refer to any column from the inner query
** (i.e. from <srclist>).
**
** 4. <e2> and <e3> must not refer to any values from the outer query.
** In other words, once <e1> has been removed, the inner query
** must not be correlated.
**
*/
static void exprAnalyzeExists(
SrcList *pSrc, /* the FROM clause */
WhereClause *pWC, /* the WHERE clause */
int idxTerm /* Index of the term to be analyzed */
){
Parse *pParse = pWC->pWInfo->pParse;
WhereTerm *pTerm = &pWC->a[idxTerm];
Expr *pExpr = pTerm->pExpr;
Select *pSel = pExpr->x.pSelect;
Expr *pDup = 0;
Expr *pEq = 0;
Expr *pRet = 0;
Expr *pInLhs = 0;
Expr **ppAnd = 0;
int idxNew;
sqlite3 *db = pParse->db;
assert( pExpr->op==TK_EXISTS );
assert( (pExpr->flags & EP_VarSelect) && (pExpr->flags & EP_xIsSelect) );
if( pSel->selFlags & SF_Aggregate ) return;
#ifndef SQLITE_OMIT_WINDOWFUNC
if( pSel->pWin ) return;
#endif
if( pSel->pPrior ) return;
if( pSel->pWhere==0 ) return;
if( pSel->pLimit ) return;
if( 0==exprAnalyzeExistsFindEq(pSel, 0, 0) ) return;
pDup = sqlite3ExprDup(db, pExpr, 0);
if( db->mallocFailed ){
sqlite3ExprDelete(db, pDup);
return;
}
pSel = pDup->x.pSelect;
sqlite3ExprListDelete(db, pSel->pEList);
pSel->pEList = 0;
pInLhs = exprAnalyzeExistsFindEq(pSel, &pEq, &ppAnd);
assert( pInLhs && pEq );
assert( pEq==pSel->pWhere || ppAnd );
if( pInLhs==pEq->pLeft ){
pRet = pEq->pRight;
}else{
CollSeq *p = sqlite3ExprCompareCollSeq(pParse, pEq);
pInLhs = sqlite3ExprAddCollateString(pParse, pInLhs, p?p->zName:"BINARY");
pRet = pEq->pLeft;
}
assert( pDup->pLeft==0 );
pDup->op = TK_IN;
pDup->pLeft = pInLhs;
pDup->flags &= ~EP_VarSelect;
if( pRet->op==TK_VECTOR ){
pSel->pEList = pRet->x.pList;
pRet->x.pList = 0;
sqlite3ExprDelete(db, pRet);
}else{
pSel->pEList = sqlite3ExprListAppend(pParse, 0, pRet);
}
pEq->pLeft = 0;
pEq->pRight = 0;
if( ppAnd ){
Expr *pAnd = *ppAnd;
Expr *pOther = (pAnd->pLeft==pEq) ? pAnd->pRight : pAnd->pLeft;
pAnd->pLeft = pAnd->pRight = 0;
sqlite3ExprDelete(db, pAnd);
*ppAnd = pOther;
}else{
assert( pSel->pWhere==pEq );
pSel->pWhere = 0;
}
sqlite3ExprDelete(db, pEq);
#ifdef WHERETRACE_ENABLED /* 0x20 */
if( sqlite3WhereTrace & 0x20 ){
sqlite3DebugPrintf("Convert EXISTS:\n");
sqlite3TreeViewExpr(0, pExpr, 0);
sqlite3DebugPrintf("into IN:\n");
sqlite3TreeViewExpr(0, pDup, 0);
}
#endif
idxNew = whereClauseInsert(pWC, pDup, TERM_VIRTUAL|TERM_DYNAMIC);
exprAnalyze(pSrc, pWC, idxNew);
markTermAsChild(pWC, idxNew, idxTerm);
pWC->a[idxTerm].wtFlags |= TERM_COPIED;
}
/*
** The input to this routine is an WhereTerm structure with only the
@@ -1377,6 +1108,7 @@ static void exprAnalyze(
if( op==TK_IS ) pTerm->wtFlags |= TERM_IS;
if( pRight
&& exprMightBeIndexed(pSrc, pTerm->prereqRight, aiCurCol, pRight, op)
&& !ExprHasProperty(pRight, EP_FixedCol)
){
WhereTerm *pNew;
Expr *pDup;
@@ -1469,16 +1201,6 @@ static void exprAnalyze(
pTerm = &pWC->a[idxTerm];
}
#endif /* SQLITE_OMIT_OR_OPTIMIZATION */
else if( pExpr->op==TK_EXISTS ){
/* Perhaps treat an EXISTS operator as an IN operator */
if( (pExpr->flags & EP_VarSelect)!=0
&& OptimizationEnabled(db, SQLITE_ExistsToIN)
){
exprAnalyzeExists(pSrc, pWC, idxTerm);
}
}
/* The form "x IS NOT NULL" can sometimes be evaluated more efficiently
** as "x>NULL" if x is not an INTEGER PRIMARY KEY. So construct a
** virtual term of that form.
+34 -12
View File
@@ -941,6 +941,14 @@ static int sqlite3WindowExtraAggFuncDepth(Walker *pWalker, Expr *pExpr){
return WRC_Continue;
}
static int disallowAggregatesInOrderByCb(Walker *pWalker, Expr *pExpr){
if( pExpr->op==TK_AGG_FUNCTION && pExpr->pAggInfo==0 ){
sqlite3ErrorMsg(pWalker->pParse,
"misuse of aggregate: %s()", pExpr->u.zToken);
}
return WRC_Continue;
}
/*
** If the SELECT statement passed as the second argument does not invoke
** any SQL window functions, this function is a no-op. Otherwise, it
@@ -950,7 +958,7 @@ static int sqlite3WindowExtraAggFuncDepth(Walker *pWalker, Expr *pExpr){
*/
int sqlite3WindowRewrite(Parse *pParse, Select *p){
int rc = SQLITE_OK;
if( p->pWin && p->pPrior==0 && (p->selFlags & SF_WinRewrite)==0 ){
if( p->pWin && p->pPrior==0 && ALWAYS((p->selFlags & SF_WinRewrite)==0) ){
Vdbe *v = sqlite3GetVdbe(pParse);
sqlite3 *db = pParse->db;
Select *pSub = 0; /* The subquery */
@@ -974,6 +982,11 @@ int sqlite3WindowRewrite(Parse *pParse, Select *p){
}
sqlite3AggInfoPersistWalkerInit(&w, pParse);
sqlite3WalkSelect(&w, p);
if( (p->selFlags & SF_Aggregate)==0 ){
w.xExprCallback = disallowAggregatesInOrderByCb;
w.xSelectCallback = 0;
sqlite3WalkExprList(&w, p->pOrderBy);
}
p->pSrc = 0;
p->pWhere = 0;
@@ -1570,6 +1583,7 @@ struct WindowCodeArg {
int regGosub; /* Register used with OP_Gosub(addrGosub) */
int regArg; /* First in array of accumulator registers */
int eDelete; /* See above */
int regRowid;
WindowCsrAndReg start;
WindowCsrAndReg current;
@@ -2246,16 +2260,24 @@ static int windowCodeOp(
/* If this is a (RANGE BETWEEN a FOLLOWING AND b FOLLOWING) or
** (RANGE BETWEEN b PRECEDING AND a PRECEDING) frame, ensure the
** start cursor does not advance past the end cursor within the
** temporary table. It otherwise might, if (a>b). */
** temporary table. It otherwise might, if (a>b). Also ensure that,
** if the input cursor is still finding new rows, that the end
** cursor does not go past it to EOF. */
if( pMWin->eStart==pMWin->eEnd && regCountdown
&& pMWin->eFrmType==TK_RANGE && op==WINDOW_AGGINVERSE
&& pMWin->eFrmType==TK_RANGE
){
int regRowid1 = sqlite3GetTempReg(pParse);
int regRowid2 = sqlite3GetTempReg(pParse);
sqlite3VdbeAddOp2(v, OP_Rowid, p->start.csr, regRowid1);
sqlite3VdbeAddOp2(v, OP_Rowid, p->end.csr, regRowid2);
sqlite3VdbeAddOp3(v, OP_Ge, regRowid2, lblDone, regRowid1);
VdbeCoverage(v);
if( op==WINDOW_AGGINVERSE ){
sqlite3VdbeAddOp2(v, OP_Rowid, p->start.csr, regRowid1);
sqlite3VdbeAddOp2(v, OP_Rowid, p->end.csr, regRowid2);
sqlite3VdbeAddOp3(v, OP_Ge, regRowid2, lblDone, regRowid1);
VdbeCoverage(v);
}else if( p->regRowid ){
sqlite3VdbeAddOp2(v, OP_Rowid, p->end.csr, regRowid1);
sqlite3VdbeAddOp3(v, OP_Ge, p->regRowid, lblDone, regRowid1);
VdbeCoverageNeverNull(v);
}
sqlite3ReleaseTempReg(pParse, regRowid1);
sqlite3ReleaseTempReg(pParse, regRowid2);
assert( pMWin->eStart==TK_PRECEDING || pMWin->eStart==TK_FOLLOWING );
@@ -2752,7 +2774,6 @@ void sqlite3WindowCodeStep(
int addrEmpty; /* Address of OP_Rewind in flush: */
int regNew; /* Array of registers holding new input row */
int regRecord; /* regNew array in record form */
int regRowid; /* Rowid for regRecord in eph table */
int regNewPeer = 0; /* Peer values for new row (part of regNew) */
int regPeer = 0; /* Peer values for current row */
int regFlushPart = 0; /* Register for "Gosub flush_partition" */
@@ -2824,7 +2845,7 @@ void sqlite3WindowCodeStep(
regNew = pParse->nMem+1;
pParse->nMem += nInput;
regRecord = ++pParse->nMem;
regRowid = ++pParse->nMem;
s.regRowid = ++pParse->nMem;
/* If the window frame contains an "<expr> PRECEDING" or "<expr> FOLLOWING"
** clause, allocate registers to store the results of evaluating each
@@ -2880,9 +2901,9 @@ void sqlite3WindowCodeStep(
}
/* Insert the new row into the ephemeral table */
sqlite3VdbeAddOp2(v, OP_NewRowid, csrWrite, regRowid);
sqlite3VdbeAddOp3(v, OP_Insert, csrWrite, regRecord, regRowid);
addrNe = sqlite3VdbeAddOp3(v, OP_Ne, pMWin->regOne, 0, regRowid);
sqlite3VdbeAddOp2(v, OP_NewRowid, csrWrite, s.regRowid);
sqlite3VdbeAddOp3(v, OP_Insert, csrWrite, regRecord, s.regRowid);
addrNe = sqlite3VdbeAddOp3(v, OP_Ne, pMWin->regOne, 0, s.regRowid);
VdbeCoverageNeverNull(v);
/* This block is run for the first row of each partition */
@@ -3000,6 +3021,7 @@ void sqlite3WindowCodeStep(
sqlite3VdbeJumpHere(v, addrGosubFlush);
}
s.regRowid = 0;
addrEmpty = sqlite3VdbeAddOp1(v, OP_Rewind, csrWrite);
VdbeCoverage(v);
if( pMWin->eEnd==TK_PRECEDING ){
+4 -4
View File
@@ -318,16 +318,16 @@ ifcapable trigger&&tempdb {
END;
INSERT INTO t1 VALUES(1, 2);
SELECT * FROM log;
SELECT * FROM log ORDER BY trig, a, b;
}
} {b 1 2 a 1 2}
} {a 1 2 b 1 2}
do_test alter4-6.2 {
execsql {
ALTER TABLE t1 ADD COLUMN c DEFAULT 'c';
INSERT INTO t1(a, b) VALUES(3, 4);
SELECT * FROM log;
SELECT * FROM log ORDER BY trig, a, b;
}
} {b 1 2 a 1 2 b 3 4 a 3 4}
} {a 1 2 a 3 4 b 1 2 b 3 4}
}
# Ticket #1183 - Make sure adding columns to large tables does not cause
+62
View File
@@ -736,5 +736,67 @@ do_catchsql_test 24.2.1 {
ALTER TABLE t1 RENAME TO t2;
} {1 {error in trigger AFTER: no such table: main.nosuchtable}}
#--------------------------------------------------------------------------
#
reset_db
do_execsql_test 25.1 {
CREATE TABLE xx(x);
CREATE VIEW v3(b) AS WITH b AS (SELECT b FROM (SELECT * FROM t2)) VALUES(1);
}
ifcapable json1&&vtab {
do_catchsql_test 25.2 {
ALTER TABLE json_each RENAME TO t4;
} {1 {table json_each may not be altered}}
}
# 2021-05-01 dbsqlfuzz bc17a306a09329bba0ecc61547077f6178bcf321
# Remove a NEVER() inserted on 2019-12-09 that is reachable after all.
#
reset_db
do_execsql_test 26.1 {
CREATE TABLE t1(k,v);
CREATE TABLE t2_a(k,v);
CREATE VIEW t2 AS SELECT * FROM t2_a;
CREATE TRIGGER r2 AFTER INSERT ON t1 BEGIN
UPDATE t1
SET (k,v)=((WITH cte1(a) AS (SELECT 1 FROM t2) SELECT t2.k FROM t2, cte1),1);
END;
ALTER TABLE t1 RENAME TO t1x;
INSERT INTO t2_a VALUES(2,3);
INSERT INTO t1x VALUES(98,99);
SELECT * FROM t1x;
} {2 1}
#-------------------------------------------------------------------------
reset_db
do_execsql_test 27.1 {
create table t_sa (
c_muyat INTEGER NOT NULL,
c_d4u TEXT
);
create table t2 ( abc );
CREATE TRIGGER trig AFTER DELETE ON t_sa
BEGIN
DELETE FROM t_sa WHERE (
SELECT 123 FROM t2
WINDOW oamat7fzf AS ( PARTITION BY t_sa.c_d4u )
);
END;
}
breakpoint
do_execsql_test 27.2 {
alter table t_sa rename column c_muyat to c_dg;
}
finish_test
+14 -12
View File
@@ -129,19 +129,21 @@ set pgnoChild [get4byte $fd $offChild]
put4byte $fd $offChild 1
close $fd
sqlite3 db test.db
do_catchsql_test 2.2 {
PRAGMA writable_schema = 1;
SELECT * FROM sqlite_schema;
} {1 {database disk image is malformed}}
if {![info exists ::G(perm:presql)]} {
sqlite3 db test.db
do_test 2.3 {
list [catch {
for {set ii $nView} {$ii<$nView*2} {incr ii} {
execsql "INSERT INTO sqlite_master VALUES(1, 2, 3, 4, 5)"
}
} msg] $msg
} {1 {database disk image is malformed}}
do_catchsql_test 2.2 {
PRAGMA writable_schema = 1;
SELECT * FROM sqlite_schema;
} {1 {database disk image is malformed}}
do_test 2.3 {
list [catch {
for {set ii $nView} {$ii<$nView*2} {incr ii} {
execsql "INSERT INTO sqlite_master VALUES(1, 2, 3, 4, 5)"
}
} msg] $msg
} {1 {database disk image is malformed}}
}
finish_test
+64 -37
View File
@@ -149,47 +149,74 @@ INSERT INTO t1(a) SELECT randomblob(null) FROM c;
} {1 {database disk image is malformed}}
reset_db
do_execsql_test 3.0 {
CREATE TABLE t1(x INTEGER PRIMARY KEY AUTOINCREMENT, y);
PRAGMA writable_schema = 1;
UPDATE sqlite_schema
SET sql = 'CREATE TABLE sqlite_sequence(name-seq)'
WHERE name = 'sqlite_sequence';
}
db close
sqlite3 db test.db
do_catchsql_test 3.1 {
PRAGMA writable_schema = 1;
INSERT INTO t1(y) VALUES('abc');
} {1 {database disk image is malformed}}
if {![info exists ::G(perm:presql)]} {
do_execsql_test 3.0 {
CREATE TABLE t1(x INTEGER PRIMARY KEY AUTOINCREMENT, y);
PRAGMA writable_schema = 1;
UPDATE sqlite_schema
SET sql = 'CREATE TABLE sqlite_sequence(name-seq)'
WHERE name = 'sqlite_sequence';
}
db close
sqlite3 db test.db
do_catchsql_test 3.1 {
PRAGMA writable_schema = 1;
INSERT INTO t1(y) VALUES('abc');
} {1 {database disk image is malformed}}
reset_db
reset_db
do_execsql_test 4.1 {
CREATE TABLE x1(a INTEGER PRIMARY KEY, b UNIQUE, c UNIQUE);
INSERT INTO x1 VALUES(1, 1, 2);
INSERT INTO x1 VALUES(2, 2, 3);
INSERT INTO x1 VALUES(3, 3, 4);
INSERT INTO x1 VALUES(4, 5, 6);
PRAGMA writable_schema = 1;
do_execsql_test 4.1 {
CREATE TABLE x1(a INTEGER PRIMARY KEY, b UNIQUE, c UNIQUE);
INSERT INTO x1 VALUES(1, 1, 2);
INSERT INTO x1 VALUES(2, 2, 3);
INSERT INTO x1 VALUES(3, 3, 4);
INSERT INTO x1 VALUES(4, 5, 6);
PRAGMA writable_schema = 1;
UPDATE sqlite_schema SET rootpage = (
SELECT rootpage FROM sqlite_schema WHERE name = 'sqlite_autoindex_x1_2'
) WHERE name = 'sqlite_autoindex_x1_1';
}
db close
sqlite3 db test.db
breakpoint
do_catchsql_test 3.1 {
PRAGMA writable_schema = 1;
PRAGMA vdbe_trace = 1;
REPLACE INTO x1 VALUES(5, 2, 3);
} {1 {database disk image is malformed}}
explain_i {
REPLACE INTO x1 VALUES(5, 2, 3);
UPDATE sqlite_schema SET rootpage = (
SELECT rootpage FROM sqlite_schema WHERE name = 'sqlite_autoindex_x1_2'
) WHERE name = 'sqlite_autoindex_x1_1';
}
db close
sqlite3 db test.db
breakpoint
do_catchsql_test 4.2 {
PRAGMA writable_schema = 1;
REPLACE INTO x1 VALUES(5, 2, 3);
} {1 {database disk image is malformed}}
}
#-------------------------------------------------------------------------
reset_db
ifcapable json1&&vtab {
db func strreplace strreplace
proc strreplace {orig a b} {
string map [list $a $b] $orig
}
do_execsql_test 5.0 {
CREATE TABLE t1(a, b);
CREATE INDEX t1a ON t1(a);
CREATE INDEX t1b ON t1(b);
PRAGMA writable_schema = 1;
UPDATE sqlite_schema
SET sql = strreplace(sql, 't1', 'json_each')
WHERE type='index';
}
db close
sqlite3 db test.db
do_execsql_test 5.1 {
PRAGMA writable_schema = 1;
SELECT * FROM t1
}
}; # ifcapable json1&&vtab
finish_test
+1 -2
View File
@@ -31,8 +31,7 @@
**
** mkdir dir
** cp dbfuzz2-seed*.db dir
** clang-6.0 -I. -g -O1 -fsanitize=fuzzer \
** -DTHREADSAFE=0 -DSQLITE_ENABLE_DESERIALIZE \
** clang-6.0 -I. -g -O1 -fsanitize=fuzzer -DTHREADSAFE=0 \
** -DSQLITE_ENABLE_DBSTAT_VTAB dbfuzz2.c sqlite3.c -ldl
** ./a.out dir
*/
-194
View File
@@ -1,194 +0,0 @@
# 2021 January 15
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
# May you find forgiveness for yourself and forgive others.
# May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library. The
# focus of this file is testing cases where EXISTS expressions are
# transformed to IN() expressions by where.c
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix exists2
do_execsql_test 1.0 {
CREATE TABLE t1(a INTEGER PRIMARY KEY, b);
INSERT INTO t1 VALUES(1, 'one');
INSERT INTO t1 VALUES(2, 'two');
INSERT INTO t1 VALUES(3, 'three');
INSERT INTO t1 VALUES(4, 'four');
INSERT INTO t1 VALUES(5, 'five');
INSERT INTO t1 VALUES(6, 'six');
INSERT INTO t1 VALUES(7, 'seven');
CREATE TABLE t2(c INTEGER, d INTEGER);
INSERT INTO t2 VALUES(1, 1);
INSERT INTO t2 VALUES(3, 2);
INSERT INTO t2 VALUES(5, 3);
INSERT INTO t2 VALUES(7, 4);
}
proc do_execsql_eqp_test {tn sql eqp res} {
uplevel [list do_eqp_test $tn.1 $sql [string trim $eqp]]
uplevel [list do_execsql_test $tn.2 $sql $res]
}
do_execsql_eqp_test 1.1 {
SELECT t1.* FROM t1 WHERE EXISTS(SELECT * FROM t2 WHERE t1.a=t2.c);
} {
USING INTEGER PRIMARY KEY
} {
1 one 3 three 5 five 7 seven
}
do_execsql_eqp_test 1.2 {
SELECT t1.* FROM t1 WHERE EXISTS(SELECT * FROM t2 WHERE t2.c=t1.a);
} {
SEARCH t1 USING INTEGER PRIMARY KEY
} {
1 one 3 three 5 five 7 seven
}
do_execsql_eqp_test 1.3 {
SELECT t1.* FROM t1 WHERE EXISTS(SELECT * FROM t2 WHERE t2.c+1=t1.a);
} {
SEARCH t1 USING INTEGER PRIMARY KEY
} {
2 two 4 four 6 six
}
do_execsql_eqp_test 1.4 {
SELECT t1.* FROM t1 WHERE EXISTS(SELECT * FROM t2 WHERE t2.c+1=t1.a+1);
} {
SCAN t1
} {
1 one 3 three 5 five 7 seven
}
do_execsql_eqp_test 1.5 {
SELECT t1.* FROM t1 WHERE EXISTS(
SELECT * FROM t2 WHERE t1.a=t2.c AND d IN (1, 2, 3)
);
} {
SEARCH t1 USING INTEGER PRIMARY KEY
} {
1 one 3 three 5 five
}
do_execsql_eqp_test 1.6 {
SELECT t1.* FROM t1 WHERE EXISTS(
SELECT * FROM t2 WHERE d IN (1, 2, 3)AND t1.a=t2.c
);
} {
SEARCH t1 USING INTEGER PRIMARY KEY
} {
1 one 3 three 5 five
}
do_execsql_eqp_test 1.7 {
SELECT t1.* FROM t1 WHERE EXISTS(
SELECT * FROM t2 WHERE d IN (1, 2, 3)AND t1.a=t2.c
);
} {
SEARCH t1 USING INTEGER PRIMARY KEY
} {
1 one 3 three 5 five
}
#-------------------------------------------------------------------------
#
reset_db
do_execsql_test 2.0 {
CREATE TABLE t3(a TEXT PRIMARY KEY, b TEXT, x INT) WITHOUT ROWID;
CREATE TABLE t4(c TEXT COLLATE nocase, y INT);
INSERT INTO t3 VALUES('one', 'i', 1);
INSERT INTO t3 VALUES('two', 'ii', 2);
INSERT INTO t3 VALUES('three', 'iii', 3);
INSERT INTO t3 VALUES('four', 'iv', 4);
INSERT INTO t3 VALUES('five', 'v', 5);
INSERT INTO t4 VALUES('FIVE',5), ('four',4), ('TWO',2), ('one',1);
}
do_execsql_test 2.1 { SELECT a FROM t3, t4 WHERE a=c } {four one}
do_execsql_test 2.2 { SELECT a FROM t3, t4 WHERE c=a } {five four one two}
do_execsql_eqp_test 2.3 {
SELECT a FROM t3 WHERE EXISTS (SELECT 1 FROM t4 WHERE a=c)
} {
SEARCH t3 USING PRIMARY KEY
} {
four one
}
do_execsql_eqp_test 2.4 {
SELECT a FROM t3 WHERE EXISTS (SELECT 1 FROM t4 WHERE c=a)
} {
SCAN t3
} {
five four one two
}
do_execsql_test 2.5 {
CREATE INDEX t3anc ON t3(a COLLATE nocase, x);
}
do_execsql_eqp_test 2.6 {
SELECT a FROM t3 WHERE EXISTS (SELECT 1 FROM t4 WHERE c=a)
} {
SEARCH t3 USING COVERING INDEX t3anc
} {
five four one two
}
do_execsql_test 2.6a {
SELECT a FROM t3 WHERE EXISTS (SELECT 1 FROM t4 WHERE (c,y)=(a,x))
} {five four one two}
do_execsql_eqp_test 2.7 {
SELECT a FROM t3 WHERE EXISTS (SELECT 1 FROM t4 WHERE a=c)
} {
SEARCH t3 USING PRIMARY KEY
} {
four one
}
do_execsql_test 2.7a {
SELECT a FROM t3 WHERE EXISTS (SELECT 1 FROM t4 WHERE (a,x)=(c,y))
} {
four one
}
do_execsql_test 2.7b {
SELECT a FROM t3 WHERE EXISTS (SELECT 1 FROM t4 WHERE (a,x)=(c,y) LIMIT 1)
} {
four one
}
# EXISTS clauses using vector expressions in the WHERE clause.
#
reset_db
do_execsql_test 3.0 {
CREATE TABLE t1(a,b);
INSERT INTO t1(a,b) VALUES(1,111),(2,222),(8,888);
CREATE TABLE t2(x INTEGER PRIMARY KEY, y);
INSERT INTO t2(x,y) VALUES(2,222),(3,333),(7,333);
SELECT y FROM t2 WHERE EXISTS(SELECT 1 FROM t1 WHERE (x,y)=(a,b));
} {222}
do_execsql_test 3.1 {
SELECT y FROM t2 WHERE EXISTS(SELECT 1 FROM t1 WHERE (a,b)=(x,y));
} {222}
do_execsql_test 3.2 {
SELECT y FROM t2 WHERE EXISTS(SELECT 1 FROM t1 WHERE (x,b)=(a,y));
} {222}
finish_test
-51
View File
@@ -1,51 +0,0 @@
# 2021 January 15
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
# May you find forgiveness for yourself and forgive others.
# May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library. The
# focus of this file is testing cases where EXISTS expressions are
# transformed to IN() expressions by where.c
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix existsfault
do_execsql_test 1 {
CREATE TABLE t1(a PRIMARY KEY, b);
INSERT INTO t1 VALUES(1, 'one');
INSERT INTO t1 VALUES(2, 'two');
INSERT INTO t1 VALUES(3, 'three');
INSERT INTO t1 VALUES(4, 'four');
INSERT INTO t1 VALUES(5, 'five');
INSERT INTO t1 VALUES(6, 'six');
INSERT INTO t1 VALUES(7, 'seven');
CREATE TABLE t2(c INTEGER, d INTEGER);
INSERT INTO t2 VALUES(1, 1);
INSERT INTO t2 VALUES(3, 2);
INSERT INTO t2 VALUES(5, 3);
INSERT INTO t2 VALUES(7, 4);
}
faultsim_save_and_close
do_faultsim_test 1 -prep {
faultsim_restore_and_reopen
} -body {
execsql {
SELECT t1.* FROM t1 WHERE EXISTS(
SELECT * FROM t2 WHERE t2.c=t1.a AND d IN (1, 2, 3)
)
}
} -test {
faultsim_test_result {0 {1 one 3 three 5 five}}
}
finish_test
+33 -16
View File
@@ -63,7 +63,7 @@
** of the global variable g.zTextName[] will identify the specific XSQL and
** DB values that were running when the crash occurred.
**
** DBSQLFUZZ:
** DBSQLFUZZ: (Added 2020-02-25)
**
** The dbsqlfuzz fuzzer includes both a database file and SQL to run against
** that database in its input. This utility can now process dbsqlfuzz
@@ -108,10 +108,10 @@ typedef unsigned char uint8_t;
*/
typedef struct VFile VFile;
struct VFile {
char *zFilename; /* Filename. NULL for delete-on-close. From malloc() */
int sz; /* Size of the file in bytes */
int nRef; /* Number of references to this file */
unsigned char *a; /* Content of the file. From malloc() */
char *zFilename; /* Filename. NULL for delete-on-close. From malloc() */
int sz; /* Size of the file in bytes */
int nRef; /* Number of references to this file */
unsigned char *a; /* Content of the file. From malloc() */
};
typedef struct VHandle VHandle;
struct VHandle {
@@ -219,7 +219,7 @@ static int progressHandler(void *pVdbeLimitFlag){
#endif
/*
** Reallocate memory. Show and error and quit if unable.
** Reallocate memory. Show an error and quit if unable.
*/
static void *safe_realloc(void *pOld, int szNew){
void *pNew = realloc(pOld, szNew<=0 ? 1 : szNew);
@@ -617,8 +617,8 @@ static int isOffset(
/*
** Decode the text starting at zIn into a binary database file.
** The maximum length of zIn is nIn bytes. Compute the binary database
** file contain in space obtained from sqlite3_malloc().
** The maximum length of zIn is nIn bytes. Store the binary database
** file in space obtained from sqlite3_malloc().
**
** Return the number of bytes of zIn consumed. Or return -1 if there
** is an error. One potential error is that the recipe specifies a
@@ -1435,9 +1435,10 @@ static void showHelp(void){
" --limit-heap N Limit heap memory to N. Default: 100M\n"
" --limit-mem N Limit memory used by test SQLite instance to N bytes\n"
" --limit-vdbe Panic if any test runs for more than 100,000 cycles\n"
" --load-sql ARGS... Load SQL scripts fron files into SOURCE-DB\n"
" --load-db ARGS... Load template databases from files into SOURCE_DB\n"
" --load-dbsql ARGS.. Load dbsqlfuzz outputs into the xsql table\n"
" --load-sql FILE.. Load SQL scripts fron files into SOURCE-DB\n"
" --load-db FILE.. Load template databases from files into SOURCE_DB\n"
" --load-dbsql FILE.. Load dbsqlfuzz outputs into the xsql table\n"
" ^^^^------ Use \"-\" for FILE to read filenames from stdin\n"
" -m TEXT Add a description to the database\n"
" --native-vfs Use the native VFS for initially empty database files\n"
" --native-malloc Turn off MEMSYS3/5 and Lookaside\n"
@@ -1778,10 +1779,25 @@ int main(int argc, char **argv){
rc = sqlite3_exec(db, "BEGIN", 0, 0, 0);
if( rc ) fatalError("cannot start a transaction");
for(i=iFirstInsArg; i<argc; i++){
sqlite3_bind_text(pStmt, 1, argv[i], -1, SQLITE_STATIC);
sqlite3_step(pStmt);
rc = sqlite3_reset(pStmt);
if( rc ) fatalError("insert failed for %s", argv[i]);
if( strcmp(argv[i],"-")==0 ){
/* A filename of "-" means read multiple filenames from stdin */
char zLine[2000];
while( rc==0 && fgets(zLine,sizeof(zLine),stdin)!=0 ){
size_t kk = strlen(zLine);
while( kk>0 && zLine[kk-1]<=' ' ) kk--;
sqlite3_bind_text(pStmt, 1, zLine, kk, SQLITE_STATIC);
if( verboseFlag ) printf("loading %.*s\n", (int)kk, zLine);
sqlite3_step(pStmt);
rc = sqlite3_reset(pStmt);
if( rc ) fatalError("insert failed for %s", zLine);
}
}else{
sqlite3_bind_text(pStmt, 1, argv[i], -1, SQLITE_STATIC);
if( verboseFlag ) printf("loading %s\n", argv[i]);
sqlite3_step(pStmt);
rc = sqlite3_reset(pStmt);
if( rc ) fatalError("insert failed for %s", argv[i]);
}
}
sqlite3_finalize(pStmt);
rc = sqlite3_exec(db, "COMMIT", 0, 0, 0);
@@ -2050,7 +2066,8 @@ int main(int argc, char **argv){
}
}
if( bSpinner ){
printf("\n");
int nTotal = g.nDb*g.nSql;
printf("\r%s: %d/%d \n", zDbName, nTotal, nTotal);
}else if( !quietFlag && !verboseFlag ){
printf(" 100%% - %d tests\n", g.nDb*g.nSql);
}
BIN
View File
Binary file not shown.
+19
View File
@@ -97,4 +97,23 @@ do_execsql_test in6-3.110 {
SELECT quote(v5) FROM v0 LEFT JOIN v3 ON v4 = NULL AND v5 IN(0);
} {NULL}
# 2021-04-29 forum https://sqlite.org/forum/forumpost/6a3ec138e9
# An early OP_IsNull bypass might skip over the OP_Affinity and
# cause the OP_IfNoHope to jump on a false-positive, resulting in
# incomplete output.
#
reset_db
do_execsql_test in6-3.120 {
CREATE TABLE t1(a TEXT, b TEXT);
INSERT INTO t1 VALUES(null,10),(0,10),(10,10);
CREATE INDEX t1ab ON t1(a,b);
SELECT quote(a), quote(b), '|' FROM t1 WHERE b in (SELECT a FROM t1) AND a=0;
} {'0' '10' |}
do_execsql_test in6-3.130 {
CREATE TABLE t2(x TEXT);
INSERT INTO t2(x) VALUES(NULL),(0),(10);
SELECT quote(x), quote(a), quote(b), 'x'
FROM t2 LEFT JOIN t1 ON a=x AND b in (null,0,10);
} {NULL NULL NULL x '0' '0' '10' x '10' '10' '10' x}
finish_test
+48
View File
@@ -0,0 +1,48 @@
# 2021 May 24
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
# May you find forgiveness for yourself and forgive others.
# May you share freely, never taking more than you give.
#
#***********************************************************************
# Tests focused on the in-memory journal.
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
source $testdir/malloc_common.tcl
set testprefix memjournal
do_execsql_test 1.0 {
PRAGMA journal_mode = memory;
CREATE TABLE t1(a);
} {memory}
set nRow [expr 1]
do_execsql_test 1.1 {
BEGIN;
INSERT INTO t1 VALUES( randomblob(500) );
} {}
do_test 1.2 {
for {set i 1} {$i <= 500} {incr i} {
execsql {
SAVEPOINT one;
UPDATE t1 SET a=randomblob(500);
}
execsql { SAVEPOINT abc }
execsql { UPDATE t1 SET a=randomblob(500) WHERE rowid<=$i AND 0 }
execsql { RELEASE abc }
}
} {}
do_execsql_test 1.3 {
COMMIT;
}
finish_test
-1
View File
@@ -26,7 +26,6 @@
*/
#define SQLITE_THREADSAFE 0
#define SQLITE_OMIT_LOAD_EXTENSION 1
#define SQLITE_ENABLE_DESERIALIZE 1
#include "sqlite3.c"
/* Content of the read-only test database */
+1
View File
@@ -131,6 +131,7 @@ set allquicktests [test_set $alltests -exclude {
fts3defer.test fts4langid.test fts3sort.test fts5unicode.test
rtree4.test
sessionbig.test
}]
if {[info exists ::env(QUICKTEST_INCLUDE)]} {
set allquicktests [concat $allquicktests $::env(QUICKTEST_INCLUDE)]
-2
View File
@@ -50,7 +50,6 @@ array set ::Configs [strip_comments {
-O2
--disable-amalgamation --disable-shared
--enable-session
-DSQLITE_ENABLE_DESERIALIZE
}
"Sanitize" {
CC=clang -fsanitize=undefined
@@ -180,7 +179,6 @@ array set ::Configs [strip_comments {
-DSQLITE_OMIT_TRACE=1
-DSQLITE_TEMP_STORE=3
-DSQLITE_THREADSAFE=2
-DSQLITE_ENABLE_DESERIALIZE=1
--enable-json1 --enable-fts5 --enable-session
}
"Locking-Style" {
-4
View File
@@ -51,7 +51,6 @@ array set ::Configs [strip_comments {
-O2
--disable-amalgamation --disable-shared
--enable-session
-DSQLITE_ENABLE_DESERIALIZE
}
"Sanitize" {
CC=clang -fsanitize=address,undefined
@@ -188,7 +187,6 @@ array set ::Configs [strip_comments {
-DSQLITE_OMIT_TRACE=1
-DSQLITE_TEMP_STORE=3
-DSQLITE_THREADSAFE=2
-DSQLITE_ENABLE_DESERIALIZE=1
--enable-json1 --enable-fts5 --enable-session
}
"Locking-Style" {
@@ -629,5 +627,3 @@ if {[string match ${cmd}* configurations] && $n==0} {
} else {
usage
}
+94
View File
@@ -224,4 +224,98 @@ do_execsql_test 10.4 {
SELECT * FROM log;
} {}
# 2021-04-27 dbsqlfuzz 78b9400770ef8cc7d9427dfba26f4fcf46ea7dc2
# Returning clauses on TEMP tables with triggers.
#
reset_db
do_execsql_test 11.1 {
CREATE TEMP TABLE t1(a,b);
CREATE TEMP TABLE t2(c,d);
CREATE TEMP TABLE t3(e,f);
CREATE TEMP TABLE log(op,x,y);
CREATE TEMP TRIGGER t1r1 AFTER INSERT ON t1 BEGIN
INSERT INTO log(op,x,y) VALUES('I1',new.a,new.b);
END;
CREATE TEMP TRIGGER t1r2 BEFORE DELETE ON t1 BEGIN
INSERT INTO log(op,x,y) VALUES('D1',old.a,old.b);
END;
CREATE TEMP TRIGGER t2r3 AFTER UPDATE ON t1 BEGIN
INSERT INTO log(op,x,y) VALUES('U1',new.a,new.b);
END;
CREATE TEMP TRIGGER t2r1 BEFORE INSERT ON t2 BEGIN
INSERT INTO log(op,x,y) VALUES('I2',new.c,new.d);
END;
CREATE TEMP TRIGGER t3r1 AFTER DELETE ON t3 BEGIN
INSERT INTO log(op,x,y) VALUES('D3',old.e,old.f);
END;
CREATE TEMP TRIGGER t3r2 BEFORE UPDATE ON t3 BEGIN
INSERT INTO log(op,x,y) VALUES('U3',new.e,new.f);
END;
INSERT INTO t1(a,b) VALUES(1,2),('happy','glad') RETURNING a, b, '|';
} {1 2 | happy glad |}
do_execsql_test 11.2 {
UPDATE t1 SET b=9 WHERE a=1 RETURNING a, b, 'x';
} {1 9 x}
do_execsql_test 11.3 {
DELETE FROM t1 WHERE a<>'xray' RETURNING a, b, '@';
} {1 9 @ happy glad @}
do_execsql_test 11.4 {
SELECT * FROM log;
DELETE FROM log;
} {I1 1 2 I1 happy glad U1 1 9 D1 1 9 D1 happy glad}
do_execsql_test 11.5 {
INSERT INTO t2 VALUES('bravo','charlie') RETURNING d, c, 'z';
} {charlie bravo z}
do_execsql_test 11.6 {
SELECT * FROM log;
DELETE FROM log;
} {I2 bravo charlie}
do_execsql_test 11.7 {
INSERT INTO t3(e) VALUES(1),(2),(3) RETURNING 'I', e;
UPDATE t3 SET f=e+100 RETURNING 'U', e, f;
DELETE FROM t3 WHERE f>100 RETURNING 'D', e, f;
} {I 1 I 2 I 3 U 1 101 U 2 102 U 3 103 D 1 101 D 2 102 D 3 103}
do_execsql_test 11.6 {
SELECT * FROM log;
DELETE FROM log;
} {U3 1 101 U3 2 102 U3 3 103 D3 1 101 D3 2 102 D3 3 103}
reset_db
do_execsql_test 11.11 {
CREATE TEMP TABLE t1(a,b);
CREATE TRIGGER r1 BEFORE INSERT ON t1 BEGIN SELECT 1; END;
DELETE FROM t1 RETURNING *;
DROP TRIGGER r1;
INSERT INTO t1 VALUES(5,30);
} {}
do_execsql_test 11.12 {
SELECT * FROM t1;
} {5 30}
# RETURNING column names are dequoted.
# https://sqlite.org/forum/forumpost/033daf0b32
#
reset_db
do_test 12.1 {
db eval {CREATE TABLE t1(x INT, y INT)}
unset -nocomplain cname
db eval {INSERT INTO t1(x) VALUES(1) RETURNING "x";} cname {}
lsort [array names cname]
} {* x}
do_test 12.2 {
unset -nocomplain cname
db eval {INSERT INTO t1(x) VALUES(2) RETURNING [x];} cname {}
lsort [array names cname]
} {* x}
do_test 12.3 {
unset -nocomplain cname
db eval {INSERT INTO t1(x) VALUES(3) RETURNING x AS [xyz];} cname {}
lsort [array names cname]
} {* xyz}
do_test 12.4 {
unset -nocomplain cname
db eval {INSERT INTO t1(x,y) VALUES(4,5) RETURNING "x"+"y";} cname {}
lsort [array names cname]
} {{"x"+"y"} *}
finish_test
+13
View File
@@ -297,5 +297,18 @@ do_execsql_test 7.3 {
);
} { 1 4 1 5 }
#-------------------------------------------------------------------------
#
do_execsql_test 8.1 {
CREATE TABLE t1(a ,b FLOAT);
CREATE INDEX t1x1 ON t1(a,b,a,a,a,a,a,a,a,a,a,b);
}
do_catchsql_test 8.2 {
SELECT a FROM t1 NATURAL JOIN t1 WHERE (a,b)> (SELECT 2 IN (SELECT 2,2), 2);
} {1 {sub-select returns 2 columns - expected 1}}
finish_test
+8 -3
View File
@@ -12,7 +12,6 @@
# focus of this file is testing aggregate functions and the
# GROUP BY and HAVING clauses of SELECT statements.
#
# $Id: select5.test,v 1.20 2008/08/21 14:15:59 drh Exp $
set testdir [file dirname $argv0]
source $testdir/tester.tcl
@@ -251,7 +250,13 @@ do_test select5-8.8 {
}
} {two 3 one 9}
# 2021-04-26 forum https://sqlite.org/forum/forumpost/74330094d8
reset_db
do_execsql_test select5-9.1 {
CREATE TABLE t1(a INT, b INT);
INSERT INTO t1(a,b) VALUES(1,null),(null,null),(1,null);
CREATE UNIQUE INDEX t1b ON t1(abs(b));
SELECT quote(a), quote(b), '|' FROM t1 GROUP BY a, abs(b);
} {NULL NULL | 1 NULL |}
finish_test
+44
View File
@@ -227,6 +227,50 @@ do_test tabfunc01-751 {
}
} {5.0 x5 | 7.0 x7 | 13.0 x13 | 17.0 x17 | 23.0 x23 |}
ifcapable altertable {
do_test tabfunc01-800 {
catchsql {
ALTER TABLE generate_series ADD COLUMN col2;
}
} {1 {virtual tables may not be altered}}
do_test tabfunc01-810 {
catchsql {
ALTER TABLE generate_series RENAME TO flubber;
}
} {1 {table generate_series may not be altered}}
do_test tabfunc01-820 {
catchsql {
ALTER TABLE generate_series RENAME start TO flubber;
}
} {1 {table generate_series may not be altered}}
do_test tabfunc01-830 {
catchsql {
ALTER TABLE generate_series DROP COLUMN start;
}
} {1 {table generate_series may not be altered}}
do_test tabfunc01-900 {
catchsql {
ALTER TABLE pragma_compile_options ADD COLUMN col2;
}
} {1 {virtual tables may not be altered}}
do_test tabfunc01-910 {
catchsql {
ALTER TABLE pragma_compile_options RENAME TO flubber;
}
} {1 {table pragma_compile_options may not be altered}}
do_test tabfunc01-920 {
catchsql {
ALTER TABLE pragma_compile_options RENAME start TO flubber;
}
} {1 {table pragma_compile_options may not be altered}}
do_test tabfunc01-930 {
catchsql {
ALTER TABLE pragma_compile_options DROP COLUMN start;
}
} {1 {table pragma_compile_options may not be altered}}
}
# Free up memory allocations
intarray_addr
int64array_addr
+339
View File
@@ -0,0 +1,339 @@
/*
** 2021-05-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.
**
*************************************************************************
**
** Testing threading behavior when multiple database connections in separate
** threads of the same process are all talking to the same database file.
**
** For best results, ensure that SQLite is compiled with HAVE_USLEEP=1
**
** Only works on unix platforms.
**
** Usage:
**
** ./threadtest5 ?DATABASE?
**
** If DATABASE is omitted, it defaults to using file:/mem?vfs=memdb.
*/
#include "sqlite3.h"
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
/* Name of the in-memory database */
static char *zDbName = 0;
/* True for debugging */
static int eVerbose = 0;
/* If rc is not SQLITE_OK, then print an error message and stop
** the test.
*/
static void error_out(int rc, const char *zCtx, int lineno){
if( rc!=SQLITE_OK ){
fprintf(stderr, "error %d at %d in \"%s\"\n", rc, lineno, zCtx);
exit(-1);
}
}
#if 0
/* Return the number of milliseconds since the Julian epoch (-4714-11-24).
*/
static sqlite3_int64 gettime(void){
sqlite3_int64 tm;
sqlite3_vfs *pVfs = sqlite3_vfs_find(0);
pVfs->xCurrentTimeInt64(pVfs, &tm);
return tm;
}
#endif
/* Run the SQL in the second argument.
*/
static int exec(
sqlite3 *db,
const char *zId,
int lineno,
const char *zFormat,
...
){
int rc;
va_list ap;
char *zSql;
va_start(ap, zFormat);
zSql = sqlite3_vmprintf(zFormat, ap);
va_end(ap);
if( eVerbose){
printf("%s:%d: [%s]\n", zId, lineno, zSql);
fflush(stdout);
}
rc = sqlite3_exec(db, zSql, 0, 0, 0);
if( rc && eVerbose ){
printf("%s:%d: return-code %d\n", zId, lineno, rc);
fflush(stdout);
}
sqlite3_free(zSql);
return rc;
}
/* Generate a perpared statement from the input SQL
*/
static sqlite3_stmt *prepare(
sqlite3 *db,
const char *zId,
int lineno,
const char *zFormat,
...
){
int rc;
va_list ap;
char *zSql;
sqlite3_stmt *pStmt = 0;
va_start(ap, zFormat);
zSql = sqlite3_vmprintf(zFormat, ap);
va_end(ap);
if( eVerbose){
printf("%s:%d: [%s]\n", zId, lineno, zSql);
fflush(stdout);
}
rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0);
if( rc ){
printf("%s:%d: ERROR - %s\n", zId, lineno, sqlite3_errmsg(db));
exit(-1);
}
sqlite3_free(zSql);
return pStmt;
}
/*
** Wait for table zTable to exist in the schema.
*/
static void waitOnTable(sqlite3 *db, const char *zWorker, const char *zTable){
while(1){
int eFound = 0;
sqlite3_stmt *q = prepare(db, zWorker, __LINE__,
"SELECT 1 FROM sqlite_schema WHERE name=%Q", zTable);
if( sqlite3_step(q)==SQLITE_ROW && sqlite3_column_int(q,0)!=0 ){
eFound = 1;
}
sqlite3_finalize(q);
if( eFound ) return;
sqlite3_sleep(1);
}
}
/*
** Return true if x is a prime number
*/
static int isPrime(int x){
int i;
if( x<2 ) return 1;
for(i=2; i*i<=x; i++){
if( (x%i)==0 ) return 0;
}
return 1;
}
/* Each worker thread runs an instance of the following */
static void *worker(void *pArg){
int rc;
const char *zName = (const char*)pArg;
sqlite3 *db = 0;
if( eVerbose ){
printf("%s: startup\n", zName);
fflush(stdout);
}
rc = sqlite3_open(zDbName, &db);
error_out(rc, "sqlite3_open", __LINE__);
sqlite3_busy_timeout(db, 2000);
while( 1 ){
sqlite3_stmt *q1;
int tid = -1;
q1 = prepare(db, zName, __LINE__,
"UPDATE task SET doneby=%Q"
" WHERE tid=(SELECT tid FROM task WHERE doneby IS NULL LIMIT 1)"
"RETURNING tid", zName
);
if( sqlite3_step(q1)==SQLITE_ROW ){
tid = sqlite3_column_int(q1,0);
}
sqlite3_finalize(q1);
if( tid<0 ) break;
if( eVerbose ){
printf("%s: starting task %d\n", zName, tid);
fflush(stdout);
}
if( tid==1 ){
exec(db, zName, __LINE__,
"CREATE TABLE IF NOT EXISTS p1(x INTEGER PRIMARY KEY);"
);
}else if( tid>=2 && tid<=51 ){
int a, b, i;
waitOnTable(db, zName, "p1");
a = (tid-2)*200 + 1;
b = a+200;
for(i=a; i<b; i++){
if( isPrime(i) ){
exec(db, zName, __LINE__,
"INSERT INTO p1(x) VALUES(%d)", i);
}
}
}else if( tid==52 ){
exec(db, zName, __LINE__,
"CREATE TABLE IF NOT EXISTS p2(x INTEGER PRIMARY KEY);"
"WITH RECURSIVE"
" c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<10000)"
"INSERT INTO p2(x) SELECT x FROM c;"
);
}else if( tid>=53 && tid<=62 ){
int a, b, i;
waitOnTable(db, zName, "p2");
a = (tid-53)*10 + 2;
b = a+9;
for(i=a; i<=b; i++){
exec(db, zName, __LINE__,
"DELETE FROM p2 WHERE x>%d AND (x %% %d)==0", i, i);
}
}
if( eVerbose ){
printf("%s: completed task %d\n", zName, tid);
fflush(stdout);
}
sqlite3_sleep(1);
}
sqlite3_close(db);
if( eVerbose ){
printf("%s: exit\n", zName);
fflush(stdout);
}
return 0;
}
/* Print a usage comment and die */
static void usage(const char *argv0){
printf("Usage: %s [options]\n", argv0);
printf(
" -num-workers N Run N worker threads\n"
" -v Debugging output\n"
);
exit(1);
}
/* Maximum number of threads */
#define MX_WORKER 100
/*
** Main routine
*/
int main(int argc, char **argv){
int i;
int nWorker = 4;
int rc;
sqlite3 *db = 0;
sqlite3_stmt *q;
pthread_t aWorker[MX_WORKER];
char aWorkerName[MX_WORKER][8];
for(i=1; i<argc; i++){
const char *zArg = argv[i];
if( zArg[0]!='-' ){
if( zDbName==0 ){
zDbName = argv[i];
continue;
}
printf("unknown argument: %s\n", zArg);
usage(argv[0]);
}
if( zArg[1]=='-' ) zArg++;
if( strcmp(zArg, "-v")==0 ){
eVerbose = 1;
continue;
}
if( strcmp(zArg, "-num-workers")==0 && i+1<argc ){
nWorker = atoi(argv[++i]);
if( nWorker<1 || nWorker>MX_WORKER ){
printf("number of threads must be between 1 and %d\n", MX_WORKER);
exit(1);
}
continue;
}
printf("unknown option: %s\n", argv[i]);
usage(argv[0]);
}
if( zDbName==0 ) zDbName = "file:/mem?vfs=memdb";
sqlite3_config(SQLITE_CONFIG_URI, (int)1);
rc = sqlite3_open(zDbName, &db);
error_out(rc, "sqlite3_open", __LINE__);
rc = exec(db, "SETUP", __LINE__,
"DROP TABLE IF EXISTS task;\n"
"DROP TABLE IF EXISTS p1;\n"
"DROP TABLE IF EXISTS p2;\n"
"DROP TABLE IF EXISTS verify;\n"
"CREATE TABLE IF NOT EXISTS task(\n"
" tid INTEGER PRIMARY KEY,\n"
" doneby TEXT\n"
");\n"
"WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<100)"
"INSERT INTO task(tid) SELECT x FROM c;\n"
);
error_out(rc, "sqlite3_exec", __LINE__);
for(i=0; i<nWorker; i++){
sqlite3_snprintf(sizeof(aWorkerName[i]), aWorkerName[i],
"W%02d", i);
pthread_create(&aWorker[i], 0, worker, aWorkerName[i]);
}
for(i=0; i<nWorker; i++){
pthread_join(aWorker[i], 0);
}
for(i=0; i<nWorker; i++){
q = prepare(db, "MAIN", __LINE__,
"SELECT group_concat(tid,',') FROM task WHERE doneby=%Q",
aWorkerName[i]);
if( sqlite3_step(q)==SQLITE_ROW ){
printf("%s: %s\n", aWorkerName[i], sqlite3_column_text(q,0));
}
sqlite3_finalize(q);
}
q = prepare(db, "MAIN", __LINE__, "SELECT count(*) FROM p2");
if( sqlite3_step(q)!=SQLITE_ROW || sqlite3_column_int(q,0)<10 ){
printf("incorrect result\n");
exit(-1);
}
sqlite3_finalize(q);
q = prepare(db, "MAIN", __LINE__, "SELECT x FROM p1 EXCEPT SELECT x FROM p2");
if( sqlite3_step(q)==SQLITE_ROW ){
printf("incorrect result\n");
exit(-1);
}
sqlite3_finalize(q);
q = prepare(db, "MAIN", __LINE__, "SELECT x FROM p2 EXCEPT SELECT x FROM p1");
if( sqlite3_step(q)==SQLITE_ROW ){
printf("incorrect result\n");
exit(-1);
}
sqlite3_finalize(q);
printf("OK\n");
sqlite3_close(db);
return 0;
}
+27
View File
@@ -353,4 +353,31 @@ do_execsql_test transitive1-570eqp {
SELECT * FROM c1 WHERE x=y AND z=y AND z='abc';
} {/SEARCH c1 USING INDEX c1x/}
# 2021-05-04 forum https://sqlite.org/forum/forumpost/eb8613976a
reset_db
do_execsql_test transitive1-600 {
CREATE TABLE t0(a0 INT, b1 INT);
CREATE INDEX t0b1 ON t0(b1);
CREATE TABLE t1(w,x,y,z3 INT);
INSERT INTO t0(a0, b1) VALUES (0,1);
INSERT INTO t1(w,x,y,z3) VALUES (7,8,9,1);
} {}
do_execsql_test transitive1-610 {
SELECT ALL * FROM t0,t1 WHERE b1=z3 AND a0=z3;
} {}
do_execsql_test transitive1-620 {
SELECT ALL * FROM t0,t1 WHERE likely(b1=z3) AND a0=z3;
} {}
do_execsql_test transitive1-630 {
DROP TABLE t0;
DROP TABLE t1;
CREATE TABLE t0(c0 INT, c1 INT UNIQUE);
CREATE TABLE t1(c0 INT);
INSERT INTO t0(c0, c1) VALUES (0, 1);
INSERT INTO t1(c0) VALUES (1);
SELECT ALL * FROM t1 NATURAL JOIN t0 WHERE (t1.c0=t0.c1);
SELECT ALL * FROM t1 NATURAL JOIN t0 WHERE (likely(t1.c0=t0.c1));
SELECT ALL * FROM t1,t0 WHERE (likely(t1.c0=t0.c1) AND t1.c0=t0.c0);
} {}
finish_test
+9
View File
@@ -355,4 +355,13 @@ do_execsql_test 6.1 {
9 10 800 100 9 10 800 400
}
# 2021-04-26 dbsqlfuzz 88ed5c66789fced139d148aed823cba7c0926dd7
reset_db
do_execsql_test 7.1 {
WITH c1(x) AS (VALUES(0) UNION ALL SELECT 100+x FROM c1 WHERE x<100 UNION ALL SELECT 1+x FROM c1 WHERE x<1)
SELECT x, y, '|'
FROM c1 AS x1, (SELECT x+1 AS y FROM c1 WHERE x<1 UNION ALL SELECT 1+x FROM c1 WHERE 1<x) AS x2
ORDER BY x, y;
} {0 1 | 0 101 | 0 102 | 1 1 | 1 101 | 1 102 | 100 1 | 100 101 | 100 102 | 101 1 | 101 101 | 101 102 |}
finish_test
+32
View File
@@ -175,4 +175,36 @@ do_execsql_test 3.1 {
SELECT * FROM t0, t1;
} {}
# Problem described by forum post https://sqlite.org/forum/forumpost/a274248080
#
reset_db
do_execsql_test 4.1 {
CREATE TABLE t1(x INT); INSERT INTO t1 VALUES(1);
CREATE TABLE t2(y INT); INSERT INTO t2 VALUES(2);
WITH t1 AS (SELECT y+100 AS x FROM t2)
UPDATE t1 SET x=(SELECT x FROM t1);
SELECT x, y FROM t1, t2;
} {102 2}
do_execsql_test 4.2 {
WITH t1 AS (SELECT y+100 AS x FROM t2)
UPDATE t1 SET x=x+y FROM t2;
SELECT x, y FROM t1, t2;
} {104 2}
# 2021-05-20
# Forum https://sqlite.org/forum/forumpost/339f487de5 by Yu Liang
# A bad assert()
#
reset_db
do_execsql_test 5.1 {
CREATE TABLE t1(a);
INSERT INTO t1(a) VALUES(5);
CREATE VIEW t2 AS SELECT a FROM t1 UNION ALL SELECT a FROM t1;
CREATE TABLE t3(b,c);
INSERT INTO t3(b,c) VALUES(1,2);
UPDATE t3 SET (c,b) = (SELECT 3,4) FROM t1, t2;
SELECT * FROM t3;
} {4 3}
finish_test
+49
View File
@@ -0,0 +1,49 @@
# 2021 May 20
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
# May you find forgiveness for yourself and forgive others.
# May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library. The
# focus of this file is testing VIEW statements.
#
# $Id: view.test,v 1.39 2008/12/14 14:45:21 danielk1977 Exp $
set testdir [file dirname $argv0]
source $testdir/tester.tcl
# Omit this entire file if the library is not configured with views enabled.
ifcapable !view {
finish_test
return
}
set testprefix view2
do_execsql_test 1.0 {
CREATE TABLE t1(x, y);
INSERT INTO t1 VALUES(1, 2);
CREATE VIEW v1 AS SELECT * FROM (
WITH x1 AS (SELECT y, x FROM t1)
SELECT * FROM x1
);
}
do_execsql_test 1.1 {
SELECT * FROM v1
} {2 1}
do_execsql_test 1.2 {
CREATE VIEW v3 AS SELECT * FROM main.t1;
WITH t1(a, b) AS ( SELECT 3, 4 ) SELECT * FROM v3;
} {1 2}
breakpoint
do_execsql_test 1.3 {
CREATE VIEW v2 AS SELECT * FROM t1;
WITH t1(a, b) AS ( SELECT 3, 4 ) SELECT * FROM v2;
} {1 2}
finish_test
+1
View File
@@ -983,6 +983,7 @@ do_test vtab1.10-5 {
proc match_func {args} {return ""}
do_test vtab1.10-6 {
set echo_module ""
sqlite_delete_function db match
db function match match_func
execsql {
SELECT * FROM e WHERE match('pattern', rowid, 'pattern2');
+18 -1
View File
@@ -982,6 +982,23 @@ do_test where9-10.2 {
}
} {1 {} 1}
# dbsqlfuzz 9df1d53c24c4c96af0dae15ee764897af415ac76
# The MULTI-INDEX OR processing evaluates the same WHERE-clause sub-expression
# twice. But if that sub-expression contains a UNION ALL SELECT statement
# subject to query flattening, the sub-expression might be transformed in a
# way that it can only be code-generated once. An assert() will fail on
# the second attempt to generate code from the same sub-expression.
# The solution is to make a copy of sub-expressions used by MULTI-INDEX OR
#
reset_db
do_execsql_test where9-11.1 {
CREATE TABLE t1(a INTEGER PRIMARY KEY, b TEXT);
CREATE TABLE t2_a(k INTEGER PRIMARY KEY, v TEXT);
CREATE TABLE t2_b(k INTEGER PRIMARY KEY, v TEXT);
CREATE VIEW t2 AS SELECT * FROM t2_a UNION ALL SELECT * FROM t2_b;
SELECT 1 FROM t1 JOIN t1 USING(a)
WHERE (a=1)
OR (a=2 AND (SELECT 4 FROM t2,(SELECT 5 FROM t1 ORDER BY a) WHERE a));
} {}
finish_test
+4 -4
View File
@@ -28,11 +28,11 @@ do_eqp_test 110 {
QUERY PLAN
`--COMPOUND QUERY
|--LEFT-MOST SUBQUERY
| |--SEARCH t2 USING INDEX sqlite_autoindex_t2_1 (a=?)
| `--SEARCH t1 USING INDEX sqlite_autoindex_t1_1 (a=?)
| |--SEARCH t1 USING INDEX sqlite_autoindex_t1_1 (a=?)
| `--SEARCH t2 USING INDEX sqlite_autoindex_t2_1 (a=?)
`--UNION ALL
|--SEARCH t3 USING INDEX sqlite_autoindex_t3_1 (a=?)
`--SEARCH t1 USING INDEX sqlite_autoindex_t1_1 (a=?)
|--SEARCH t1 USING INDEX sqlite_autoindex_t1_1 (a=?)
`--SEARCH t3 USING INDEX sqlite_autoindex_t3_1 (a=?)
}
# The scan of the t1 table goes first since that enables the ORDER BY
+112
View File
@@ -0,0 +1,112 @@
# 2021 May 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.
#
#***********************************************************************
# Tests focused on the "constant propagation" that occurs within the
# WHERE clause of a SELECT statemente.
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
source $testdir/malloc_common.tcl
set testprefix whereM
do_execsql_test 1.0 {
CREATE TABLE t1(a, b INTEGER, c TEXT, d REAL, e BLOB);
INSERT INTO t1 VALUES(10.0, 10.0, 10.0, 10.0, 10.0);
SELECT * FROM t1;
} {
10.0 10 10.0 10.0 10.0
}
do_execsql_test 1.1.1 {
SELECT a=10, a = '10.0', a LIKE '10.0' FROM t1;
} {1 0 1}
do_execsql_test 1.1.2 {
SELECT count(*) FROM t1 WHERE a=10 AND a = '10.0'
} {0}
do_execsql_test 1.1.3 {
SELECT count(*) FROM t1 WHERE a=10 AND a LIKE '10.0'
} {1}
do_execsql_test 1.1.4 {
SELECT count(*) FROM t1 WHERE a='10.0' AND a LIKE '10.0'
} {0}
do_execsql_test 1.2.1 {
SELECT b=10, b = '10.0', b LIKE '10.0', b LIKE '10' FROM t1;
} {1 1 0 1}
do_execsql_test 1.2.2 {
SELECT count(*) FROM t1 WHERE b=10 AND b = '10.0'
} {1}
do_execsql_test 1.2.3 {
SELECT count(*) FROM t1 WHERE b=10 AND b LIKE '10.0'
} {0}
do_execsql_test 1.2.4 {
SELECT count(*) FROM t1 WHERE b='10.0' AND b LIKE '10.0'
} {0}
do_execsql_test 1.2.3 {
SELECT count(*) FROM t1 WHERE b=10 AND b LIKE '10'
} {1}
do_execsql_test 1.2.4 {
SELECT count(*) FROM t1 WHERE b='10.0' AND b LIKE '10'
} {1}
do_execsql_test 1.3.1 {
SELECT c=10, c = 10.0, c = '10.0', c LIKE '10.0' FROM t1;
} {0 1 1 1}
do_execsql_test 1.3.2 {
SELECT count(*) FROM t1 WHERE c=10 AND c = '10.0'
} {0}
do_execsql_test 1.3.3 {
SELECT count(*) FROM t1 WHERE c=10 AND c LIKE '10.0'
} {0}
do_execsql_test 1.3.4 {
SELECT count(*) FROM t1 WHERE c='10.0' AND c LIKE '10.0'
} {1}
do_execsql_test 1.3.5 {
SELECT count(*) FROM t1 WHERE c=10.0 AND c = '10.0'
} {1}
do_execsql_test 1.3.6 {
SELECT count(*) FROM t1 WHERE c=10.0 AND c LIKE '10.0'
} {1}
do_execsql_test 1.4.1 {
SELECT d=10, d = 10.0, d = '10.0', d LIKE '10.0', d LIKE '10' FROM t1;
} {1 1 1 1 0}
do_execsql_test 1.4.2 {
SELECT count(*) FROM t1 WHERE d=10 AND d = '10.0'
} {1}
do_execsql_test 1.4.3 {
SELECT count(*) FROM t1 WHERE d=10 AND d LIKE '10.0'
} {1}
do_execsql_test 1.4.4 {
SELECT count(*) FROM t1 WHERE d='10.0' AND d LIKE '10.0'
} {1}
do_execsql_test 1.4.5 {
SELECT count(*) FROM t1 WHERE d='10' AND d LIKE '10.0'
} {1}
do_execsql_test 1.5.1 {
SELECT e=10, e = '10.0', e LIKE '10.0', e LIKE '10' FROM t1;
} {1 0 1 0}
do_execsql_test 1.5.2 {
SELECT count(*) FROM t1 WHERE e=10 AND e = '10.0'
} {0}
do_execsql_test 1.5.3 {
SELECT count(*) FROM t1 WHERE e=10 AND e LIKE '10.0'
} {1}
do_execsql_test 1.5.4 {
SELECT count(*) FROM t1 WHERE e='10.0' AND e LIKE '10.0'
} {0}
do_execsql_test 1.5.5 {
SELECT count(*) FROM t1 WHERE e=10.0 AND e LIKE '10.0'
} {1}
finish_test
+86 -2
View File
@@ -1915,11 +1915,59 @@ do_execsql_test 60.1 {
# the Parse object is destroyed.
#
reset_db
do_execsql_test 61.1 {
do_catchsql_test 61.1 {
CREATE TABLE t1(a);
INSERT INTO t1 VALUES(5),(NULL),('seventeen');
SELECT (SELECT max(x)OVER(ORDER BY x) % min(x)OVER(ORDER BY CASE x WHEN 889 THEN x WHEN x THEN x END)) FROM (SELECT (SELECT sum(CAST(a IN(SELECT (SELECT max(x)OVER(ORDER BY CASE x WHEN 889 THEN 299 WHEN 863 THEN 863 END)) FROM (SELECT (SELECT sum(CAST((SELECT (SELECT max(x)OVER(ORDER BY x) / min(x)OVER(ORDER BY CASE x WHEN 889 THEN 299 WHEN -true THEN 863 END)) FROM (SELECT (SELECT sum(CAST(a IN(SELECT (SELECT max(x) & sum ( a )OVER(ORDER BY CASE x WHEN -8 THEN 299 WHEN 863 THEN 863 END)) FROM (SELECT (SELECT sum(CAST(a AS )) FROM t1) AS x FROM t1)) AS t1 )) FROM t1) AS x FROM t1)) AS x )) FROM t1) AS x FROM t1)) AS real)) FROM t1) AS x FROM t1);
} {{} {} {}}
} {0 {{} {} {}}}
foreach tn {1 2} {
if {$tn==2} { optimization_control db query-flattener 0 }
do_catchsql_test 61.2.$tn {
SELECT
(SELECT max(x)OVER(ORDER BY x) / min(x) OVER() )
FROM (
SELECT (SELECT sum(a) FROM t1 ) AS x FROM t1
)
} {0 {1.0 1.0 1.0}}
}
reset_db
optimization_control db all 0
do_execsql_test 61.3.0 {
CREATE TABLE t1(a);
CREATE TABLE t2(y);
}
do_execsql_test 61.3.1 {
SELECT (
SELECT count(a) OVER ( ORDER BY (SELECT sum(y) FROM t2) )
+ total(a) OVER()
)
FROM t1
} {}
do_execsql_test 61.4.2 {
SELECT (
SELECT count(a) OVER ( ORDER BY sum(a) )
+ total(a) OVER()
)
FROM t1
} {0.0}
do_catchsql_test 61.4.3 {
SELECT
sum(a) OVER ( ORDER BY a )
FROM t1
ORDER BY (SELECT sum(a) FROM t2)
} {1 {misuse of aggregate: sum()}}
do_execsql_test 61.4.4 {
SELECT
sum(a) OVER ( ORDER BY a )
FROM t1
ORDER BY (SELECT sum(y) FROM t2)
}
#-------------------------------------------------------------------------
reset_db
@@ -2090,6 +2138,42 @@ do_catchsql_test 67.1 {
SELECT nth_value(a,2) OVER w1
WINDOW w1 AS ( ORDER BY ((SELECT 1 FROM v1)) )
)
} {1 {no such table: v1}}
do_catchsql_test 67.2 {
SELECT a,c,b FROM t1 INTERSECT SELECT a,b,c FROM t1 ORDER BY (
SELECT nth_value(a,2) OVER w1
WINDOW w1 AS ( ORDER BY ((SELECT 1 FROM t2)) )
)
} {1 {1st ORDER BY term does not match any column in the result set}}
# 2021-05-07
# Do not allow aggregate functions in the ORDER BY clause even if
# there are window functions in the result set.
# Forum: /forumpost/540fdfef77
#
reset_db
do_catchsql_test 68.0 {
CREATE TABLE t1(a,b);
INSERT INTO t1(a,b) VALUES(0,0),(1,1),(2,4),(3,9),(4,99);
SELECT rowid, a, b, sum(a)OVER() FROM t1 ORDER BY count(b);
} {1 {misuse of aggregate: count()}}
# 2021-05-22
# Forum https://sqlite.org/forum/forumpost/7e484e225c
#
reset_db
do_catchsql_test 69.0 {
CREATE TABLE t1(a,b);
CREATE INDEX t1ba ON t1(b,a);
SELECT * FROM t1 WHERE b = (SELECT b FROM t1 ORDER BY lead(b) OVER () AND sum(a));
} {1 {misuse of aggregate: sum()}}
do_catchsql_test 69.1 {
SELECT * FROM t1 WHERE b >= (SELECT b FROM t1 ORDER BY lead(b) OVER () AND sum(a));
} {1 {misuse of aggregate: sum()}}
do_catchsql_test 69.2 {
SELECT * FROM t1 WHERE b <= (SELECT b FROM t1 ORDER BY lead(b) OVER () AND sum(a));
} {1 {misuse of aggregate: sum()}}
finish_test
+70
View File
@@ -418,6 +418,76 @@ execsql_test 7.$tn.9 "
"
}
==========
execsql_test 8.0 {
DROP TABLE IF EXISTS tx;
CREATE TABLE tx(a INTEGER PRIMARY KEY);
INSERT INTO tx VALUES(1), (2), (3), (4), (5), (6);
DROP TABLE IF EXISTS map;
CREATE TABLE map(v INTEGER PRIMARY KEY, t TEXT);
INSERT INTO map VALUES
(1, 'odd'), (2, 'even'), (3, 'odd'),
(4, 'even'), (5, 'odd'), (6, 'even');
}
execsql_test 8.1 {
SELECT sum(a) OVER (
PARTITION BY (
SELECT t FROM map WHERE v=a
) ORDER BY a
) FROM tx;
}
execsql_test 8.2 {
SELECT sum(a) OVER win FROM tx
WINDOW win AS (
PARTITION BY (
SELECT t FROM map WHERE v=a
) ORDER BY a
);
}
execsql_test 8.3 {
WITH map2 AS (
SELECT * FROM map
)
SELECT sum(a) OVER (
PARTITION BY (
SELECT t FROM map2 WHERE v=a
) ORDER BY a
) FROM tx;
}
execsql_test 8.4 {
WITH map2 AS (
SELECT * FROM map
)
SELECT sum(a) OVER win FROM tx
WINDOW win AS (
PARTITION BY (
SELECT t FROM map2 WHERE v=a
) ORDER BY a
);
}
==========
execsql_test 9.1 {
DROP TABLE IF EXISTS t1;
DROP TABLE IF EXISTS t2;
CREATE TABLE t1(a INTEGER);
CREATE TABLE t2(y INTEGER);
}
execsql_test 9.2 {
SELECT (
SELECT max(a) OVER ( ORDER BY (SELECT sum(a) FROM t1) )
+ min(a) OVER()
)
FROM t1
}
finish_test
+71
View File
@@ -6469,4 +6469,75 @@ do_execsql_test 7.4.9 {
);
} {4 4 4 {} {} {}}
#==========================================================================
do_execsql_test 8.0 {
DROP TABLE IF EXISTS tx;
CREATE TABLE tx(a INTEGER PRIMARY KEY);
INSERT INTO tx VALUES(1), (2), (3), (4), (5), (6);
DROP TABLE IF EXISTS map;
CREATE TABLE map(v INTEGER PRIMARY KEY, t TEXT);
INSERT INTO map VALUES
(1, 'odd'), (2, 'even'), (3, 'odd'),
(4, 'even'), (5, 'odd'), (6, 'even');
} {}
do_execsql_test 8.1 {
SELECT sum(a) OVER (
PARTITION BY (
SELECT t FROM map WHERE v=a
) ORDER BY a
) FROM tx;
} {2 6 12 1 4 9}
do_execsql_test 8.2 {
SELECT sum(a) OVER win FROM tx
WINDOW win AS (
PARTITION BY (
SELECT t FROM map WHERE v=a
) ORDER BY a
);
} {2 6 12 1 4 9}
do_execsql_test 8.3 {
WITH map2 AS (
SELECT * FROM map
)
SELECT sum(a) OVER (
PARTITION BY (
SELECT t FROM map2 WHERE v=a
) ORDER BY a
) FROM tx;
} {2 6 12 1 4 9}
do_execsql_test 8.4 {
WITH map2 AS (
SELECT * FROM map
)
SELECT sum(a) OVER win FROM tx
WINDOW win AS (
PARTITION BY (
SELECT t FROM map2 WHERE v=a
) ORDER BY a
);
} {2 6 12 1 4 9}
#==========================================================================
do_execsql_test 9.1 {
DROP TABLE IF EXISTS t1;
DROP TABLE IF EXISTS t2;
CREATE TABLE t1(a INTEGER);
CREATE TABLE t2(y INTEGER);
} {}
do_execsql_test 9.2 {
SELECT (
SELECT max(a) OVER ( ORDER BY (SELECT sum(a) FROM t1) )
+ min(a) OVER()
)
FROM t1
} {}
finish_test
+44 -14
View File
@@ -1149,20 +1149,26 @@ do_execsql_test 24.2 {
# had to continue to recognize "true" and "false" as identifiers for
# backwards compatibility.
#
reset_db
do_execsql_test 25.1 {
CREATE TABLE dual(dummy);
INSERT INTO dual(dummy) VALUES('X');
WITH cte1 AS (
SELECT TRUE, (
WITH cte2 AS (SELECT avg(DISTINCT TRUE) FROM dual)
SELECT 2571 FROM cte2
) AS subquery1
FROM dual
GROUP BY 1
)
SELECT (SELECT 1324 FROM cte1) FROM cte1;
} {1324}
foreach {id dual} {
1 {CREATE TABLE dual AS SELECT 'X' AS dummy}
2 {CREATE TEMP TABLE dual AS SELECT 'X' AS dummy}
3 {CREATE VIEW dual(dummy) AS VALUES('X')}
4 {CREATE TEMP VIEW dual(dummy) AS VALUES('X')}
} {
reset_db
db eval $dual
do_execsql_test 25.$id {
WITH cte1 AS (
SELECT TRUE, (
WITH cte2 AS (SELECT avg(DISTINCT TRUE) FROM dual)
SELECT 2571 FROM cte2
) AS subquery1
FROM dual
GROUP BY 1
)
SELECT (SELECT 1324 FROM cte1) FROM cte1;
} {1324}
}
do_catchsql_test 26.0 {
WITH i(x) AS (
@@ -1207,4 +1213,28 @@ do_execsql_test 26.3 {
SELECT * FROM cte ORDER BY +label, +step;
} {a 1 a 2 a 3 b 1 b 2 b 3}
# 2021-05-20
# forum post https://sqlite.org/forum/forumpost/8590e3f6dc
#
reset_db
do_execsql_test 27.1 {
CREATE TABLE t1(k);
CREATE TABLE log(k, cte_map, main_map);
CREATE TABLE map(k, v);
INSERT INTO map VALUES(1, 'main1'), (2, 'main2');
CREATE TRIGGER tr1 AFTER INSERT ON t1 BEGIN
INSERT INTO log
WITH map(k,v) AS (VALUES(1,'cte1'),(2,'cte2'))
SELECT
new.k,
(SELECT v FROM map WHERE k=new.k),
(SELECT v FROM main.map WHERE k=new.k);
END;
INSERT INTO t1 VALUES(1);
INSERT INTO t1 VALUES(2);
SELECT k, cte_map, main_map, '|' FROM log ORDER BY k;
} {1 cte1 main1 | 2 cte2 main2 |}
finish_test
+62
View File
@@ -549,4 +549,66 @@ do_execsql_test 10.1 {
)
} {1}
# 2021-05-21
# Forum post https://sqlite.org/forum/forumpost/aa4a7a3980
#
reset_db
do_execsql_test 11.1 {
CREATE TABLE t1(a);
CREATE VIEW v2(c) AS
WITH x AS (
WITH y AS (
WITH z AS(SELECT * FROM t1)
SELECT * FROM v2
) SELECT a
) SELECT * from t1;
ALTER TABLE t1 RENAME COLUMN a TO b;
SELECT sql FROM sqlite_schema WHERE name='t1';
} {{CREATE TABLE t1(b)}}
do_catchsql_test 11.2 {
INSERT INTO t1 VALUES(55);
SELECT * FROM v2;
} {0 55}
do_catchsql_test 11.3 {
DROP VIEW v2;
CREATE VIEW v2(c) AS
WITH x AS (
WITH y AS (
WITH z AS(SELECT * FROM t1)
SELECT * FROM v2
) SELECT a
) SELECT * from t1, x;
SELECT * FROM v2;
} {1 {no such column: a}}
do_catchsql_test 11.4 {
DROP VIEW v2;
CREATE VIEW v2(c) AS
WITH x AS (
WITH y AS (
WITH z AS(SELECT * FROM t1)
SELECT * FROM v2
) SELECT *
) SELECT * from t1, x;
SELECT * FROM v2;
} {1 {no tables specified}}
do_catchsql_test 11.5 {
WITH x AS (
WITH y AS (
WITH z AS(SELECT * FROM t1)
SELECT * FROM no_such_table
) SELECT a
) SELECT * from t1;
} {0 55}
# 2021-05-23 dbsqlfuzz 6b7a144674e215f06ddfeb9042c873d9ee956ac0 */
reset_db
do_execsql_test 12.1 {
CREATE TABLE t1(a);
INSERT INTO t1 VALUES(1),('hello'),(4.25),(NULL),(x'3c626c6f623e');
CREATE VIEW v2(c) AS WITH x AS (WITH y AS (WITH z AS(SELECT * FROM t1) SELECT * FROM v2) SELECT a) SELECT * from t1;
CREATE VIEW v3(c) AS WITH x AS (WITH y AS (WITH z AS(SELECT * FROM v2) SELECT * FROM v3) SELECT a) SELECT * from t1;
ALTER TABLE t1 RENAME TO t1x;
SELECT quote(c) FROM v3;
} {1 'hello' 4.25 NULL X'3C626C6F623E'}
finish_test
+13
View File
@@ -452,5 +452,18 @@ do_execsql_test 13.10 {
PRAGMA integrity_check;
SELECT * FROM t0, t1;
} {ok abc xyz abc xyz}
# 2021-05-13 https://sqlite.org/forum/forumpost/6c8960f545
reset_db
do_execsql_test 14.1 {
CREATE TABLE t1(a INT PRIMARY KEY) WITHOUT ROWID;
INSERT INTO t1(a) VALUES(10);
ALTER TABLE t1 ADD COLUMN b INT;
SELECT * FROM t1 WHERE a=20 OR (a=10 AND b=10);
} {}
do_execsql_test 14.2 {
CREATE TABLE dual AS SELECT 'X' AS dummy;
EXPLAIN QUERY PLAN SELECT * FROM dual, t1 WHERE a=10 AND b=10;
} {~/b=/}
finish_test
+12
View File
@@ -843,4 +843,16 @@ do_catchsql_test 16.20 {
REPLACE INTO zipfile VALUES(null,null,null,null,null,123,null);
} {1 {zipfile: missing filename}}
# 2021-04-22 forum https://sqlite.org/forum/forumpost/d82289d69f
do_execsql_test 17.1 {
WITH vlist(x) AS (
VALUES(9223372036854775807),
(-9223372036854775808),
(9223372036854775806),
(-9223372036854775807)
)
SELECT DISTINCT typeof(zipfile(0,0,x,0)) FROM vlist;
} {blob}
finish_test
+99
View File
@@ -0,0 +1,99 @@
#!/usr/bin/tcl
#
# Run this script to test to see that the latest trunk changes can be
# merged into LTS branches without breaking anything.
#
# To Use:
#
# * Copy this script into a directory above the sqlite checkout
# * Run "fossil update trunk" and "fossil revert"
# * Run "tclsh ../merge-test.tcl" (in other words run this script)
#
# Operation:
#
# This script changes to each LTS branch to be tested, merges the latest
# trunk changes into the branch (without committing them) and then
# runs "make test". Any errors are stored in local files.
#
# Limitations:
#
# Some LTS branches are not synced directly from trunk but rather from
# other LTS branches. These other branches cannot be tested because
# there is no good way to generate the intermediate merges.
#
###############################################################################
# Run a shell command contained in arguments. Put the return code in
# global variable ::res and the output string in global variable ::result
#
proc safeexec {args} {
global res result
set res [catch "exec $args" result]
}
# Run the shell command contained in arguments. Print an error and exit
# if anything goes wrong.
#
proc mustbeok {args} {
global res result
set res [catch "exec $args" result]
if {$res} {
puts "FAILED: $args"
puts $result
exit 1
}
}
# Write $content into a file named $filename. The file is overwritten if it
# already exist. The file is create if it does not already exist.
#
proc writefile {filename content} {
set fd [open $filename wb]
puts $fd $content
close $fd
}
# Run the merge-test
#
foreach {branch configopts} {
begin-concurrent {--enable-json1}
begin-concurrent-pnu {--enable-json1}
wal2 {--enable-all}
reuse-schema {--enable-all}
} {
puts $branch
set errorfile ${branch}-error.txt
mustbeok fossil revert
mustbeok fossil up $branch
safeexec fossil merge trunk
if {$res} {
puts " merge failed - see $errorfile"
writefile $errorfile $result
} else {
puts " merge ok"
safeexec ./configure --enable-debug {*}$configopts
if {$res} {
puts " configure failed - see $errorfile"
writefile $errorfile $result
} else {
puts " configure ok"
safeexec make fuzzcheck sqlite3 testfixture
if {$res} {
puts " build failed - see $errorfile"
writefile $errorfile $result
} else {
puts " build ok"
safeexec make test
if {$res} {
puts " test failed - see $errorfile"
writefile $errorfile $result
} else {
puts " test ok"
}
}
}
}
}
mustbeok fossil revert
mustbeok fossil up trunk
puts "reset back to trunk"
+131 -29
View File
@@ -4,16 +4,28 @@
#
# const char **azCompileOpt[]
#
# declaration used in src/ctime.c, run this script.
# definition used in src/ctime.c, run this script from
# the checkout root. It alters src/ctime.c in-place.
#
# All Boolean compile time options.
# All Boolean compile time options which default to something
# other than 0 or empty. The default is paired with the PP
# symbol so that a differing define can be detected.
#
set boolean_options {
set boolean_defnnz_options {
{SQLITE_HOMEGROWN_RECURSIVE_MUTEX 1}
{SQLITE_POWERSAFE_OVERWRITE 1}
{SQLITE_DEFAULT_MEMSTATUS 1}
{SQLITE_OMIT_TRACE 1}
{SQLITE_ALLOW_COVERING_INDEX_SCAN 1}
}
# All Boolean compile time options which default to 0 or empty.
#
set boolean_defnil_options {
SQLITE_32BIT_ROWID
SQLITE_4_BYTE_ALIGNED_MALLOC
SQLITE_64BIT_STATS
SQLITE_ALLOW_COVERING_INDEX_SCAN
SQLITE_ALLOW_URI_AUTHORITY
SQLITE_BUG_COMPATIBLE_20160819
SQLITE_CASE_SENSITIVE_LIKE
@@ -25,7 +37,6 @@ set boolean_options {
SQLITE_DEFAULT_CKPTFULLFSYNC
SQLITE_DEFAULT_FOREIGN_KEYS
SQLITE_DEFAULT_LOCKING_MODE
SQLITE_DEFAULT_MEMSTATUS
SQLITE_DEFAULT_RECURSIVE_TRIGGERS
SQLITE_DEFAULT_SYNCHRONOUS
SQLITE_DEFAULT_WAL_SYNCHRONOUS
@@ -40,40 +51,49 @@ set boolean_options {
SQLITE_ENABLE_8_3_NAMES
SQLITE_ENABLE_API_ARMOR
SQLITE_ENABLE_ATOMIC_WRITE
SQLITE_ENABLE_CEROD
SQLITE_ENABLE_BATCH_ATOMIC_WRITE
SQLITE_ENABLE_BYTECODE_VTAB
SQLITE_ENABLE_COLUMN_METADATA
SQLITE_ENABLE_COLUMN_USED_MASK
SQLITE_ENABLE_COSTMULT
SQLITE_ENABLE_CURSOR_HINTS
SQLITE_ENABLE_DBPAGE_VTAB
SQLITE_ENABLE_DBSTAT_VTAB
SQLITE_ENABLE_EXPENSIVE_ASSERT
SQLITE_ENABLE_FTS1
SQLITE_ENABLE_FTS2
SQLITE_ENABLE_EXPLAIN_COMMENTS
SQLITE_ENABLE_FTS3
SQLITE_ENABLE_FTS3_PARENTHESIS
SQLITE_ENABLE_FTS3_TOKENIZER
SQLITE_ENABLE_FTS4
SQLITE_ENABLE_FTS5
SQLITE_ENABLE_GEOPOLY
SQLITE_ENABLE_HIDDEN_COLUMNS
SQLITE_ENABLE_ICU
SQLITE_ENABLE_IOTRACE
SQLITE_ENABLE_JSON1
SQLITE_ENABLE_LOAD_EXTENSION
SQLITE_ENABLE_LOCKING_STYLE
SQLITE_ENABLE_MATH_FUNCTIONS
SQLITE_ENABLE_MEMORY_MANAGEMENT
SQLITE_ENABLE_MEMSYS3
SQLITE_ENABLE_MEMSYS5
SQLITE_ENABLE_MULTIPLEX
SQLITE_ENABLE_NORMALIZE
SQLITE_ENABLE_NULL_TRIM
SQLITE_ENABLE_OFFSET_SQL_FUNC
SQLITE_ENABLE_OVERSIZE_CELL_CHECK
SQLITE_ENABLE_PREUPDATE_HOOK
SQLITE_ENABLE_QPSG
SQLITE_ENABLE_RBU
SQLITE_ENABLE_RTREE
SQLITE_ENABLE_SELECTTRACE
SQLITE_ENABLE_SESSION
SQLITE_ENABLE_SNAPSHOT
SQLITE_ENABLE_SORTER_REFERENCES
SQLITE_ENABLE_SQLLOG
SQLITE_ENABLE_STAT4
SQLITE_ENABLE_STMT_SCANSTATUS
SQLITE_ENABLE_STMTVTAB
SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION
SQLITE_ENABLE_UNLOCK_NOTIFY
SQLITE_ENABLE_UPDATE_DELETE_LIMIT
@@ -85,8 +105,6 @@ set boolean_options {
SQLITE_EXTRA_IFNULLROW
SQLITE_FTS5_ENABLE_TEST_MI
SQLITE_FTS5_NO_WITHOUT_ROWID
SQLITE_HAS_CODEC
SQLITE_HOMEGROWN_RECURSIVE_MUTEX
SQLITE_IGNORE_AFP_LOCK_ERRORS
SQLITE_IGNORE_FLOCK_LOCK_ERRORS
SQLITE_INLINE_MEMCPY
@@ -98,7 +116,6 @@ set boolean_options {
SQLITE_MIXED_ENDIAN_64BIT_FLOAT
SQLITE_MMAP_READWRITE
SQLITE_MUTEX_NOOP
SQLITE_MUTEX_NREF
SQLITE_MUTEX_OMIT
SQLITE_MUTEX_PTHREADS
SQLITE_MUTEX_W32
@@ -116,16 +133,15 @@ set boolean_options {
SQLITE_OMIT_AUTOVACUUM
SQLITE_OMIT_BETWEEN_OPTIMIZATION
SQLITE_OMIT_BLOB_LITERAL
SQLITE_OMIT_BTREECOUNT
SQLITE_OMIT_CAST
SQLITE_OMIT_CHECK
SQLITE_OMIT_COMPLETE
SQLITE_OMIT_COMPOUND_SELECT
SQLITE_OMIT_CONFLICT_CLAUSE
SQLITE_OMIT_CTE
SQLITE_OMIT_DATETIME_FUNCS
SQLITE_OMIT_DECLTYPE
SQLITE_OMIT_DEPRECATED
SQLITE_OMIT_DESERIALIZE
SQLITE_OMIT_DISKIO
SQLITE_OMIT_EXPLAIN
SQLITE_OMIT_FLAG_PRAGMAS
@@ -135,6 +151,7 @@ set boolean_options {
SQLITE_OMIT_HEX_INTEGER
SQLITE_OMIT_INCRBLOB
SQLITE_OMIT_INTEGRITY_CHECK
SQLITE_OMIT_INTROSPECTION_PRAGMAS
SQLITE_OMIT_LIKE_OPTIMIZATION
SQLITE_OMIT_LOAD_EXTENSION
SQLITE_OMIT_LOCALTIME
@@ -156,7 +173,6 @@ set boolean_options {
SQLITE_OMIT_TCL_VARIABLE
SQLITE_OMIT_TEMPDB
SQLITE_OMIT_TEST_CONTROL
SQLITE_OMIT_TRACE
SQLITE_OMIT_TRIGGER
SQLITE_OMIT_TRUNCATE_OPTIMIZATION
SQLITE_OMIT_UTF16
@@ -168,7 +184,6 @@ set boolean_options {
SQLITE_OMIT_XFER_OPT
SQLITE_PCACHE_SEPARATE_HEADER
SQLITE_PERFORMANCE_TRACE
SQLITE_POWERSAFE_OVERWRITE
SQLITE_PREFER_PROXY_LOCKING
SQLITE_PROXY_DEBUG
SQLITE_REVERSE_UNORDERED_SELECTS
@@ -177,7 +192,6 @@ set boolean_options {
SQLITE_SMALL_STACK
SQLITE_SOUNDEX
SQLITE_SUBSTR_COMPATIBILITY
SQLITE_SYSTEM_MALLOC
SQLITE_TCL
SQLITE_TEST
SQLITE_UNLINK_AFTER_CLOSE
@@ -191,7 +205,15 @@ set boolean_options {
SQLITE_ZERO_MALLOC
}
# All compile time options for which the assigned value is other than boolean.
# All compile time options for which the assigned value is other than boolean
# and is a comma-separated scalar pair.
#
set value2_options {
SQLITE_DEFAULT_LOOKASIDE
}
# All compile time options for which the assigned value is other than boolean
# and is a single scalar.
#
set value_options {
SQLITE_BITMASK_TYPE
@@ -200,7 +222,6 @@ set value_options {
SQLITE_DEFAULT_FILE_PERMISSIONS
SQLITE_DEFAULT_JOURNAL_SIZE_LIMIT
SQLITE_DEFAULT_LOCKING_MODE
SQLITE_DEFAULT_LOOKASIDE
SQLITE_DEFAULT_MMAP_SIZE
SQLITE_DEFAULT_PAGE_SIZE
SQLITE_DEFAULT_PCACHE_INITSZ
@@ -212,6 +233,7 @@ set value_options {
SQLITE_DEFAULT_WAL_SYNCHRONOUS
SQLITE_DEFAULT_WORKER_THREADS
SQLITE_ENABLE_8_3_NAMES
SQLITE_ENABLE_CEROD
SQLITE_ENABLE_LOCKING_STYLE
SQLITE_EXTRA_INIT
SQLITE_EXTRA_SHUTDOWN
@@ -245,13 +267,6 @@ set value_options {
# Options that require custom code.
#
set options(ENABLE_STAT3) {
#if defined(SQLITE_ENABLE_STAT4)
"ENABLE_STAT4",
#elif defined(SQLITE_ENABLE_STAT3)
"ENABLE_STAT3",
#endif
}
set options(COMPILER) {
#if defined(__clang__) && defined(__clang_major__)
"COMPILER=clang-" CTIMEOPT_VAL(__clang_major__) "."
@@ -268,13 +283,26 @@ set options(HAVE_ISNAN) {
"HAVE_ISNAN",
#endif
}
set options(OMIT_DATETIME_FUNCS) {
#if defined(SQLITE_OMIT_DATETIME_FUNCS) || defined(SQLITE_OMIT_FLOATING_POINT)
"OMIT_DATETIME_FUNCS",
#endif
}
set options(SYSTEM_MALLOC) "\
#if (!defined(SQLITE_WIN32_MALLOC) \\
&& !defined(SQLITE_ZERO_MALLOC) \\
&& !defined(SQLITE_MEMDEBUG) \\
) || defined(SQLITE_SYSTEM_MALLOC)
\"SYSTEM_MALLOC\",
#endif
"
set options(THREADSAFE) {
#if defined(SQLITE_THREADSAFE)
"THREADSAFE=" CTIMEOPT_VAL(SQLITE_THREADSAFE),
#elif defined(THREADSAFE)
"THREADSAFE=" CTIMEOPT_VAL(THREADSAFE),
#else
"THREADSAFE=1"
"THREADSAFE=1",
#endif
}
@@ -286,7 +314,20 @@ proc trim_name {in} {
return $ret
}
foreach b $boolean_options {
foreach name_defval $boolean_defnnz_options {
set b [lindex $name_defval 0]
set defval [lindex $name_defval 1]
set name [trim_name $b]
set options($name) [subst {
#ifdef $b
# if $b != $defval
"$name=" CTIMEOPT_VAL($b),
# endif
#endif
}]
}
foreach b $boolean_defnil_options {
set name [trim_name $b]
set options($name) [subst {
#if $b
@@ -303,9 +344,70 @@ foreach v $value_options {
#endif
}]
}
foreach v $value2_options {
set name [trim_name $v]
set options($name) [subst {
#ifdef $v
"$name=" CTIMEOPT_VAL2($v),
#endif
}]
}
foreach o [lsort [array names options]] {
puts [string trim $options($o)]
# Split a string on a regex, return all parts in order.
# Any elements with an even index may be empty.
# Elements with odd indices will match the regex.
proc split_on_re {re str {nrepps 1}} {
set chunks {}
set cix 0
set resm [regexp -all -inline -indices $re $str]
if {[llength $resm]==0} {
return $str
}
set rix 0
while {$rix < [llength $resm]} {
set mre [lindex $resm $rix]
incr rix $nrepps
set mbx [lindex $mre 0]
set mex [lindex $mre 1]
lappend chunks [string range $str $cix [expr $mbx - 1]]
lappend chunks [string range $str $mbx $mex]
set cix [expr $mex + 1]
}
lappend chunks [string range $str $cix end]
return $chunks
}
set ctime_c "src/ctime.c"
if {[catch {set cfd [open $ctime_c r]}]!=0} {
puts stderr "File '$ctime_c' unreadable. Run this script from checkout root."
exit 1;
}
set ctfc [read $cfd]
close $cfd
set re {/\*\s+\*+\s*((BEGIN)|(END)) CODE GENERATED BY (\S+)\s+\*/\s+}
set renpp 5
set ctfcChunks [split_on_re $re $ctfc $renpp]
if {[llength $ctfcChunks] != 5} {
puts stderr "File '$ctime_c' has too few generated code markers."
exit 1;
}
if {[catch {set cfd [open $ctime_c w]}]!=0} {
puts stderr "File '$ctime_c' unwritable."
exit 1;
}
puts -nonewline $cfd [lindex $ctfcChunks 0]
puts -nonewline $cfd [lindex $ctfcChunks 1]
foreach o [lsort [array names options]] {
puts $cfd [string trim $options($o)]
}
puts -nonewline $cfd [lindex $ctfcChunks 3]
puts -nonewline $cfd [lindex $ctfcChunks 4]
close $cfd
+6 -5
View File
@@ -145,7 +145,9 @@ foreach name {OP_Noop OP_Explain OP_Abortable} {
incr nOp
}
# The following are the opcodes that are processed by resolveP2Values()
# The following are the opcodes that receive special processing in the
# resolveP2Values() routine. Update this list whenever new cases are
# added to the pOp->opcode switch within resolveP2Values().
#
set rp2v_ops {
OP_Transaction
@@ -157,13 +159,11 @@ set rp2v_ops {
OP_VUpdate
OP_VFilter
OP_Next
OP_NextIfOpen
OP_SorterNext
OP_Prev
OP_PrevIfOpen
}
# Assign small values to opcodes that are processed by resolveP2Values()
# Assign the smallest values to opcodes that are processed by resolveP2Values()
# to make code generation for the switch() statement smaller and faster.
#
set cnt -1
@@ -177,6 +177,7 @@ for {set i 0} {$i<$nOp} {incr i} {
set def($cnt) $name
}
}
set mxCase1 $cnt
# Assign the next group of values to JUMP opcodes
#
@@ -311,7 +312,7 @@ for {set i 0} {$i<=$max} {incr i} {
}
puts "\175"
puts ""
puts "/* The sqlite3P2Values() routine is able to run faster if it knows"
puts "/* The resolve3P2Values() routine is able to run faster if it knows"
puts "** the value of the largest JUMP opcode. The smaller the maximum"
puts "** JUMP opcode the better, so the mkopcodeh.tcl script that"
puts "** generated this include file strives to group all JUMP opcodes"
+1
View File
@@ -206,6 +206,7 @@ proc main {argv} {
SQLITE_OMIT_DATETIME_FUNCS \
SQLITE_OMIT_DECLTYPE \
SQLITE_OMIT_DEPRECATED \
SQLITE_OMIT_DESERIALIZE \
SQLITE_OMIT_DISKIO \
SQLITE_OMIT_EXPLAIN \
SQLITE_OMIT_FLAG_PRAGMAS \
+11 -2
View File
@@ -912,10 +912,19 @@ static void page_usage_btree(
int cellstart = hdr+12;
u32 child;
for(i=0; i<nCell; i++){
u32 cellidx;
u32 ofst;
ofst = cellstart + i*2;
ofst = a[ofst]*256 + a[ofst+1];
cellidx = cellstart + i*2;
if( cellidx+1 >= g.pagesize ){
printf("ERROR: page %d too many cells (%d)\n", pgno, nCell);
break;
}
ofst = a[cellidx]*256 + a[cellidx+1];
if( ofst<cellidx+2 || ofst+4>=g.pagesize ){
printf("ERROR: page %d cell %d out of bounds\n", pgno, i);
continue;
}
child = decodeInt32(a+ofst);
page_usage_btree(child, pgno, i, zName);
}