Compare commits

..

138 Commits

Author SHA1 Message Date
shearer 4598bf806c Prettify btree.h headings. Close branch.
FossilOrigin-Name: ee9689ad2fadb3b9c11235312bfc32a1db294485b4503a07692bbdbce71e021d
2020-10-27 11:58:37 +00:00
shearer 608e2f0919 Typo in btree.h (and unwanted merge; this branch for cherrypicking btree.h only)
FossilOrigin-Name: eb6e5fc1891be52acf378269405a99bab92b9bf501b7eba04eae07c851ed3027
2020-10-27 11:13:37 +00:00
shearer f311315ffd Final commit in btree.h reorg. No more unknowns.
FossilOrigin-Name: ea06f1d1f9683b3299107f42912169de9d2bbc91386eb953520c2f44e309c715
2020-10-27 11:07:16 +00:00
drh ed7974dee5 Always create a statement journal when using the OP_ParseSchema opcode,
as you never know when it might fail.  See the discussion on
[forum:/forumpost/daa2c728cc|forum post daa2c728cc].

FossilOrigin-Name: aa512f72cf5adfece6299db17bd122aeff0cdee2a25f83f60e2ebb05e99c9591
2020-10-26 18:14:12 +00:00
dan 19f7bd3b07 Ensure that the table argument passed to Tcl_GetIndexFromObjStruct() in the sessions module test code is declared "static".
FossilOrigin-Name: 80eba105d6d1b49ba8ca2ad4e14ddec2de0bdc2f6686c2f8a1c1d24fc1fe846f
2020-10-26 16:22:31 +00:00
dan d1d43efa4f Prevent fts5 tokenizer unicode61 from considering '\0' to be a token characters, even if other characters of class "Cc" are.
FossilOrigin-Name: b7b7bde9b7a03665e3691c6d51118965f216d2dfb1617f138b9f9e60e418ed2f
2020-10-26 13:24:36 +00:00
drh beb22d086b Minor tweaks to query planning weights so that when STAT4 is enabled
and functioning, a full table scan is more likely to be selected if
that seems like the fastest solution.  Only do this when STAT4 info
is available because an error has a large potential downside.

FossilOrigin-Name: 0e7e113d9f2c929c1f8a85e2cfad8e2e60f0e8770212b5e5320fb2a2c42911f8
2020-10-22 18:50:30 +00:00
drh 461ff3594b Test case updates.
FossilOrigin-Name: 27c681c9c6672ad7098d8ff2c41e76d3e9e55866b6327ed85e73f63bd623ceed
2020-10-22 18:16:17 +00:00
drh 403869680b Sometimes it makes sense to do a full table scan rather than try to use
an index when most of the rows will be selected.  This branch is trying to
tune the query planner to make that happen more often.

FossilOrigin-Name: 0f42099ad65855c94af8472f3a6fddac7fc2a82e8fdfcc06a298eb6683a28688
2020-10-22 15:47:48 +00:00
drh 672f07c642 Fix the sqlite3_hard_heap_limit() so that it works with sqlite3_realloc64()
in addition to sqlite3_malloc64().  Improvements to OOM processing and
debugging aids in the fuzzcheck utility.

FossilOrigin-Name: 602d7369166d406a26834aa47d71d565a17d377d32e41f308821a50b41f91896
2020-10-20 14:40:53 +00:00
drh 1a56fce614 Fix an assert() inside of debug-only code that can fail following an OOM.
FossilOrigin-Name: 79da254f41a0d7d5fdc57f0cc40b3560bfcf7f79eed24a9fada1b6b4ca3adb5a
2020-10-20 12:37:51 +00:00
drh 94d6f3f836 Fix an incorrect table ref-count in the new recursive CTE logic that might
result in a reference to freed memory following a syntax error.

FossilOrigin-Name: 75a0288871ccb2a69a636cbb328fe19045a0d0ef96a193ecd118b9a196784d2d
2020-10-19 20:49:54 +00:00
drh 787f6d418d Enhance recursive common table expressions to support two or more
recursive terms.

FossilOrigin-Name: 77e64647ec429c6e0d884abbd00dabebe738f89544a4984d6fd7a702b928ccfd
2020-10-19 12:35:08 +00:00
drh 07d7a8dca9 New test cases for recursive CTEs with multiple recursive terms.
FossilOrigin-Name: cd5182bd6f5969ba0812275f471224908296960358013327cebbe0c52b820f04
2020-10-19 01:44:43 +00:00
drh 340558540e Allow multiple recursive terms in the compound SELECT of a recursive CTE.
This facilitates writing a query to find find the connected components of
an undirected graph.

FossilOrigin-Name: 5481fa8c79c34f434e99ab633ff3d0942a309a74fb0cf38e3d3617b51d5d21dd
2020-10-19 01:23:48 +00:00
mistachkin a00a016740 Fix harmless compiler warnings.
FossilOrigin-Name: 7f8802bb7be61fdf7c7a591945d533d848bc46d2989f7739dd9ad89e1b6a9c65
2020-10-18 18:35:34 +00:00
drh ff01ee34c9 Fix the SQLITE_DESERIALIZE_FREEONCLOSE flag so that it works as it is
documented to work.
See [forum:/forumpost/ba1dff667a|forum post ba1dff667a]

FossilOrigin-Name: d6fac8a1d3efeb2c4f03dae437b5b314765c93770a70603803a8039291dbcabb
2020-10-17 22:13:16 +00:00
drh e93986a93b Fix an incorrect printf() in debugging logic in where.c.
Problem reported [forum:/info/80a9c47769772207|by forum post 80a9c47769772207].

FossilOrigin-Name: 883da4dadc88809192e4ed2f753f8883471fb43aa330bc58b017c66e1acedc6c
2020-10-17 19:09:04 +00:00
drh 71cb422055 Minor fixes to the cksumvfs documentation in the header comment of the source
file.  Enhance speedtest1.c so that it can more easily do performance
comparisons of cksumvfs.

FossilOrigin-Name: ed3bb818f58b75c087f2875331ec944397b6c61a5b14d8af4b9ec6f376bd1872
2020-10-15 17:59:38 +00:00
drh f8c4c3a09f The windows VFS accepts query parameter "exclusive=true" to cause it to
take a mandatory file lock, preventing other applications from even
reading the file.

FossilOrigin-Name: 05b573fdb27abec7d75aa1375325d45043cfd674f5b346fb341f001d7e04d160
2020-10-15 14:37:27 +00:00
mistachkin d5157e01b8 Enhancements to TclKit batch tool for MSVC.
FossilOrigin-Name: 2a8a4552112be6e39e3475e9a8579582b5157086d3efd37971463c0e3958068d
2020-10-14 21:31:20 +00:00
mistachkin 05881886a6 Fix typo in a documentation comment.
FossilOrigin-Name: 462adc7d6b14de3862c2a3e57dba7efaf2ba9c104e1c127a5801a7b892059872
2020-10-14 21:30:56 +00:00
drh 7207be402d Enhanced documentation for sqlite3_vtab_nochange() to make it clear that
it is an optimization and that virtual table implementations should be
prepared for it to always return false.

FossilOrigin-Name: 3e2643619d122616663688533977d6c60d45a269b4e2bdc330fd3ee5d39f2e03
2020-10-14 15:46:29 +00:00
dan f6b0464e36 Fix some fts5 problems with signed integer overflow causing segfaults in -ftrapv builds.
FossilOrigin-Name: 7e17c2f4b7dc9b563d0b4da949bb134dc7c4fc9c86ce03891432a884ca6409d5
2020-10-12 18:09:16 +00:00
drh c6712647c6 Improved quoting of the table name argument for the ".import" command
of the CLI.  See [forum:34591fefbe|forum post 34591fefbe].

FossilOrigin-Name: ce97b56d63d6e03b909e049a0a62251d98c7bf643448193a28b42a5871899387
2020-10-12 17:57:29 +00:00
drh c196219dd4 Add options --data-only and --nosys to the ".dump" command in the CLI.
FossilOrigin-Name: 57123b14a71027c21cb5eee089fcbc9330d07bf9091b01aecc4f9e3b9e4f7b09
2020-10-12 16:54:28 +00:00
dan 936a30598e Fix ALTER TABLE so that it can run even if the schema contains unknown collation sequences.
FossilOrigin-Name: bc4bb9433fed519386511796cce475d74100b8ed707cdbffd8cbdf683b0faf35
2020-10-12 15:27:50 +00:00
drh bbb29ecfb4 Add the --nosys option to the .schema command in the CLI.
FossilOrigin-Name: b72ee694532c0c5d2285dd580154546eb592fd6892cad9ad7a49e98737adb974
2020-10-12 14:56:47 +00:00
dan 4d906f1b5a Fix UPDATE FROM statements on virtual tables that are declared WITHOUT ROWID.
FossilOrigin-Name: bcb0bc6a7b7006f07adb7266b1fecca39bf85a0adea6d78a341623a3546f2c2a
2020-10-12 14:29:11 +00:00
drh 1ca037f41e Fix BEGIN IMMEDIATE and BEGIN EXCLUSIVE so that they work even if one or
more of the database files in the connection are read-only.  Test cases
for this are in TH3.

FossilOrigin-Name: 2fa08c3963f008d4723c3f4f4496abcb6d4b575c85ba4a911a6aed5730b5948b
2020-10-12 13:24:00 +00:00
drh 0897c3c056 In the CSV extension, use SQLITE_TRANSIENT rather than SQLITE_STATIC on
return values that can in fact change.

FossilOrigin-Name: 54b54f02c66c5aeaa3504c52a04614e2fb4d7260da8367840d5ea5a71cdc2fda
2020-10-07 11:24:45 +00:00
shearer a41cc5c6f0 More additions and improvements to btree.h documentation
FossilOrigin-Name: a49a7cdec7f50c27c2d5f9919ba71e41858a57e2eb0cfc7a13d53165f2f2ea9b
2020-10-06 15:48:59 +00:00
dan f46be6a1b9 Allow fts5 trigram tables created with detail=column or detail=none to optimize LIKE and GLOB queries. Allow case-insensitive tables to optimize GLOB as well as LIKE.
FossilOrigin-Name: 64782463be62b72b5cd0bfaa7c9b69aa487d807c5fe0e65a272080b7739fd21b
2020-10-05 16:41:56 +00:00
dan a344ad47f3 Do not apply affinities when creating entries for automatic indexes on views. Fix for [95302bdb].
FossilOrigin-Name: df12f097224ebc9473d9e2a8933bd7efed6490d09af2c012c9b59a7892369b7f
2020-10-03 19:16:36 +00:00
dan 12a6a1eaf9 Fix a segfault caused by running "column LIKE NULL" against an fts5 table using the trigram tokenizer. Fix for [e33ee62575fc22].
FossilOrigin-Name: 6e72a08de764077f2bba6f7e3b99ea29001941671a971f2ccf7ceeb9c682fb1a
2020-10-03 17:06:02 +00:00
dan 95dca8d0cf FTS5 does not handle tokens that contain embedded nul characters. Prevent the trigram tokenizer from returning such tokens. Fix for [2ba5930b2].
FossilOrigin-Name: b1d048748c054575425a4bebf0c5d09962f9329d5ce6a978cf54e508b238584c
2020-10-03 14:36:06 +00:00
dan 7093a3be03 Fix some test code so that testfixture can build with SQLITE_OMIT_WAL defined.
FossilOrigin-Name: dd009cd7aec3598e930806907601f4f0f9b0021ea99fa6c5e29e88f1246066ed
2020-10-02 15:15:18 +00:00
drh 7d14ffe4e1 Additional corner-case fixes for the in-scan-vs-index or OP_SeekScan
optimization.

FossilOrigin-Name: ad5ab24ebd557e7af1d92ab3fbcb3747c04da5ad4ed779fb6391dc94042687dd
2020-10-02 13:48:57 +00:00
drh 64208b50ce Remove an incorrect assert() from the OP_SeekScan opcode.
FossilOrigin-Name: c0400f8c0bcb85ba39004feff753eae2f8e82065539e52b5788febd7644c417b
2020-10-02 12:49:06 +00:00
drh 9bb612f2c8 Fix a faulty assert() statement. Add new test cases.
FossilOrigin-Name: 80ecdb3da4558bb08ee3ec6edbde906ad5b3b8182e672b5ba0d5dfa8041cee0a
2020-10-02 12:42:51 +00:00
drh 04e70ce07d For the OP_SeekScan optimization, the OP_IdxGT does not necessarily come
right after the OP_SeekGE.   So use the P2 operand of OP_SeekScan to point
to the first instruction after OP_IdxGT.  Problem found by dbsqlfuzz.

FossilOrigin-Name: 091d71939411bf2079098f09ddc0525f11f380119fd27114e2b3eec9a8ac0db4
2020-10-02 11:55:07 +00:00
drh 4ad1a1c74c Disable the OP_SeekScan opcode of the in-scan-vs-index optimization when
in PRAGMA reverse_unordered_selects mode, as the OP_SeekScan only works
with forwards scans.  Thanks to OSSFuzz for pointing out the problem to
us.

FossilOrigin-Name: c75c3a3b756635bfdab44e4b56a337e4a88af3a8803cd3e9a67abf3d0d3450dc
2020-10-02 02:02:18 +00:00
dan d7d406e81c Add experimental "trigram" tokenizer to fts5.
FossilOrigin-Name: c4e8ec7907de7cb9e610ef9f4930caf5c046618151fb4f61d5716b9fa3f31423
2020-10-01 17:24:36 +00:00
dan a22c1c84cc Add the -trigram option to the fts5txt2db.tcl script.
FossilOrigin-Name: a394dd260252e7b7dcbc90fd321dfd40d9375f0598ea52b01001c568cbdbafce
2020-10-01 17:15:12 +00:00
dan ccf578d435 Add tests for the trigram tokenizer. Fix minor issues.
FossilOrigin-Name: 897ced99b44085012aa44d3264940dcbd4c77b295a894a1b58fb2c03a0f7fee8
2020-10-01 16:10:22 +00:00
drh deaa61072d Fix the OP_SeekScan opcode so that its variable names do not cause problems
for the test/vdbe-compress.tcl script.

FossilOrigin-Name: 7a78274a072324b94d6f79e5b7a198b2fa9321ff5d6a528b51f57d3ee95c765b
2020-10-01 15:46:21 +00:00
drh 644f43c0f7 Remove a debugging printf() accidentally left in the previous check-in.
FossilOrigin-Name: e9d1efa597fb073dc4bc4286e03059a350ed05d3e6476cd3247e6cde626f458b
2020-10-01 14:38:39 +00:00
drh 67306cb3b4 The IN-early-out optimization does not work for virtual tables. Do
not try to use it there.  Fix for ticket [2d5a3163563d559f].  Test
cases in TH3.

FossilOrigin-Name: dbec6910d9648f4907373c818a5cb347a2e487784208751ccecfacca752ff99d
2020-10-01 14:36:15 +00:00
dan 33a99fad08 Add experimental unicode-aware trigram tokenizer to fts5. And support for LIKE and GLOB optimizations for fts5 tables that use said tokenizer.
FossilOrigin-Name: 0d7810c1aea93c0a3da1ccc4911dbce8a1b6e1dbfe1ab7e800289a0c783b5985
2020-09-30 20:35:37 +00:00
drh fad4dd0fd1 Improved query optimization for multi-column indexes where the second or
later columns are constrained by an IN operator and the earlier index columns
limit the search to a small number of rows.  Use the new OP_SeekScan opcode
which does scanning of the relevant range of the index but gives up and
falls back to doing a seek if the number of rows scanned grows to large,
in order to guard against pathological cases where the estimated number
of rows to be scanned is far too small.

FossilOrigin-Name: 4a43430fd23f88352c33b29c4c105b72f6dc821f94bf362040c41a1648c402e5
2020-09-30 18:06:51 +00:00
drh 4f65b3bbfb For the OP_SeekScan opcode, adjust the number of steps run before giving
up based on the estimated number of comparisons needed to perform a seek.

FossilOrigin-Name: dc4172e6b8e1f62dc7329a3adb2223f290bc4c8055c265e88182ef432f4bcf10
2020-09-30 18:03:22 +00:00
drh 395a60dad4 Back out the incorrect optimization of check-in [e51ecadcbdef5ce6] as
ticket [5c4e7aa793943803] reports a case where the optimization does not
work.

FossilOrigin-Name: 7395e96b8cc370c8ac2657fb805915b0992a15d80f8bf256d277b423fec64675
2020-09-30 17:32:22 +00:00
drh af3711536b In the query flattener when substituting expression Y in place of expression X,
if X is marked has having come from an ON or USING clause of a LEFT JOIN, then
be sure that all subexpressions of Y, not just the root node of Y, are
similarly marked.  Otherwise, if Y is an AND operator, it will be split up
during WHERE clause analysis and the subexpressions will not get the special
treatment needed by LEFT JOIN ON/USING clauses.
Fix for ticket [66e4b0e271c47145].

FossilOrigin-Name: 69f9eb7343a416c5ab426c8e1b9f0ae576544b4ccc5d87f5481c8ff884f696e1
2020-09-30 15:36:03 +00:00
shearer 1e6c58dee2 Better understanding of savepoint code
FossilOrigin-Name: ce6d8d621505f25e4fd43e7cf27445e1a2ddd58d79108d63499c2ae30cc9f610
2020-09-30 09:17:53 +00:00
drh a957e22fa4 Add an sqlite3FaultSim() call to btreeNext() to make it easier to
simulate I/O errors in calls to sqlite3BtreeNext(), and in OP_SeekScan.

FossilOrigin-Name: 29cca775d3f5411624f0a8d55d34a038a24f1009d25b097315adb64e70c4b299
2020-09-30 00:48:45 +00:00
drh f287d00108 In the OP_SeekScan opcode, changes to pOp must occur after the call
to VdbeBranchTaken() so that the VdbeBranchTaken() attributes the branch
to the correct opcode.

FossilOrigin-Name: 61fbe7aa7cc0e8fe3e6b1c5aec277183d8cd7c86b1e835c38e0b37a9b8063343
2020-09-30 00:10:22 +00:00
drh a54e1b1fc8 The OP_SeekScan opcode is a no-op if the cursor is not pointing to a valid
row upon entry.

FossilOrigin-Name: 4afc96b5fe80bd192a23e0230edc207e641931c3bf48296b1a385c786386f1b7
2020-09-29 23:52:25 +00:00
drh 0b2949c36e Coverage testing of the OP_SeekScan opcode. Fix a problem that comes up when
OP_SeekScan reaches the end of the table.

FossilOrigin-Name: 9e57e758a6a33f54d28a546b4eebfb5cfacef30dc4e0207e43bb9d2c06fc3439
2020-09-29 20:22:19 +00:00
drh dfbaae7572 Improved comments on the new OP_SeekScan opcode.
FossilOrigin-Name: 6110fdd5bb7b4ae5c065404c802ae726362ef084966b73cffe58c4bfb98689d2
2020-09-29 17:29:11 +00:00
drh c40076a8cf Improved performance by manually in-lining the sqlite3VdbeIdxKeyCompare()
routine for the OP_IdxGT opcode and its kin.

FossilOrigin-Name: 2206a2c848a122ee220c89427f9be0460cba0706f58852139d7b37184ce29a29
2020-09-29 16:05:09 +00:00
drh 46f0f4e56d Typo fix to repair the early-out optimization. Also avoid unnecessary
OP_SeekHit opcodes.

FossilOrigin-Name: 8fd7d8dfcd515aa6b65d6eb27b033d3b3a31db467b9100cc13c62bc60113019e
2020-09-29 15:32:54 +00:00
drh f761d937c2 The OP_SeekScan opcode works, but using it requires disabling the
IN-earlyout optimization because the OP_IfNoHope opcode might move the
cursor.

FossilOrigin-Name: f3c36b840c9a29c0add28039db216f4207a308e5057fc76e3f0004024a8267ac
2020-09-29 01:48:46 +00:00
drh 68cf0ace3d Revisiting the IN-scan optimization to try to fix it for the corner case
where the statistics deceive the query planner into using a scan when
an indexed lookup would be better.  This check-in changes the code
generation to do the IN-scan using a new OP_SeekScan opcode.  That new
opcode is designed to abandon the scan and fall back to a seek if
it doesn't find a match quickly enough.  For this work-in-progress check-in, 
OP_SeekScan is still a no-op and OP_SeekGE still ends up doing all the work.

FossilOrigin-Name: d720b6981eeb0ffdb14494ca63eca298ee724ae4ad4863c7c7cbfdad7fa52519
2020-09-28 19:51:54 +00:00
drh 75fa266341 Small performance improvement and size reduction by reducing the size of
the WhereTerm object.

FossilOrigin-Name: 43f7ddad800acf40917c5cc3d926640dbec17c34d5f1cbbb74bd80f44eeed0a5
2020-09-28 15:49:43 +00:00
drh f573b4fb94 Avoid the possibility of integer overflow on the --pagecache option to
the CLI. See [forum:10a2892377|forum post 10a2892377]

FossilOrigin-Name: d3d13df31a97648f952beb2e1a783f947a80ec843227985ad9ebd14452d2f654
2020-09-28 13:34:05 +00:00
shearer f36cbefe81 Clarify
FossilOrigin-Name: 14dba0f3b5defef148c78e7613fc33044598008df4dee834f752bd10891e3684
2020-09-25 17:17:24 +00:00
shearer 399b740986 Distinguish between checkpoints (WAL-only, implementation specific) and
savepoints (Btree internal implementation of COMMIT/ROLLBACK subtransactions) 
and SQL SAVEPOINT (identical name for SQL-level subtransactions)

FossilOrigin-Name: ae686ab6a84ad19fec5873034e873b3d8d933a792b9742626627fa0677002a08
2020-09-25 16:54:55 +00:00
shearer 3a8847a5fc Reset to trunk's func. Still learning Fossil.
FossilOrigin-Name: a4840cf5c682a22f32eb1890fc4ecc35a367d967142b284e5993c7faf512d71e
2020-09-25 14:26:49 +00:00
shearer fc1070bfc4 More classification of functions.
Fix incorrect comment that sqlite3BtreeCursorHasHint() is only used within
asserts.

FossilOrigin-Name: 78d8db7cb73284644cde1636a14e4e3598e1a2a7e94a04dfc7406422aab93ae5
2020-09-25 13:56:31 +00:00
shearer 9e3b8ae1e0 Merging with trunk
FossilOrigin-Name: 3a576608e6f26ae8642ec4b2b1c2f2b91b1acda3dc9928b9d67e401684c254b3
2020-09-25 09:42:37 +00:00
shearer 9a28680095 Add reminder comment that, by definition, these functions won't be called from
elsewhere in SQLite. Useful to remember for beginners who may suspect unusued code.

FossilOrigin-Name: 6f5c1fde245e18d80dd5b1d33ad36b8320960dc644c666351b0c9b60d8e545ca
2020-09-25 08:17:58 +00:00
shearer abd2779560 Added context to explain that the test coverage is about MC/DC in general, not
just an SQLite-specifc test harness.

FossilOrigin-Name: 770dbedddc7ce7fa2355df5db5f77ef08c53549cf7c85d0496b1978e0612c1ab
2020-09-24 11:41:18 +00:00
shearer 153fa608bf Group metadata definitions together
FossilOrigin-Name: 5c306f42514a42fce40fddbfed83df71c3897cc36843ed4e9e968de85ec80b42
2020-09-24 06:37:18 +00:00
shearer b4e313a5b0 Figured out where/how sqlite3BtreeRowCountEst() is called
FossilOrigin-Name: a46537153c0db06a324320fb5fb1a6aa5191a7559b6d1cabfa6bf4b9457b3bae
2020-09-23 17:31:30 +00:00
mistachkin 273ee15121 Fix harmless compiler warning seen with MSVC.
FossilOrigin-Name: 4591ee03d7a1ef3f0f6ad0629493fdb7a1c0ddb3277a9e87aa244cb0ca770593
2020-09-21 20:18:44 +00:00
dan 7548ab20e6 In fts5 integrity checks, do not compare the contents of the index against an external content table unless specifically requested.
FossilOrigin-Name: 782163693f37aeb65209bebbaeb6659a36881b8c4b4bec778b366658488bf966
2020-09-21 14:53:21 +00:00
drh 9ca41fbfa9 Remove a new assert() that the compiler finds is always true at compile-time,
to avoid a compiler warning.

FossilOrigin-Name: 8bbaee238593741da107b92b254cb5f0cf8b6bcc760bf2b25d20e46c8edee2a9
2020-09-20 13:33:28 +00:00
drh 79d9af960b Attempt to silence harmless static analyzer warnings in Lemon and in the
Lemon-generated parser.

FossilOrigin-Name: de8ce22a46c90afa5475cd24c28b7a82b26410dc72d662af2f9d9e5e528e0eec
2020-09-20 12:10:28 +00:00
dan 68cffa65fb Fix a typo in the documentation comment for sqlite3_preupdate_hook().
FossilOrigin-Name: 4542d194e2fef5e21e1c3679914bd9e21fab31cfb111cf640524fb3514a8afa3
2020-09-17 21:11:25 +00:00
dan 39c7125a97 Fix a problem in sqlite-expert causing it to ignore equality constraints on the second or subsequent columns of a multi-column PRIMARY KEY.
FossilOrigin-Name: c666c85a433fbc83edef4dbfb0399672e570f5d7979ab61cb39ff5488595d822
2020-09-17 17:01:16 +00:00
dan f2e151aeab Fix a problem in fts5 causing the in-memory hash table to be flushed more often than necessary.
FossilOrigin-Name: 9a55601d072bcd1ac0f6f1633216c7c8b3ff3e037451e2cfd285cbe19b60b9fc
2020-09-17 15:16:50 +00:00
shearer acc225a7a1 Order btree.h by logical function, add comments
FossilOrigin-Name: ab53b317953c07c12970e530efda0ce39fa259dc29be980c1aa4784dcf9a39fb
2020-09-17 15:04:16 +00:00
dan 3acd3fb9d8 Fix a "jump depends on unitialized value" valgrind/asan error in fts5.
FossilOrigin-Name: 66f94d623c16b4527e42f0519e32ec78eaf9ee6fd61ee7d0eb657cc59a8f7d68
2020-09-17 14:16:02 +00:00
drh f2fa084cf1 Earlier detection of corruption in the rtreecheck() SQL function to prevent
a (harmless) read of an uninitialized value.

FossilOrigin-Name: e2074b24788149562b15022ccd2784d6649f08ebc41410e3bfb2401baf0892e2
2020-09-17 11:56:04 +00:00
drh bc2e95140b Prevent use-after-free of the u.vtab.idxStr string following an OOM
while generating the OP_VFilter opcode.

FossilOrigin-Name: 751fe4edb2d4602e652523c2759de3f4fffd29d5c66cae68caf45b30fd8b750a
2020-09-17 11:32:14 +00:00
drh f1ea425560 DISTINCT may not be ignored inside a UNION ALL common table expression.
Fix for ticket [c51489c3b8f919c5]

FossilOrigin-Name: 7d2b590d3abd66a7e6ae9046198eb669e0fd2f223f7691281e9ad795a12b8903
2020-09-17 00:46:09 +00:00
drh d96e3821e4 Fix a pair of assert()s in "PRAGMA foreign_key_check" that might have given
a false-positive following an OOM.

FossilOrigin-Name: 9ea3039b538ffd0f348c8fbc9452af1fbf899a1f668af9a2404bdd0f8dd21351
2020-09-16 19:48:23 +00:00
drh 18ef40e563 Fix harmless compiler warnings in Lemon.
FossilOrigin-Name: 6c94ba4b1c16b676978808dcb24f63c2f22915af5dcfe9f635c037011affcf4b
2020-09-16 16:55:56 +00:00
dan b5a69238b4 Fix a buffer overread found by OSSFuzz that could occur if a WITHOUT ROWID table with many columns was NATURAL JOINed against itself.
FossilOrigin-Name: 3d35fa0be866213274fc09250225b345f6b08a9b4ec373d53d95e627e24512be
2020-09-15 20:48:30 +00:00
drh ddcfe92105 Do not invoke usleep() for more than 999999 microseconds.
FossilOrigin-Name: 1f5ed852f25515bbc0a7aaf236fdef40fa7e31805eee1249277fde4e68f95130
2020-09-15 12:29:35 +00:00
dan 86f477edaa Catch fts5 index corruption caused by issuing 'delete' commands with incorrect data earlier in some cases. Also fix a couple of test script problems.
FossilOrigin-Name: b79f19edfd33c2a75f936c352668e14e81f35acf4f07edc27a21f941a7304b38
2020-09-11 15:01:49 +00:00
drh 94acc2ef42 Try again to fix the typo in the sqlite3_txn_state() documentation.
FossilOrigin-Name: 6d1ab0403c2855b595f5d294305f41f56a7a93503f2a58d1b1d12431d480704e
2020-09-10 15:09:11 +00:00
drh 4fb8452875 Fix typo in the documentation for the new sqlite3_txn_state() interface.
FossilOrigin-Name: 23f7d01758cbcf22bd34e78fb8284c7af18f3059a03c4ff6ab3e556ca11fce19
2020-09-10 14:54:57 +00:00
drh 786142a994 If an amalgamation is created using SQLITE_ENABLE_UPDATE_DELETE_LIMIT,
ensure that it can still be compiled without that option by setting the
SQLITE_UDL_CAPABLE_PARSER flag in the preamble.

FossilOrigin-Name: 5b905d7d7714d1d2c433ff58f5d6917d6d27302d44ca347aa740e768f1354b16
2020-09-10 12:41:46 +00:00
dan ebd2ecdda7 Fix another (harmless in practice) tsan error in shared-cache mode.
FossilOrigin-Name: 5a74fa3f0a64f462c8add9beae231a9bbdd19e54d07b54f08726cb1411fc8d3a
2020-09-07 11:14:27 +00:00
drh 8ab0809473 Remove an artifical limitation on the length of columns in the "box"
output mode of the command-line shell.

FossilOrigin-Name: 783fa887c9ed1a7d72c310df1dd9de91c016061b05fdeec87fbb2a7eb0b952ea
2020-09-06 17:40:38 +00:00
drh 2b75d3beb0 Fix a bug in Fossil that might cause it to crash if there is
a multi-terminal token with a space following the "|" separator.
This does not affect SQLite.

FossilOrigin-Name: 430c5d1da57af452f236cc862139d84ab97b6020f6d327dae5268c58e6e83a87
2020-09-05 06:21:54 +00:00
dan 78f04753ae Fix a tsan error that could occur when using shared-cache mode.
FossilOrigin-Name: de80bc87300257cc49d98e2d22e914211f213dce912f320c8b37b3883c73923c
2020-09-04 19:10:43 +00:00
dan 2b06b0769e Ensure that the busy-handler count is reset at the end of each sqlite3_file_control() and sqlite3_prepare() (and _v2() and _v3()).
FossilOrigin-Name: 5dd05940617fb05ee2faf212b15afc3a8e9695318eccb76761b37359fea681d1
2020-09-04 17:30:59 +00:00
mistachkin 52cfe0312a Fix harmless compiler warning.
FossilOrigin-Name: a711e8cd2c7b64e06241736ecef478ac64ddbe7b58e0933b6febba63f7fb06e1
2020-09-01 19:02:52 +00:00
drh 512aa78ca2 In the Lemon output, add a prefix comment that explains that the output file
is automatically generated and shows the name of the source file.

FossilOrigin-Name: d34caf3bb63d0512ea116a8c8c8343b76aa39441bd4b3e98231747a705b91d54
2020-09-01 12:26:55 +00:00
drh 60c71b02ca Lemon updates: (1) include the #defines for all tokens in the generated C
file, so that the C-file can be stand-alone.  (2) If the grammar begins with
a %include {...} directive on line one, make that directive the header for
the generated C file.  (3) Enhance the lemon.html documentation.

FossilOrigin-Name: 84d54eb35716174195ee7e5ac846f47308e5dbb0056e8ff568daa133860bab74
2020-09-01 11:20:03 +00:00
drh fa17e134b2 Improvements to the IN-early-out optimization so that it works more
efficiently when there are two or more indexed IN clauses on a single table.

FossilOrigin-Name: 35505c68c1945c35babd2496e02bc4907a15c8e7b8d77f05f230bd0e9d4891d7
2020-09-01 01:52:03 +00:00
drh d321b6f4ad Fix a harmless compiler warning.
FossilOrigin-Name: 3ca0b7d54d73d07cd6b32e650a809174bb1cd66ce5ecdb36f65b70899ea05824
2020-09-01 00:26:21 +00:00
drh 37ccfcfeb9 New test-control that returns the number of calls to
sqlite3BtreeMovetoUnpacked() on the main database and then resets the
counter.  This only works for SQLITE_DEBUG builds.

FossilOrigin-Name: dca5b91926431768babac28a6faf7674a5014db95caba727995b470e92b3182a
2020-08-31 18:49:04 +00:00
drh c51ceeb049 Fix the documentation for the OP_IdxGT family of opcodes to show that the
P5 operand is not used.

FossilOrigin-Name: 62f7d2a61259f296ffdcb3b3ee1a13925c4563ac8ed669f8a8a63fc7bc3a0a37
2020-08-31 12:29:03 +00:00
dan acd3c8a995 Fix a sanitizer warning in zipfile.c.
FossilOrigin-Name: ded1a75b3cf39834d38a385f38ae969b296f6c9409856b7eea08645e861b1ac2
2020-08-29 19:00:19 +00:00
dan d49c0c83ef Improve performance of wal-mode locking on unix in cases where there are hundreds of connections to a single database within the same process.
FossilOrigin-Name: a1c19eea8f141b89a0921da0724096feb21a772ef6654f164e2c36ebf9f7871e
2020-08-29 15:15:07 +00:00
dan 6acdee6765 Fix handling of an xShmLock(SHARED, UNLOCK) call when the caller does not hold any lock on the specified slot, but another connection in the same process holds an EXCLUSIVE.
FossilOrigin-Name: 3eb365027b885e1f61965efd53a3643b6ff441ae01e79038a091314516a50dd4
2020-08-28 20:01:06 +00:00
dan 8337da6678 Modify the unixShmLock() function to avoid iterating through the (possibly large) set of connections to the same database file.
FossilOrigin-Name: e0faddf0dfc3a40b6b94408296dd781dd0264ecc9f2129ce4405438433fb00e0
2020-08-28 19:27:15 +00:00
mistachkin 72c38d87bf Add the miscellaneous 'series' extension to the shell.
FossilOrigin-Name: fc0856dccfab273d50457052fa3c6da768d0eb2504ad04d9540da4e3222fc829
2020-08-28 18:47:39 +00:00
drh 7b8524168e Update Lemon documentation. Patches from sgbeal.
FossilOrigin-Name: f5dc83442bf010bc4083e083b3a1acbb9918b7e685ca676dd899a0e09df196bc
2020-08-28 13:10:00 +00:00
drh e2678b93af Fix a couple of unreachable branches.
FossilOrigin-Name: f2d26f2b11317abd4f993faa1a4df7afcd1a2d4e448ecc69ca05e9ebf102cd62
2020-08-28 12:58:21 +00:00
dan 832aa023c6 Add fts5 test to confirm that for a table with columns a, b, c and d, "{a b}" and "-{c d}" are handled similarly.
FossilOrigin-Name: 1a04920998368e56276fd0b100be8343609c6ff8a731cf8e26a0490f9c6dabdf
2020-08-28 11:19:49 +00:00
drh 04cd60e18c Remove a (harmless) redundant variable from the CLI implementation.
FossilOrigin-Name: 3f7bbb840de0a9b1ca89288805cb151aea6fcb82efda9ba39f51abf1b17c070b
2020-08-27 20:55:54 +00:00
drh 92e21ef079 Include the original text of the CHECK constraint in the error message for
anonymous CHECK constraints.

FossilOrigin-Name: 5ce34a955bb36d77edc9951cb7ac2ef9c876d7d3ff5852af682f558e248f428c
2020-08-27 18:36:30 +00:00
drh 359941bd33 Apple the same fix for ticket [9eda2697f5cc1aba] to text-to-integer
conversions that was done for floating point conversions by
check-in [1c76f1d8ec0937a2].

FossilOrigin-Name: aafb7a21041090e529491b0ce30c3902420be0551b1b2c55840a5fbb9105fb7d
2020-08-27 16:28:30 +00:00
dan ca3ee7e18a Do not attempt to run test script analyze3.test as part of the "prepare" permutation.
FossilOrigin-Name: f7f13cb1bc699c034a3f5f7a2431c8055cb79e2a14d5e70e1fc5dd6dec00fb26
2020-08-27 14:53:47 +00:00
drh 60081a0382 Enhance the ".databases" command in the CLI so that it shows the result
of sqlite3_db_readonly() and sqlite3_txn_state() for each database file.

FossilOrigin-Name: 0ffd16d23dd3b6467cce31af506c70fde44c3796d386c2a03896e43a6d683e60
2020-08-26 19:07:18 +00:00
drh 30497f4169 If the argument to the ".read" command in the CLI begins with "|" then
run the remainder of the argument as a command and read input from the
output of that command.

FossilOrigin-Name: 6c716f4b556ea8f9c9f15cffd81cb970488eadf1d5da2ba6b366d3bdeb36e492
2020-08-26 10:50:48 +00:00
drh 99744fa4ab Add support for the sqlite3_txn_state() interface.
FossilOrigin-Name: ad195e3dd89d0f33b50070c18fb8f43c4eb24162515dfdd7c04d9e7d96b902a2
2020-08-25 19:09:07 +00:00
drh 58d6f633ba Reduce the N in the logN term for the sorting cost associated with computing
DISTINCT by B-Tree by half, under the assumption that the DISTINCT will
eliminate about half the rows of output.  This is really a wild guess.  But
we do not have any better way of estimating what the row-count reduction due
to DISTINCT will actually be.

FossilOrigin-Name: 8787417ec1da8071d84c6ff0d7a90b5fd458ab6baba871327f36bc4e1bceca61
2020-08-24 23:44:27 +00:00
dan 599456f0ab Correctly handle expressions like "x IS (not) true/false" within the rhs of IN() expressions. Fix for [f3ff1472].
FossilOrigin-Name: 493a25949b9a6d0be82169b597133e491d8be4f4147b6eae135b06c1d810abd3
2020-08-24 10:52:52 +00:00
dan 6c3b4b07d1 Fix a crash that could occur in SQLITE_MAX_EXPR_DEPTH=0 builds when processing SQL containing syntax errors.
FossilOrigin-Name: 5f58dd3a19605b6f49b4364fa29892502eff35f12a7693a8694100e1844711ea
2020-08-20 16:25:26 +00:00
dan 7b14b990d0 Avoid a buffer overrun in test code that could occur if certain test functions were passed a hex-string containing an odd number of digits.
FossilOrigin-Name: 3c5e63c22ffbfeb66eb6ee38912d29fad6f2bd4d74b6a25e89bd36bf40eaa661
2020-08-20 11:03:33 +00:00
drh 14f38b3d0a Try to make SQLite easier to compiler for Mac Catalyst. See
[https://sqlite.org/forum/forumpost/803387a1c5|forum post 803387a1c5].

FossilOrigin-Name: e1595a20d71e61957944cc2b634578968cda8fba08a1f1e75edba20dc9c6080b
2020-08-19 23:51:54 +00:00
drh 46fe138d98 Do not skip over TK_IF_NULL_ROW operators when bypassing TK_COLLATE operators.
Fix to check-in [ac31edd3eeafcef4] which was itself a fix for ticket
[45f4bf4eb4ffd788].

FossilOrigin-Name: 871f2ddcfbb9196dbd851a350e3471ee6d242d86bbd755201f7e2406fce3ac55
2020-08-19 23:32:06 +00:00
dan 1d42e619ac Update releasetest_data.tcl so that the "Fast-One" configuration runs bigmmap.test as part of release testing.
FossilOrigin-Name: a0aa35aaa5694a96638a7c7b1cd69c7523750cbe95831a13c1ee5a6d48256b76
2020-08-19 15:24:19 +00:00
dan fce445b8fa Fix a problem in test file bigmmap.test.
FossilOrigin-Name: d8e47382160e98be646ce3ba568578493088d1bb11d513ded3e00b576fb07f06
2020-08-19 15:21:52 +00:00
drh 9191c702fc Fix the -quote option on the CLI to set the correct column separator.
FossilOrigin-Name: c778f8295c3c9b6cd6107b33fd7664ae75c97840fc974c9f971755a523f185c4
2020-08-17 09:11:21 +00:00
drh 1d8f892a31 Optimization to sqlite3BeginWriteOperation().
FossilOrigin-Name: 2173d4c6e3addc75964508f2fc8e42755376b3bc285286fa90df4831a6fa280b
2020-08-16 00:30:44 +00:00
drh 45d827cb6a Optimization of the sqlite3SrcListDelete() routine.
FossilOrigin-Name: 1b4acd1ac4a8d24f8804c6d0770f5b0022f569d51742b6954b26e525f04d38ca
2020-08-15 23:48:22 +00:00
drh 289a0c849b Remove more unnecessary sqlite3GetVdbe() calls, replacing them with assert()s.
FossilOrigin-Name: b7dc932197665f0ebde3ffb8f0785c22da07ce307cfd5f0eab69e86e4b38fcde
2020-08-15 22:23:00 +00:00
drh f0b41745c5 Avoid unnecessary calls to the sqlite3GetVdbe() routine. Add assert()
statements to prove each call is unnecessary.

FossilOrigin-Name: 86d3790caf92e9cb7a9aaaa110f309b4b6945ac30cfd53fc3e5aa1ec3075ada5
2020-08-15 21:55:14 +00:00
drh 398221e2ad Omit the unnecessary not-NULL check on the upper bound of a forward index
range scan.  The subsequent OP_IdxGT will always catch the NULL.  Similarly,
omit the not-NULL check on the lower bound of a reverse index range scan,
as the SeekLE opcode will disallow the NULL.

FossilOrigin-Name: e51ecadcbdef5ce6e41d68412aee70aa4a1416c850358a6fa7e9a1ab443e719d
2020-08-15 19:58:59 +00:00
drh 861889e4f8 When doing an UPDATE or DELETE using a multi-column index where only a few
of the earlier columns of the index are useful for the index lookup,
postpone doing the main table seek until after all WHERE clause constraints
have been evaluated, in case those constraints can be covered by unused
later terms of the index, thus avoiding unnecessary main table seeks.

FossilOrigin-Name: 7fee0b1075d622835dc6828c061be516102da9e2809f52d9ab7c4bbef7dfb871
2020-08-14 21:51:02 +00:00
drh a3d6d6a93f Update the version number to 3.34.0 for the next development cycle.
FossilOrigin-Name: 70f34f3df5358d36c8578afbc05756450c46da36b8dce339ed87fc0b9d4057cb
2020-08-14 21:37:32 +00:00
dan e0404386f2 Fix an inconsequential memory leak in sqldiff. Update the "Sanitize" case in wapptest.tcl to use -fsanitize=address,undefined, and to run more tests.
FossilOrigin-Name: 613fb5c2525be77e48bad0a74e8b7bf53489365060fb9c7713a0caddb1820c71
2020-08-14 16:14:40 +00:00
122 changed files with 3807 additions and 1189 deletions
+1 -1
View File
@@ -1 +1 @@
3.33.0
3.34.0
Vendored
+9 -9
View File
@@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.69 for sqlite 3.33.0.
# Generated by GNU Autoconf 2.69 for sqlite 3.34.0.
#
#
# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
@@ -726,8 +726,8 @@ MAKEFLAGS=
# Identity of this package.
PACKAGE_NAME='sqlite'
PACKAGE_TARNAME='sqlite'
PACKAGE_VERSION='3.33.0'
PACKAGE_STRING='sqlite 3.33.0'
PACKAGE_VERSION='3.34.0'
PACKAGE_STRING='sqlite 3.34.0'
PACKAGE_BUGREPORT=''
PACKAGE_URL=''
@@ -1467,7 +1467,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
\`configure' configures sqlite 3.33.0 to adapt to many kinds of systems.
\`configure' configures sqlite 3.34.0 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1532,7 +1532,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
short | recursive ) echo "Configuration of sqlite 3.33.0:";;
short | recursive ) echo "Configuration of sqlite 3.34.0:";;
esac
cat <<\_ACEOF
@@ -1659,7 +1659,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
sqlite configure 3.33.0
sqlite configure 3.34.0
generated by GNU Autoconf 2.69
Copyright (C) 2012 Free Software Foundation, Inc.
@@ -2078,7 +2078,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
It was created by sqlite $as_me 3.33.0, which was
It was created by sqlite $as_me 3.34.0, which was
generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@
@@ -12243,7 +12243,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
This file was extended by sqlite $as_me 3.33.0, which was
This file was extended by sqlite $as_me 3.34.0, which was
generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -12309,7 +12309,7 @@ _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\
sqlite config.status 3.33.0
sqlite config.status 3.34.0
configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\"
+329 -170
View File
File diff suppressed because it is too large Load Diff
+41
View File
@@ -326,6 +326,47 @@ do_setup_rec_test $tn.16 {
SCAN TABLE t1
}
do_setup_rec_test $tn.17.1 {
CREATE TABLE example (A INTEGER, B INTEGER, C INTEGER, PRIMARY KEY (A,B));
} {
SELECT * FROM example WHERE a=?
} {
(no new indexes)
SEARCH TABLE example USING INDEX sqlite_autoindex_example_1 (A=?)
}
do_setup_rec_test $tn.17.2 {
CREATE TABLE example (A INTEGER, B INTEGER, C INTEGER, PRIMARY KEY (A,B));
} {
SELECT * FROM example WHERE b=?
} {
CREATE INDEX example_idx_00000042 ON example(B);
SEARCH TABLE example USING INDEX example_idx_00000042 (B=?)
}
do_setup_rec_test $tn.17.3 {
CREATE TABLE example (A INTEGER, B INTEGER, C INTEGER, PRIMARY KEY (A,B));
} {
SELECT * FROM example WHERE a=? AND b=?
} {
(no new indexes)
SEARCH TABLE example USING INDEX sqlite_autoindex_example_1 (A=? AND B=?)
}
do_setup_rec_test $tn.17.4 {
CREATE TABLE example (A INTEGER, B INTEGER, C INTEGER, PRIMARY KEY (A,B));
} {
SELECT * FROM example WHERE a=? AND b>?
} {
(no new indexes)
SEARCH TABLE example USING INDEX sqlite_autoindex_example_1 (A=? AND B>?)
}
do_setup_rec_test $tn.17.5 {
CREATE TABLE example (A INTEGER, B INTEGER, C INTEGER, PRIMARY KEY (A,B));
} {
SELECT * FROM example WHERE a>? AND b=?
} {
CREATE INDEX example_idx_0000cb3f ON example(B, A);
SEARCH TABLE example USING INDEX example_idx_0000cb3f (B=? AND A>?)
}
}
proc do_candidates_test {tn sql res} {
+3 -1
View File
@@ -685,6 +685,7 @@ static int idxGetTableInfo(
IdxTable *pNew = 0;
int rc, rc2;
char *pCsr = 0;
int nPk = 0;
rc = idxPrintfPrepareStmt(db, &p1, pzErrmsg, "PRAGMA table_info=%Q", zTab);
while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(p1) ){
@@ -695,6 +696,7 @@ static int idxGetTableInfo(
);
nByte += 1 + STRLEN(zCol);
nCol++;
nPk += (sqlite3_column_int(p1, 5)>0);
}
rc2 = sqlite3_reset(p1);
if( rc==SQLITE_OK ) rc = rc2;
@@ -714,7 +716,7 @@ static int idxGetTableInfo(
const char *zCol = (const char*)sqlite3_column_text(p1, 1);
int nCopy = STRLEN(zCol) + 1;
pNew->aCol[nCol].zName = pCsr;
pNew->aCol[nCol].iPk = sqlite3_column_int(p1, 5);
pNew->aCol[nCol].iPk = (sqlite3_column_int(p1, 5)==1 && nPk==1);
memcpy(pCsr, zCol, nCopy);
pCsr += nCopy;
+23 -9
View File
@@ -184,6 +184,7 @@ struct Fts5Config {
Fts5Tokenizer *pTok;
fts5_tokenizer *pTokApi;
int bLock; /* True when table is preparing statement */
int ePattern; /* FTS_PATTERN_XXX constant */
/* Values loaded from the %_config table */
int iCookie; /* Incremented when %_config is modified */
@@ -204,17 +205,19 @@ struct Fts5Config {
};
/* Current expected value of %_config table 'version' field */
#define FTS5_CURRENT_VERSION 4
#define FTS5_CURRENT_VERSION 4
#define FTS5_CONTENT_NORMAL 0
#define FTS5_CONTENT_NONE 1
#define FTS5_CONTENT_EXTERNAL 2
#define FTS5_DETAIL_FULL 0
#define FTS5_DETAIL_NONE 1
#define FTS5_DETAIL_COLUMNS 2
#define FTS5_DETAIL_FULL 0
#define FTS5_DETAIL_NONE 1
#define FTS5_DETAIL_COLUMNS 2
#define FTS5_PATTERN_NONE 0
#define FTS5_PATTERN_LIKE 65 /* matches SQLITE_INDEX_CONSTRAINT_LIKE */
#define FTS5_PATTERN_GLOB 66 /* matches SQLITE_INDEX_CONSTRAINT_GLOB */
int sqlite3Fts5ConfigParse(
Fts5Global*, sqlite3*, int, const char **, Fts5Config**, char**
@@ -484,7 +487,7 @@ int sqlite3Fts5IndexSetAverages(Fts5Index *p, const u8*, int);
/*
** Functions called by the storage module as part of integrity-check.
*/
int sqlite3Fts5IndexIntegrityCheck(Fts5Index*, u64 cksum);
int sqlite3Fts5IndexIntegrityCheck(Fts5Index*, u64 cksum, int bUseCksum);
/*
** Called during virtual module initialization to register UDF
@@ -554,8 +557,7 @@ int sqlite3Fts5GetTokenizer(
Fts5Global*,
const char **azArg,
int nArg,
Fts5Tokenizer**,
fts5_tokenizer**,
Fts5Config*,
char **pzErr
);
@@ -639,7 +641,7 @@ int sqlite3Fts5StorageDelete(Fts5Storage *p, i64, sqlite3_value**);
int sqlite3Fts5StorageContentInsert(Fts5Storage *p, sqlite3_value**, i64*);
int sqlite3Fts5StorageIndexInsert(Fts5Storage *p, sqlite3_value**, i64);
int sqlite3Fts5StorageIntegrity(Fts5Storage *p);
int sqlite3Fts5StorageIntegrity(Fts5Storage *p, int iArg);
int sqlite3Fts5StorageStmt(Fts5Storage *p, int eStmt, sqlite3_stmt**, char**);
void sqlite3Fts5StorageStmtRelease(Fts5Storage *p, int eStmt, sqlite3_stmt*);
@@ -684,11 +686,19 @@ struct Fts5Token {
/* Parse a MATCH expression. */
int sqlite3Fts5ExprNew(
Fts5Config *pConfig,
int bPhraseToAnd,
int iCol, /* Column on LHS of MATCH operator */
const char *zExpr,
Fts5Expr **ppNew,
char **pzErr
);
int sqlite3Fts5ExprPattern(
Fts5Config *pConfig,
int bGlob,
int iCol,
const char *zText,
Fts5Expr **pp
);
/*
** for(rc = sqlite3Fts5ExprFirst(pExpr, pIdx, bDesc);
@@ -797,6 +807,10 @@ int sqlite3Fts5AuxInit(fts5_api*);
*/
int sqlite3Fts5TokenizerInit(fts5_api*);
int sqlite3Fts5TokenizerPattern(
int (*xCreate)(void*, const char**, int, Fts5Tokenizer**),
Fts5Tokenizer *pTok
);
/*
** End of interface to code in fts5_tokenizer.c.
**************************************************************************/
+2 -4
View File
@@ -325,7 +325,7 @@ static int fts5ConfigParseSpecial(
rc = SQLITE_ERROR;
}else{
rc = sqlite3Fts5GetTokenizer(pGlobal,
(const char**)azArg, (int)nArg, &pConfig->pTok, &pConfig->pTokApi,
(const char**)azArg, (int)nArg, pConfig,
pzErr
);
}
@@ -397,9 +397,7 @@ static int fts5ConfigParseSpecial(
*/
static int fts5ConfigDefaultTokenizer(Fts5Global *pGlobal, Fts5Config *pConfig){
assert( pConfig->pTok==0 && pConfig->pTokApi==0 );
return sqlite3Fts5GetTokenizer(
pGlobal, 0, 0, &pConfig->pTok, &pConfig->pTokApi, 0
);
return sqlite3Fts5GetTokenizer(pGlobal, 0, 0, pConfig, 0);
}
/*
+215 -52
View File
@@ -128,6 +128,7 @@ struct Fts5Parse {
int nPhrase; /* Size of apPhrase array */
Fts5ExprPhrase **apPhrase; /* Array of all phrases */
Fts5ExprNode *pExpr; /* Result of a successful parse */
int bPhraseToAnd; /* Convert "a+b" to "a AND b" */
};
void sqlite3Fts5ParseError(Fts5Parse *pParse, const char *zFmt, ...){
@@ -216,6 +217,7 @@ static void fts5ParseFree(void *p){ sqlite3_free(p); }
int sqlite3Fts5ExprNew(
Fts5Config *pConfig, /* FTS5 Configuration */
int bPhraseToAnd,
int iCol,
const char *zExpr, /* Expression text */
Fts5Expr **ppNew,
@@ -231,6 +233,7 @@ int sqlite3Fts5ExprNew(
*ppNew = 0;
*pzErr = 0;
memset(&sParse, 0, sizeof(sParse));
sParse.bPhraseToAnd = bPhraseToAnd;
pEngine = sqlite3Fts5ParserAlloc(fts5ParseAlloc);
if( pEngine==0 ){ return SQLITE_NOMEM; }
sParse.pConfig = pConfig;
@@ -273,6 +276,7 @@ int sqlite3Fts5ExprNew(
pNew->pConfig = pConfig;
pNew->apExprPhrase = sParse.apPhrase;
pNew->nPhrase = sParse.nPhrase;
pNew->bDesc = 0;
sParse.apPhrase = 0;
}
}else{
@@ -284,6 +288,81 @@ int sqlite3Fts5ExprNew(
return sParse.rc;
}
/*
** This function is only called when using the special 'trigram' tokenizer.
** Argument zText contains the text of a LIKE or GLOB pattern matched
** against column iCol. This function creates and compiles an FTS5 MATCH
** expression that will match a superset of the rows matched by the LIKE or
** GLOB. If successful, SQLITE_OK is returned. Otherwise, an SQLite error
** code.
*/
int sqlite3Fts5ExprPattern(
Fts5Config *pConfig, int bGlob, int iCol, const char *zText, Fts5Expr **pp
){
i64 nText = strlen(zText);
char *zExpr = (char*)sqlite3_malloc64(nText*4 + 1);
int rc = SQLITE_OK;
if( zExpr==0 ){
rc = SQLITE_NOMEM;
}else{
char aSpec[3];
int iOut = 0;
int i = 0;
int iFirst = 0;
if( bGlob==0 ){
aSpec[0] = '_';
aSpec[1] = '%';
aSpec[2] = 0;
}else{
aSpec[0] = '*';
aSpec[1] = '?';
aSpec[2] = '[';
}
while( i<=nText ){
if( i==nText
|| zText[i]==aSpec[0] || zText[i]==aSpec[1] || zText[i]==aSpec[2]
){
if( i-iFirst>=3 ){
int jj;
zExpr[iOut++] = '"';
for(jj=iFirst; jj<i; jj++){
zExpr[iOut++] = zText[jj];
if( zText[jj]=='"' ) zExpr[iOut++] = '"';
}
zExpr[iOut++] = '"';
zExpr[iOut++] = ' ';
}
if( zText[i]==aSpec[2] ){
i += 2;
if( zText[i-1]=='^' ) i++;
while( i<nText && zText[i]!=']' ) i++;
}
iFirst = i+1;
}
i++;
}
if( iOut>0 ){
int bAnd = 0;
if( pConfig->eDetail!=FTS5_DETAIL_FULL ){
bAnd = 1;
if( pConfig->eDetail==FTS5_DETAIL_NONE ){
iCol = pConfig->nCol;
}
}
zExpr[iOut] = '\0';
rc = sqlite3Fts5ExprNew(pConfig, bAnd, iCol, zExpr, pp,pConfig->pzErrmsg);
}else{
*pp = 0;
}
sqlite3_free(zExpr);
}
return rc;
}
/*
** Free the expression node object passed as the only argument.
*/
@@ -1661,6 +1740,20 @@ void sqlite3Fts5ParseFinished(Fts5Parse *pParse, Fts5ExprNode *p){
pParse->pExpr = p;
}
static int parseGrowPhraseArray(Fts5Parse *pParse){
if( (pParse->nPhrase % 8)==0 ){
sqlite3_int64 nByte = sizeof(Fts5ExprPhrase*) * (pParse->nPhrase + 8);
Fts5ExprPhrase **apNew;
apNew = (Fts5ExprPhrase**)sqlite3_realloc64(pParse->apPhrase, nByte);
if( apNew==0 ){
pParse->rc = SQLITE_NOMEM;
return SQLITE_NOMEM;
}
pParse->apPhrase = apNew;
}
return SQLITE_OK;
}
/*
** This function is called by the parser to process a string token. The
** string may or may not be quoted. In any case it is tokenized and a
@@ -1696,16 +1789,9 @@ Fts5ExprPhrase *sqlite3Fts5ParseTerm(
}else{
if( pAppend==0 ){
if( (pParse->nPhrase % 8)==0 ){
sqlite3_int64 nByte = sizeof(Fts5ExprPhrase*) * (pParse->nPhrase + 8);
Fts5ExprPhrase **apNew;
apNew = (Fts5ExprPhrase**)sqlite3_realloc64(pParse->apPhrase, nByte);
if( apNew==0 ){
pParse->rc = SQLITE_NOMEM;
fts5ExprPhraseFree(sCtx.pPhrase);
return 0;
}
pParse->apPhrase = apNew;
if( parseGrowPhraseArray(pParse) ){
fts5ExprPhraseFree(sCtx.pPhrase);
return 0;
}
pParse->nPhrase++;
}
@@ -2112,6 +2198,67 @@ static void fts5ExprAddChildren(Fts5ExprNode *p, Fts5ExprNode *pSub){
}
}
/*
** This function is used when parsing LIKE or GLOB patterns against
** trigram indexes that specify either detail=column or detail=none.
** It converts a phrase:
**
** abc + def + ghi
**
** into an AND tree:
**
** abc AND def AND ghi
*/
static Fts5ExprNode *fts5ParsePhraseToAnd(
Fts5Parse *pParse,
Fts5ExprNearset *pNear
){
int nTerm = pNear->apPhrase[0]->nTerm;
int ii;
int nByte;
Fts5ExprNode *pRet;
assert( pNear->nPhrase==1 );
assert( pParse->bPhraseToAnd );
nByte = sizeof(Fts5ExprNode) + nTerm*sizeof(Fts5ExprNode*);
pRet = (Fts5ExprNode*)sqlite3Fts5MallocZero(&pParse->rc, nByte);
if( pRet ){
pRet->eType = FTS5_AND;
pRet->nChild = nTerm;
fts5ExprAssignXNext(pRet);
pParse->nPhrase--;
for(ii=0; ii<nTerm; ii++){
Fts5ExprPhrase *pPhrase = (Fts5ExprPhrase*)sqlite3Fts5MallocZero(
&pParse->rc, sizeof(Fts5ExprPhrase)
);
if( pPhrase ){
if( parseGrowPhraseArray(pParse) ){
fts5ExprPhraseFree(pPhrase);
}else{
pParse->apPhrase[pParse->nPhrase++] = pPhrase;
pPhrase->nTerm = 1;
pPhrase->aTerm[0].zTerm = sqlite3Fts5Strndup(
&pParse->rc, pNear->apPhrase[0]->aTerm[ii].zTerm, -1
);
pRet->apChild[ii] = sqlite3Fts5ParseNode(pParse, FTS5_STRING,
0, 0, sqlite3Fts5ParseNearset(pParse, 0, pPhrase)
);
}
}
}
if( pParse->rc ){
sqlite3Fts5ParseNodeFree(pRet);
pRet = 0;
}else{
sqlite3Fts5ParseNearsetFree(pNear);
}
}
return pRet;
}
/*
** Allocate and return a new expression object. If anything goes wrong (i.e.
** OOM error), leave an error code in pParse and return NULL.
@@ -2136,51 +2283,58 @@ Fts5ExprNode *sqlite3Fts5ParseNode(
if( eType!=FTS5_STRING && pLeft==0 ) return pRight;
if( eType!=FTS5_STRING && pRight==0 ) return pLeft;
if( eType==FTS5_NOT ){
nChild = 2;
}else if( eType==FTS5_AND || eType==FTS5_OR ){
nChild = 2;
if( pLeft->eType==eType ) nChild += pLeft->nChild-1;
if( pRight->eType==eType ) nChild += pRight->nChild-1;
}
if( eType==FTS5_STRING
&& pParse->bPhraseToAnd
&& pNear->apPhrase[0]->nTerm>1
){
pRet = fts5ParsePhraseToAnd(pParse, pNear);
}else{
if( eType==FTS5_NOT ){
nChild = 2;
}else if( eType==FTS5_AND || eType==FTS5_OR ){
nChild = 2;
if( pLeft->eType==eType ) nChild += pLeft->nChild-1;
if( pRight->eType==eType ) nChild += pRight->nChild-1;
}
nByte = sizeof(Fts5ExprNode) + sizeof(Fts5ExprNode*)*(nChild-1);
pRet = (Fts5ExprNode*)sqlite3Fts5MallocZero(&pParse->rc, nByte);
nByte = sizeof(Fts5ExprNode) + sizeof(Fts5ExprNode*)*(nChild-1);
pRet = (Fts5ExprNode*)sqlite3Fts5MallocZero(&pParse->rc, nByte);
if( pRet ){
pRet->eType = eType;
pRet->pNear = pNear;
fts5ExprAssignXNext(pRet);
if( eType==FTS5_STRING ){
int iPhrase;
for(iPhrase=0; iPhrase<pNear->nPhrase; iPhrase++){
pNear->apPhrase[iPhrase]->pNode = pRet;
if( pNear->apPhrase[iPhrase]->nTerm==0 ){
pRet->xNext = 0;
pRet->eType = FTS5_EOF;
if( pRet ){
pRet->eType = eType;
pRet->pNear = pNear;
fts5ExprAssignXNext(pRet);
if( eType==FTS5_STRING ){
int iPhrase;
for(iPhrase=0; iPhrase<pNear->nPhrase; iPhrase++){
pNear->apPhrase[iPhrase]->pNode = pRet;
if( pNear->apPhrase[iPhrase]->nTerm==0 ){
pRet->xNext = 0;
pRet->eType = FTS5_EOF;
}
}
}
if( pParse->pConfig->eDetail!=FTS5_DETAIL_FULL ){
Fts5ExprPhrase *pPhrase = pNear->apPhrase[0];
if( pNear->nPhrase!=1
|| pPhrase->nTerm>1
|| (pPhrase->nTerm>0 && pPhrase->aTerm[0].bFirst)
){
assert( pParse->rc==SQLITE_OK );
pParse->rc = SQLITE_ERROR;
assert( pParse->zErr==0 );
pParse->zErr = sqlite3_mprintf(
"fts5: %s queries are not supported (detail!=full)",
pNear->nPhrase==1 ? "phrase": "NEAR"
);
sqlite3_free(pRet);
pRet = 0;
if( pParse->pConfig->eDetail!=FTS5_DETAIL_FULL ){
Fts5ExprPhrase *pPhrase = pNear->apPhrase[0];
if( pNear->nPhrase!=1
|| pPhrase->nTerm>1
|| (pPhrase->nTerm>0 && pPhrase->aTerm[0].bFirst)
){
assert( pParse->rc==SQLITE_OK );
pParse->rc = SQLITE_ERROR;
assert( pParse->zErr==0 );
pParse->zErr = sqlite3_mprintf(
"fts5: %s queries are not supported (detail!=full)",
pNear->nPhrase==1 ? "phrase": "NEAR"
);
sqlite3_free(pRet);
pRet = 0;
}
}
}else{
fts5ExprAddChildren(pRet, pLeft);
fts5ExprAddChildren(pRet, pRight);
}
}else{
fts5ExprAddChildren(pRet, pLeft);
fts5ExprAddChildren(pRet, pRight);
}
}
}
@@ -2401,8 +2555,17 @@ static char *fts5ExprPrint(Fts5Config *pConfig, Fts5ExprNode *pExpr){
int iTerm;
if( pNear->pColset ){
int iCol = pNear->pColset->aiCol[0];
zRet = fts5PrintfAppend(zRet, "%s : ", pConfig->azCol[iCol]);
int ii;
Fts5Colset *pColset = pNear->pColset;
if( pColset->nCol>1 ) zRet = fts5PrintfAppend(zRet, "{");
for(ii=0; ii<pColset->nCol; ii++){
zRet = fts5PrintfAppend(zRet, "%s%s",
pConfig->azCol[pColset->aiCol[ii]], ii==pColset->nCol-1 ? "" : " "
);
}
if( zRet ){
zRet = fts5PrintfAppend(zRet, "%s : ", pColset->nCol>1 ? "}" : "");
}
if( zRet==0 ) return 0;
}
@@ -2525,7 +2688,7 @@ static void fts5ExprFunction(
rc = sqlite3Fts5ConfigParse(pGlobal, db, nConfig, azConfig, &pConfig, &zErr);
if( rc==SQLITE_OK ){
rc = sqlite3Fts5ExprNew(pConfig, pConfig->nCol, zExpr, &pExpr, &zErr);
rc = sqlite3Fts5ExprNew(pConfig, 0, pConfig->nCol, zExpr, &pExpr, &zErr);
}
if( rc==SQLITE_OK ){
char *zText;
+2 -2
View File
@@ -306,7 +306,6 @@ int sqlite3Fts5HashWrite(
p->iCol = (pHash->eDetail==FTS5_DETAIL_FULL ? 0 : -1);
}
nIncr += p->nData;
}else{
/* Appending to an existing hash-entry. Check that there is enough
@@ -339,8 +338,9 @@ int sqlite3Fts5HashWrite(
/* If this is a new rowid, append the 4-byte size field for the previous
** entry, and the new rowid for this entry. */
if( iRowid!=p->iRowid ){
u64 iDiff = (u64)iRowid - (u64)p->iRowid;
fts5HashAddPoslistSize(pHash, p, 0);
p->nData += sqlite3Fts5PutVarint(&pPtr[p->nData], iRowid - p->iRowid);
p->nData += sqlite3Fts5PutVarint(&pPtr[p->nData], iDiff);
p->iRowid = iRowid;
bNew = 1;
p->iSzPoslist = p->nData;
+12 -9
View File
@@ -1754,7 +1754,7 @@ static void fts5SegIterReverseInitPage(Fts5Index *p, Fts5SegIter *pIter){
ASSERT_SZLEAF_OK(pIter->pLeaf);
while( 1 ){
i64 iDelta = 0;
u64 iDelta = 0;
if( eDetail==FTS5_DETAIL_NONE ){
/* todo */
@@ -1769,7 +1769,7 @@ static void fts5SegIterReverseInitPage(Fts5Index *p, Fts5SegIter *pIter){
i += nPos;
}
if( i>=n ) break;
i += fts5GetVarint(&a[i], (u64*)&iDelta);
i += fts5GetVarint(&a[i], &iDelta);
pIter->iRowid += iDelta;
/* If necessary, grow the pIter->aRowidOffset[] array. */
@@ -1868,7 +1868,7 @@ static void fts5SegIterNext_Reverse(
if( pIter->iRowidOffset>0 ){
u8 *a = pIter->pLeaf->p;
int iOff;
i64 iDelta;
u64 iDelta;
pIter->iRowidOffset--;
pIter->iLeafOffset = pIter->aRowidOffset[pIter->iRowidOffset];
@@ -1877,7 +1877,7 @@ static void fts5SegIterNext_Reverse(
if( p->pConfig->eDetail!=FTS5_DETAIL_NONE ){
iOff += pIter->nPos;
}
fts5GetVarint(&a[iOff], (u64*)&iDelta);
fts5GetVarint(&a[iOff], &iDelta);
pIter->iRowid -= iDelta;
}else{
fts5SegIterReverseNewPage(p, pIter);
@@ -4997,7 +4997,9 @@ static void fts5MergePrefixLists(
** at most 20 bytes of unexpected space. */
fts5MergeAppendDocid(&out, iLastRowid, i2.iRowid);
fts5BufferZero(&tmp);
sqlite3Fts5BufferSize(&p->rc, &tmp, i1.nPoslist + i2.nPoslist + 10 + 10);
sqlite3Fts5BufferSize(&p->rc, &tmp,
i1.nPoslist + i2.nPoslist + 10 + 10 + FTS5_DATA_ZERO_PADDING
);
if( p->rc ) break;
sqlite3Fts5PoslistNext64(a1, i1.nPoslist, &iOff1, &iPos1);
@@ -5071,9 +5073,10 @@ static void fts5MergePrefixLists(
}
assert_nc( out.n<=(p1->n+p2->n+9) );
fts5BufferSet(&p->rc, p1, out.n, out.p);
fts5BufferFree(p1);
fts5BufferFree(&tmp);
fts5BufferFree(&out);
memset(&out.p[out.n], 0, FTS5_DATA_ZERO_PADDING);
*p1 = out;
}
}
@@ -6059,7 +6062,7 @@ static void fts5IndexIntegrityCheckSegment(
** error, or some other SQLite error code if another error (e.g. OOM)
** occurs.
*/
int sqlite3Fts5IndexIntegrityCheck(Fts5Index *p, u64 cksum){
int sqlite3Fts5IndexIntegrityCheck(Fts5Index *p, u64 cksum, int bUseCksum){
int eDetail = p->pConfig->eDetail;
u64 cksum2 = 0; /* Checksum based on contents of indexes */
Fts5Buffer poslist = {0,0,0}; /* Buffer used to hold a poslist */
@@ -6130,7 +6133,7 @@ int sqlite3Fts5IndexIntegrityCheck(Fts5Index *p, u64 cksum){
fts5TestTerm(p, &term, 0, 0, cksum2, &cksum3);
fts5MultiIterFree(pIter);
if( p->rc==SQLITE_OK && cksum!=cksum2 ) p->rc = FTS5_CORRUPT;
if( p->rc==SQLITE_OK && bUseCksum && cksum!=cksum2 ) p->rc = FTS5_CORRUPT;
fts5StructureRelease(pStruct);
#ifdef SQLITE_DEBUG
+80 -37
View File
@@ -464,6 +464,23 @@ static void fts5SetUniqueFlag(sqlite3_index_info *pIdxInfo){
#endif
}
static int fts5UsePatternMatch(
Fts5Config *pConfig,
struct sqlite3_index_constraint *p
){
assert( FTS5_PATTERN_GLOB==SQLITE_INDEX_CONSTRAINT_GLOB );
assert( FTS5_PATTERN_LIKE==SQLITE_INDEX_CONSTRAINT_LIKE );
if( pConfig->ePattern==FTS5_PATTERN_GLOB && p->op==FTS5_PATTERN_GLOB ){
return 1;
}
if( pConfig->ePattern==FTS5_PATTERN_LIKE
&& (p->op==FTS5_PATTERN_LIKE || p->op==FTS5_PATTERN_GLOB)
){
return 1;
}
return 0;
}
/*
** Implementation of the xBestIndex method for FTS5 tables. Within the
** WHERE constraint, it searches for the following:
@@ -493,7 +510,9 @@ static void fts5SetUniqueFlag(sqlite3_index_info *pIdxInfo){
**
** Match against table column: "m"
** Match against rank column: "r"
** Match against other column: "<column-number>"
** Match against other column: "M<column-number>"
** LIKE against other column: "L<column-number>"
** GLOB against other column: "G<column-number>"
** Equality constraint against the rowid: "="
** A < or <= against the rowid: "<"
** A > or >= against the rowid: ">"
@@ -554,7 +573,7 @@ static int fts5BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){
return SQLITE_ERROR;
}
idxStr = (char*)sqlite3_malloc(pInfo->nConstraint * 6 + 1);
idxStr = (char*)sqlite3_malloc(pInfo->nConstraint * 8 + 1);
if( idxStr==0 ) return SQLITE_NOMEM;
pInfo->idxStr = idxStr;
pInfo->needToFreeIdxStr = 1;
@@ -578,25 +597,29 @@ static int fts5BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){
if( bSeenRank ) continue;
idxStr[iIdxStr++] = 'r';
bSeenRank = 1;
}else{
}else if( iCol>=0 ){
bSeenMatch = 1;
idxStr[iIdxStr++] = 'm';
if( iCol<nCol ){
sqlite3_snprintf(6, &idxStr[iIdxStr], "%d", iCol);
idxStr += strlen(&idxStr[iIdxStr]);
assert( idxStr[iIdxStr]=='\0' );
}
idxStr[iIdxStr++] = 'M';
sqlite3_snprintf(6, &idxStr[iIdxStr], "%d", iCol);
idxStr += strlen(&idxStr[iIdxStr]);
assert( idxStr[iIdxStr]=='\0' );
}
pInfo->aConstraintUsage[i].argvIndex = ++iCons;
pInfo->aConstraintUsage[i].omit = 1;
}
}
else if( p->usable && bSeenEq==0
&& p->op==SQLITE_INDEX_CONSTRAINT_EQ && iCol<0
){
idxStr[iIdxStr++] = '=';
bSeenEq = 1;
pInfo->aConstraintUsage[i].argvIndex = ++iCons;
}else if( p->usable ){
if( iCol>=0 && iCol<nCol && fts5UsePatternMatch(pConfig, p) ){
assert( p->op==FTS5_PATTERN_LIKE || p->op==FTS5_PATTERN_GLOB );
idxStr[iIdxStr++] = p->op==FTS5_PATTERN_LIKE ? 'L' : 'G';
sqlite3_snprintf(6, &idxStr[iIdxStr], "%d", iCol);
idxStr += strlen(&idxStr[iIdxStr]);
pInfo->aConstraintUsage[i].argvIndex = ++iCons;
assert( idxStr[iIdxStr]=='\0' );
}else if( bSeenEq==0 && p->op==SQLITE_INDEX_CONSTRAINT_EQ && iCol<0 ){
idxStr[iIdxStr++] = '=';
bSeenEq = 1;
pInfo->aConstraintUsage[i].argvIndex = ++iCons;
}
}
}
@@ -1229,19 +1252,14 @@ static int fts5FilterMethod(
case 'r':
pRank = apVal[i];
break;
case 'm': {
case 'M': {
const char *zText = (const char*)sqlite3_value_text(apVal[i]);
if( zText==0 ) zText = "";
if( idxStr[iIdxStr]>='0' && idxStr[iIdxStr]<='9' ){
iCol = 0;
do{
iCol = iCol*10 + (idxStr[iIdxStr]-'0');
iIdxStr++;
}while( idxStr[iIdxStr]>='0' && idxStr[iIdxStr]<='9' );
}else{
iCol = pConfig->nCol;
}
iCol = 0;
do{
iCol = iCol*10 + (idxStr[iIdxStr]-'0');
iIdxStr++;
}while( idxStr[iIdxStr]>='0' && idxStr[iIdxStr]<='9' );
if( zText[0]=='*' ){
/* The user has issued a query of the form "MATCH '*...'". This
@@ -1251,7 +1269,7 @@ static int fts5FilterMethod(
goto filter_out;
}else{
char **pzErr = &pTab->p.base.zErrMsg;
rc = sqlite3Fts5ExprNew(pConfig, iCol, zText, &pExpr, pzErr);
rc = sqlite3Fts5ExprNew(pConfig, 0, iCol, zText, &pExpr, pzErr);
if( rc==SQLITE_OK ){
rc = sqlite3Fts5ExprAnd(&pCsr->pExpr, pExpr);
pExpr = 0;
@@ -1261,6 +1279,25 @@ static int fts5FilterMethod(
break;
}
case 'L':
case 'G': {
int bGlob = (idxStr[iIdxStr-1]=='G');
const char *zText = (const char*)sqlite3_value_text(apVal[i]);
iCol = 0;
do{
iCol = iCol*10 + (idxStr[iIdxStr]-'0');
iIdxStr++;
}while( idxStr[iIdxStr]>='0' && idxStr[iIdxStr]<='9' );
if( zText ){
rc = sqlite3Fts5ExprPattern(pConfig, bGlob, iCol, zText, &pExpr);
}
if( rc==SQLITE_OK ){
rc = sqlite3Fts5ExprAnd(&pCsr->pExpr, pExpr);
pExpr = 0;
}
if( rc!=SQLITE_OK ) goto filter_out;
break;
}
case '=':
pRowidEq = apVal[i];
break;
@@ -1508,7 +1545,8 @@ static int fts5SpecialInsert(
int nMerge = sqlite3_value_int(pVal);
rc = sqlite3Fts5StorageMerge(pTab->pStorage, nMerge);
}else if( 0==sqlite3_stricmp("integrity-check", zCmd) ){
rc = sqlite3Fts5StorageIntegrity(pTab->pStorage);
int iArg = sqlite3_value_int(pVal);
rc = sqlite3Fts5StorageIntegrity(pTab->pStorage, iArg);
#ifdef SQLITE_DEBUG
}else if( 0==sqlite3_stricmp("prefix-index", zCmd) ){
pConfig->bPrefixIndex = sqlite3_value_int(pVal);
@@ -2671,8 +2709,7 @@ int sqlite3Fts5GetTokenizer(
Fts5Global *pGlobal,
const char **azArg,
int nArg,
Fts5Tokenizer **ppTok,
fts5_tokenizer **ppTokApi,
Fts5Config *pConfig,
char **pzErr
){
Fts5TokenizerModule *pMod;
@@ -2684,16 +2721,22 @@ int sqlite3Fts5GetTokenizer(
rc = SQLITE_ERROR;
*pzErr = sqlite3_mprintf("no such tokenizer: %s", azArg[0]);
}else{
rc = pMod->x.xCreate(pMod->pUserData, &azArg[1], (nArg?nArg-1:0), ppTok);
*ppTokApi = &pMod->x;
if( rc!=SQLITE_OK && pzErr ){
*pzErr = sqlite3_mprintf("error in tokenizer constructor");
rc = pMod->x.xCreate(
pMod->pUserData, &azArg[1], (nArg?nArg-1:0), &pConfig->pTok
);
pConfig->pTokApi = &pMod->x;
if( rc!=SQLITE_OK ){
if( pzErr ) *pzErr = sqlite3_mprintf("error in tokenizer constructor");
}else{
pConfig->ePattern = sqlite3Fts5TokenizerPattern(
pMod->x.xCreate, pConfig->pTok
);
}
}
if( rc!=SQLITE_OK ){
*ppTokApi = 0;
*ppTok = 0;
pConfig->pTokApi = 0;
pConfig->pTok = 0;
}
return rc;
+78 -65
View File
@@ -429,9 +429,16 @@ static int fts5StorageDeleteFromIndex(
zText, nText, (void*)&ctx, fts5StorageInsertCallback
);
p->aTotalSize[iCol-1] -= (i64)ctx.szCol;
if( p->aTotalSize[iCol-1]<0 ){
rc = FTS5_CORRUPT;
}
}
}
p->nTotalRow--;
if( rc==SQLITE_OK && p->nTotalRow<1 ){
rc = FTS5_CORRUPT;
}else{
p->nTotalRow--;
}
rc2 = sqlite3_reset(pSeek);
if( rc==SQLITE_OK ) rc = rc2;
@@ -874,13 +881,14 @@ static int fts5StorageIntegrityCallback(
** some other SQLite error code if an error occurs while attempting to
** determine this.
*/
int sqlite3Fts5StorageIntegrity(Fts5Storage *p){
int sqlite3Fts5StorageIntegrity(Fts5Storage *p, int iArg){
Fts5Config *pConfig = p->pConfig;
int rc; /* Return code */
int rc = SQLITE_OK; /* Return code */
int *aColSize; /* Array of size pConfig->nCol */
i64 *aTotalSize; /* Array of size pConfig->nCol */
Fts5IntegrityCtx ctx;
sqlite3_stmt *pScan;
int bUseCksum;
memset(&ctx, 0, sizeof(Fts5IntegrityCtx));
ctx.pConfig = p->pConfig;
@@ -889,83 +897,88 @@ int sqlite3Fts5StorageIntegrity(Fts5Storage *p){
aColSize = (int*)&aTotalSize[pConfig->nCol];
memset(aTotalSize, 0, sizeof(i64) * pConfig->nCol);
/* Generate the expected index checksum based on the contents of the
** %_content table. This block stores the checksum in ctx.cksum. */
rc = fts5StorageGetStmt(p, FTS5_STMT_SCAN, &pScan, 0);
if( rc==SQLITE_OK ){
int rc2;
while( SQLITE_ROW==sqlite3_step(pScan) ){
int i;
ctx.iRowid = sqlite3_column_int64(pScan, 0);
ctx.szCol = 0;
if( pConfig->bColumnsize ){
rc = sqlite3Fts5StorageDocsize(p, ctx.iRowid, aColSize);
}
if( rc==SQLITE_OK && pConfig->eDetail==FTS5_DETAIL_NONE ){
rc = sqlite3Fts5TermsetNew(&ctx.pTermset);
}
for(i=0; rc==SQLITE_OK && i<pConfig->nCol; i++){
if( pConfig->abUnindexed[i] ) continue;
ctx.iCol = i;
bUseCksum = (pConfig->eContent==FTS5_CONTENT_NORMAL
|| (pConfig->eContent==FTS5_CONTENT_EXTERNAL && iArg)
);
if( bUseCksum ){
/* Generate the expected index checksum based on the contents of the
** %_content table. This block stores the checksum in ctx.cksum. */
rc = fts5StorageGetStmt(p, FTS5_STMT_SCAN, &pScan, 0);
if( rc==SQLITE_OK ){
int rc2;
while( SQLITE_ROW==sqlite3_step(pScan) ){
int i;
ctx.iRowid = sqlite3_column_int64(pScan, 0);
ctx.szCol = 0;
if( pConfig->eDetail==FTS5_DETAIL_COLUMNS ){
if( pConfig->bColumnsize ){
rc = sqlite3Fts5StorageDocsize(p, ctx.iRowid, aColSize);
}
if( rc==SQLITE_OK && pConfig->eDetail==FTS5_DETAIL_NONE ){
rc = sqlite3Fts5TermsetNew(&ctx.pTermset);
}
if( rc==SQLITE_OK ){
const char *zText = (const char*)sqlite3_column_text(pScan, i+1);
int nText = sqlite3_column_bytes(pScan, i+1);
rc = sqlite3Fts5Tokenize(pConfig,
FTS5_TOKENIZE_DOCUMENT,
zText, nText,
(void*)&ctx,
fts5StorageIntegrityCallback
);
}
if( rc==SQLITE_OK && pConfig->bColumnsize && ctx.szCol!=aColSize[i] ){
rc = FTS5_CORRUPT;
}
aTotalSize[i] += ctx.szCol;
if( pConfig->eDetail==FTS5_DETAIL_COLUMNS ){
sqlite3Fts5TermsetFree(ctx.pTermset);
ctx.pTermset = 0;
for(i=0; rc==SQLITE_OK && i<pConfig->nCol; i++){
if( pConfig->abUnindexed[i] ) continue;
ctx.iCol = i;
ctx.szCol = 0;
if( pConfig->eDetail==FTS5_DETAIL_COLUMNS ){
rc = sqlite3Fts5TermsetNew(&ctx.pTermset);
}
if( rc==SQLITE_OK ){
const char *zText = (const char*)sqlite3_column_text(pScan, i+1);
int nText = sqlite3_column_bytes(pScan, i+1);
rc = sqlite3Fts5Tokenize(pConfig,
FTS5_TOKENIZE_DOCUMENT,
zText, nText,
(void*)&ctx,
fts5StorageIntegrityCallback
);
}
if( rc==SQLITE_OK && pConfig->bColumnsize && ctx.szCol!=aColSize[i] ){
rc = FTS5_CORRUPT;
}
aTotalSize[i] += ctx.szCol;
if( pConfig->eDetail==FTS5_DETAIL_COLUMNS ){
sqlite3Fts5TermsetFree(ctx.pTermset);
ctx.pTermset = 0;
}
}
sqlite3Fts5TermsetFree(ctx.pTermset);
ctx.pTermset = 0;
if( rc!=SQLITE_OK ) break;
}
sqlite3Fts5TermsetFree(ctx.pTermset);
ctx.pTermset = 0;
if( rc!=SQLITE_OK ) break;
rc2 = sqlite3_reset(pScan);
if( rc==SQLITE_OK ) rc = rc2;
}
rc2 = sqlite3_reset(pScan);
if( rc==SQLITE_OK ) rc = rc2;
}
/* Test that the "totals" (sometimes called "averages") record looks Ok */
if( rc==SQLITE_OK ){
int i;
rc = fts5StorageLoadTotals(p, 0);
for(i=0; rc==SQLITE_OK && i<pConfig->nCol; i++){
if( p->aTotalSize[i]!=aTotalSize[i] ) rc = FTS5_CORRUPT;
/* Test that the "totals" (sometimes called "averages") record looks Ok */
if( rc==SQLITE_OK ){
int i;
rc = fts5StorageLoadTotals(p, 0);
for(i=0; rc==SQLITE_OK && i<pConfig->nCol; i++){
if( p->aTotalSize[i]!=aTotalSize[i] ) rc = FTS5_CORRUPT;
}
}
}
/* Check that the %_docsize and %_content tables contain the expected
** number of rows. */
if( rc==SQLITE_OK && pConfig->eContent==FTS5_CONTENT_NORMAL ){
i64 nRow = 0;
rc = fts5StorageCount(p, "content", &nRow);
if( rc==SQLITE_OK && nRow!=p->nTotalRow ) rc = FTS5_CORRUPT;
}
if( rc==SQLITE_OK && pConfig->bColumnsize ){
i64 nRow = 0;
rc = fts5StorageCount(p, "docsize", &nRow);
if( rc==SQLITE_OK && nRow!=p->nTotalRow ) rc = FTS5_CORRUPT;
/* Check that the %_docsize and %_content tables contain the expected
** number of rows. */
if( rc==SQLITE_OK && pConfig->eContent==FTS5_CONTENT_NORMAL ){
i64 nRow = 0;
rc = fts5StorageCount(p, "content", &nRow);
if( rc==SQLITE_OK && nRow!=p->nTotalRow ) rc = FTS5_CORRUPT;
}
if( rc==SQLITE_OK && pConfig->bColumnsize ){
i64 nRow = 0;
rc = fts5StorageCount(p, "docsize", &nRow);
if( rc==SQLITE_OK && nRow!=p->nTotalRow ) rc = FTS5_CORRUPT;
}
}
/* Pass the expected checksum down to the FTS index module. It will
** verify, amongst other things, that it matches the checksum generated by
** inspecting the index itself. */
if( rc==SQLITE_OK ){
rc = sqlite3Fts5IndexIntegrityCheck(p->pIndex, ctx.cksum);
rc = sqlite3Fts5IndexIntegrityCheck(p->pIndex, ctx.cksum, bUseCksum);
}
sqlite3_free(aTotalSize);
+126
View File
@@ -1258,6 +1258,131 @@ static int fts5PorterTokenize(
);
}
/**************************************************************************
** Start of trigram implementation.
*/
typedef struct TrigramTokenizer TrigramTokenizer;
struct TrigramTokenizer {
int bFold; /* True to fold to lower-case */
};
/*
** Free a trigram tokenizer.
*/
static void fts5TriDelete(Fts5Tokenizer *p){
sqlite3_free(p);
}
/*
** Allocate a trigram tokenizer.
*/
static int fts5TriCreate(
void *pCtx,
const char **azArg,
int nArg,
Fts5Tokenizer **ppOut
){
int rc = SQLITE_OK;
TrigramTokenizer *pNew = (TrigramTokenizer*)sqlite3_malloc(sizeof(*pNew));
if( pNew==0 ){
rc = SQLITE_NOMEM;
}else{
int i;
pNew->bFold = 1;
for(i=0; rc==SQLITE_OK && i<nArg; i+=2){
const char *zArg = azArg[i+1];
if( 0==sqlite3_stricmp(azArg[i], "case_sensitive") ){
if( (zArg[0]!='0' && zArg[0]!='1') || zArg[1] ){
rc = SQLITE_ERROR;
}else{
pNew->bFold = (zArg[0]=='0');
}
}else{
rc = SQLITE_ERROR;
}
}
if( rc!=SQLITE_OK ){
fts5TriDelete((Fts5Tokenizer*)pNew);
pNew = 0;
}
}
*ppOut = (Fts5Tokenizer*)pNew;
return rc;
}
/*
** Trigram tokenizer tokenize routine.
*/
static int fts5TriTokenize(
Fts5Tokenizer *pTok,
void *pCtx,
int flags,
const char *pText, int nText,
int (*xToken)(void*, int, const char*, int, int, int)
){
TrigramTokenizer *p = (TrigramTokenizer*)pTok;
int rc = SQLITE_OK;
char aBuf[32];
const unsigned char *zIn = (const unsigned char*)pText;
const unsigned char *zEof = &zIn[nText];
u32 iCode;
while( 1 ){
char *zOut = aBuf;
int iStart = zIn - (const unsigned char*)pText;
const unsigned char *zNext;
READ_UTF8(zIn, zEof, iCode);
if( iCode==0 ) break;
zNext = zIn;
if( zIn<zEof ){
if( p->bFold ) iCode = sqlite3Fts5UnicodeFold(iCode, 0);
WRITE_UTF8(zOut, iCode);
READ_UTF8(zIn, zEof, iCode);
if( iCode==0 ) break;
}else{
break;
}
if( zIn<zEof ){
if( p->bFold ) iCode = sqlite3Fts5UnicodeFold(iCode, 0);
WRITE_UTF8(zOut, iCode);
READ_UTF8(zIn, zEof, iCode);
if( iCode==0 ) break;
if( p->bFold ) iCode = sqlite3Fts5UnicodeFold(iCode, 0);
WRITE_UTF8(zOut, iCode);
}else{
break;
}
rc = xToken(pCtx, 0, aBuf, zOut-aBuf, iStart, iStart + zOut-aBuf);
if( rc!=SQLITE_OK ) break;
zIn = zNext;
}
return rc;
}
/*
** Argument xCreate is a pointer to a constructor function for a tokenizer.
** pTok is a tokenizer previously created using the same method. This function
** returns one of FTS5_PATTERN_NONE, FTS5_PATTERN_LIKE or FTS5_PATTERN_GLOB
** indicating the style of pattern matching that the tokenizer can support.
** In practice, this is:
**
** "trigram" tokenizer, case_sensitive=1 - FTS5_PATTERN_GLOB
** "trigram" tokenizer, case_sensitive=0 (the default) - FTS5_PATTERN_LIKE
** all other tokenizers - FTS5_PATTERN_NONE
*/
int sqlite3Fts5TokenizerPattern(
int (*xCreate)(void*, const char**, int, Fts5Tokenizer**),
Fts5Tokenizer *pTok
){
if( xCreate==fts5TriCreate ){
TrigramTokenizer *p = (TrigramTokenizer*)pTok;
return p->bFold ? FTS5_PATTERN_LIKE : FTS5_PATTERN_GLOB;
}
return FTS5_PATTERN_NONE;
}
/*
** Register all built-in tokenizers with FTS5.
*/
@@ -1269,6 +1394,7 @@ int sqlite3Fts5TokenizerInit(fts5_api *pApi){
{ "unicode61", {fts5UnicodeCreate, fts5UnicodeDelete, fts5UnicodeTokenize}},
{ "ascii", {fts5AsciiCreate, fts5AsciiDelete, fts5AsciiTokenize }},
{ "porter", {fts5PorterCreate, fts5PorterDelete, fts5PorterTokenize }},
{ "trigram", {fts5TriCreate, fts5TriDelete, fts5TriTokenize}},
};
int rc = SQLITE_OK; /* Return code */
+1
View File
@@ -773,4 +773,5 @@ void sqlite3Fts5UnicodeAscii(u8 *aArray, u8 *aAscii){
}
iTbl++;
}
aAscii[0] = 0; /* 0x00 is never a token character */
}
+19
View File
@@ -82,5 +82,24 @@ foreach_detail_mode $::testprefix {
} {1 {unable to use function MATCH in the requested context}}
}
#-------------------------------------------------------------------------
# Confirm that the expression parser creates the same expression tree
# for:
#
# {a b} : (abc AND def)
# -{c d} : (abc AND def)
#
# Assuming that the table columns are (a, b, c, d).
#
do_execsql_test 5.1 {
SELECT fts5_expr('abcd AND cdef');
} {{"abcd" AND "cdef"}}
do_execsql_test 5.2 {
SELECT fts5_expr('{a b} : (abcd AND cdef)', 'a', 'b', 'c', 'd');
} {{{a b} : "abcd" AND {a b} : "cdef"}}
do_execsql_test 5.3 {
SELECT fts5_expr('-{c d} : (abcd AND cdef)', 'a', 'b', 'c', 'd');
} {{{a b} : "abcd" AND {a b} : "cdef"}}
finish_test
+104 -1
View File
@@ -9691,7 +9691,7 @@ do_test 65.0 {
do_catchsql_test 65.1 {
SELECT ( MATCH (t1,591)) FROM t1 WHERE t1 MATCH 'e*eŸ'
} {1 {database disk image is malformed}}
} {1 {malformed database schema (t2) - invalid rootpage}}
#-------------------------------------------------------------------------
#
@@ -10324,6 +10324,109 @@ do_catchsql_test 69.2 {
SELECT * FROM t1 WHERE a MATCH 'fx*'
} {1 {database disk image is malformed}}
#-------------------------------------------------------------------------
reset_db
do_test 70.0 {
sqlite3 db {}
db deserialize [decode_hexdb {
.open --hexdb
| size 24576 pagesize 4096 filename sql022250.txt.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 00 00 00 06 0d e2 00 0f c4 0f 6a ...............j
| 112: 0e fc 0e 9d 0e 3d 0d e2 00 00 00 00 00 00 00 00 .....=..........
| 3552: 00 00 59 06 06 17 21 21 01 7f 74 61 62 6c 65 74 ..Y...!!..tablet
| 3568: 74 74 5f 63 6f 6e 66 69 67 74 74 74 5f 63 6f 6e tt_configttt_con
| 3584: 66 69 67 06 43 52 45 41 54 45 20 54 41 42 4c 45 fig.CREATE TABLE
| 3600: 20 27 74 74 74 5f 63 6f 6e 66 69 67 27 28 6b 20 'ttt_config'(k
| 3616: 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 76 29 20 PRIMARY KEY, v)
| 3632: 57 49 54 48 4f 55 54 20 52 4f 57 49 44 5e 15 07 WITHOUT ROWID^..
| 3648: 17 23 23 01 81 03 74 61 62 6c 65 74 74 74 5f 64 .##...tablettt_d
| 3664: 6f 63 73 69 7a 65 74 74 74 5f 64 6f 63 73 69 7a ocsizettt_docsiz
| 3680: 65 05 43 52 45 41 54 45 20 54 41 42 4c 45 20 27 e.CREATE TABLE '
| 3696: 74 74 74 5f 64 6f 63 73 69 7a 65 27 28 69 64 20 ttt_docsize'(id
| 3712: 49 4d 54 45 47 45 52 20 50 52 49 4d 41 52 59 20 IMTEGER PRIMARY
| 3728: 4b 45 59 2c 20 73 7a 20 42 4c 4f 20 29 5d 04 07 KEY, sz BLO )]..
| 3744: 17 23 23 01 81 01 74 61 62 6c 65 74 74 74 5f 63 .##...tablettt_c
| 3760: 6f 6e 74 65 6e 74 74 74 74 5f 63 6f 6e 74 65 6e ontentttt_conten
| 3776: 74 04 43 52 45 41 54 45 20 54 41 42 4c 45 20 27 t.CREATE TABLE '
| 3792: 74 74 74 5f 63 6f 6e 74 65 6e 74 27 28 69 64 20 ttt_content'(id
| 3808: 49 4e 54 45 47 45 52 20 50 52 49 4d 41 52 59 20 INTEGER PRIMARY
| 3824: 4b 45 59 2c 20 63 30 2c 20 63 31 29 6c 03 07 17 KEY, c0, c1)l...
| 3840: 1b 1b 01 81 2f 74 61 62 6c 65 74 74 74 5f 69 64 ..../tablettt_id
| 3856: 78 74 74 74 5f 69 64 78 03 43 52 45 41 54 45 20 xttt_idx.CREATE
| 3872: 54 41 42 4c 45 20 27 74 74 74 5f 69 64 78 27 28 TABLE 'ttt_idx'(
| 3888: 73 65 67 69 64 2c 20 74 65 72 6d 2c 20 70 67 6e segid, term, pgn
| 3904: 6f 2c 20 50 52 49 4d 41 52 59 20 4b 45 59 28 73 o, PRIMARY KEY(s
| 3920: 65 67 69 64 2c 20 74 65 72 6d 29 29 20 57 49 54 egid, term)) WIT
| 3936: 48 4f 55 54 20 52 4f 57 49 44 58 02 07 17 1d 1d HOUT ROWIDX.....
| 3952: 01 81 03 74 61 62 6c 65 74 74 74 5f 64 61 74 61 ...tablettt_data
| 3968: 74 74 74 5f 64 61 74 61 02 43 52 45 41 54 45 20 ttt_data.CREATE
| 3984: 54 41 42 4c 45 20 27 74 74 74 5f 64 61 74 61 27 TABLE 'ttt_data'
| 4000: 28 69 64 20 49 4e 54 45 47 45 52 20 50 52 49 4d (id INTEGER PRIM
| 4016: 41 52 59 20 4b 45 59 2c 20 62 6c 6f 63 6b 20 42 ARY KEY, block B
| 4032: 4c 4f 42 29 3a 01 06 17 13 13 08 5f 74 61 62 6c LOB):......_tabl
| 4048: 65 74 74 74 74 74 74 43 52 45 41 54 45 20 56 49 ettttttCREATE VI
| 4064: 52 54 55 41 4c 20 54 41 42 4c 45 20 74 74 74 20 RTUAL TABLE ttt
| 4080: 55 53 49 4e 47 20 66 74 73 35 28 61 2c 20 62 29 USING fts5(a, b)
| page 2 offset 4096
| 0: 0d 0f 54 00 05 0e 81 00 0f e7 0e 81 0f af 0f 58 ..T............X
| 16: 0e 98 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
| 3712: 00 15 0a 03 00 30 00 00 00 00 01 03 03 00 03 01 .....0..........
| 3728: 01 01 02 01 01 03 01 01 81 24 8c 80 80 80 80 01 .........$......
| 3744: 04 00 82 4c 00 00 00 9b 02 30 65 03 1a 02 05 05 ...L.....0e.....
| 3760: 07 05 01 01 04 03 03 08 03 03 01 2e 02 05 05 07 ................
| 3776: 05 07 05 07 05 01 01 14 03 03 08 03 03 08 03 bf ................
| 3792: 07 f2 f3 02 01 65 03 1e 03 05 05 04 05 05 01 01 .....e..........
| 3808: 03 06 04 04 06 04 03 01 36 03 05 05 04 05 05 04 ........6.......
| 3824: 05 15 04 05 05 01 01 03 06 04 04 06 04 04 a1 04 ................
| 3840: 04 06 04 03 03 01 65 03 14 04 05 07 05 05 01 01 ......e.........
| 3856: 02 09 0a 01 20 04 05 07 05 07 05 07 05 05 01 01 .... ...........
| 3872: 02 0f da 0a 0a 04 01 64 f3 02 0a 01 06 0a 0a 0a .......d........
| 3888: 05 01 65 03 06 01 01 0a 01 0a 01 01 0a 0a 0a 04 ..e.............
| 3904: 2b 31 21 0b 0f ef 00 14 2a 00 00 00 00 01 02 02 +1!.....*.......
| 3920: 00 02 01 01 01 02 01 01 50 88 80 80 80 80 01 04 ........P.......
| 3936: 00 81 24 00 00 00 47 01 30 65 02 1a 02 05 05 07 ..$...G.0e......
| 3952: 05 01 01 04 03 03 08 03 03 02 01 65 02 1d f3 05 ...........e....
| 3968: 05 04 05 05 01 01 04 06 04 04 06 04 03 03 01 65 ...............e
| 3984: 02 14 04 05 07 05 05 01 01 02 08 0a 04 01 65 02 ..............e.
| 4000: 02 0a 05 01 65 02 06 01 01 0a 04 12 14 0f 06 31 ....e..........1
| 4016: 84 80 80 80 80 01 03 00 68 00 00 00 2b 02 30 65 ........h...+.0e
| 4032: 01 10 02 05 05 01 01 04 03 03 02 01 66 01 12 03 ............f...
| 4048: 05 05 01 01 03 06 04 03 03 01 65 01 0e 04 05 05 ..........e.....
| 4064: 01 01 02 08 04 0d 0e 06 01 03 00 12 04 4c 4c 00 .............LL.
| 4080: 00 00 11 24 00 00 00 00 01 01 01 00 01 01 01 01 ...$............
| page 3 offset 8192
| 0: 0a 2f 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ./..............
| page 4 offset 12288
| 3344: 00 00 00 00 00 00 00 00 00 00 81 52 04 06 10 81 ...........R....
| 3360: 5d 81 55 65 20 65 65 20 65 65 65 20 65 20 65 65 ].Ue ee eee e ee
| 3376: 20 65 65 65 20 65 20 65 65 20 65 65 65 65 20 65 eee e ee eeee e
| 3392: 65 20 65 65 65 24 a5 20 65 65 20 65 65 65 20 65 e eee$. ee eee e
| 3408: 24 05 65 20 65 65 65 65 20 65 65 20 65 65 65 20 $.e eeee ee eee
| 3424: 65 20 65 65 20 65 65 65 20 65 20 65 65 20 65 65 e ee eee e ee ee
| 3440: 65 65 20 65 65 20 65 65 65 20 65 20 65 65 10 65 ee ee eee e ee.e
| 3456: 65 65 20 65 20 65 65 20 65 65 65 65 65 65 20 65 ee e ee eeeeee e
| 3472: 65 20 65 20 65 20 65 20 65 65 20 65 65 65 20 65 e e e e ee eee e
| 3488: 1f 20 65 65 66 65 65 20 65 65 20 65 20 65 20 2d . eefee ee e e -
| page 5 offset 16384
| 4064: 00 00 00 00 05 04 d0 00 10 21 21 05 03 03 00 10 .........!!.....
| 4080: 11 11 05 02 03 00 10 11 10 05 01 03 00 10 09 09 ................
| page 6 offset 20480
| 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.
| end sql022250.txt.db
}]} {}
do_catchsql_test 70.1 {
SELECT snippet(ttt, -1, '', '','','>')FROM ttt('e* NOT ee*e* NOT ee*');
} {1 {database disk image is malformed}}
do_catchsql_test 70.2 {
SELECT snippet(ttt, -1, '', '','',13)FROM ttt('e* NOT ee*e* NOT ee*')
} {1 {database disk image is malformed}}
sqlite3_fts5_may_be_corrupt 0
finish_test
+43
View File
@@ -50,4 +50,47 @@ do_test 1.2 {
}
} {}
#-------------------------------------------------------------------------
reset_db
do_execsql_test 2.0 {
CREATE TABLE test (
id INTEGER PRIMARY KEY,
name TEXT,
value TEXT
);
CREATE VIRTUAL TABLE test_idx USING fts5(
name, content=test, content_rowid=id
);
}
do_catchsql_test 2.1 {
INSERT INTO test_idx (test_idx, rowid, name) VALUES('delete', 1, 'quick');
} {1 {database disk image is malformed}}
do_catchsql_test 2.2 {
INSERT INTO test_idx(rowid, name) VALUES(123, 'one one one');
INSERT INTO test_idx (test_idx, rowid, name) VALUES('delete', 123, 'one');
INSERT INTO test_idx (test_idx, rowid, name) VALUES('delete', 123, 'one');
} {1 {database disk image is malformed}}
do_execsql_test 2.3 {
DROP TABLE test_idx;
CREATE VIRTUAL TABLE test_idx USING fts5(
name, content=test, content_rowid=id
);
INSERT INTO test_idx(rowid, name) VALUES(123, 'one one one');
INSERT INTO test_idx(rowid, name) VALUES(124, 'two two two');
INSERT INTO test_idx(rowid, name) VALUES(125, 'two two two');
INSERT INTO test_idx (test_idx, rowid, name) VALUES('delete', 123, 'one');
INSERT INTO test_idx (test_idx, rowid, name) VALUES('delete', 123, 'one');
INSERT INTO test_idx (test_idx, rowid, name) VALUES('delete', 123, 'one');
}
do_catchsql_test 2.4 {
SELECT rowid FROM test_idx WHERE test_idx MATCH 'two' ORDER BY rank;
} {1 {database disk image is malformed}}
finish_test
+1 -1
View File
@@ -14,7 +14,7 @@
source [file join [file dirname [info script]] fts5_common.tcl]
source $testdir/malloc_common.tcl
set testprefix fts5faultA
set testprefix fts5faultD
# If SQLITE_ENABLE_FTS3 is defined, omit this file.
ifcapable !fts5 {
+71
View File
@@ -0,0 +1,71 @@
# 2016 February 2
#
# 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 is focused on OOM errors.
#
source [file join [file dirname [info script]] fts5_common.tcl]
source $testdir/malloc_common.tcl
set testprefix fts5faultE
# If SQLITE_ENABLE_FTS5 is not defined, omit this file.
ifcapable !fts5 {
finish_test
return
}
faultsim_save_and_close
do_faultsim_test 1 -prep {
faultsim_restore_and_reopen
} -body {
execsql { CREATE VIRTUAL TABLE t1 USING fts5(x, y, tokenize=trigram) }
} -test {
faultsim_test_result {0 {}} {1 {vtable constructor failed: t1}}
}
reset_db
do_execsql_test 2.0 {
CREATE VIRTUAL TABLE t1 USING fts5(x, y, tokenize=trigram);
}
faultsim_save_and_close
do_faultsim_test 2 -prep {
faultsim_restore_and_reopen
} -body {
execsql {
INSERT INTO t1 VALUES('abcdefghijklmnopqrstuvwxyz', NULL);
SELECT count(*) FROM t1 WHERE x LIKE '%mnop%' AND t1 MATCH 'jkl';
}
} -test {
faultsim_test_result {0 1} {1 {vtable constructor failed: t1}}
}
reset_db
do_execsql_test 3.0 {
CREATE VIRTUAL TABLE t1 USING fts5(x, y, tokenize=trigram, detail=none);
INSERT INTO t1 VALUES('abcdefghijklmnopqrstuvwxyz', NULL);
}
faultsim_save_and_close
do_faultsim_test 3 -prep {
faultsim_restore_and_reopen
} -body {
execsql {
SELECT count(*) FROM t1 WHERE x LIKE '%mnopqrs%' AND t1 MATCH 'abc'
}
} -test {
faultsim_test_result {0 1} {1 {vtable constructor failed: t1}}
}
finish_test
+38 -1
View File
@@ -112,7 +112,7 @@ foreach_detail_mode $testprefix {
# Add a small and very large token with the same hash value to an
# empty table. At one point this would provoke an asan error.
#
do_test 2.0 {
do_test 1.5 {
set big [string repeat 12345 40]
set hash [sqlite3_fts5_token_hash 1024 $big]
while {1} {
@@ -128,4 +128,41 @@ foreach_detail_mode $testprefix {
} ;# foreach_detail_mode
#-------------------------------------------------------------------------
reset_db
do_execsql_test 2.1 {
CREATE VIRTUAL TABLE t1 USING fts5(x);
INSERT INTO t1(t1, rank) VALUES('hashsize', 1024);
INSERT INTO t1(t1, rank) VALUES('automerge', 0);
INSERT INTO t1(t1, rank) VALUES('crisismerge', 1000);
}
do_execsql_test 2.2 {
BEGIN;
INSERT INTO t1 VALUES('abc def ghi');
SELECT count(*) FROM t1_data;
} {2}
do_execsql_test 2.3 {
WITH s(i) AS (
SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<1024
)
INSERT INTO t1 SELECT 'abc def ghi' FROM s;
SELECT (SELECT count(*) FROM t1_data) > 10;
} {1}
do_execsql_test 2.4 {
COMMIT;
DROP TABLE t1;
CREATE VIRTUAL TABLE t1 USING fts5(x);
INSERT INTO t1(t1, rank) VALUES('hashsize', 1024);
INSERT INTO t1(t1, rank) VALUES('automerge', 0);
INSERT INTO t1(t1, rank) VALUES('crisismerge', 1000);
WITH s(i) AS (
SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<1024
)
INSERT INTO t1 SELECT 'abc' || i || ' def' || i || ' ghi' || i FROM s;
SELECT (SELECT count(*) FROM t1_data) > 100;
} {1}
finish_test
+36 -1
View File
@@ -273,7 +273,6 @@ do_execsql_test 9.1.2 {
SELECT quote(x'37');
} {X'37'}
breakpoint
do_execsql_test 9.2 {
INSERT INTO vt0 VALUES (SUBSTR(x'37', 0));
-- INSERT INTO vt0 VALUES (x'37');
@@ -282,4 +281,40 @@ do_execsql_test 9.3 {
INSERT INTO vt0(vt0) VALUES('integrity-check');
}
#-------------------------------------------------------------------------
reset_db
do_execsql_test 10.0 {
CREATE TABLE t1(i INTEGER PRIMARY KEY, a, b);
CREATE VIRTUAL TABLE vt0 USING fts5(a, b, content=t1);
INSERT INTO vt0(rowid, a, b) VALUES(1, 'abc', 'def');
}
do_catchsql_test 10.1 {
INSERT INTO vt0(vt0) VALUES('integrity-check');
} {0 {}}
do_catchsql_test 10.2 {
INSERT INTO vt0(vt0, rank) VALUES('integrity-check', 0);
} {0 {}}
do_catchsql_test 10.3 {
INSERT INTO vt0(vt0, rank) VALUES('integrity-check', 1);
} {1 {database disk image is malformed}}
do_catchsql_test 10.3 {
INSERT INTO t1 VALUES(1, 'abc', 'def');
INSERT INTO vt0(vt0, rank) VALUES('integrity-check', 1);
} {0 {}}
do_execsql_test 10.4 {
CREATE VIRTUAL TABLE vt1 USING fts5(a, b, content=);
INSERT INTO vt1(rowid, a, b) VALUES(1, 'abc', 'def');
}
do_catchsql_test 10.5.1 {
INSERT INTO vt0(vt0, rank) VALUES('integrity-check', 0);
} {0 {}}
do_catchsql_test 10.5.2 {
INSERT INTO vt0(vt0, rank) VALUES('integrity-check', 1);
} {0 {}}
do_catchsql_test 10.5.3 {
INSERT INTO vt0(vt0) VALUES('integrity-check');
} {0 {}}
finish_test
+2 -2
View File
@@ -31,7 +31,7 @@ do_eqp_test 1.1 {
} {
QUERY PLAN
|--SCAN TABLE t1
`--SCAN TABLE f1 VIRTUAL TABLE INDEX 0:m
`--SCAN TABLE f1 VIRTUAL TABLE INDEX 0:M1
}
do_eqp_test 1.2 {
@@ -46,7 +46,7 @@ do_eqp_test 1.3 {
SELECT * FROM f1 WHERE f1 MATCH ? ORDER BY ff
} {
QUERY PLAN
|--SCAN TABLE f1 VIRTUAL TABLE INDEX 0:m
|--SCAN TABLE f1 VIRTUAL TABLE INDEX 0:M1
`--USE TEMP B-TREE FOR ORDER BY
}
+35
View File
@@ -111,5 +111,40 @@ do_catchsql_test 2.1 {
SELECT * FROM t4;
} {1 {SQL logic error}}
#-------------------------------------------------------------------------
# Embedded 0x00 characters.
#
reset_db
do_execsql_test 3.1.0 {
CREATE VIRTUAL TABLE t1 USING fts5(z);
CREATE VIRTUAL TABLE tt USING fts5vocab(t1, 'instance');
INSERT INTO t1 VALUES('abc' || char(0) || 'def');
SELECT * FROM tt;
} { abc 1 z 0 def 1 z 1 }
do_execsql_test 3.1.1 {
SELECT hex(z) FROM t1;
} {61626300646566}
do_execsql_test 3.1.2 {
INSERT INTO t1(t1) VALUES('integrity-check');
} {}
do_execsql_test 3.2.0 {
CREATE VIRTUAL TABLE t2 USING fts5(z,
tokenize="unicode61 categories 'L* N* Co Cc'"
);
CREATE VIRTUAL TABLE tu USING fts5vocab(t2, 'instance');
INSERT INTO t2 VALUES('abc' || char(0) || 'def');
SELECT * FROM tu;
} { abc 1 z 0 def 1 z 1 }
do_execsql_test 3.2.1 {
SELECT hex(z) FROM t1;
} {61626300646566}
do_execsql_test 3.2.2 {
INSERT INTO t1(t1) VALUES('integrity-check');
} {}
finish_test
+201
View File
@@ -0,0 +1,201 @@
# 2020 September 30
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
# May you find forgiveness for yourself and forgive others.
# May you share freely, never taking more than you give.
#
#*************************************************************************
#
# Tests for the fts5 "trigram" tokenizer.
#
source [file join [file dirname [info script]] fts5_common.tcl]
ifcapable !fts5 { finish_test ; return }
set ::testprefix fts5trigram
do_execsql_test 1.0 {
CREATE VIRTUAL TABLE t1 USING fts5(y, tokenize=trigram);
INSERT INTO t1 VALUES('abcdefghijklm');
INSERT INTO t1 VALUES('กรุงเทพมหานคร');
}
foreach {tn s res} {
1 abc "(abc)defghijklm"
2 defgh "abc(defgh)ijklm"
3 abcdefghijklm "(abcdefghijklm)"
4 กรุ "(กรุ)งเทพมหานคร"
5 งเทพมห "กรุ(งเทพมห)านคร"
6 กรุงเทพมหานคร "(กรุงเทพมหานคร)"
7 Abc "(abc)defghijklm"
8 deFgh "abc(defgh)ijklm"
9 aBcdefGhijKlm "(abcdefghijklm)"
} {
do_execsql_test 1.1.$tn {
SELECT highlight(t1, 0, '(', ')') FROM t1($s)
} $res
}
do_execsql_test 1.2.0 {
SELECT fts5_expr('ABCD', 'tokenize=trigram')
} {{"abc" + "bcd"}}
do_execsql_test 1.2.1 {
SELECT * FROM t1 WHERE y LIKE ? ESCAPE 'a'
}
foreach {tn like res} {
1 {%cDef%} 1
2 {cDef%} {}
3 {%f%} 1
4 {%f_h%} 1
5 {%f_g%} {}
6 {abc%klm} 1
7 {ABCDEFG%} 1
8 {%รุงเ%} 2
} {
do_execsql_test 1.3.$tn {
SELECT rowid FROM t1 WHERE y LIKE $like
} $res
}
#-------------------------------------------------------------------------
reset_db
do_execsql_test 2.0 {
CREATE VIRTUAL TABLE t1 USING fts5(y, tokenize="trigram case_sensitive 1");
INSERT INTO t1 VALUES('abcdefghijklm');
INSERT INTO t1 VALUES('กรุงเทพมหานคร');
}
foreach {tn s res} {
1 abc "(abc)defghijklm"
2 defgh "abc(defgh)ijklm"
3 abcdefghijklm "(abcdefghijklm)"
4 กรุ "(กรุ)งเทพมหานคร"
5 งเทพมห "กรุ(งเทพมห)านคร"
6 กรุงเทพมหานคร "(กรุงเทพมหานคร)"
7 Abc ""
8 deFgh ""
9 aBcdefGhijKlm ""
} {
do_execsql_test 2.1.$tn {
SELECT highlight(t1, 0, '(', ')') FROM t1($s)
} $res
}
foreach {tn like res} {
1 {%cDef%} 1
2 {cDef%} {}
3 {%f%} 1
4 {%f_h%} 1
5 {%f_g%} {}
6 {abc%klm} 1
7 {ABCDEFG%} 1
8 {%รุงเ%} 2
} {
do_execsql_test 2.2.$tn {
SELECT rowid FROM t1 WHERE y LIKE $like
} $res
}
foreach {tn like res} {
1 {*cdef*} 1
2 {cdef*} {}
3 {*f*} 1
4 {*f?h*} 1
5 {*f?g*} {}
6 {abc*klm} 1
7 {abcdefg*} 1
8 {*รุงเ*} 2
9 {abc[d]efg*} 1
10 {abc[]d]efg*} 1
11 {abc[^]d]efg*} {}
12 {abc[^]XYZ]efg*} 1
} {
do_execsql_test 2.3.$tn {
SELECT rowid FROM t1 WHERE y GLOB $like
} $res
}
do_execsql_test 2.3.null.1 {
SELECT rowid FROM t1 WHERE y LIKE NULL
}
#-------------------------------------------------------------------------
reset_db
do_catchsql_test 3.1 {
CREATE VIRTUAL TABLE ttt USING fts5(c, tokenize="trigram case_sensitive 2");
} {1 {error in tokenizer constructor}}
do_catchsql_test 3.2 {
CREATE VIRTUAL TABLE ttt USING fts5(c, tokenize="trigram case_sensitive 11");
} {1 {error in tokenizer constructor}}
do_catchsql_test 3.3 {
CREATE VIRTUAL TABLE ttt USING fts5(c, "tokenize=trigram case_sensitive 1");
} {0 {}}
#-------------------------------------------------------------------------
reset_db
do_execsql_test 4.0 {
CREATE VIRTUAL TABLE t0 USING fts5(b, tokenize = "trigram");
}
do_execsql_test 4.1 {
INSERT INTO t0 VALUES (x'000b01');
}
do_execsql_test 4.2 {
INSERT INTO t0(t0) VALUES('integrity-check');
}
#-------------------------------------------------------------------------
reset_db
foreach_detail_mode $::testprefix {
foreach {ci} {0 1} {
reset_db
do_execsql_test 5.cs=$ci.0.1 "
CREATE VIRTUAL TABLE t1 USING fts5(
y, tokenize=\"trigram case_sensitive $ci\", detail=%DETAIL%
);
"
do_execsql_test 5.cs=$ci.0.2 {
INSERT INTO t1 VALUES('abcdefghijklm');
INSERT INTO t1 VALUES('กรุงเทพมหานคร');
}
foreach {tn like res} {
1 {%cDef%} 1
2 {cDef%} {}
3 {%f%} 1
4 {%f_h%} 1
5 {%f_g%} {}
6 {abc%klm} 1
7 {ABCDEFG%} 1
8 {%รุงเ%} 2
} {
do_execsql_test 5.cs=$ci.1.$tn {
SELECT rowid FROM t1 WHERE y LIKE $like
} $res
}
}
}
do_execsql_test 6.0 {
CREATE VIRTUAL TABLE ci0 USING fts5(x, tokenize="trigram");
CREATE VIRTUAL TABLE ci1 USING fts5(x, tokenize="trigram case_sensitive 1");
}
# LIKE and GLOB both work with case-insensitive tokenizers. Only GLOB works
# with case-sensitive.
do_eqp_test 6.1 {
SELECT * FROM ci0 WHERE x LIKE ?
} {VIRTUAL TABLE INDEX 0:L0}
do_eqp_test 6.2 {
SELECT * FROM ci0 WHERE x GLOB ?
} {VIRTUAL TABLE INDEX 0:G0}
do_eqp_test 6.3 {
SELECT * FROM ci1 WHERE x LIKE ?
} {{SCAN TABLE ci1 VIRTUAL TABLE INDEX 0:}}
do_eqp_test 6.4 {
SELECT * FROM ci1 WHERE x GLOB ?
} {VIRTUAL TABLE INDEX 0:G0}
finish_test
+2
View File
@@ -12,6 +12,7 @@ proc process_cmdline {} {
cmdline::process ::A $::argv {
{fts5 "use fts5 (this is the default)"}
{fts4 "use fts4"}
{trigram "Use tokenize=trigram"}
{colsize "10 10 10" "list of column sizes"}
{tblname "t1" "table name to create"}
{detail "full" "Fts5 detail mode to use"}
@@ -175,6 +176,7 @@ proc create_table {} {
set sql "CREATE VIRTUAL TABLE IF NOT EXISTS $A(tblname) USING $A(fts) ("
append sql [join $cols ,]
if {$A(fts)=="fts5"} { append sql ",detail=$A(detail)" }
if {$A(trigram)} { append sql ",tokenize=trigram" }
append sql ", prefix='$A(prefix)');"
db eval $sql
+3 -3
View File
@@ -54,11 +54,11 @@
** statically linked against the application, initialize it using
** a single API call as follows:
**
** sqlite3_cksumvfs_init();
** sqlite3_register_cksumvfs();
**
** Cksumvfs is a VFS Shim. When loaded, "cksmvfs" becomes the new
** default VFS and it uses the prior default VFS as the next VFS
** down in the stack. This is normally what you want. However, it
** down in the stack. This is normally what you want. However, in
** complex situations where multiple VFS shims are being loaded,
** it might be important to ensure that cksumvfs is loaded in the
** correct order so that it sequences itself into the default VFS
@@ -79,7 +79,7 @@
** the reserve-bytes value to 8 by runing:
**
** int n = 8;
** sqlite3_file_control(db, 0, SQLITE_FCNTL_RESERVED_BYTES, &n);
** sqlite3_file_control(db, 0, SQLITE_FCNTL_RESERVE_BYTES, &n);
**
** If you do this immediately after creating a new database file,
** before anything else has been written into the file, then that
+1 -1
View File
@@ -776,7 +776,7 @@ static int csvtabColumn(
CsvCursor *pCur = (CsvCursor*)cur;
CsvTable *pTab = (CsvTable*)cur->pVtab;
if( i>=0 && i<pTab->nCol && pCur->azVal[i]!=0 ){
sqlite3_result_text(ctx, pCur->azVal[i], -1, SQLITE_STATIC);
sqlite3_result_text(ctx, pCur->azVal[i], -1, SQLITE_TRANSIENT);
}
return SQLITE_OK;
}
+9 -7
View File
@@ -523,14 +523,16 @@ static int zipfileAppendData(
const u8 *aWrite,
int nWrite
){
size_t n;
fseek(pTab->pWriteFd, (long)pTab->szCurrent, SEEK_SET);
n = fwrite(aWrite, 1, nWrite, pTab->pWriteFd);
if( (int)n!=nWrite ){
pTab->base.zErrMsg = sqlite3_mprintf("error in fwrite()");
return SQLITE_ERROR;
if( nWrite>0 ){
size_t n = nWrite;
fseek(pTab->pWriteFd, (long)pTab->szCurrent, SEEK_SET);
n = fwrite(aWrite, 1, nWrite, pTab->pWriteFd);
if( (int)n!=nWrite ){
pTab->base.zErrMsg = sqlite3_mprintf("error in fwrite()");
return SQLITE_ERROR;
}
pTab->szCurrent += nWrite;
}
pTab->szCurrent += nWrite;
return SQLITE_OK;
}
+1 -1
View File
@@ -759,7 +759,7 @@ static int nodeAcquire(
** are the leaves, and so on. If the depth as specified on the root node
** is greater than RTREE_MAX_DEPTH, the r-tree structure must be corrupt.
*/
if( pNode && iNode==1 ){
if( pNode && rc==SQLITE_OK && iNode==1 ){
pRtree->iDepth = readInt16(pNode->zData);
if( pRtree->iDepth>RTREE_MAX_DEPTH ){
rc = SQLITE_CORRUPT_VTAB;
+3 -3
View File
@@ -227,7 +227,7 @@ static int SQLITE_TCLAPI test_session_cmd(
){
TestSession *p = (TestSession*)clientData;
sqlite3_session *pSession = p->pSession;
struct SessionSubcmd {
static struct SessionSubcmd {
const char *zSub;
int nArg;
const char *zMsg;
@@ -1131,7 +1131,7 @@ static int SQLITE_TCLAPI test_rebaser_cmd(
int objc,
Tcl_Obj *CONST objv[]
){
struct RebaseSubcmd {
static struct RebaseSubcmd {
const char *zSub;
int nArg;
const char *zMsg;
@@ -1248,7 +1248,7 @@ static int SQLITE_TCLAPI test_sqlite3session_config(
int objc,
Tcl_Obj *CONST objv[]
){
struct ConfigOpt {
static struct ConfigOpt {
const char *zSub;
int op;
} aSub[] = {
+127 -122
View File
@@ -1,5 +1,5 @@
C Optimizations\sto\sthe\slogic\sthat\sconverts\smain\stable\saccesses\sinto\sequivalent\nindex\saccesses.\s\sCode\sis\snow\sslightly\ssmaller\sand\sfaster\sthan\strunk.
D 2020-08-14T21:32:16.882
C Prettify\sbtree.h\sheadings.\sClose\sbranch.
D 2020-10-27T11:58:37.756
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@@ -7,7 +7,7 @@ F Makefile.in 19374a5db06c3199ec1bab71ab74a103d8abf21053c05e9389255dc58083f806
F Makefile.linux-gcc f609543700659711fbd230eced1f01353117621dccae7b9fb70daa64236c5241
F Makefile.msc 48f5a3fc32672c09ad73795749f6253e406a31526935fbbffd8f021108d54574
F README.md 1514a365ffca3c138e00c5cc839906108a01011a6b082bad19b09781e3aa498a
F VERSION 5db2ee2cfcc790af73775fa485c13b2e8ccaa5936c6e1f47aedeba7056041ca5
F VERSION 4027b9aea92d64385570778ebd14388c0b23e92aafda15e7b89c45886c9b920a
F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50
F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2
F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90
@@ -34,11 +34,11 @@ F autoconf/tea/win/rules.vc c511f222b80064096b705dbeb97060ee1d6b6d63
F config.guess 883205ddf25b46f10c181818bf42c09da9888884af96f79e1719264345053bd6
F config.h.in 6376abec766e9a0785178b1823b5a587e9f1ccbc
F config.sub c2d0260f17f3e4bc0b6808fccf1b291cb5e9126c14fc5890efc77b9fd0175559
F configure a97f98dfff699495aef66ae3d9c424345778a663f583e0d6e7522670518f87c1 x
F configure 63af83d31b9fdf304f2dbb1e1638530d4ceff31702d1e19550d1fbf3bdf9471e x
F configure.ac 40d01e89cb325c28b33f5957e61fede0bd17da2b5e37d9b223a90c8a318e88d4
F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad
F doc/F2FS.txt c1d4a0ae9711cfe0e1d8b019d154f1c29e0d3abfe820787ba1e9ed7691160fcd
F doc/lemon.html 1edc0f916e771212792d4d077aedc05168bf13fd65d64d41b2c13e46ac0063a8
F doc/lemon.html c5d8ba85ac1daef7be8c2d389899480eb62451ff5c09b0c28ff8157bb8770746
F doc/pager-invariants.txt 27fed9a70ddad2088750c4a2b493b63853da2710
F doc/trusted-schema.md 33625008620e879c7bcfbbfa079587612c434fa094d338b08242288d358c3e8a
F doc/vfs-shm.txt e101f27ea02a8387ce46a05be2b1a902a021d37a
@@ -49,8 +49,8 @@ F ext/async/sqlite3async.c 6f247666b495c477628dd19364d279c78ea48cd90c72d9f9b98ad
F ext/async/sqlite3async.h 46b47c79357b97ad85d20d2795942c0020dc20c532114a49808287f04aa5309a
F ext/expert/README.md b321c2762bb93c18ea102d5a5f7753a4b8bac646cb392b3b437f633caf2020c3
F ext/expert/expert.c d548d603a4cc9e61f446cc179c120c6713511c413f82a4a32b1e1e69d3f086a4
F ext/expert/expert1.test 2e10ff875c31c9e6fc5e324767624181273859771fe34c5daeeadf3f2974a4f7
F ext/expert/sqlite3expert.c b5eae75862d34a204d16c45dcb813888b5f86bdc156c6136b0f79094c0da4f79
F ext/expert/expert1.test dba6e752cc701621771f925f3872b183fa688f7b4a9f4822631fc02bdbffc45a
F ext/expert/sqlite3expert.c 2778d9f06b3a8bfa859cb6b75b82f004477bf5dd78edd17d954319750ca963f3
F ext/expert/sqlite3expert.h ca81efc2679a92373a13a3e76a6138d0310e32be53d6c3bfaedabd158ea8969b
F ext/expert/test_expert.c d56c194b769bdc90cf829a14c9ecbc1edca9c850b837a4d0b13be14095c32a72
F ext/fts1/README.txt 20ac73b006a70bcfd80069bdaf59214b6cf1db5e
@@ -112,20 +112,20 @@ F ext/fts3/unicode/mkunicode.tcl bf7fcaa6d68e6d38223467983785d054f1cff4d9e3905dd
F ext/fts3/unicode/parseunicode.tcl a981bd6466d12dd17967515801c3ff23f74a281be1a03cf1e6f52a6959fc77eb
F ext/fts5/extract_api_docs.tcl a36e54ec777172ddd3f9a88daf593b00848368e0
F ext/fts5/fts5.h c132a9323f22a972c4c93a8d5a3d901113a6e612faf30ca8e695788438c5ca2a
F ext/fts5/fts5Int.h d7cbc214ee167496f70905667e18f73ea0402f7ef09236ce305e117e0efc866a
F ext/fts5/fts5Int.h 26c74dd5776f798436fbf604a0bf0e8de263b35b5060b05c15f9085845d9fda2
F ext/fts5/fts5_aux.c dcc627d8b6e3fc773db528ff67b39955dab7b51628f9dba8e15849e5bedfd7fa
F ext/fts5/fts5_buffer.c 5a5fe0159752c0fb0a5a93c722e9db2662822709490769d482b76a6dc8aaca70
F ext/fts5/fts5_config.c b447948f35ad3354e8fe5e242e0a7e7b5b941555400b9404259944e3aa570037
F ext/fts5/fts5_expr.c 2be456484786333d559dc2987a00f2750981fab91d52db8452a8046278c5f22e
F ext/fts5/fts5_hash.c 1cc0095646f5f3b46721aa112fb4f9bf29ae175cb5338f89dcec66ed97acfe75
F ext/fts5/fts5_index.c de14c9a30f45e2b847ff9284b14776d9d07961e545e8f1546a6aa3f915af721f
F ext/fts5/fts5_main.c e881a2ea0bf01b3a3ff0bc1b31373c58fd54b6c9f3c43ea3d431bea4e5d4025e
F ext/fts5/fts5_storage.c 3ecda8edadc1f62a355d6789776be0da609f8658c50d72e422674093ab7e1528
F ext/fts5/fts5_config.c be54f44fca491e96c6923a4b9a736f2da2b13811600eb6e38d1bcc91c4ea2e61
F ext/fts5/fts5_expr.c e527e3a7410393075598cec544e3831798a8c88b3e8878e2cfb7cb147113e925
F ext/fts5/fts5_hash.c 1aa93c9b5f461afba66701ee226297dc78402b3bdde81e90a10de5fe3df14959
F ext/fts5/fts5_index.c fb8ed13cb8f2ddeb80ea6ade6e35d59b0bc01b9bd741f7e60a1c58a92877d5d7
F ext/fts5/fts5_main.c b4e4931c7fcc9acfa0c3b8b5e5e80b5b424b8d9207aae3a22b674bd35ccf149d
F ext/fts5/fts5_storage.c 58ba71e6cd3d43a5735815e7956ee167babb4d2cbfe206905174792af4d09d75
F ext/fts5/fts5_tcl.c 39bcbae507f594aad778172fa914cad0f585bf92fd3b078c686e249282db0d95
F ext/fts5/fts5_test_mi.c 08c11ec968148d4cb4119d96d819f8c1f329812c568bac3684f5464be177d3ee
F ext/fts5/fts5_test_tok.c f96c6e193c466711d6d7828d5f190407fe7ab897062d371426dd3036f01258e7
F ext/fts5/fts5_tokenize.c 2e508c6a3bd8ee56c48e98a38052e1a650e49b32a484cce9b189984114bc3b88
F ext/fts5/fts5_unicode2.c 8bd0cd07396b74c1a05590e4070d635bccfc849812c305619f109e6c0485e250
F ext/fts5/fts5_tokenize.c 6f47244681c670ec3c1364f19b2ec0cca191249ff3543755a65e1fc1df348061
F ext/fts5/fts5_unicode2.c 85f64663cbd8ddd09d3a1e8823759b07085018b4a53158632e264cd785f88763
F ext/fts5/fts5_varint.c e64d2113f6e1bfee0032972cffc1207b77af63319746951bf1d09885d1dadf80
F ext/fts5/fts5_vocab.c 7a071833064dc8bca236c3c323e56aac36f583aa2c46ce916d52e31ce87462c9
F ext/fts5/fts5parse.y eb526940f892ade5693f22ffd6c4f2702543a9059942772526eac1fde256bb05
@@ -151,7 +151,7 @@ F ext/fts5/test/fts5bigpl.test 6466c89b38439f0aba26ac09e232a6b963f29b1cbe1304f6a
F ext/fts5/test/fts5bigtok.test 541119e616c637caea925a8c028c37c2c29e94383e00aa2f9198d530724b6e36
F ext/fts5/test/fts5cat.test daba0b80659460b0cb60bd1f40b402478a761fe7ea414c3c94c2be25568cc33a
F ext/fts5/test/fts5circref.test f880dfd0d99f6fb73b88ccacb0927d18e833672fd906cc47d6b4e529419eaa62
F ext/fts5/test/fts5colset.test a30473451321bbf0b6218af62e96b4ae5fa99931cfdb210b5ecc804623b30f75
F ext/fts5/test/fts5colset.test 7031ce84fb4d312df5a99fc4e7b324e660ccb513c97eccdef469bfd52d3d0f8f
F ext/fts5/test/fts5columnsize.test 45459ce4dd9fd853b6044cdc9674921bff89e3d840f348ca8c1630f9edbf5482
F ext/fts5/test/fts5config.test 60094712debc59286c59aef0e6cf511c37d866802776a825ce437d26afe0817f
F ext/fts5/test/fts5conflict.test 655925678e630d3cdf145d18725a558971806416f453ac8410ca8c04d934238d
@@ -159,9 +159,9 @@ 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 7afe0fea5b2160798fdc3306395048768c6fc13acefc0e7129d4075b6e1bb224
F ext/fts5/test/fts5corrupt3.test b8d4d6f167b8189999dac7162ddec614ab9dca4fe5e9dcfd315e383a5e15444b
F ext/fts5/test/fts5corrupt4.test ea805c4d7c68b5f185b9db5d2060a7ae5875339738dd48203c92162f41e7ca91
F ext/fts5/test/fts5delete.test cbf87e3b8867c4d5cfcaed975c7475fd3f99d072bce2075fcedf43d1f82af775
F ext/fts5/test/fts5delete.test 4a15fb03b6c7eac62ac807a3a32b7f0dc74f0d479c410e3e3568ae96b9469290
F ext/fts5/test/fts5detail.test 31b240dbf6d44ac3507e2f8b65f29fdc12465ffd531212378c7ce1066766f54e
F ext/fts5/test/fts5determin.test 1b77879b2ae818b5b71c859e534ee334dac088b7cf3ff3bf76a2c82b1c788d11
F ext/fts5/test/fts5dlidx.test b90852c55881b29dbac6380b274de27beae623ac4b6d567c6c8fb9cdc315a86e
@@ -179,12 +179,13 @@ F ext/fts5/test/fts5fault8.test 318238659d35f82ad215ecb57ca4c87486ea85d45dbeedae
F ext/fts5/test/fts5fault9.test 098e6b894bbdf9b2192f994a30f4043673fb3f338b6b8ab1624c704422f39119
F ext/fts5/test/fts5faultA.test be4487576bff8c22cee6597d1893b312f306504a8c6ccd3c53ca85af12290c8c
F ext/fts5/test/fts5faultB.test d606bdb8e81aaeb6f41de3fc9fc7ae315733f0903fbff05cf54f5b045b729ab5
F ext/fts5/test/fts5faultD.test cc5d1225556e356615e719c612e845d41bff7d5a
F ext/fts5/test/fts5faultD.test e7ed7895abfe6bc98a5e853826f6b74956e7ba7f594f1860bbf9e504b9647996
F ext/fts5/test/fts5faultE.test 844586ce71dab4be85bb86880e87b624d089f851654cd22e4710c77eb8ce7075
F ext/fts5/test/fts5first.test 3fcf2365c00a15fc9704233674789a3b95131d12de18a9b996159f6909dc8079
F ext/fts5/test/fts5full.test e1701a112354e0ff9a1fdffb0c940c576530c33732ee20ac5e8361777070d717
F ext/fts5/test/fts5fuzz1.test 238d8c45f3b81342aa384de3e581ff2fa330bf922a7b69e484bbc06051a1080e
F ext/fts5/test/fts5hash.test a4cf51acad99bfc43c16fb74f9d22495dc221ae0701fc5e908ca963a9b26a02b
F ext/fts5/test/fts5integrity.test 8ffabcd91b058d812aba3e3e0a06f76ce165ba402a18cca20e34204a7feec92e
F ext/fts5/test/fts5hash.test dc7bc7e0cdeb42cfce31294ad2f8fcf43192bfd0145bb7f3ecc5465d8c72696f
F ext/fts5/test/fts5integrity.test e387b2bd1c83e50f4a12f58a5fd399111bbab36be2f1c9fd5bb974be08a32de6
F ext/fts5/test/fts5interrupt.test 09613247b273a99889808ef852898177e671406fe71fdde7ea00e78ea283d227
F ext/fts5/test/fts5lastrowid.test be98fe3e03235296585b72daad7aed5717ba0062bae5e5c18dd6e04e194c6b28
F ext/fts5/test/fts5leftjoin.test c0b4cafb9661379e576dc4405c0891d8fcc2782680740513c4d1fc114b43d4ad
@@ -198,7 +199,7 @@ F ext/fts5/test/fts5near.test 211477940142d733ac04fad97cb24095513ab2507073a99c27
F ext/fts5/test/fts5onepass.test f9b7d9b2c334900c6542a869760290e2ab5382af8fbd618834bf1fcc3e7b84da
F ext/fts5/test/fts5optimize.test 36a752d24c818792032e4ff502936fc9cc5ef938721696396fdc79214b2717f1
F ext/fts5/test/fts5phrase.test 13e5d8e9083077b3d9c74315b3c92ec723cc6eb37c8155e0bfe1bba00559f07b
F ext/fts5/test/fts5plan.test 771b999d161e24fd803ce0290adb7c6e7c9b9cc2c6a0adb344813fb89473aa32
F ext/fts5/test/fts5plan.test 79d35b5e83bbdcba48d946a7f008df161f6b0ede1a966892d0aa6c8dd0b6e773
F ext/fts5/test/fts5porter.test 8d08010c28527db66bc3feebd2b8767504aaeb9b101a986342fa7833d49d0d15
F ext/fts5/test/fts5porter2.test 0d251a673f02fa13ca7f011654873b3add20745f7402f108600a23e52d8c7457
F ext/fts5/test/fts5prefix.test a0fa67b06650f2deaa7bf27745899d94e0fb547ad9ecbd08bfad98c04912c056
@@ -213,9 +214,10 @@ F ext/fts5/test/fts5simple2.test 258a1b0c590409bfa5271e872c79572b319d2a56554d058
F ext/fts5/test/fts5simple3.test d5c74a9d3ca71bd5dd5cacb7c55b86ea12cdddfc8b1910e3de2995206898380f
F ext/fts5/test/fts5synonym.test 1651815b8008de170e8e600dcacc17521d765482ea8f074ae82cfa870d8bb7fb
F ext/fts5/test/fts5synonym2.test b54cce5c34ec08ed616f646635538ae82e34a0e28f947ec60b6fadbc4b3fb17a
F ext/fts5/test/fts5tok1.test ce6551e41ff56f30b69963577324624733bed0d1753589f06120d664d9cd45c9
F ext/fts5/test/fts5tok1.test 1f7817499f5971450d8c4a652114b3d833393c8134e32422d0af27884ffe9cef
F ext/fts5/test/fts5tok2.test dcacb32d4a2a3f0dd3215d4a3987f78ae4be21a2
F ext/fts5/test/fts5tokenizer.test ac3c9112b263a639fb0508ae73a3ee886bf4866d2153771a8e8a20c721305a43
F ext/fts5/test/fts5trigram.test e2ce256fd0ccd6707e740aa3596206aedb0d5834b100c0cb49e344dcd1d8463c
F ext/fts5/test/fts5umlaut.test a42fe2fe6387c40c49ab27ccbd070e1ae38e07f38d05926482cc0bccac9ad602
F ext/fts5/test/fts5unicode.test 17056f4efe6b0a5d4f41fdf7a7dc9af2873004562eaa899d40633b93dc95f5a9
F ext/fts5/test/fts5unicode2.test 9b3df486de05fb4bde4aa7ee8de2e6dae1df6eb90e3f2e242c9383b95d314e3e
@@ -227,7 +229,7 @@ F ext/fts5/test/fts5version.test c8f2cc105f0abf0224965f93e584633dee3e06c91478bc6
F ext/fts5/test/fts5vocab.test 7ed80d9af1ddaaa1637da05e406327b5aac250848bc604c1c1cc667908b87760
F ext/fts5/test/fts5vocab2.test e0fdc3a3095f6eda68ac9bf9a443ff929a124d46f00af19933604085712e9d47
F ext/fts5/tool/fts5speed.tcl b0056f91a55b2d1a3684ec05729de92b042e2f85
F ext/fts5/tool/fts5txt2db.tcl 526a9979c963f1c54fd50976a05a502e533a4c59
F ext/fts5/tool/fts5txt2db.tcl c0d43c8590656f8240e622b00957b3a0facc49482411a9fdc2870b45c0c82f9f
F ext/fts5/tool/loadfts5.tcl 95b03429ee6b138645703c6ca192c3ac96eaf093
F ext/fts5/tool/mkfts5c.tcl d1c2a9ab8e0ec690a52316f33dd9b1d379942f45
F ext/fts5/tool/showfts5.tcl d54da0e067306663e2d5d523965ca487698e722c
@@ -286,11 +288,11 @@ F ext/misc/appendvfs.c 55121d311d408ba9c62c3cfa367408887638f02f9522dd9859891d0ee
F ext/misc/blobio.c a867c4c4617f6ec223a307ebfe0eabb45e0992f74dd47722b96f3e631c0edb2a
F ext/misc/btreeinfo.c d28ce349b40054eaa9473e835837bad7a71deec33ba13e39f963d50933bfa0f9
F ext/misc/carray.c 91e9a7f512fda934894bed30464552fffa7d3073b5be04189ae0bd0c59f26bfd
F ext/misc/cksumvfs.c 0f022867786b615d7f68fb3ab3a16627fe6a730442abf804735e18a73f835a83
F ext/misc/cksumvfs.c 910848f3d9739908cf77cad66a76dd45001546f46ff5ef4ca5c20c5476e77e98
F ext/misc/closure.c dbfd8543b2a017ae6b1a5843986b22ddf99ff126ec9634a2f4047cd14c85c243
F ext/misc/completion.c 6dafd7f4348eecc7be9e920d4b419d1fb2af75d938cd9c59a20cfe8beb2f22b9
F ext/misc/compress.c 3354c77a7c8e86e07d849916000cdac451ed96500bfb5bd83b20eb61eee012c9
F ext/misc/csv.c 3ed979c1eb35e35a98b30ef545a2facf62994594217681d9138b4b75faf6b0d7
F ext/misc/csv.c 53b3338d4fa812eda51a2637df30233a4dae16b964ee5666e2051b9672ed8bb4
F ext/misc/dbdata.c e316fba936571584e55abd5b974a32a191727a6b746053a0c9d439bd2cf93940
F ext/misc/dbdump.c b8592f6f2da292c62991a13864a60d6c573c47a9cc58362131b9e6a64f823e01
F ext/misc/decimal.c 3ddbf8162015be4d5ec2395dee4538f1e638bb517174bb148274b132df6e1d08
@@ -332,7 +334,7 @@ F ext/misc/vfsstat.c 389ea13983d3af926504c314f06a83cc858d5adc24b40af74aaed1fece0
F ext/misc/vtablog.c 5538acd0c8ddaae372331bee11608d76973436b77d6a91e8635cfc9432fba5ae
F ext/misc/vtshim.c 1976e6dd68dd0d64508c91a6dfab8e75f8aaf6cd
F ext/misc/wholenumber.c 520f34c3099e5b7d546f13708607dc2fa173c46b68952eecf0d19cd675fec85e
F ext/misc/zipfile.c d1be54ea83ac9ad71b8b6ffc4b60db8946ce2ceacdf6bff063fcd9489f41bb49
F ext/misc/zipfile.c e35e035bc2765b1ccdcb15f9815c2112843fcbc8f36aa071f0e5935df7072228
F ext/misc/zorder.c b0ff58fa643afa1d846786d51ea8d5c4b6b35aa0254ab5a82617db92f3adda64
F ext/rbu/rbu.c 8681f6157db6adc82c34af24b14ea8a3be0146ad2a3b6c1d5da6cb8a5796c8ce
F ext/rbu/rbu1.test 221d9c18a5e600ac9ac6b1810d99d9f99163a7909ba61597876ab6e4d4beb3d6
@@ -388,7 +390,7 @@ F ext/repair/test/checkindex01.test b530f141413b587c9eb78ff734de6bb79bc3515c3350
F ext/repair/test/test.tcl 686d76d888dffd021f64260abf29a55c57b2cedfa7fc69150b42b1d6119aac3c
F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761
F ext/rtree/geopoly.c f15cc6845d64a629035627d863cbe3eadc9cb30f9ca77bd823b0ca8a5a3f8b00
F ext/rtree/rtree.c f87ffcc91f49272862119cfdd256b02514351893786a710d88f85933790608d4
F ext/rtree/rtree.c 60f6f1675134201974be4189dbd219494c13e1ed30e80bd92ae0dcc86df1b035
F ext/rtree/rtree.h 4a690463901cb5e6127cf05eb8e642f127012fd5003830dbc974eca5802d9412
F ext/rtree/rtree1.test 00792b030a4e188ff1b22e8530e8aa0452bb5dd81c2b18cb004afc7dc63e040e
F ext/rtree/rtree2.test 9d9deddbb16fd0c30c36e6b4fdc3ee3132d765567f0f9432ee71e1303d32603d
@@ -450,7 +452,7 @@ F ext/session/sessionstat1.test 218d351cf9fcd6648f125a26b607b140310160184723c266
F ext/session/sessionwor.test 67b5ab91d4f93ce65ff1f58240ac5ddf73f8670facc1ffa49cef56293d52818d
F ext/session/sqlite3session.c 2c76b8c3a5d6dab736686f8a48833b8bdac0871ecc6f447f9839d28bd4a63d6c
F ext/session/sqlite3session.h a2db5b72b938d12c727b4b4ec632254ca493670a9c0de597af3271a7f774fc57
F ext/session/test_session.c 98797aba475a799376c9a42214f2d1debf2d0c3cb657d9c8bbf4f70bf3fb4aec
F ext/session/test_session.c 24286d958dc6f4ca4d7e710f09bc0fa9d50956a40dd99fd8223e7488024c71fe
F ext/userauth/sqlite3userauth.h 7f3ea8c4686db8e40b0a0e7a8e0b00fac13aa7a3
F ext/userauth/user-auth.txt e6641021a9210364665fe625d067617d03f27b04
F ext/userauth/userauth.c 7f00cded7dcaa5d47f54539b290a43d2e59f4b1eb5f447545fa865f002fc80cb
@@ -470,24 +472,24 @@ F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b
F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786
F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a
F src/alter.c 805de23ddca536181f8f0439df989fdd4a2f76c40bc305ec9fe2f211f68c89e8
F src/analyze.c 5cffff3d355858cd22bfc6e20ac7203510d2e1cc935086eb06f4abb2f579f628
F src/attach.c 0b11e00c166b622c84ec176773b1d691c61ad07d247809e3e1635d4e99e71d30
F src/analyze.c 01c6c6765cb4d40b473b71d85535093730770bb186f2f473abac25f07fcdee5c
F src/attach.c 0f497c15c4cfe3bdcb214f0dbdbbb6c5ed7e8a9308ac445c7959f5e5780437a9
F src/auth.c a3d5bfdba83d25abed1013a8c7a5f204e2e29b0c25242a56bc02bb0c07bf1e06
F src/backup.c b1c90cd4110248c8e1273ff4578d3a84c0c34725e1b96dacd4a6294a908702de
F src/backup.c 3014889fa06e20e6adfa0d07b60097eec1f6e5b06671625f476a714d2356513d
F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33
F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6
F src/btree.c 1439fd9b45d4d1883c53752daef42af489adaa1a1508fa39dedbc9c80ea21a2f
F src/btree.h 7af72bbb4863c331c8f6753277ab40ee67d2a2125a63256d5c25489722ec162b
F src/btreeInt.h 83166f6daeb91062b6ae9ee6247b3ad07e40eba58f3c05ba9e8dedad4ab1ea38
F src/build.c dbdaee54ffef924a070eb6202017e10d6be56baab953ef0a8e714a6def683198
F src/btree.c ad0a38e4d4a0b6b3e003b5478556dbe890c0d58c7a95362e02d1fa539631af19
F src/btree.h c16c855f7e2ef5bfe8fb119a20339fb8e24a3efe6edce17be4df66bce4e20241
F src/btreeInt.h ffd66480520d9d70222171b3a026d78b80833b5cea49c89867949f3e023d5f43
F src/build.c f6449d4e85e998e14d3f537e8ea898dca2fcb83c277db3e60945af9b9177db81
F src/callback.c d0b853dd413255d2e337b34545e54d888ea02f20da5ad0e63585b389624c4a6c
F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e
F src/ctime.c e98518d2d3d4029a13c805e07313fb60c877be56db76e90dd5f3af73085d0ce6
F src/date.c dace306a10d9b02ee553d454c8e1cf8d3c9b932e137738a6b15b90253a9bfc10
F src/dbpage.c 8a01e865bf8bc6d7b1844b4314443a6436c07c3efe1d488ed89e81719047833a
F src/dbstat.c 3aa79fc3aed7ce906e4ea6c10e85d657299e304f6049861fe300053ac57de36c
F src/delete.c a2a603ab07cced8560065b0e2c4c9c842f2c5a2fd43d87355f95eb53bae7fe21
F src/expr.c 58c06940d964c2cf455b979cf66a648499d294a5ee6dadcaeaed447257c1dc75
F src/delete.c 927cf8f900583e79aca8f1a321979e0a8f053babd9a690b44b38f79de2cc09fe
F src/expr.c 2cfe739c81e9751123b900dee54f6d34f8ec4b747515a51f1771de8e2840650d
F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007
F src/fkey.c 83372403298e6a7dd989a47aaacdbaa5b4307b5199dbd56e07d4896066b3de72
F src/func.c 2333eb4277f55a5efdc12ef754e7d7ec9105d257b2fd00301d23ce1e8fa67dc0
@@ -496,17 +498,17 @@ F src/hash.c 8d7dda241d0ebdafb6ffdeda3149a412d7df75102cecfc1021c98d6219823b19
F src/hash.h 9d56a9079d523b648774c1784b74b89bd93fac7b365210157482e4319a468f38
F src/hwtime.h cb1d7e3e1ed94b7aa6fde95ae2c2daccc3df826be26fc9ed7fd90d1750ae6144
F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71
F src/insert.c 957254a2d0542597455d0d4c640e4e3f3eea8c6d78f04582df03dfc626f07925
F src/insert.c 7e081d33aab4a9d761c39dccf3c3872c35501565d2ed9db66301918d23bc7901
F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa
F src/loadext.c 436af4968c6954d304fce9efa12719367bd8f37b19b93b71d6ad607e85adbb47
F src/main.c 09580279145f27f3db206ef44dcb3a8875a42644230f79c7e54aff35e71668f0
F src/malloc.c 22d5bdd9fe88ae4fad1b91a1b9735104b82853ffef868f1f05517d60dc1875f5
F src/main.c 54d61d1e94f225636053c862c930d7dd7b29162b93d3f3ecb00439910ccba02a
F src/malloc.c 413b0ffea2b45c37c6cf2ed5509f6d6b508b0a033caa9b4bf90bed4ee044a2ff
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 d58e398e315e88f95f8d07d17e80ab11259ebd6d1a10397434329eeabd1985e3
F src/memdb.c ab0632d42407e866d2b616bd19d4211ac0ad1b430f04c4e187d60005b8700b98
F src/memjournal.c 90b2ca7e2f465d57c16b69d15a9f3e3294af61088eb4938f2f7664d5ac50f813
F src/msvc.h 3a15918220367a8876be3fa4f2abe423a861491e84b864fb2b7426bf022a28f8
F src/mutex.c 5e3409715552348732e97b9194abe92fdfcd934cfb681df4ba0ab87ac6c18d25
@@ -519,38 +521,38 @@ F src/os.c 80e4cf3e5da06be03ca641661e331ce60eeeeabf0d7354dbb1c0e166d0eedbbe
F src/os.h 48388821692e87da174ea198bf96b1b2d9d83be5dfc908f673ee21fafbe0d432
F src/os_common.h b2f4707a603e36811d9b1a13278bffd757857b85
F src/os_setup.h 0dbaea40a7d36bf311613d31342e0b99e2536586
F src/os_unix.c 9b1b860163fd2d4d7679b5260d384d1a9f88ef917a90f28963eca8acd472d8c8
F src/os_win.c a2149ff0a85c1c3f9cc102a46c673ce87e992396ba3411bfb53db66813b32f1d
F src/os_unix.c b16ae8f19de9fb91836164b8ff122c069d0b177179df7bb632cf41bf61308d89
F src/os_win.c 77d39873836f1831a9b0b91894fec45ab0e9ca8e067dc8c549e1d1eca1566fe9
F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a
F src/pager.c 3700a1c55427a3d4168ad1f1b8a8b0cb9ace1d107e4506e30a8f1e66d8a1195e
F src/pager.h 4bf9b3213a4b2bebbced5eaa8b219cf25d4a82f385d093cd64b7e93e5285f66f
F src/parse.y 5bdb760a29c0b25caf7e80e82210b81cd2ea3066d5199ca29e6eac40b34bc184
F src/parse.y 9ce4dfb772608ed5bd3c32f33e943e021e3b06cfd2c01932d4280888fdd2ebed
F src/pcache.c 385ff064bca69789d199a98e2169445dc16e4291fa807babd61d4890c3b34177
F src/pcache.h 4f87acd914cef5016fae3030343540d75f5b85a1877eed1a2a19b9f284248586
F src/pcache1.c 6596e10baf3d8f84cc1585d226cf1ab26564a5f5caf85a15757a281ff977d51a
F src/pragma.c bdb600be936f66b9fe69d26dfbba4528beaaf4f95c479c85b328a92484e0bf71
F src/pragma.c 6daaaecc26a4b09481d21722525b079ce756751a43a79cc1d8f122d686806193
F src/pragma.h 8dc78ab7e9ec6ce3ded8332810a2066f1ef6267e2e03cd7356ee00276125c6cf
F src/prepare.c 3d5a761d026052bc888d1b803a06dd2bfe245e8e836d4689f927003549148b0f
F src/printf.c 9efcd4e984f22bcccb1ded37a1178cac98f6e3a0534e1e0629f64899971f8838
F src/prepare.c 270170a239c0f66bd3c228f373afe24447c2614a6829ae22080babc64f241931
F src/printf.c 30e92b638fac71dcd85cdea1d12ecfae354c9adee2c71e8e1ae4727cde7c91ed
F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384
F src/resolve.c d74715aceed2a8f493ba244d535646fa93132042a4400a29dfd26ec841514048
F src/resolve.c 97b91fb25d86881ff20c9ad2ad98412c6c1bb5f7d6c9bb044db250cbc9cfcd4b
F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92
F src/select.c 510fdf819f218be3dac2683d3eaaf64e5080f548061a4dd12205590beda976bb
F src/shell.c.in b9b819feede7b85585ab0826490a352e04e2ee46e8132c92597d29972b2be1d7
F src/sqlite.h.in d2c03414a8ee5d4a6855c04dd7cd5998e45139b0fe66b65bae86d4223edd091f
F src/select.c 645aa47fb8ce95e95290d4852d44cf5997c89c3e754a74c91e010459a8db7a72
F src/shell.c.in b317d851046496c92e28529eb96f9d2ec1ad480590b1676e0362865f5466f886
F src/sqlite.h.in ff32663b457306eb88c3039868280aa39da31162ed69c4e71fa8e028684e7277
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
F src/sqlite3ext.h 2d1af80082edffd71c6f96f70ad1ce6a4fb46615ad10291fc77fe0dea9ff0197
F src/sqliteInt.h 86ad0f9164cbadb2ba9598cc6cf5b32bdb47b343c0da5ca62f3d73b60be55b65
F src/sqliteLimit.h 95cb8479ca459496d9c1c6a9f76b38aee12203a56ce1092fe13e50ae2454c032
F src/sqliteInt.h c6c4c310b699364eff6457f05beb47fd30943687d511bf99b6f722af236377fb
F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657
F src/status.c 4b8bc2a6905163a38b739854a35b826c737333fab5b1f8e03fa7eb9a4799c4c1
F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1
F src/tclsqlite.c 986b6391f02cd9b53c1d688be55899f6ffddeb8e8014cd83c1b73ff912579a71
F src/test1.c 24b9cd0863ecc4d3920f4999c40e876c2bd92f3cc5879c48b99abe02c546ed18
F src/test1.c 9e52fb797bf74fa327295df38881aa3ade0824bfb0c14abd0719e555b169fd55
F src/test2.c 3efb99ab7f1fc8d154933e02ae1378bac9637da5
F src/test3.c 61798bb0d38b915067a8c8e03f5a534b431181f802659a6616f9b4ff7d872644
F src/test4.c 7c4420e01c577b5c4add2cb03119743b1a357543d347773b9e717195ea967159
F src/test5.c 328aae2c010c57a9829d255dc099d6899311672d
F src/test6.c e8d839fbc552ce044bec8234561a2d5b8819b48e29548ad0ba400471697946a8
F src/test6.c ae73a3a42bbc982fb9e301b84d30bda65a307be48c6dff20aba1461e17a9b0ce
F src/test7.c 5612e9aecf934d6df7bba6ce861fdf5ba5456010
F src/test8.c 7fb971777c2c79c734bb52757191d68d4af659b8de9b4a071be3f527a9d19a02
F src/test9.c 12e5ba554d2d1cbe0158f6ab3f7ffcd7a86ee4e5
@@ -563,10 +565,10 @@ F src/test_btree.c 8b2dc8b8848cf3a4db93f11578f075e82252a274
F src/test_config.c 5ea19bf0972a9d91728518b4d30e91477acce80496003ecbef3a7fb18d0bd081
F src/test_delete.c e2fe07646dff6300b48d49b2fee2fe192ed389e834dd635e3b3bac0ce0bf9f8f
F src/test_demovfs.c 86142ba864d4297d54c5b2e972e74f3141ae4b30f05b3a95824184ed2d3d7f91
F src/test_devsym.c 6109b45c3db3ef7b002320947ed448c027356ab8b885156ff535fd8684d4a571
F src/test_devsym.c aff2255ea290d7718da08af30cdf18e470ff7325a5eff63e0057b1496ed66593
F src/test_fs.c ba1e1dc18fd3159fdba0b9c4256f14032159785320dfbd6776eb9973cb75d480
F src/test_func.c 181f992e5495644434c4f0e3cc72362a78c295eb2cf3ff4d02498b8bde7aa276
F src/test_hexio.c d170d0e1a6431afdeac086a250d2595078288c2257615d37949355361399bcaa
F src/test_hexio.c 9478e56a0f08e07841a014a93b20e4ba2709ab56d039d1ca8020e26846aa19bd
F src/test_init.c 4413c211a94b62157ca4c145b3f27c497f03c664
F src/test_intarray.c 39b4181662a0f33a427748d87218e7578d913e683dc27eab7098bb41617cac71
F src/test_intarray.h d57ae92f420cda25e22790dac474d60961bd0c500cbaa3338a05152d4a669ef7
@@ -592,7 +594,7 @@ F src/test_tclsh.c eeafce33ad2136d57e5dec10f1e9a4347447eb72ffd504a1c7b9c6bfe2e71
F src/test_tclvar.c 33ff42149494a39c5fbb0df3d25d6fafb2f668888e41c0688d07273dcb268dfc
F src/test_thread.c 269ea9e1fa5828dba550eb26f619aa18aedbc29fd92f8a5f6b93521fbb74a61c
F src/test_vdbecov.c f60c6f135ec42c0de013a1d5136777aa328a776d33277f92abac648930453d43
F src/test_vfs.c 36822d696789535bdd0260f07d2c9a46546082fea8bb1d0a7354c7f9366e37ea
F src/test_vfs.c 2cc38a79892017702d13da79ad5152c196eec19bbd67fbde4d88065aac894a84
F src/test_vfstrace.c bab9594adc976cbe696ff3970728830b4c5ed698
F src/test_windirent.c a895e2c068a06644eef91a7f0a32182445a893b9a0f33d0cdb4283dca2486ac1
F src/test_windirent.h 90dfbe95442c9762357fe128dc7ae3dc199d006de93eb33ba3972e0a90484215
@@ -602,19 +604,19 @@ F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c
F src/tokenize.c 4dc01b267593537e2a0d0efe9f80dabe24c5b6f7627bc6971c487fa6a1dacbbf
F src/treeview.c 4b92992176fb2caefbe06ba5bd06e0e0ebcde3d5564758da672631f17aa51cda
F src/trigger.c ef67bde309a831515dc3c2173d792574309f2f42d45f8c078743fae9f7f98c75
F src/update.c 55a6203008d033fc1a9c125d7a0a61efdb79bbb2e6db427b917d1d427b4639be
F src/update.c 1f6167d4acff9f2ae800f7dade84877afbd595c155cdeb7d56f08165d75570c4
F src/upsert.c 2920de71b20f04fe25eb00b655d086f0ba60ea133c59d7fa3325c49838818e78
F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0
F src/util.c c8bf30c4356b091bcc3b624d0e24b2b4d11b8be4d6c90d8e0705971e15cc819b
F src/vacuum.c 1c4f8e2f39d950037f4cf946b6858c993d3a54c3101f78e05c76460a073afcf0
F src/vdbe.c e9f7f818f128c8600058c0eabb6b3975974c95153a104d340f419adabbc15b9f
F src/util.c c0c7977de7ef9b8cb10f6c85f2d0557889a658f817b0455909a49179ba4c8002
F src/vacuum.c 492422c1463c076473bae1858799c7a0a5fe87a133d1223239447c422cd26286
F src/vdbe.c 6f3fb4f058c478b38c5280ccfc939745076c6a693999e49846c99fdc761c9c90
F src/vdbe.h 83603854bfa5851af601fc0947671eb260f4363e62e960e8a994fb9bbcd2aaa1
F src/vdbeInt.h 762abffb7709f19c2cb74af1bba73a900f762e64f80d69c31c9ae89ed1066b60
F src/vdbeInt.h 3ca5e9fd6e095a8b6cf6bc3587a46fc93499503b2fe48951e1034ba9e2ce2f6e
F src/vdbeapi.c c5e7cb2ab89a24d7f723e87b508f21bfb1359a04db5277d8a99fd1e015c12eb9
F src/vdbeaux.c 73854da7a9a4f12db72a855758214173c82f46a14be6cb19e63677ba02c97cae
F src/vdbeaux.c c4c0389aed3ac31f835904c3d1f730d6818742633f9474140d8ce174c10f2267
F src/vdbeblob.c 253ed82894924c362a7fa3079551d3554cd1cdace39aa833da77d3bc67e7c1b1
F src/vdbemem.c 947f2a65910edb4014dc981d33e414a68c51f169f9df8c4c493a0ba840b6eb1f
F src/vdbesort.c 2be76d26998ce2b3324cdcc9f6443728e54b6c7677c553ad909c7d7cfab587df
F src/vdbesort.c f5b5e473a7cee44e47a94817b042fd7172cf3aa2c0a7928a8339d612bcfdec5a
F src/vdbetrace.c fa3bf238002f0bbbdfb66cc8afb0cea284ff9f148d6439bc1f6f2b4c3b7143f0
F src/vdbevtab.c f99b275366c5fc5e2d99f734729880994ab9500bdafde7fae3b02d562b9d323c
F src/vtab.c 5f5fc793092f53bbdfde296c50f563fb7bda58cf48e9cf6a8bdfbc5abd409845
@@ -622,14 +624,14 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9
F src/wal.c 69e770e96fd56cc21608992bf2c6f1f3dc5cf2572d0495c6a643b06c3a679f14
F src/wal.h c3aa7825bfa2fe0d85bef2db94655f99870a285778baa36307c0a16da32b226a
F src/walker.c 3df26a33dc4f54e8771600fb7fdebe1ece0896c2ad68c30ab40b017aa4395049
F src/where.c 396ba2c62defd56283ef54a4b221f698f4733fe8fbfca4aa8b1cc4f8c58d12ee
F src/whereInt.h eb8c2847fb464728533777efec1682b3c074224293b2da73513c61a609efbeab
F src/wherecode.c cb9bc7cef99578c99baceafeea9c9bcc738d5be37f56dbfe3a1c61ea52483fd0
F src/whereexpr.c 264d58971eaf8256eb5b0917bcd7fc7a1f1109fdda183a8382308a1b18a2dce7
F src/where.c 03d35ea488e694849923e28ccdce1ef377a5c3738405b5323ff97eb9aa7569c1
F src/whereInt.h 59077fbd0b3d01bc8715e746c86a99ebf4c85bde8a57077ec04d2a23e59666ec
F src/wherecode.c a3a1aff30fe99a818d8e7c607980f033f40c68d890e03ed25838b9dbb7908bee
F src/whereexpr.c 2a05552e808047a93845278c98c6ca64a265fa8e9ffd087c161bb11bfe339866
F src/window.c edd6f5e25a1e8f2b6f5305b7f5f7da7bb35f07f0d432b255b1d4c2fcab4205aa
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
F test/affinity2.test ce1aafc86e110685b324e9a763eab4f2a73f737842ec3b687bd965867de90627
F test/affinity3.test 6a101af2fc945ce2912f6fe54dd646018551710d
F test/affinity3.test eecb0dabee4b7765a8465439d5e99429279ffba23ca74a7eae270a452799f9e7
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
F test/aggnested.test 2f65ec8132e0ca896de550b9908094d49ad65a99116a9d79deeb6017604ad4f6
F test/alias.test 4529fbc152f190268a15f9384a5651bbbabc9d87
@@ -644,12 +646,12 @@ F test/altercol.test 1d6a6fe698b81e626baea4881f5717f9bc53d7d07f1cd23ee7ad1b931f1
F test/alterlegacy.test 82022721ce0de29cedc9a7af63bc9fcc078b0ee000f8283b4b6ea9c3eab2f44b
F test/altermalloc.test 167a47de41b5c638f5f5c6efb59784002b196fff70f98d9b4ed3cd74a3fb80c9
F test/altermalloc2.test fa7b1c1139ea39b8dec407cf1feb032ca8e0076bd429574969b619175ad0174b
F test/altertab.test b8b2104212e8ea87c75c3cbe3cb78ed7236a6c828ee2e59ed09d3dbe9812d002
F test/altertab.test 6d7bbac2c4a6ef71b775094a3298fa3a92274d95034ee23157ffba92768e47e6
F test/altertab2.test b0d62f323ca5dab42b0bc028c52e310ebdd13e655e8fac070fe622bad7852c2b
F test/altertab3.test d0d51e652aaa11e37de1f1215181d88334fefcb185f3b9bd91e06e98260c4694
F test/amatch1.test b5ae7065f042b7f4c1c922933f4700add50cdb9f
F test/analyze.test 547bb700f903107b38611b014ca645d6b5bb819f5210d7bf39c40802aafeb7d7
F test/analyze3.test 01f0b122e3e54ad2544f14f7cc7dcb4c2cb8753cad5e88c6b8d49615b3fd6a2b
F test/analyze3.test fca2a9de0017becfdcc201647f03b1cfd5ba0e7b5b5c852936e4ec62780cde49
F test/analyze4.test cdf88f3f72b0f0643a1ff6c730fc5af1e42464d47478d9fbac84c333f72c014e
F test/analyze5.test fa5131952303ac4146aba101b116b9c8cb89e2637531c334a6df7f7d19dddc0d
F test/analyze6.test 6c3f7df2996cb6872f355a6ac1eb6d5de00a5a9288214bad7ef25c97d9cc72dc
@@ -667,7 +669,7 @@ F test/async2.test c0a9bd20816d7d6a2ceca7b8c03d3d69c28ffb8b
F test/async3.test d73a062002376d7edc1fe3edff493edbec1fc2f7
F test/async4.test 1787e3952128aa10238bf39945126de7ca23685a
F test/async5.test 383ab533fdb9f7ad228cc99ee66e1acb34cc0dc0
F test/atof1.test 1ccfc96a6888566597b83d882c81b3c04258dc39317e8c1cec89ba481eaa2fba
F test/atof1.test 10049623e77006691c4c2978c1dc8a3f75276377a53417811aa85bda7493f963
F test/atomic.test 065a453dde33c77ff586d91ccaa6ed419829d492dbb1a5694b8a09f3f9d7d061
F test/atomic2.test b6863b4aa552543874f80b42fb3063f1c8c2e3d8e56b6562f00a3cc347b5c1da
F test/atrc.c c388fac43dbba05c804432a7135ae688b32e8f25818e9994ffba4b64cf60c27c
@@ -709,7 +711,7 @@ F test/bestindex7.test f36ada201973d3022cf7afffffe08de9e58341996020e7a2df9a1d2f2
F test/between.test 68137a6e941c221417c15b6fe2d55f27bb1b6ab48bdf9e2aa51efdd85bc53802
F test/bigfile.test aa74f4e5db51c8e54a1d9de9fa65d01d1eb20b59
F test/bigfile2.test 1b489a3a39ae90c7f027b79110d6b4e1dbc71bfc
F test/bigmmap.test 31dad31573638bd32de866cdefd11843f75685be4ba6aec1a47918f098f1899b
F test/bigmmap.test e906cf9729d7c362270ffe9fa6471f4c39c28ba83f0f77fb795e1b4d38a22ba0
F test/bigrow.test f0aeb7573dcb8caaafea76454be3ade29b7fc747
F test/bigsort.test 8299fa9298f4f1e02fc7d2712e8b77d6cd60e5a2
F test/bind.test 1e136709b306f7ed3192d349c2930d89df6ab621654ad6f1a72381d3fe76f483
@@ -728,7 +730,7 @@ F test/btree01.test e08b3613540145b353f20c81cb18ead54ff12e0f
F test/btree02.test 7555a5440453d900410160a52554fe6478af4faf53098f7235f1f443d5a1d6cc
F test/btreefault.test c2bcb542685eea44621275cfedbd8a13f65201e3
F test/busy.test 510dc6daaad18bcbbc085bcc6217d6dc418def5e73f72ce1475eea0cb7834727
F test/busy2.test 2499cb62c9e58e18335892602c158cb35639c411803adca6423401b31e46c503
F test/busy2.test 26ae3b8b74235c851f27326807de94292af4d359476c629f80dc106f35c8293e
F test/cache.test 13bc046b26210471ca6f2889aceb1ea52dc717de
F test/cacheflush.test af25bb1509df04c1da10e38d8f322d66eceedf61
F test/cachespill.test 895997f84a25b323b166aecb69baab2d6380ea98f9e0bcc688c4493c535cfab9
@@ -738,9 +740,9 @@ F test/capi3b.test efb2b9cfd127efa84433cd7a2d72ce0454ae0dc4
F test/capi3c.test 54e2dc0c8fd7c34ad1590d1be6864397da2438c95a9f5aee2f8fbc60c112e44b
F test/capi3d.test aba917805573a03deed961a21f07a5a84505ad0a616f7e3fc1508844a15bccc4
F test/capi3e.test 3d49c01ef2a1a55f41d73cba2b23b5059ec460fe
F test/cast.test 2906ccab6a3ebd147ffa63304b635be903ce58264110d0a0eb4fd9939422bb53
F test/cast.test 336fa21989b5170ebcaf90c24266be22dd97b3e23d1fad5ecf6ad4efb04c4423
F test/cffault.test 9d6b20606afe712374952eec4f8fd74b1a8097ef
F test/check.test 9776af795bb5d0f197b7f8fe248052e3ca2ed35304d863efcdbf8b1316e11f65
F test/check.test 4a2a91ed67eee84a6be16057c48d5198b6fb24849cd6da6cd855981de3fbb416
F test/checkfault.test da6cb3d50247169efcb20bdf57863a3ccfa1d27d9e55cd324f0680096970f014
F test/chunksize.test 427d87791743486cbf0c3b8c625002f3255cb3a89c6eba655a98923b1387b760
F test/close.test eccbad8ecd611d974cbf47278c3d4e5874faf02d811338d5d348af42d56d647c
@@ -759,8 +761,8 @@ F test/collateA.test b8218ab90d1fa5c59dcf156efabb1b2599c580d6
F test/collateB.test 1e68906951b846570f29f20102ed91d29e634854ee47454d725f2151ecac0b95
F test/colmeta.test 2c765ea61ee37bc43bbe6d6047f89004e6508eb1
F test/colname.test 87ad5458bb8709312dac0d6755fd30e8e4ca83298d0a9ef6e5c24277a3c3390e
F test/conflict.test 58857e2533fb9f2e0358ea7cb191215657846be1dd9da3b3d6df3e750c02ae03
F test/conflict2.test bb0b94cf7196c64a3cbd815c66d3ee98c2fecd9c
F test/conflict.test ac0667090f66130ac77d5fb764655558ca6600dd6d88f670ca9123b61c448337
F test/conflict2.test 5557909ce683b1073982f5d1b61dfb1d41e369533bfdaf003180c5bc87282dd1
F test/conflict3.test 81865d9599609aca394fb3b9cd5f561d4729ea5b176bece3644f6ecb540f88ac
F test/contrib01.test 2a1cbc0f2f48955d7d073f725765da6fbceda6b4
F test/corrupt.test d7cb0300e4a297147b6a05e92a1684bc8973635c3bcaa3d66e983c9cbdbf47a3
@@ -807,7 +809,7 @@ F test/cursorhint.test 0175e4404181ace3ceca8b114eb0a98eae600d565aa4e2705abbe6614
F test/cursorhint2.test 6f3aa9cb19e7418967a10ec6905209bcbb5968054da855fc36c8beee9ae9c42f
F test/dataversion1.test 6e5e86ac681f0782e766ebcb56c019ae001522d114e0e111e5ebf68ccf2a7bb8
F test/date.test 9b73bbeb1b82d9c1f44dec5cf563bf7da58d2373
F test/date2.test 5ef8265c71460cda6b1698bf18f4bb0ffb40ac08c5092f6afe84d398c2feb5be
F test/date2.test 520a1708e4e14c682cf514560f3e9f2e5affa9d66560fbc2a6941ae291260daf
F test/dbdata.test 042f49acff3438f940eeba5868d3af080ae64ddf26ae78f80c92bec3ca7d8603
F test/dbfuzz.c 73047c920d6210e5912c87cdffd9a1c281d4252e
F test/dbfuzz001.test 55e1a3504f8dea84155e09912fe3b1c3ad77e0b1a938ec42ca03b8e51b321e30
@@ -828,14 +830,14 @@ F test/descidx2.test a0ba347037ff3b811f4c6ceca5fd0f9d5d72e74e59f2d9de346a9d2f6ad
F test/descidx3.test 953c831df7ea219c73826dfbf2f6ee02d95040725aa88ccb4fa43d1a1999b926
F test/diskfull.test 106391384780753ea6896b7b4f005d10e9866b6e
F test/distinct.test e7d0cf371944dd0cbedff86420744e2f1ea2b528156451c97eb6ff41a99b9236
F test/distinct2.test 11b0594c932098e969d084ba45ab81d5040f4d4e766db65d49146705a305ed98
F test/distinct2.test cd1d15a4a2abf579298f7161e821ed50c0119136fe0424db85c52cf0adc230d1
F test/distinctagg.test 1a6ef9c87a58669438fc771450d7a72577417376
F test/e_blobbytes.test 439a945953b35cb6948a552edaec4dc31fd70a05
F test/e_blobclose.test 4b3c8c60c2171164d472059c73e9f3c1844bb66d
F test/e_blobopen.test e95e1d40f995056f6f322cd5e1a1b83a27e1a145
F test/e_blobwrite.test f87ff598b67af5b3ec002a8d83e804dc8d23808e88cf0080c176612fc9ffce14
F test/e_changes.test fd66105385153dbf21fdb35eb8ef6c3e1eade579
F test/e_createtable.test ea27082d6f84df61e1d9e383f3fd79220418856a4a8afc41af75d458b8e7ac33
F test/e_createtable.test 7107f5deda2324ea12dbf105044dc9265195401e9dbb3eead6a2c1a3da4bb5b7
F test/e_delete.test ab39084f26ae1f033c940b70ebdbbd523dc4962e
F test/e_droptrigger.test 235c610f8bf8ec44513e222b9085c7e49fad65ad0c1975ac2577109dd06fd8fa
F test/e_dropview.test 74e405df7fa0f762e0c9445b166fe03955856532e2bb234c372f7c51228d75e7
@@ -879,7 +881,7 @@ F test/filter2.tcl 44e525497ce07382915f01bd29ffd0fa49dab3adb87253b5e5103ba8f9339
F test/filter2.test 485cf95d1f6d6ceee5632201ca52a71868599836f430cdee42e5f7f14666e30a
F test/filterfault.test c08fb491d698e8df6c122c98f7db1c65ffcfcad2c1ab0e07fa8a5be1b34eaa8b
F test/fkey1.test d11dbb8a93ead9b5c46ae5d02da016d61245d47662fb2d844c99214f6163f768
F test/fkey2.test b1b6a8c5556dc0ccf31291b1fed8aa57e404b38f3236110e19ab4dc6aa93edf2
F test/fkey2.test 1063d65e5923c054cfb8f0555a92a3ae0fa8c067275a33ee1715bd856cdb304c
F test/fkey3.test 76d475c80b84ee7a5d062e56ccb6ea68882e2b49
F test/fkey4.test 86446017011273aad8f9a99c1a65019e7bd9ca9d
F test/fkey5.test 6727452e163a427147e84e739da18713da553d79f9783559b04fdcd36d5c7421
@@ -1017,7 +1019,7 @@ F test/full.test 6b3c8fb43c6beab6b95438c1675374b95fab245d
F test/func.test f673822636fb8ed618dd2b80230d16e495d19c8f2e2e7d6c22e93e2b3de097ad
F test/func2.test 772d66227e4e6684b86053302e2d74a2500e1e0f
F test/func3.test 2bb0f31ab7baaed690b962a88544d7be6b34fa389364bc36a44e441ed3e3f1e6
F test/func4.test a94858a8c1f10a408b0b3db439c990b59dbb2349411d503de011ac4e2b5f27a6
F test/func4.test 2285fb5792d593fef442358763f0fd9de806eda47dbc7a5934df57ffdc484c31
F test/func5.test 863e6d1bd0013d09c17236f8a13ea34008dd857d87d85a13a673960e4c25d82a
F test/func6.test 90e42b64c4f9fb6f04f44cb8a1da586c8542502e926b19c76504fe74ff2a9b7c
F test/fuzz-oss1.test e58330d01cbbd8215ee636b17a03fe220b37dbfa
@@ -1027,7 +1029,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 656ee850f331872a784e7d6a10649efe2af123bdaacb728b5a03e4faee8b959c
F test/fuzzcheck.c 5f81f2cc65f13068620245f2e2c6059657d3b26be476df379ae2da539f17676d
F test/fuzzdata1.db d36e88741b4f23bcbaaf55b006290669d03c6c891cf13c7b3a53bc1b097b693f
F test/fuzzdata2.db 128b3feeb78918d075c9b14b48610145a0dd4c8d6f1ca7c2870c7e425f5bf31f
F test/fuzzdata3.db c6586d3e3cef0fbc18108f9bb649aa77bfc38aba
@@ -1035,7 +1037,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 99f99201280962430f3287e879e050ba88fe458d05cbf28e37ecab369ffe2e86
F test/fuzzdata8.db f8451a1fd38efbea8c1a7cdf5d02259c4702446a9fabf566becd306b64a50236
F test/fuzzer1.test 3d4c4b7e547aba5e5511a2991e3e3d07166cfbb8
F test/fuzzer2.test a85ef814ce071293bce1ad8dffa217cbbaad4c14
F test/fuzzerfault.test 8792cd77fd5bce765b05d0c8e01b9edcf8af8536
@@ -1050,7 +1052,7 @@ F test/hook2.test b9ff3b8c6519fb67f33192f1afe86e7782ee4ac8
F test/icu.test 716a6b89fbabe5cc63e0cd4c260befb08fd7b9d761f04d43669233292f0753b1
F test/ieee754.test b0945d12be7d255f3dfa18e2511b17ca37e0edd2b803231c52d05b86c04ab26e
F test/imposter1.test c3f1db2d3db2c24611a6596a3fc0ffc14f1466c8
F test/in.test ae4ba0fe3232fdd84ef1090a68c5cd6ccd93f1f8774d5c967dd0c1b301492eed
F test/in.test 688ed2011d922d83141a45af431601738674a4c0bdde34b6351f688b82a169b3
F test/in2.test 5d4c61d17493c832f7d2d32bef785119e87bde75
F test/in3.test 3cbf58c87f4052cee3a58b37b6389777505aa0c0
F test/in4.test 65460600d48933adba4283c6ebd089aae173d16136ab9d01f74c89089090c5a5
@@ -1084,7 +1086,7 @@ F test/init.test 15c823093fdabbf7b531fe22cf037134d09587a7
F test/insert.test 4e3f0de67aac3c5be1f4aaedbcea11638f1b5cdc9a3115be14d19aa9db7623c6
F test/insert2.test 4d14b8f1b810a41995f6286b64a6943215d52208
F test/insert3.test 1b7db95a03ad9c5013fdf7d6722b6cd66ee55e30
F test/insert4.test fb9e0f752c75f453555990250b449f6d123ae6a3ebf054d14e4470de4498dce3
F test/insert4.test 59cb99521be01a5aefc9be8e8b5a51ee7f3944781d4d7f6201b9f774fcd51662
F test/insert5.test 394f96728d1258f406fe5f5aeb0aaf29487c39a6
F test/insertfault.test ac63d14ea3b49c573673a572f4014b9117383a03e497c58f308b5c776e4a7f74
F test/instr.test 107df2b9b74a4b59315916b575590a08f2a714de0754abe541f10a0971d0a2a4
@@ -1101,13 +1103,13 @@ F test/ioerr3.test d3cec5e1a11ad6d27527d0d38573fbff14c71bdd
F test/ioerr4.test f130fe9e71008577b342b8874d52984bd04ede2c
F test/ioerr5.test 2edfa4fb0f896f733071303b42224df8bedd9da4
F test/ioerr6.test a395a6ab144b26a9e3e21059a1ab6a7149cca65b
F test/istrue.test 06f92ea38750fa74df7dbbe6920205251c2310861fbbe23a3adfa918a2e2ba74
F test/join.test bca044589e94bb466e4c1e91fb6fecdc3f3326ca6b3f590f555f1958156eb321
F test/join2.test 7d24d095ab88d3910228d53a3b548b7baf2e0e7d8aac6731a273e300e1b34b61
F test/istrue.test 9619a2d77580f676048aaff7a16a0bcfea2b96c6c660dfaded2e53c873418899
F test/join.test 25da4f53523a4aa17c893134b47fba6aa4799bb33350517b157785878290e238
F test/join2.test 21fc30e54ab35ed66bf51b89cec18729205497f5cc43c83bc042f96a73721593
F test/join3.test 6f0c774ff1ba0489e6c88a3e77b9d3528fb4fda0
F test/join4.test 1a352e4e267114444c29266ce79e941af5885916
F test/join5.test 3a96dc62f0b45402d7207e22d1993fe0c2fce1c57644a11439891dd62b990eb7
F test/join6.test cfe6503791ceb0cbb509966740286ec423cbf10b
F test/join6.test f809c025fa253f9e150c0e9afd4cef8813257bceeb6f46e04041228c9403cc2c
F test/journal1.test c7b768041b7f494471531e17abc2f4f5ebf9e5096984f43ed17c4eb80ba34497
F test/journal2.test 9dac6b4ba0ca79c3b21446bbae993a462c2397c4
F test/journal3.test 7c3cf23ffc77db06601c1fcfc9743de8441cb77db9d1aa931863d94f5ffa140e
@@ -1207,7 +1209,7 @@ F test/notify1.test 669b2b743618efdc18ca4b02f45423d5d2304abf
F test/notify2.test 2ecabaa1305083856b7c39cf32816b612740c161
F test/notify3.test 10ff25cde502e72a92053a2f215d64bece4ef934
F test/notnull.test a37b663d5bb728d66fc182016613fb8e4a0a4bbf3d75b8876a7527f7d4ed3f18
F test/null.test 0dcce4f04284ec66108c503327ad6d224c0752b3
F test/null.test b7ff206a1c60fe01aa2abd33ef9ea83c93727d993ca8a613de86e925c9f2bc6f
F test/nulls1.test 82c5bc33148405f21205865abf13c786084438d573a4ac4e87e11b6091cde526
F test/numcast.test 5d126f7f581432e86a90d1e35cac625164aec4a1
F test/numindex1.test 20a5450d4b056e48cd5db30e659f13347a099823
@@ -1230,7 +1232,7 @@ F test/oserror.test 1fc9746b83d778e70d115049747ba19c7fba154afce7cc165b09feb6ca6a
F test/ossfuzz.c 9636dad2092a05a32110df0ca06713038dd0c43dd89a77dabe4b8b0d71096715
F test/ossshell.c f125c5bd16e537a2549aa579b328dd1c59905e7ab1338dfc210e755bb7b69f17
F test/ovfl.test 199c482696defceacee8c8e0e0ef36da62726b2f
F test/pager1.test 4fba160bf450cea19f6bf1d6483ef467545bac6405570e176c83c2c4b5d6d0d5
F test/pager1.test 293c7ad1f19a07e548179b97534c6588249d4e40058b378ea26e75cc84d936f5
F test/pager2.test 67b8f40ae98112bcdba1f2b2d03ea83266418c71
F test/pager3.test 4e9a83d6ca0838d7c602c9eb93d1357562d9059c1e02ffb138a8271020838370
F test/pager4.test a122e9e6925d5b23b31e3dfef8c6a44bbf19590e
@@ -1262,7 +1264,7 @@ F test/quick.test 1681febc928d686362d50057c642f77a02c62e57
F test/quota-glob.test 32901e9eed6705d68ca3faee2a06b73b57cb3c26
F test/quota.test bfb269ce81ea52f593f9648316cd5013d766dd2a
F test/quota2.test 7dc12e08b11cbc4c16c9ba2aa2e040ea8d8ab4b8
F test/quote.test 626149eda89ee64d81a3790de370f9f0211921b11568a49c28c861f394330508
F test/quote.test 3f9238ab0e1db70dea89af9afa5859dbd759b0ce0a63da67d547553e2c316475
F test/randexpr1.tcl 40dec52119ed3a2b8b2a773bce24b63a3a746459
F test/randexpr1.test eda062a97e60f9c38ae8d806b03b0ddf23d796df
F test/rbu.test 168573d353cd0fd10196b87b0caa322c144ef736
@@ -1272,7 +1274,7 @@ F test/regexp1.test 497ea812f264d12b6198d6e50a76be4a1973a9d8
F test/regexp2.test 40e894223b3d6672655481493f1be12012f2b33c
F test/reindex.test cd9d6021729910ece82267b4f5e1b5ac2911a7566c43b43c176a6a4732e2118d
F test/releasetest.tcl fb76d8fcc95ac29d6356cd9e52b726ab9e43a24082897618dfbcb7c2b0049153 x
F test/releasetest_data.tcl 9919fc6ac5bc92f8878fecfd1840db15999f660a6c9f609240b41aa62b885c88
F test/releasetest_data.tcl b9cb30360759b80d92d4ea86b84ebfd8035b97f9078a482deb3cf9d0b2442655
F test/resetdb.test 8062cf10a09d8c048f8de7711e94571c38b38168db0e5877ba7561789e5eeb2b
F test/resolver01.test f4022acafda7f4d40eca94dbf16bc5fc4ac30ceb
F test/rollback.test 06680159bc6746d0f26276e339e3ae2f951c64812468308838e0a3362d911eaa
@@ -1312,7 +1314,7 @@ F test/schema6.test e4bd1f23d368695eb9e7b51ef6e02ca0642ea2ab4a52579959826b5e7dce
F test/schemafault.test 1936bceca55ac82c5efbcc9fc91a1933e45c8d1e1d106b9a7e56c972a5a2a51e
F test/securedel.test 2f70b2449186a1921bd01ec9da407fbfa98c3a7a5521854c300c194b2ff09384
F test/securedel2.test 2d54c28e46eb1fd6902089958b20b1b056c6f1c5
F test/select1.test 009a6d8eacd9684d046302b8d13b50846a87e39d6f08e92178aa13e95ea29a2d
F test/select1.test 0ed936740777f52858b6607f39ffac4b2b63b8fc7edf3ab2ebad3c3553ceecee
F test/select2.test 352480e0e9c66eda9c3044e412abdf5be0215b56
F test/select3.test c49fbb758903f3718e2de5aa4655eda4838131cbea24a86db908f8b6889aa68c
F test/select4.test e8a2502e3623f3058871030599a48abb35789d2244d5b380ecf3696873fdd4a4
@@ -1344,7 +1346,7 @@ F test/sharedA.test 49d87ec54ab640fbbc3786ee3c01de94aaa482a3a9f834ad3fe92770eb69
F test/sharedB.test 16cc7178e20965d75278f410943109b77b2e645e
F test/shared_err.test 32634e404a3317eeb94abc7a099c556a346fdb8fb3858dbe222a4cbb8926a939
F test/sharedlock.test 5ede3c37439067c43b0198f580fd374ebf15d304
F test/shell1.test 1305efc92f132a1fcf97c00ac02b1b192865b4d33d44cab499e0bdcff71ce045
F test/shell1.test 161353b1d52cfdc7772ebf03f34cc11384f7d8621ae3013394adcddc5357bace
F test/shell2.test e242a9912f44f4c23c3d1d802a83e934e84c853b
F test/shell3.test ac8c2b744014c3e9a0e26bfd829ab65f00923dc1a91ffd044863e9423cc91494
F test/shell4.test 1c6aef11daaa2d6830acaba3ac9cbec93fbc1c3d5530743a637f39b3987d08ce
@@ -1360,7 +1362,7 @@ F test/sidedelete.test f0ad71abe6233e3b153100f3b8d679b19a488329
F test/skipscan1.test ed524bc86f27646b3a297f45d6557b55db338977b6838f8064b196b35848b31b
F test/skipscan2.test 3eb703ce794f139e7b83567911046298bcde29606116727f9b700ce34f559d2d
F test/skipscan3.test ec5bab3f81c7038b43450e7b3062e04a198bdbb5
F test/skipscan5.test 67817a4b6857c47e0e33ba3e506da6f23ef68de2
F test/skipscan5.test 980875ad45d8aacfe7bdec7c288343520cd1d14e84befdcfe50c785f9e6c8709
F test/skipscan6.test 0b4cd1b4ac9f84d91454df513c99a4932fa07e8f27b8049bea605068b3e34ac7
F test/snapshot.test a504f2e7009f512ef66c719f0ea1c55a556bdaf1e1312c80a04d46fc1a3e9632
F test/snapshot2.test 8d6ff5dd9cc503f6e12d408a30409c3f9c653507b24408d9cd7195931c89bc54
@@ -1385,7 +1387,7 @@ F test/speed3.test 694affeb9100526007436334cf7d08f3d74b85ef
F test/speed4.test abc0ad3399dcf9703abed2fff8705e4f8e416715
F test/speed4p.explain 6b5f104ebeb34a038b2f714150f51d01143e59aa
F test/speed4p.test 377a0c48e5a92e0b11c1c5ebb1bc9d83a7312c922bc0cb05970ef5d6a96d1f0c
F test/speedtest1.c ac0e6ebadb97b54b7ac45288d1beea633a219d5fb98aa3395cb8364c31c985cb
F test/speedtest1.c 6f74bbfd6b78c8cf3aa9fc4d2cd3e261322bb140f42fee34df909c76b50fff53
F test/spellfix.test 951a6405d49d1a23d6b78027d3877b4a33eeb8221dcab5704b499755bb4f552e
F test/spellfix2.test dfc8f519a3fc204cb2dfa8b4f29821ae90f6f8c3
F test/spellfix3.test 0f9efaaa502a0e0a09848028518a6fb096c8ad33
@@ -1437,7 +1439,7 @@ F test/thread2.test f35d2106452b77523b3a2b7d1dcde2e5ee8f9e46
F test/thread_common.tcl 334639cadcb9f912bf82aa73f49efd5282e6cadd
F test/threadtest1.c 6029d9c5567db28e6dc908a0c63099c3ba6c383b
F test/threadtest2.c a70a8e94bef23339d34226eb9521015ef99f4df8
F test/threadtest3.c 38a612ea62854349ed66372f330a40d73c5cf956
F test/threadtest3.c e63013af10cf236c7610eb06d33bde08c861806dc64be811940ff4d9ddd34a4f
F test/threadtest4.c c1e67136ceb6c7ec8184e56ac61db28f96bd2925
F test/time-wordcount.sh 8e0b0f8109367827ad5d58f5cc849705731e4b90
F test/tkt-02a8e81d44.test 6c80d9c7514e2a42d4918bf87bf6bc54f379110c
@@ -1588,7 +1590,7 @@ F test/tpch01.test 7c4eb8cdd79c568f46d344b3e789c9fdb8a766d112871352704861f3fca32
F test/trace.test a659a9862957f4789e37a92b3bf6d2caf5c86b02cdeefc41e850ae53acf6992a
F test/trace2.test f5cb67ad3bc09e0c58e8cca78dfd0b5639259983
F test/trace3.test 1dff966888773ff1bfea01c080caf15417892b3f998408fe920c4791f7337144
F test/trans.test 6e1b4c6a42dba31bd65f8fa5e61a2708e08ddde6
F test/trans.test 45f6f9ab6f66a7b5744f1caac06b558f95da62501916906cf55586a896f9f439
F test/trans2.test 62bd045bfc7a1c14c5ba83ba64d21ade31583f76
F test/trans3.test 91a100e5412b488e22a655fe423a14c26403ab94
F test/transitive1.test 293300f46916569f08875cdb2fe2134be2c27677
@@ -1613,6 +1615,7 @@ F test/trustschema1.test 4e970aef0bfe0cee139703cc7209d0e0f07725d999b180ba50770f4
F test/tt3_checkpoint.c 9e75cf7c1c364f52e1c47fd0f14c4340a9db0fe1
F test/tt3_index.c 39eec10a35f57672225be4d182862152896dee4a
F test/tt3_lookaside1.c 0377e202c3c2a50d688cb65ba203afeda6fafeb9
F test/tt3_shared.c b37d22defc944a2ac4c91c927fd06c1d48cd51e2ce9d004fe868625bd2399f93
F test/tt3_stress.c f9a769ca8b026ecc76ee93ca8c9700a5619f8e51c581107c4053ba6ac97f616f
F test/tt3_vacuum.c 1753f45917699c9c1f66b64c717a717c9379f776
F test/types.test bf816ce73c7dfcfe26b700c19f97ef4050d194ff
@@ -1649,7 +1652,7 @@ F test/vacuum5.test 263b144d537e92ad8e9ca8a73cc6e1583f41cfd0dda9432b87f7806174a2
F test/vacuummem.test 7b42abb3208bd82dd23a7536588396f295a314f2
F test/varint.test bbce22cda8fc4d135bcc2b589574be8410614e62
F test/veryquick.test 57ab846bacf7b90cf4e9a672721ea5c5b669b661
F test/view.test 10ea54300a097d7c0337fd104abffe4a4786d1598b94017a37efe0e0d3e04dd5
F test/view.test fd48eddb32a35a98c3de70062ebac66ebf4a2bbfc75a1cc1109159ef8bfc47a9
F test/vtab1.test c5d9e90ed02bcacd776dcbb7360199d290f7f53c26b484ddece543060c54319f
F test/vtab2.test 14d4ab26cee13ba6cf5c5601b158e4f57552d3b055cdd9406cf7f711e9c84082
F test/vtab3.test b45f47d20f225ccc9c28dc915d92740c2dee311e
@@ -1667,7 +1670,7 @@ F test/vtabE.test 2a143fe75a11275781d1fd1988d86b66a3f69cb98f4add62e3da8fd0f637b4
F test/vtabF.test 1918844c7c902f6a16c8dacf1ec8f84886d6e78b
F test/vtabH.test 2efb5a24b0bb50796b21eca23032cfb77abfa4b0c03938e38ce5897abac404ca
F test/vtabI.test 751b07636700dbdea328e4265b6077ccd6811a3f
F test/vtabJ.test d7b73675708cf63cfcb9d443bb451fc01a028347275b7311e51f9fdf3ca6757f
F test/vtabJ.test a6aef49d558af90fae10565b29501f82a95781cb4f797f2d13e2d19f9b6bc77b
F test/vtab_alter.test 736e66fb5ec7b4fee58229aa3ada2f27ec58bc58c00edae4836890c3784c6783
F test/vtab_err.test dcc8b7b9cb67522b3fe7a272c73856829dae4ab7fdb30399aea1b6981bda2b65
F test/vtab_shared.test 5253bff2355a9a3f014c15337da7e177ab0ef8ad
@@ -1710,7 +1713,7 @@ F test/walthread.test 14b20fcfa6ae152f5d8e12f5dc8a8a724b7ef189f5d8ef1e2ceab79f2a
F test/walvfs.test a2913001a83b19c1d20220e556cee14d87d47ecb6949b5e0a2e9e2590abecf1e
F test/wapp.tcl b440cd8cf57953d3a49e7ee81e6a18f18efdaf113b69f7d8482b0710a64566ec
F test/wapptest.tcl 899594e25684861d5b0c0880fb012364def50ef8097041b8ddf74be5ba7fa270 x
F test/where.test f5e62453537e5b335b69f3b09f8a02ce3328289fad5d866e25371284b837d78d
F test/where.test e713c0c64e3e6b062235e39a2f7e5508c517df16b63d69fd786e26bc7330b1c6
F test/where2.test 478d2170637b9211f593120648858593bf2445a1
F test/where3.test 2341a294e17193a6b1699ea7f192124a5286ca6acfcc3f4b06d16c931fbcda2c
F test/where4.test 4a371bfcc607f41d233701bdec33ac2972908ba8
@@ -1719,13 +1722,13 @@ F test/where6.test 5da5a98cec820d488e82708301b96cb8c18a258b
F test/where7.test 75722434c486ac9e74718caa6cce234f45ba34c0b6c0f9555b29eb8bb5f6ade1
F test/where8.test 461ca40265ed996a6305da99bb024b0e41602bb586acf544c08f95922358e49f
F test/where9.test 8e3e0ff42cc17156f52361a1c012281550d0d632912fec92d1d6df74db7a8e6d
F test/whereA.test 6c6a420ca7d313242f9b1bd471dc80e4d0f8323700ba9c78df0bb843d4daa3b4
F test/whereA.test 9d1077b117f1b68d5f739d94f36956c36cf995eb87bb19b77b2e81af020edd20
F test/whereB.test 0def95db3bdec220a731c7e4bec5930327c1d8c5
F test/whereC.test cae295158703cb3fc23bf1a108a9ab730efff0f6
F test/whereD.test c1c335e914e28b122e000e9310f02d2be83e1c9dbca2e29f46bd732703944d1b
F test/whereE.test b3a055eef928c992b0a33198a7b8dc10eea5ad2f
F test/whereF.test 3d9412b1199d3e2bed34fcb76b4c48d0bf4df95d27e3f8dd27b6f8b4716d0d89
F test/whereG.test 9363b2a97d914cb1b81aff5069ef0cf2a071a67e2b604eac6fe9c0114017d9aa
F test/whereG.test 77127a4d214bb21da3b5c695cf4106cd9e418c60d9c24471ba55d3772067cd35
F test/whereH.test e4b07f7a3c2f5d31195cd33710054c78667573b2
F test/whereI.test a2874062140ed4aba9ffae76e6190a3df6fc73d1373fdfa8fd632945082a5364
F test/whereJ.test 88287550f6ee604422403b053455b1ad894eeaa5c35d348532dfa1439286cb9a
@@ -1758,14 +1761,15 @@ F test/windowB.test 7a983ea1cc1cf72be7f378e4b32f6cb2d73014c5cd8b25aaee825164cd42
F test/windowerr.tcl f5acd6fbc210d7b5546c0e879d157888455cd4a17a1d3f28f07c1c8a387019e0
F test/windowerr.test a8b752402109c15aa1c5efe1b93ccb0ce1ef84fa964ae1cd6684dd0b3cc1819b
F test/windowfault.test 72375ae71031eabf96bc88d0af128c8628a091ddc99b5a394e848b3df5fc17ad
F test/with1.test 584580a5ae79868a91873863f8cb2d00040006dc1e4c332ef1d8642f2815dc6e
F test/with1.test 780be387f01e290e768bdfd1827280f9e37ba37223eb4736aba386864fac5a94
F test/with2.test e0030e2f0267a910d6c0e4f46f2dfe941c1cc0d4f659ba69b3597728e7e8f1ab
F test/with3.test 13b3336739da648a9e4dfa11bb04e73a920c97620041007c5f75d5d14084c346
F test/with3.test a261f0ea225c4af0ce6447f1157bb603959b2a665f14a03951c2883d2ef1c0f0
F test/with4.test 257be66c0c67fee1defbbac0f685c3465e2cad037f21ce65f23f86084f198205
F test/with5.test 6248213c41fab36290b5b73aa3f937309dfba337004d9d8434c3fabc8c7d4be8
F test/withM.test 693b61765f2b387b5e3e24a4536e2e82de15ff64
F test/without_rowid1.test 9cfb83705c506e3849fa7efc88a3c9a15f9a50bf9b1516b41757a7cef9bba8c3
F test/without_rowid1.test e4034c0849ccc2e8bb749c69f15bd69bb9fcf8fe77e8d17ce02369604242fe83
F test/without_rowid2.test af260339f79d13cb220288b67cd287fbcf81ad99
F test/without_rowid3.test 96426a6c9a2a5cf62bbe55ea1ad038eaaf4bf743f40a1ad517233b8e5a3d4339
F test/without_rowid3.test 39ab0dd773eaa62e59b17093f875327630f54c4145458f6d2b053d68d4b2f67b
F test/without_rowid4.test 4e08bcbaee0399f35d58b5581881e7a6243d458a
F test/without_rowid5.test 89b1c587bd92a0590e440da33e7666bf4891572a
F test/without_rowid6.test 8463b20098e9f75a501a9f17dfb42fffc79068eac0b2775fe56ef2281d2df45e
@@ -1778,7 +1782,7 @@ F test/zipfile.test 429cb81c518487fa1b644b6b04b6e9af704a4fa767bd1a110204c5f03b2e
F test/zipfile2.test 9903388a602a3834189857a985106ff95c3bba6a3969e0134127df991889db5d
F test/zipfilefault.test 44d4d7a7f7cca7521d569d7f71026b241d65a6b1757aa409c1a168827edbbc2c
F tool/GetFile.cs 47852aa0d806fe47ed1ac5138bdce7f000fe87aaa7f28107d0cb1e26682aeb44
F tool/GetTclKit.bat 8995df40c4209808b31f24de0b58f90930239a234f7591e3675d45bfbb990c5d
F tool/GetTclKit.bat e95747c0f7a9fe279a9979178b71f6431a21f945b390fc3120244897ff3f5135
F tool/Replace.cs 02c67258801c2fb5f63231e0ac0f220b4b36ba91
F tool/build-all-msvc.bat c12328d06c45fec8baada5949e3d5af54bf8c887 x
F tool/build-shell.sh 950f47c6174f1eea171319438b93ba67ff5bf367
@@ -1798,8 +1802,8 @@ F tool/genfkey.test b6afd7b825d797a1e1274f519ab5695373552ecad5cd373530c63533638a
F tool/getlock.c f4c39b651370156cae979501a7b156bdba50e7ce
F tool/index_usage.c f62a0c701b2c7ff2f3e21d206f093c123f222dbf07136a10ffd1ca15a5c706c5
F tool/kvtest-speed.sh 4761a9c4b3530907562314d7757995787f7aef8f
F tool/lemon.c 600a58b9d1b8ec5419373982428e927ca208826edacb91ca42ab94514d006039
F tool/lempar.c e8899b28488f060d0ff931539ea6311b16b22dce068c086c788a06d5e8d01ab7
F tool/lemon.c 70eedc31614a58fe31a71025c17ebd1502a6ce9cfef0ed5e33acb0b5b737b291
F tool/lempar.c 0e1d5eeb9736108d3dba782a9dd56f4e7cb69006b6ee181308b7ebfb15313a12
F tool/libvers.c caafc3b689638a1d88d44bc5f526c2278760d9b9
F tool/loadfts.c c3c64e4d5e90e8ba41159232c2189dba4be7b862
F tool/logest.c 11346aa019e2e77a00902aa7d0cabd27bd2e8cca
@@ -1817,7 +1821,7 @@ F tool/mkshellc.tcl 70a9978e363b0f3280ca9ce1c46d72563ff479c1930a12a7375e3881b732
F tool/mksourceid.c 36aa8020014aed0836fd13c51d6dc9219b0df1761d6b5f58ff5b616211b079b9
F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97
F tool/mksqlite3c-noext.tcl 4f7cfef5152b0c91920355cbfc1d608a4ad242cb819f1aea07f6d0274f584a7f
F tool/mksqlite3c.tcl f4ef476510eca4124c874a72029f1e01bc54a896b1724e8f9eef0d8bfae0e84c
F tool/mksqlite3c.tcl 00c4c0382eb000153182da2bee2547ca05554eeeed10177efe5894c54e4e6d4d
F tool/mksqlite3h.tcl 1f5e4a1dbbbc43c83cc6e74fe32c6c620502240b66c7c0f33a51378e78fc4edf
F tool/mksqlite3internalh.tcl eb994013e833359137eb53a55acdad0b5ae1049b
F tool/mkvsix.tcl b9e0777a213c23156b6542842c238479e496ebf5
@@ -1844,7 +1848,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
F tool/speedtest8inst1.c 7ce07da76b5e745783e703a834417d725b7d45fd
F tool/split-sqlite3c.tcl 3efcd4240b738f6bb2b5af0aea7e1e0ef9bc1c61654f645076cec883030b710c
F tool/sqldiff.c 5046b8e227213ad016b336eb5a933e252e1f0fd1e07060c5755e259a30891287
F tool/sqldiff.c a3362140091b6d8a0771a589aaff147c114b13eb915927390587f0fa78c2040d
F tool/sqlite3_analyzer.c.in 7eeaae8b0d7577662acaabbb11107af0659d1b41bc1dfdd4d91422de27127968
F tool/sqltclsh.c.in 1bcc2e9da58fadf17b0bf6a50e68c1159e602ce057210b655d50bad5aaaef898
F tool/sqltclsh.tcl 862f4cf1418df5e1315b5db3b5ebe88969e2a784525af5fbf9596592f14ed848
@@ -1879,7 +1883,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
P a495f60d315e34b1a1bc5fb1336e05047add52c8fb2710b577c97b10a5e734f6
R 54b8b0b6f00b6cfab28e2e5a52014ff6
U drh
Z a854ac35ef1e1fa9d5bc731176f5cbf6
P eb6e5fc1891be52acf378269405a99bab92b9bf501b7eba04eae07c851ed3027
R 4d578fe854f29eb4522630d2ff1014ab
T +closed *
U shearer
Z 451aeadec2dd7d0cf13fe0ace3038992
+1 -1
View File
@@ -1 +1 @@
611b640442025e57b8e161f8ddac1f19bd3be9a3d5266f4cef287595c3ed9257
ee9689ad2fadb3b9c11235312bfc32a1db294485b4503a07692bbdbce71e021d
+1
View File
@@ -1772,6 +1772,7 @@ static int loadStatTbl(
}
pSpace = (tRowcnt*)&pIdx->aSample[nSample];
pIdx->aAvgEq = pSpace; pSpace += nIdxCol;
pIdx->pTable->tabFlags |= TF_HasStat4;
for(i=0; i<nSample; i++){
pIdx->aSample[i].anEq = pSpace; pSpace += nIdxCol;
pIdx->aSample[i].anLt = pSpace; pSpace += nIdxCol;
+3 -1
View File
@@ -293,7 +293,9 @@ static void detachFunc(
sqlite3_snprintf(sizeof(zErr),zErr, "cannot detach database %s", zName);
goto detach_error;
}
if( sqlite3BtreeIsInReadTrans(pDb->pBt) || sqlite3BtreeIsInBackup(pDb->pBt) ){
if( sqlite3BtreeTxnState(pDb->pBt)!=SQLITE_TXN_NONE
|| sqlite3BtreeIsInBackup(pDb->pBt)
){
sqlite3_snprintf(sizeof(zErr),zErr, "database %s is locked", zName);
goto detach_error;
}
+4 -4
View File
@@ -123,7 +123,7 @@ static int setDestPgsz(sqlite3_backup *p){
** message in database handle db.
*/
static int checkReadTransaction(sqlite3 *db, Btree *p){
if( sqlite3BtreeIsInReadTrans(p) ){
if( sqlite3BtreeTxnState(p)!=SQLITE_TXN_NONE ){
sqlite3ErrorWithMsg(db, SQLITE_ERROR, "destination database is in use");
return SQLITE_ERROR;
}
@@ -354,7 +354,7 @@ int sqlite3_backup_step(sqlite3_backup *p, int nPage){
** one now. If a transaction is opened here, then it will be closed
** before this function exits.
*/
if( rc==SQLITE_OK && 0==sqlite3BtreeIsInReadTrans(p->pSrc) ){
if( rc==SQLITE_OK && SQLITE_TXN_NONE==sqlite3BtreeTxnState(p->pSrc) ){
rc = sqlite3BtreeBeginTrans(p->pSrc, 0, 0);
bCloseTrans = 1;
}
@@ -726,7 +726,7 @@ int sqlite3BtreeCopyFile(Btree *pTo, Btree *pFrom){
sqlite3BtreeEnter(pTo);
sqlite3BtreeEnter(pFrom);
assert( sqlite3BtreeIsInTrans(pTo) );
assert( sqlite3BtreeTxnState(pTo)==SQLITE_TXN_WRITE );
pFd = sqlite3PagerFile(sqlite3BtreePager(pTo));
if( pFd->pMethods ){
i64 nByte = sqlite3BtreeGetPageSize(pFrom)*(i64)sqlite3BtreeLastPage(pFrom);
@@ -762,7 +762,7 @@ int sqlite3BtreeCopyFile(Btree *pTo, Btree *pFrom){
sqlite3PagerClearCache(sqlite3BtreePager(b.pDest));
}
assert( sqlite3BtreeIsInTrans(pTo)==0 );
assert( sqlite3BtreeTxnState(pTo)!=SQLITE_TXN_WRITE );
copy_finished:
sqlite3BtreeLeave(pFrom);
sqlite3BtreeLeave(pTo);
+23 -13
View File
@@ -112,6 +112,17 @@ int sqlite3_enable_shared_cache(int enable){
#define hasReadConflicts(a, b) 0
#endif
#ifdef SQLITE_DEBUG
/*
** Return an reset the seek counter for a Btree object.
*/
sqlite3_uint64 sqlite3BtreeSeekCount(Btree *pBt){
u64 n = pBt->nSeek;
pBt->nSeek = 0;
return n;
}
#endif
/*
** Implementation of the SQLITE_CORRUPT_PAGE() macro. Takes a single
** (MemPage*) as an argument. The (MemPage*) must not be NULL.
@@ -2605,7 +2616,7 @@ btree_open_out:
** do not change the pager-cache size.
*/
if( sqlite3BtreeSchema(p, 0, 0)==0 ){
sqlite3PagerSetCachesize(p->pBt->pPager, SQLITE_DEFAULT_CACHE_SIZE);
sqlite3BtreeSetCacheSize(p, SQLITE_DEFAULT_CACHE_SIZE);
}
pFile = sqlite3PagerFile(pBt->pPager);
@@ -5459,6 +5470,10 @@ int sqlite3BtreeMovetoUnpacked(
}
}
#ifdef SQLITE_DEBUG
pCur->pBtree->nSeek++; /* Performance measurement during testing */
#endif
if( pIdxKey ){
xRecordCompare = sqlite3VdbeFindCompare(pIdxKey);
pIdxKey->errCode = 0;
@@ -5735,7 +5750,7 @@ static SQLITE_NOINLINE int btreeNext(BtCursor *pCur){
pPage = pCur->pPage;
idx = ++pCur->ix;
if( !pPage->isInit ){
if( !pPage->isInit || sqlite3FaultSim(412) ){
/* The only known way for this to happen is for there to be a
** recursive SQL function that does a DELETE operation as part of a
** SELECT which deletes content out from under an active cursor
@@ -10310,11 +10325,12 @@ const char *sqlite3BtreeGetJournalname(Btree *p){
}
/*
** Return non-zero if a transaction is active.
** Return one of SQLITE_TXN_NONE, SQLITE_TXN_READ, or SQLITE_TXN_WRITE
** to describe the current transaction state of Btree p.
*/
int sqlite3BtreeIsInTrans(Btree *p){
int sqlite3BtreeTxnState(Btree *p){
assert( p==0 || sqlite3_mutex_held(p->db->mutex) );
return (p && (p->inTrans==TRANS_WRITE));
return p ? p->inTrans : 0;
}
#ifndef SQLITE_OMIT_WAL
@@ -10343,14 +10359,8 @@ int sqlite3BtreeCheckpoint(Btree *p, int eMode, int *pnLog, int *pnCkpt){
#endif
/*
** Return non-zero if a read (or write) transaction is active.
** Return true if there is currently a backup running on Btree p.
*/
int sqlite3BtreeIsInReadTrans(Btree *p){
assert( p );
assert( sqlite3_mutex_held(p->db->mutex) );
return p->inTrans!=TRANS_NONE;
}
int sqlite3BtreeIsInBackup(Btree *p){
assert( p );
assert( sqlite3_mutex_held(p->db->mutex) );
@@ -10532,7 +10542,7 @@ int sqlite3BtreeSetVersion(Btree *pBtree, int iVersion){
/*
** Return true if the cursor has a hint specified. This routine is
** only used from within assert() statements
** only used from within or around assert() statements
*/
int sqlite3BtreeCursorHasHint(BtCursor *pCsr, unsigned int mask){
return (pCsr->hints & mask)!=0;
+348 -168
View File
@@ -9,17 +9,99 @@
** May you share freely, never taking more than you give.
**
*************************************************************************
** This header file defines the interface that the sqlite B-Tree file
** subsystem. See comments in the source code for a detailed description
** of what each interface routine does.
** This header file defines the interface to the sqlite B-Tree storage
** subsystem. All SQLite database operations become calls to the B-Tree
** storage layer. The B-Tree layer requires a key-value store underneath
** that is capable of MVCC - that is, transaction commit and rollback,
** locking and concurrent access. See comments in btree.c for a detailed
** description of each interface routine.
**
** The btree module organises an SQL database of tables and rows into
** multiple key-value pair stores, which in turn are represented as
** fixed-size pages in the memory-based page cache. The BTree functions
** operate on pages in the page cache. A separate B-tree is used for each
** table and each index in the database. Databases are stored in an on-disk
** Database Image, which the B-Tree module knows nothing about except for
** opening and closing.
**
** The architecture is described at https://www.sqlite.org/arch.html .
**
** A Btree record is also called a payload in SQLite source. A Btree
** record for table data contains only two fields: the unique key value
** ROWID, and the table row data. A Btree record for an index btree or
** a WITHOUT ROWID table contain an arbitary key and no (uninitialised) data.
** Btree pages are a fixed size. There will usually be multiple payloads
** per page, but large payloads (eg BLOB data) may spill over to multiple
** pages.
**
** Functions in this header file are grouped according to their logical task:
**
** Opening and Closing Database Connections
**
** Database Image Configuration and Querying
**
** Btree Connection Configuration and Querying
**
** Mutex Function Wrappers
**
** Transaction and Savepoint Functions
**
** Cursors and Cursor Functions
**
** Record and Payload Handling Functions
**
** Table Functions
**
** Reading and Writing Metadata
**
*/
#ifndef SQLITE_BTREE_H
#define SQLITE_BTREE_H
/* TODO: This definition is just included so other modules compile. It
** needs to be revisited.
/*
** Forward declarations of structure
*/
typedef struct Btree Btree;
typedef struct BtCursor BtCursor;
typedef struct BtShared BtShared;
typedef struct BtreePayload BtreePayload;
/*
********************************************
* Opening and Closing Database Connections
********************************************
*/
int sqlite3BtreeOpen(
sqlite3_vfs *pVfs, /* VFS to use with this b-tree */
const char *zFilename, /* Name of database file to open */
sqlite3 *db, /* Associated database connection */
Btree **ppBtree, /* Return open Btree* here */
int flags, /* Flags */
int vfsFlags /* Flags passed through to VFS open */
);
/* The flags parameter to sqlite3BtreeOpen can be the bitwise OR of the
** following values.
**
** NOTE: These values must match the corresponding PAGER_ values in
** pager.h.
*/
#define BTREE_OMIT_JOURNAL 1 /* No create/use journal in temp databases */
#define BTREE_MEMORY 2 /* This is an in-memory DB */
#define BTREE_SINGLE 4 /* The file contains at most 1 b-tree */
#define BTREE_UNORDERED 8 /* Use of a hash implementation is OK */
/* Only a BTREE_SINGLE can be BTREE_UNORDERED */
int sqlite3BtreeClose(Btree*);
/*
**********************************************
** Database Image Configuration and Querying
**********************************************
*/
#define SQLITE_N_BTREE_META 16
/*
** If defined as non-zero, auto-vacuum is enabled by default. Otherwise
@@ -33,124 +115,148 @@
#define BTREE_AUTOVACUUM_FULL 1 /* Do full auto-vacuum */
#define BTREE_AUTOVACUUM_INCR 2 /* Incremental vacuum */
/*
** Forward declarations of structure
*/
typedef struct Btree Btree;
typedef struct BtCursor BtCursor;
typedef struct BtShared BtShared;
typedef struct BtreePayload BtreePayload;
int sqlite3BtreeSetPageSize(Btree *p, int nPagesize, int nReserve, int eFix);
int sqlite3BtreeGetPageSize(Btree*);
int sqlite3BtreeSetAutoVacuum(Btree *, int);
int sqlite3BtreeGetAutoVacuum(Btree *);
int sqlite3BtreeOpen(
sqlite3_vfs *pVfs, /* VFS to use with this b-tree */
const char *zFilename, /* Name of database file to open */
sqlite3 *db, /* Associated database connection */
Btree **ppBtree, /* Return open Btree* here */
int flags, /* Flags */
int vfsFlags /* Flags passed through to VFS open */
);
/* The flags parameter to sqlite3BtreeOpen can be the bitwise or of the
** following values.
**
** NOTE: These values must match the corresponding PAGER_ values in
** pager.h.
*/
#define BTREE_OMIT_JOURNAL 1 /* Do not create or use a rollback journal */
#define BTREE_MEMORY 2 /* This is an in-memory DB */
#define BTREE_SINGLE 4 /* The file contains at most 1 b-tree */
#define BTREE_UNORDERED 8 /* Use of a hash implementation is OK */
int sqlite3BtreeClose(Btree*);
int sqlite3BtreeSetCacheSize(Btree*,int);
int sqlite3BtreeSetSpillSize(Btree*,int);
#if SQLITE_MAX_MMAP_SIZE>0
int sqlite3BtreeSetMmapLimit(Btree*,sqlite3_int64);
#endif
int sqlite3BtreeSetPagerFlags(Btree*,unsigned);
int sqlite3BtreeSetPageSize(Btree *p, int nPagesize, int nReserve, int eFix);
int sqlite3BtreeGetPageSize(Btree*);
Pgno sqlite3BtreeMaxPageCount(Btree*,Pgno);
Pgno sqlite3BtreeLastPage(Btree*);
int sqlite3BtreeSecureDelete(Btree*,int);
int sqlite3BtreeGetRequestedReserve(Btree*);
int sqlite3BtreeGetReserveNoMutex(Btree *p);
int sqlite3BtreeSetAutoVacuum(Btree *, int);
int sqlite3BtreeGetAutoVacuum(Btree *);
/* Implements PRAGMA integrity_check on a Btree and its associated file.
* Only called from vdbe.c/OP_IntegrityCk */
char *sqlite3BtreeIntegrityCheck(sqlite3*,Btree*,Pgno*aRoot,int nRoot,int,int*);
/* A single step of an incremental vacuum. For PRAGMA incremental_vacuum(N) */
/* Neither autovacuum mode nor the VACUUM SQLite command use this function. */
int sqlite3BtreeIncrVacuum(Btree *);
/* Copy a complete Btree into another Btree, ie from one file into another */
/* Used only in the case of a backup and vacuum operations */
int sqlite3BtreeCopyFile(Btree *, Btree *);
/*
************************************************
** Btree Connection Configuration and Querying
************************************************
*/
int sqlite3BtreeSetCacheSize(Btree*,int);
Pgno sqlite3BtreeMaxPageCount(Btree*,Pgno);
Pgno sqlite3BtreeLastPage(Btree*);
const char *sqlite3BtreeGetFilename(Btree *);
const char *sqlite3BtreeGetJournalname(Btree *);
int sqlite3BtreeIsReadonly(Btree *pBt);
/* Estimate number of rows in table
* called only by OP IsSmaller, from PRAGMA optimize
*/
i64 sqlite3BtreeRowCountEst(BtCursor*);
/* Return the pager associated with a BTree */
struct Pager *sqlite3BtreePager(Btree*);
/*
****************************
** Mutex Function Wrappers
****************************
**
** Every lock applies to an entire BTree. These functions are
** wrappers for the sqlite3_mutex* functions, which are called
** outside btree.c
*/
/*
** If we are not using shared cache, then there is no need to
** use mutexes to access the BtShared structures. So make the
** Enter and Leave procedures no-ops.
*/
#ifndef SQLITE_OMIT_SHARED_CACHE
void sqlite3BtreeEnter(Btree*);
void sqlite3BtreeEnterAll(sqlite3*);
int sqlite3BtreeSharable(Btree*);
void sqlite3BtreeEnterCursor(BtCursor*);
int sqlite3BtreeConnectionCount(Btree*);
#else
# define sqlite3BtreeEnter(X)
# define sqlite3BtreeEnterAll(X)
# define sqlite3BtreeSharable(X) 0
# define sqlite3BtreeEnterCursor(X)
# define sqlite3BtreeConnectionCount(X) 1
#endif
#if !defined(SQLITE_OMIT_SHARED_CACHE) && SQLITE_THREADSAFE
void sqlite3BtreeLeave(Btree*);
void sqlite3BtreeLeaveCursor(BtCursor*);
void sqlite3BtreeLeaveAll(sqlite3*);
#ifndef NDEBUG
/* These routines are used inside assert() statements only. */
int sqlite3BtreeHoldsMutex(Btree*);
int sqlite3BtreeHoldsAllMutexes(sqlite3*);
int sqlite3SchemaMutexHeld(sqlite3*,int,Schema*);
#endif
#else
# define sqlite3BtreeLeave(X)
# define sqlite3BtreeLeaveCursor(X)
# define sqlite3BtreeLeaveAll(X)
# define sqlite3BtreeHoldsMutex(X) 1
# define sqlite3BtreeHoldsAllMutexes(X) 1
# define sqlite3SchemaMutexHeld(X,Y,Z) 1
#endif
/*
****************************************
** Transaction and SavePoint Functions
****************************************
*/
int sqlite3BtreeBeginTrans(Btree*,int,int*);
int sqlite3BtreeCommitPhaseOne(Btree*, const char*);
int sqlite3BtreeCommitPhaseOne(Btree*, const char *zMaster);
int sqlite3BtreeCommitPhaseTwo(Btree*, int);
int sqlite3BtreeCommit(Btree*);
int sqlite3BtreeRollback(Btree*,int,int);
int sqlite3BtreeBeginStmt(Btree*,int);
int sqlite3BtreeCreateTable(Btree*, Pgno*, int flags);
int sqlite3BtreeIsInTrans(Btree*);
int sqlite3BtreeIsInReadTrans(Btree*);
int sqlite3BtreeTxnState(Btree*);
int sqlite3BtreeIsInBackup(Btree*);
void *sqlite3BtreeSchema(Btree *, int, void(*)(void *));
int sqlite3BtreeSchemaLocked(Btree *pBtree);
#ifndef SQLITE_OMIT_SHARED_CACHE
int sqlite3BtreeLockTable(Btree *pBtree, int iTab, u8 isWriteLock);
#endif
/* Savepoints are named, nestable SQL transactions mostly implemented */
/* in vdbe.c and pager.c See https://sqlite.org/lang_savepoint.html */
int sqlite3BtreeSavepoint(Btree *, int, int);
const char *sqlite3BtreeGetFilename(Btree *);
const char *sqlite3BtreeGetJournalname(Btree *);
int sqlite3BtreeCopyFile(Btree *, Btree *);
/* A statement sub-transaction is an internal-only transaction used */
/* only by OP_Transaction, see comments in vdbe.c. A statement */
/* sub-transaction is implemented as an anonymous savepoint. */
int sqlite3BtreeBeginStmt(Btree*,int);
int sqlite3BtreeIncrVacuum(Btree *);
/* A checkpoint refers to only to WAL. See https://sqlite.org/wal.html#ckpt */
#ifndef SQLITE_OMIT_WAL
int sqlite3BtreeCheckpoint(Btree*, int, int *, int *);
#endif
/* The flags parameter to sqlite3BtreeCreateTable can be the bitwise OR
** of the flags shown below.
**
** Every SQLite table must have either BTREE_INTKEY or BTREE_BLOBKEY set.
** With BTREE_INTKEY, the table key is a 64-bit integer and arbitrary data
** is stored in the leaves. (BTREE_INTKEY is used for SQL tables.) With
** BTREE_BLOBKEY, the key is an arbitrary BLOB and no content is stored
** anywhere - the key is the content. (BTREE_BLOBKEY is used for SQL
** indices.)
*/
#define BTREE_INTKEY 1 /* Table has only 64-bit signed integer keys */
#define BTREE_BLOBKEY 2 /* Table has keys only - no data */
int sqlite3BtreeDropTable(Btree*, int, int*);
int sqlite3BtreeClearTable(Btree*, int, int*);
int sqlite3BtreeClearTableOfCursor(BtCursor*);
/* Set all relevant cursors to error state on transaction rollback */
int sqlite3BtreeTripAllCursors(Btree*, int, int);
void sqlite3BtreeGetMeta(Btree *pBtree, int idx, u32 *pValue);
int sqlite3BtreeUpdateMeta(Btree*, int idx, u32 value);
int sqlite3BtreeNewDb(Btree *p);
/*
** The second parameter to sqlite3BtreeGetMeta or sqlite3BtreeUpdateMeta
** should be one of the following values. The integer values are assigned
** to constants so that the offset of the corresponding field in an
** SQLite database header may be found using the following formula:
*********************************
** Cursors and Cursor functions
*********************************
**
** offset = 36 + (idx * 4)
**
** For example, the free-page-count field is located at byte offset 36 of
** the database file header. The incr-vacuum-flag field is located at
** byte offset 64 (== 36+4*7).
**
** The BTREE_DATA_VERSION value is not really a value stored in the header.
** It is a read-only number computed by the pager. But we merge it with
** the header value access routines since its access pattern is the same.
** Call it a "virtual meta value".
*/
#define BTREE_FREE_PAGE_COUNT 0
#define BTREE_SCHEMA_VERSION 1
#define BTREE_FILE_FORMAT 2
#define BTREE_DEFAULT_CACHE_SIZE 3
#define BTREE_LARGEST_ROOT_PAGE 4
#define BTREE_TEXT_ENCODING 5
#define BTREE_USER_VERSION 6
#define BTREE_INCR_VACUUM 7
#define BTREE_APPLICATION_ID 8
#define BTREE_DATA_VERSION 15 /* A virtual meta-value */
/*
** Kinds of hints that can be passed into the sqlite3BtreeCursorHint()
@@ -225,12 +331,28 @@ int sqlite3BtreeNewDb(Btree *p);
int sqlite3BtreeCursor(
Btree*, /* BTree containing table to open */
Pgno iTable, /* Index of root page */
Pgno iTable, /* Index of root page */
int wrFlag, /* 1 for writing. 0 for read-only */
struct KeyInfo*, /* First argument to compare function */
BtCursor *pCursor /* Space to write cursor structure */
);
/* True if hint specified, used in or around assert statements only */
int sqlite3BtreeCursorHasHint(BtCursor*, unsigned int mask);
BtCursor *sqlite3BtreeFakeValidCursor(void);
#ifdef SQLITE_DEBUG
sqlite3_uint64 sqlite3BtreeSeekCount(Btree*);
#else
# define sqlite3BtreeSeekCount(X) 0
#endif
#ifndef NDEBUG
int sqlite3BtreeCursorIsValid(BtCursor*);
#endif
int sqlite3BtreeCursorIsValidNN(BtCursor*);
int sqlite3BtreeCursorSize(void);
void sqlite3BtreeCursorZero(BtCursor*);
void sqlite3BtreeCursorHintFlags(BtCursor*, unsigned);
@@ -238,7 +360,10 @@ void sqlite3BtreeCursorHintFlags(BtCursor*, unsigned);
void sqlite3BtreeCursorHint(BtCursor*, int, ...);
#endif
void sqlite3BtreeClearCursor(BtCursor *);
int sqlite3BtreeCloseCursor(BtCursor*);
/* Cursor seek to a specified rowid in the Btree */
int sqlite3BtreeMovetoUnpacked(
BtCursor*,
UnpackedRecord *pUnKey,
@@ -246,9 +371,42 @@ int sqlite3BtreeMovetoUnpacked(
int bias,
int *pRes
);
int sqlite3BtreeCursorHasMoved(BtCursor*);
int sqlite3BtreeCursorRestore(BtCursor*, int*);
int sqlite3BtreeDelete(BtCursor*, u8 flags);
int sqlite3BtreeFirst(BtCursor*, int *pRes);
int sqlite3BtreeLast(BtCursor*, int *pRes);
int sqlite3BtreeNext(BtCursor*, int flags);
int sqlite3BtreeEof(BtCursor*);
int sqlite3BtreePrevious(BtCursor*, int flags);
i64 sqlite3BtreeIntegerKey(BtCursor*);
int sqlite3BtreeCount(sqlite3*, BtCursor*, i64*);
void *sqlite3BtreeSchema(Btree *, int, void(*)(void *));
int sqlite3BtreeSchemaLocked(Btree *pBtree);
#ifndef SQLITE_OMIT_SHARED_CACHE
int sqlite3BtreeLockTable(Btree *pBtree, int iTab, u8 isWriteLock);
#endif
void sqlite3BtreeCursorPin(BtCursor*);
void sqlite3BtreeCursorUnpin(BtCursor*);
int sqlite3BtreeCursorHasMoved(BtCursor*);
int sqlite3BtreeCursorRestore(BtCursor*, int*);
#ifdef SQLITE_TEST
int sqlite3BtreeCursorInfo(BtCursor*, int*, int);
void sqlite3BtreeCursorList(Btree*);
#endif
/*
******************************************
** Record and Payload handling functions
******************************************
**
** A Btree record is a key-value pair consisting of a rowid key, and arbitary
** data value. The record is also called a payload.
**
*/
/* Allowed flags for sqlite3BtreeDelete() and sqlite3BtreeInsert() */
#define BTREE_SAVEPOSITION 0x02 /* Leave cursor pointing at NEXT or PREV */
@@ -300,92 +458,114 @@ struct BtreePayload {
int sqlite3BtreeInsert(BtCursor*, const BtreePayload *pPayload,
int flags, int seekResult);
int sqlite3BtreeFirst(BtCursor*, int *pRes);
int sqlite3BtreeLast(BtCursor*, int *pRes);
int sqlite3BtreeNext(BtCursor*, int flags);
int sqlite3BtreeEof(BtCursor*);
int sqlite3BtreePrevious(BtCursor*, int flags);
i64 sqlite3BtreeIntegerKey(BtCursor*);
void sqlite3BtreeCursorPin(BtCursor*);
void sqlite3BtreeCursorUnpin(BtCursor*);
int sqlite3BtreeDelete(BtCursor*, u8 flags);
#ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC
i64 sqlite3BtreeOffset(BtCursor*);
#endif
int sqlite3BtreePayload(BtCursor*, u32 offset, u32 amt, void*);
const void *sqlite3BtreePayloadFetch(BtCursor*, u32 *pAmt);
u32 sqlite3BtreePayloadSize(BtCursor*);
sqlite3_int64 sqlite3BtreeMaxRecordSize(BtCursor*);
char *sqlite3BtreeIntegrityCheck(sqlite3*,Btree*,Pgno*aRoot,int nRoot,int,int*);
struct Pager *sqlite3BtreePager(Btree*);
i64 sqlite3BtreeRowCountEst(BtCursor*);
/* These functions deal with arbitary-sized binary blobs in a Btree */
#ifndef SQLITE_OMIT_INCRBLOB
int sqlite3BtreePayloadChecked(BtCursor*, u32 offset, u32 amt, void*);
int sqlite3BtreePutData(BtCursor*, u32 offset, u32 amt, void*);
void sqlite3BtreeIncrblobCursor(BtCursor *);
#endif
void sqlite3BtreeClearCursor(BtCursor *);
int sqlite3BtreeSetVersion(Btree *pBt, int iVersion);
int sqlite3BtreeCursorHasHint(BtCursor*, unsigned int mask);
int sqlite3BtreeIsReadonly(Btree *pBt);
int sqlite3HeaderSizeBtree(void);
#ifndef NDEBUG
int sqlite3BtreeCursorIsValid(BtCursor*);
#endif
int sqlite3BtreeCursorIsValidNN(BtCursor*);
int sqlite3BtreeCount(sqlite3*, BtCursor*, i64*);
#ifdef SQLITE_TEST
int sqlite3BtreeCursorInfo(BtCursor*, int*, int);
void sqlite3BtreeCursorList(Btree*);
#endif
#ifndef SQLITE_OMIT_WAL
int sqlite3BtreeCheckpoint(Btree*, int, int *, int *);
#endif
/*
** If we are not using shared cache, then there is no need to
** use mutexes to access the BtShared structures. So make the
** Enter and Leave procedures no-ops.
********************
** Table functions
********************
**
*/
#ifndef SQLITE_OMIT_SHARED_CACHE
void sqlite3BtreeEnter(Btree*);
void sqlite3BtreeEnterAll(sqlite3*);
int sqlite3BtreeSharable(Btree*);
void sqlite3BtreeEnterCursor(BtCursor*);
int sqlite3BtreeConnectionCount(Btree*);
#else
# define sqlite3BtreeEnter(X)
# define sqlite3BtreeEnterAll(X)
# define sqlite3BtreeSharable(X) 0
# define sqlite3BtreeEnterCursor(X)
# define sqlite3BtreeConnectionCount(X) 1
#endif
#if !defined(SQLITE_OMIT_SHARED_CACHE) && SQLITE_THREADSAFE
void sqlite3BtreeLeave(Btree*);
void sqlite3BtreeLeaveCursor(BtCursor*);
void sqlite3BtreeLeaveAll(sqlite3*);
#ifndef NDEBUG
/* These routines are used inside assert() statements only. */
int sqlite3BtreeHoldsMutex(Btree*);
int sqlite3BtreeHoldsAllMutexes(sqlite3*);
int sqlite3SchemaMutexHeld(sqlite3*,int,Schema*);
#endif
#else
/* The flags parameter to sqlite3BtreeCreateTable can be the bitwise OR
** of the flags shown below.
**
** Every SQLite table must have either BTREE_INTKEY or BTREE_BLOBKEY set.
** With BTREE_INTKEY, the table key is a 64-bit integer and arbitrary data
** is stored in the leaves. (BTREE_INTKEY is used for SQL tables.) With
** BTREE_BLOBKEY, the key is an arbitrary BLOB and no content is stored
** anywhere - the key is the content. (BTREE_BLOBKEY is used for SQL
** indices.)
*/
# define sqlite3BtreeLeave(X)
# define sqlite3BtreeLeaveCursor(X)
# define sqlite3BtreeLeaveAll(X)
#define BTREE_INTKEY 1 /* Table has only 64-bit signed integer keys */
#define BTREE_BLOBKEY 2 /* Table has keys only - no data */
# define sqlite3BtreeHoldsMutex(X) 1
# define sqlite3BtreeHoldsAllMutexes(X) 1
# define sqlite3SchemaMutexHeld(X,Y,Z) 1
#endif
int sqlite3BtreeDropTable(Btree*, int, int*);
int sqlite3BtreeClearTable(Btree*, int, int*);
int sqlite3BtreeClearTableOfCursor(BtCursor*);
/*
*********************************
** Reading and Writing Metadata
*********************************
**
** Note there is metadata which is not in the first database page
** including (as below) some visible via the os.h API
*/
/*
** The second parameter to sqlite3BtreeGetMeta or sqlite3BtreeUpdateMeta
** should be one of the following values. The integer values are assigned
** to constants so that the offset of the corresponding field in an
** SQLite database header may be found using the following formula:
**
** offset = 36 + (idx * 4)
**
** For example, the free-page-count field is located at byte offset 36 of
** the database file header. The incr-vacuum-flag field is located at
** byte offset 64 (== 36+4*7).
**
** The BTREE_DATA_VERSION value is not really a value stored in the header.
** It is a read-only number computed by the pager. But we merge it with
** the header value access routines since its access pattern is the same.
** Call it a "virtual meta value".
*/
#define BTREE_FREE_PAGE_COUNT 0
#define BTREE_SCHEMA_VERSION 1
#define BTREE_FILE_FORMAT 2
#define BTREE_DEFAULT_CACHE_SIZE 3
#define BTREE_LARGEST_ROOT_PAGE 4
#define BTREE_TEXT_ENCODING 5
#define BTREE_USER_VERSION 6
#define BTREE_INCR_VACUUM 7
#define BTREE_APPLICATION_ID 8
#define BTREE_DATA_VERSION 15 /* A virtual meta-value */
/* Refers to the size of the per-page header, not per-database header */
/* Used for configuring the size of the pages in the page cache */
int sqlite3HeaderSizeBtree(void);
/* TODO: This definition is only used in asserts to determine whether
* the metadata index (second parameter of Get/UpdateMeta functions)
* is out of range. It is only included here so other modules compile. It
* ** needs to be revisited.
* */
#define SQLITE_N_BTREE_META 16
void sqlite3BtreeGetMeta(Btree *pBtree, int idx, u32 *pValue);
int sqlite3BtreeUpdateMeta(Btree*, int idx, u32 value);
/* This returns the size of the current database file, ie the same */
/* result as sqlite3OsFileSize in os.h . */
sqlite3_int64 sqlite3BtreeMaxRecordSize(BtCursor*);
/* Version number of the file format must be either 1 or 2 */
/* 1=legacy, 2=WAL . Read and write versions set to same value */
int sqlite3BtreeSetVersion(Btree *pBt, int iVersion);
/* Initialize the first page of the database file and return */
int sqlite3BtreeNewDb(Btree *p);
#endif /* SQLITE_BTREE_H */
+17
View File
@@ -353,6 +353,9 @@ struct Btree {
u32 iDataVersion; /* Combines with pBt->pPager->iDataVersion */
Btree *pNext; /* List of other sharable Btrees from the same db */
Btree *pPrev; /* Back pointer of the same list */
#ifdef SQLITE_DEBUG
u64 nSeek; /* Calls to sqlite3BtreeMovetoUnpacked() */
#endif
#ifndef SQLITE_OMIT_SHARED_CACHE
BtLock lock; /* Object used to lock page 1 */
#endif
@@ -364,11 +367,25 @@ struct Btree {
** If the shared-data extension is enabled, there may be multiple users
** of the Btree structure. At most one of these may open a write transaction,
** but any number may have active read transactions.
**
** These values must match SQLITE_TXN_NONE, SQLITE_TXN_READ, and
** SQLITE_TXN_WRITE
*/
#define TRANS_NONE 0
#define TRANS_READ 1
#define TRANS_WRITE 2
#if TRANS_NONE!=SQLITE_TXN_NONE
# error wrong numeric code for no-transaction
#endif
#if TRANS_READ!=SQLITE_TXN_READ
# error wrong numeric code for read-transaction
#endif
#if TRANS_WRITE!=SQLITE_TXN_WRITE
# error wrong numeric code for write-transaction
#endif
/*
** An instance of this object represents a single database file.
**
+48 -24
View File
@@ -53,7 +53,7 @@ void sqlite3TableLock(
u8 isWriteLock, /* True for a write lock */
const char *zName /* Name of the table to be locked */
){
Parse *pToplevel = sqlite3ParseToplevel(pParse);
Parse *pToplevel;
int i;
int nBytes;
TableLock *p;
@@ -61,6 +61,7 @@ void sqlite3TableLock(
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];
if( p->iDb==iDb && p->iTab==iTab ){
@@ -90,10 +91,8 @@ void sqlite3TableLock(
*/
static void codeTableLocks(Parse *pParse){
int i;
Vdbe *pVdbe;
pVdbe = sqlite3GetVdbe(pParse);
assert( pVdbe!=0 ); /* sqlite3GetVdbe cannot fail: VDBE already allocated */
Vdbe *pVdbe = pParse->pVdbe;
assert( pVdbe!=0 );
for(i=0; i<pParse->nTableLock; i++){
TableLock *p = &pParse->aTableLock[i];
@@ -1618,8 +1617,10 @@ primary_key_exit:
** Add a new CHECK constraint to the table currently under construction.
*/
void sqlite3AddCheckConstraint(
Parse *pParse, /* Parsing context */
Expr *pCheckExpr /* The check expression */
Parse *pParse, /* Parsing context */
Expr *pCheckExpr, /* The check expression */
const char *zStart, /* Opening "(" */
const char *zEnd /* Closing ")" */
){
#ifndef SQLITE_OMIT_CHECK
Table *pTab = pParse->pNewTable;
@@ -1630,6 +1631,13 @@ void sqlite3AddCheckConstraint(
pTab->pCheck = sqlite3ExprListAppend(pParse, pTab->pCheck, pCheckExpr);
if( pParse->constraintName.n ){
sqlite3ExprListSetName(pParse, pTab->pCheck, &pParse->constraintName, 1);
}else{
Token t;
for(zStart++; sqlite3Isspace(zStart[0]); zStart++){}
while( sqlite3Isspace(zEnd[-1]) ){ zEnd--; }
t.z = zStart;
t.n = (int)(zEnd - t.z);
sqlite3ExprListSetName(pParse, pTab->pCheck, &t, 1);
}
}else
#endif
@@ -1648,7 +1656,7 @@ void sqlite3AddCollateType(Parse *pParse, Token *pToken){
char *zColl; /* Dequoted name of collation sequence */
sqlite3 *db;
if( (p = pParse->pNewTable)==0 ) return;
if( (p = pParse->pNewTable)==0 || IN_RENAME_OBJECT ) return;
i = p->nCol-1;
db = pParse->db;
zColl = sqlite3NameFromToken(db, pToken);
@@ -1883,12 +1891,15 @@ static int resizeIndexObject(sqlite3 *db, Index *pIdx, int N){
int nByte;
if( pIdx->nColumn>=N ) return SQLITE_OK;
assert( pIdx->isResized==0 );
nByte = (sizeof(char*) + sizeof(i16) + 1)*N;
nByte = (sizeof(char*) + sizeof(LogEst) + sizeof(i16) + 1)*N;
zExtra = sqlite3DbMallocZero(db, nByte);
if( zExtra==0 ) return SQLITE_NOMEM_BKPT;
memcpy(zExtra, pIdx->azColl, sizeof(char*)*pIdx->nColumn);
pIdx->azColl = (const char**)zExtra;
zExtra += sizeof(char*)*N;
memcpy(zExtra, pIdx->aiRowLogEst, sizeof(LogEst)*(pIdx->nKeyCol+1));
pIdx->aiRowLogEst = (LogEst*)zExtra;
zExtra += sizeof(LogEst)*N;
memcpy(zExtra, pIdx->aiColumn, sizeof(i16)*pIdx->nColumn);
pIdx->aiColumn = (i16*)zExtra;
zExtra += sizeof(i16)*N;
@@ -4449,7 +4460,7 @@ void sqlite3SrcListAssignCursors(Parse *pParse, SrcList *pList){
assert(pList || pParse->db->mallocFailed );
if( pList ){
for(i=0, pItem=pList->a; i<pList->nSrc; i++, pItem++){
if( pItem->iCursor>=0 ) break;
if( pItem->iCursor>=0 ) continue;
pItem->iCursor = pParse->nTab++;
if( pItem->pSelect ){
sqlite3SrcListAssignCursors(pParse, pItem->pSelect->pSrc);
@@ -4466,15 +4477,15 @@ void sqlite3SrcListDelete(sqlite3 *db, SrcList *pList){
struct SrcList_item *pItem;
if( pList==0 ) return;
for(pItem=pList->a, i=0; i<pList->nSrc; i++, pItem++){
sqlite3DbFree(db, pItem->zDatabase);
if( pItem->zDatabase ) sqlite3DbFreeNN(db, pItem->zDatabase);
sqlite3DbFree(db, pItem->zName);
sqlite3DbFree(db, pItem->zAlias);
if( pItem->zAlias ) sqlite3DbFreeNN(db, pItem->zAlias);
if( pItem->fg.isIndexedBy ) sqlite3DbFree(db, pItem->u1.zIndexedBy);
if( pItem->fg.isTabFunc ) sqlite3ExprListDelete(db, pItem->u1.pFuncArg);
sqlite3DeleteTable(db, pItem->pTab);
sqlite3SelectDelete(db, pItem->pSelect);
sqlite3ExprDelete(db, pItem->pOn);
sqlite3IdListDelete(db, pItem->pUsing);
if( pItem->pSelect ) sqlite3SelectDelete(db, pItem->pSelect);
if( pItem->pOn ) sqlite3ExprDelete(db, pItem->pOn);
if( pItem->pUsing ) sqlite3IdListDelete(db, pItem->pUsing);
}
sqlite3DbFreeNN(db, pList);
}
@@ -4646,7 +4657,16 @@ void sqlite3BeginTransaction(Parse *pParse, int type){
if( !v ) return;
if( type!=TK_DEFERRED ){
for(i=0; i<db->nDb; i++){
sqlite3VdbeAddOp2(v, OP_Transaction, i, (type==TK_EXCLUSIVE)+1);
int eTxnType;
Btree *pBt = db->aDb[i].pBt;
if( pBt && sqlite3BtreeIsReadonly(pBt) ){
eTxnType = 0; /* Read txn */
}else if( type==TK_EXCLUSIVE ){
eTxnType = 2; /* Exclusive txn */
}else{
eTxnType = 1; /* Write txn */
}
sqlite3VdbeAddOp2(v, OP_Transaction, i, eTxnType);
sqlite3VdbeUsesBtree(v, i);
}
}
@@ -4735,13 +4755,11 @@ int sqlite3OpenTempDatabase(Parse *pParse){
** will occur at the end of the top-level VDBE and will be generated
** later, by sqlite3FinishCoding().
*/
void sqlite3CodeVerifySchema(Parse *pParse, int iDb){
Parse *pToplevel = sqlite3ParseToplevel(pParse);
assert( iDb>=0 && iDb<pParse->db->nDb );
assert( pParse->db->aDb[iDb].pBt!=0 || iDb==1 );
static void sqlite3CodeVerifySchemaAtToplevel(Parse *pToplevel, int iDb){
assert( iDb>=0 && iDb<pToplevel->db->nDb );
assert( pToplevel->db->aDb[iDb].pBt!=0 || iDb==1 );
assert( iDb<SQLITE_MAX_ATTACHED+2 );
assert( sqlite3SchemaMutexHeld(pParse->db, iDb, 0) );
assert( sqlite3SchemaMutexHeld(pToplevel->db, iDb, 0) );
if( DbMaskTest(pToplevel->cookieMask, iDb)==0 ){
DbMaskSet(pToplevel->cookieMask, iDb);
if( !OMIT_TEMPDB && iDb==1 ){
@@ -4749,6 +4767,10 @@ void sqlite3CodeVerifySchema(Parse *pParse, int iDb){
}
}
}
void sqlite3CodeVerifySchema(Parse *pParse, int iDb){
sqlite3CodeVerifySchemaAtToplevel(sqlite3ParseToplevel(pParse), iDb);
}
/*
** If argument zDb is NULL, then call sqlite3CodeVerifySchema() for each
@@ -4780,7 +4802,7 @@ void sqlite3CodeVerifyNamedSchema(Parse *pParse, const char *zDb){
*/
void sqlite3BeginWriteOperation(Parse *pParse, int setStatement, int iDb){
Parse *pToplevel = sqlite3ParseToplevel(pParse);
sqlite3CodeVerifySchema(pParse, iDb);
sqlite3CodeVerifySchemaAtToplevel(pToplevel, iDb);
DbMaskSet(pToplevel->writeMask, iDb);
pToplevel->isMultiWrite |= setStatement;
}
@@ -4831,7 +4853,9 @@ void sqlite3HaltConstraint(
i8 p4type, /* P4_STATIC or P4_TRANSIENT */
u8 p5Errmsg /* P5_ErrMsg type */
){
Vdbe *v = sqlite3GetVdbe(pParse);
Vdbe *v;
assert( pParse->pVdbe!=0 );
v = sqlite3GetVdbe(pParse);
assert( (errCode&0xff)==SQLITE_CONSTRAINT || pParse->nested );
if( onError==OE_Abort ){
sqlite3MayAbort(pParse);
-4
View File
@@ -942,10 +942,6 @@ int sqlite3GenerateIndexKey(
}
if( regOut ){
sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase, nCol, regOut);
if( pIdx->pTable->pSelect ){
const char *zAff = sqlite3IndexAffinityStr(pParse->db, pIdx);
sqlite3VdbeChangeP4(v, -1, zAff, P4_TRANSIENT);
}
}
sqlite3ReleaseTempRange(pParse, regBase, nCol);
return regBase;
+7 -4
View File
@@ -44,8 +44,10 @@ char sqlite3TableColumnAffinity(Table *pTab, int iCol){
*/
char sqlite3ExprAffinity(const Expr *pExpr){
int op;
while( ExprHasProperty(pExpr, EP_Skip) ){
assert( pExpr->op==TK_COLLATE || pExpr->op==TK_IF_NULL_ROW );
while( ExprHasProperty(pExpr, EP_Skip|EP_IfNullRow) ){
assert( pExpr->op==TK_COLLATE
|| pExpr->op==TK_IF_NULL_ROW
|| (pExpr->op==TK_REGISTER && pExpr->op2==TK_IF_NULL_ROW) );
pExpr = pExpr->pLeft;
assert( pExpr!=0 );
}
@@ -115,7 +117,7 @@ Expr *sqlite3ExprAddCollateString(Parse *pParse, Expr *pExpr, const char *zC){
*/
Expr *sqlite3ExprSkipCollate(Expr *pExpr){
while( pExpr && ExprHasProperty(pExpr, EP_Skip) ){
assert( pExpr->op==TK_COLLATE || pExpr->op==TK_IF_NULL_ROW );
assert( pExpr->op==TK_COLLATE );
pExpr = pExpr->pLeft;
}
return pExpr;
@@ -134,7 +136,7 @@ Expr *sqlite3ExprSkipCollateAndLikely(Expr *pExpr){
assert( pExpr->op==TK_FUNCTION );
pExpr = pExpr->x.pList->a[0].pExpr;
}else{
assert( pExpr->op==TK_COLLATE || pExpr->op==TK_IF_NULL_ROW );
assert( pExpr->op==TK_COLLATE );
pExpr = pExpr->pLeft;
}
}
@@ -768,6 +770,7 @@ int sqlite3SelectExprHeight(Select *p){
** Expr.flags.
*/
void sqlite3ExprSetHeightAndFlags(Parse *pParse, Expr *p){
if( pParse->nErr ) return;
if( p && p->x.pList && !ExprHasProperty(p, EP_xIsSelect) ){
p->flags |= EP_Propagate & sqlite3ExprListFlags(p->x.pList);
}
+6 -5
View File
@@ -32,7 +32,8 @@ void sqlite3OpenTable(
){
Vdbe *v;
assert( !IsVirtual(pTab) );
v = sqlite3GetVdbe(pParse);
assert( pParse->pVdbe!=0 );
v = pParse->pVdbe;
assert( opcode==OP_OpenWrite || opcode==OP_OpenRead );
sqlite3TableLock(pParse, iDb, pTab->tnum,
(opcode==OP_OpenWrite)?1:0, pTab->zName);
@@ -1531,7 +1532,7 @@ void sqlite3GenerateConstraintChecks(
isUpdate = regOldData!=0;
db = pParse->db;
v = sqlite3GetVdbe(pParse);
v = pParse->pVdbe;
assert( v!=0 );
assert( pTab->pSelect==0 ); /* This table is not a VIEW */
nCol = pTab->nCol;
@@ -1685,7 +1686,7 @@ void sqlite3GenerateConstraintChecks(
sqlite3VdbeGoto(v, ignoreDest);
}else{
char *zName = pCheck->a[i].zEName;
if( zName==0 ) zName = pTab->zName;
assert( zName!=0 || pParse->db->mallocFailed );
if( onError==OE_Replace ) onError = OE_Abort; /* IMP: R-26383-51744 */
sqlite3HaltConstraint(pParse, SQLITE_CONSTRAINT_CHECK,
onError, zName, P4_TRANSIENT,
@@ -2304,7 +2305,7 @@ void sqlite3CompleteInsertion(
|| update_flags==(OPFLAG_ISUPDATE|OPFLAG_SAVEPOSITION)
);
v = sqlite3GetVdbe(pParse);
v = pParse->pVdbe;
assert( v!=0 );
assert( pTab->pSelect==0 ); /* This table is not a VIEW */
for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
@@ -2405,7 +2406,7 @@ int sqlite3OpenTableAndIndices(
return 0;
}
iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);
v = sqlite3GetVdbe(pParse);
v = pParse->pVdbe;
assert( v!=0 );
if( iBase<0 ) iBase = pParse->nTab;
iDataCur = iBase++;
+57 -6
View File
@@ -897,7 +897,7 @@ int sqlite3_db_cacheflush(sqlite3 *db){
sqlite3BtreeEnterAll(db);
for(i=0; rc==SQLITE_OK && i<db->nDb; i++){
Btree *pBt = db->aDb[i].pBt;
if( pBt && sqlite3BtreeIsInTrans(pBt) ){
if( pBt && sqlite3BtreeTxnState(pBt)==SQLITE_TXN_WRITE ){
Pager *pPager = sqlite3BtreePager(pBt);
rc = sqlite3PagerFlush(pPager);
if( rc==SQLITE_BUSY ){
@@ -1241,6 +1241,36 @@ static int sqlite3Close(sqlite3 *db, int forceZombie){
return SQLITE_OK;
}
/*
** Return the transaction state for a single databse, or the maximum
** transaction state over all attached databases if zSchema is null.
*/
int sqlite3_txn_state(sqlite3 *db, const char *zSchema){
int iDb, nDb;
int iTxn = -1;
#ifdef SQLITE_ENABLE_API_ARMOR
if( !sqlite3SafetyCheckOk(db) ){
(void)SQLITE_MISUSE_BKPT;
return -1;
}
#endif
sqlite3_mutex_enter(db->mutex);
if( zSchema ){
nDb = iDb = sqlite3FindDbName(db, zSchema);
if( iDb<0 ) nDb--;
}else{
iDb = 0;
nDb = db->nDb-1;
}
for(; iDb<=nDb; iDb++){
Btree *pBt = db->aDb[iDb].pBt;
int x = pBt!=0 ? sqlite3BtreeTxnState(pBt) : SQLITE_TXN_NONE;
if( x>iTxn ) iTxn = x;
}
sqlite3_mutex_leave(db->mutex);
return iTxn;
}
/*
** Two variations on the public interface for closing a database
** connection. The sqlite3_close() version returns SQLITE_BUSY and
@@ -1401,7 +1431,7 @@ void sqlite3RollbackAll(sqlite3 *db, int tripCode){
for(i=0; i<db->nDb; i++){
Btree *p = db->aDb[i].pBt;
if( p ){
if( sqlite3BtreeIsInTrans(p) ){
if( sqlite3BtreeTxnState(p)==SQLITE_TXN_WRITE ){
inTrans = 1;
}
sqlite3BtreeRollback(p, tripCode, !schemaChange);
@@ -3822,7 +3852,9 @@ int sqlite3_file_control(sqlite3 *db, const char *zDbName, int op, void *pArg){
}
rc = SQLITE_OK;
}else{
int nSave = db->busyHandler.nBusy;
rc = sqlite3OsFileControl(fd, op, pArg);
db->busyHandler.nBusy = nSave;
}
sqlite3BtreeLeave(pBtree);
}
@@ -4205,6 +4237,25 @@ int sqlite3_test_control(int op, ...){
sqlite3ResultIntReal(pCtx);
break;
}
/* sqlite3_test_control(SQLITE_TESTCTRL_SEEK_COUNT,
** sqlite3 *db, // Database connection
** u64 *pnSeek // Write seek count here
** );
**
** This test-control queries the seek-counter on the "main" database
** file. The seek-counter is written into *pnSeek and is then reset.
** The seek-count is only available if compiled with SQLITE_DEBUG.
*/
case SQLITE_TESTCTRL_SEEK_COUNT: {
sqlite3 *db = va_arg(ap, sqlite3*);
u64 *pn = va_arg(ap, sqlite3_uint64*);
*pn = sqlite3BtreeSeekCount(db->aDb->pBt);
(void)db; /* Silence harmless unused variable warning */
break;
}
}
va_end(ap);
#endif /* SQLITE_UNTESTABLE */
@@ -4440,7 +4491,7 @@ int sqlite3_snapshot_get(
int iDb = sqlite3FindDbName(db, zDb);
if( iDb==0 || iDb>1 ){
Btree *pBt = db->aDb[iDb].pBt;
if( 0==sqlite3BtreeIsInTrans(pBt) ){
if( SQLITE_TXN_WRITE!=sqlite3BtreeTxnState(pBt) ){
rc = sqlite3BtreeBeginTrans(pBt, 0, 0);
if( rc==SQLITE_OK ){
rc = sqlite3PagerSnapshotGet(sqlite3BtreePager(pBt), ppSnapshot);
@@ -4476,10 +4527,10 @@ int sqlite3_snapshot_open(
iDb = sqlite3FindDbName(db, zDb);
if( iDb==0 || iDb>1 ){
Btree *pBt = db->aDb[iDb].pBt;
if( sqlite3BtreeIsInTrans(pBt)==0 ){
if( sqlite3BtreeTxnState(pBt)!=SQLITE_TXN_WRITE ){
Pager *pPager = sqlite3BtreePager(pBt);
int bUnlock = 0;
if( sqlite3BtreeIsInReadTrans(pBt) ){
if( sqlite3BtreeTxnState(pBt)!=SQLITE_TXN_NONE ){
if( db->nVdbeActive==0 ){
rc = sqlite3PagerSnapshotCheck(pPager, pSnapshot);
if( rc==SQLITE_OK ){
@@ -4528,7 +4579,7 @@ int sqlite3_snapshot_recover(sqlite3 *db, const char *zDb){
iDb = sqlite3FindDbName(db, zDb);
if( iDb==0 || iDb>1 ){
Btree *pBt = db->aDb[iDb].pBt;
if( 0==sqlite3BtreeIsInReadTrans(pBt) ){
if( SQLITE_TXN_NONE==sqlite3BtreeTxnState(pBt) ){
rc = sqlite3BtreeBeginTrans(pBt, 0, 0);
if( rc==SQLITE_OK ){
rc = sqlite3PagerSnapshotRecover(sqlite3BtreePager(pBt));
+6 -1
View File
@@ -474,12 +474,17 @@ void *sqlite3Realloc(void *pOld, u64 nBytes){
if( nOld==nNew ){
pNew = pOld;
}else if( sqlite3GlobalConfig.bMemstat ){
sqlite3_int64 nUsed;
sqlite3_mutex_enter(mem0.mutex);
sqlite3StatusHighwater(SQLITE_STATUS_MALLOC_SIZE, (int)nBytes);
nDiff = nNew - nOld;
if( nDiff>0 && sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED) >=
if( nDiff>0 && (nUsed = sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED)) >=
mem0.alarmThreshold-nDiff ){
sqlite3MallocAlarm(nDiff);
if( mem0.hardLimit>0 && nUsed >= mem0.hardLimit - nDiff ){
sqlite3_mutex_leave(mem0.mutex);
return 0;
}
}
pNew = sqlite3GlobalConfig.m.xRealloc(pOld, nNew);
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
+15 -4
View File
@@ -126,11 +126,14 @@ static const sqlite3_io_methods memdb_io_methods = {
** Close an memdb-file.
**
** The pData pointer is owned by the application, so there is nothing
** to free.
** to free. Unless the SQLITE_DESERIALIZE_FREEONCLOSE flag is set,
** in which case we own the pData pointer and need to free it.
*/
static int memdbClose(sqlite3_file *pFile){
MemFile *p = (MemFile *)pFile;
if( p->mFlags & SQLITE_DESERIALIZE_FREEONCLOSE ) sqlite3_free(p->aData);
if( p->mFlags & SQLITE_DESERIALIZE_FREEONCLOSE ){
sqlite3_free(p->aData);
}
return SQLITE_OK;
}
@@ -573,8 +576,12 @@ int sqlite3_deserialize(
goto end_deserialize;
}
zSql = sqlite3_mprintf("ATTACH x AS %Q", zSchema);
rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0);
sqlite3_free(zSql);
if( zSql==0 ){
rc = SQLITE_NOMEM;
}else{
rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0);
sqlite3_free(zSql);
}
if( rc ) goto end_deserialize;
db->init.iDb = (u8)iDb;
db->init.reopenMemdb = 1;
@@ -589,6 +596,7 @@ int sqlite3_deserialize(
rc = SQLITE_ERROR;
}else{
p->aData = pData;
pData = 0;
p->sz = szDb;
p->szAlloc = szBuf;
p->szMax = szBuf;
@@ -601,6 +609,9 @@ int sqlite3_deserialize(
end_deserialize:
sqlite3_finalize(pStmt);
if( pData && (mFlags & SQLITE_DESERIALIZE_FREEONCLOSE)!=0 ){
sqlite3_free(pData);
}
sqlite3_mutex_leave(db->mutex);
return rc;
}
+92 -55
View File
@@ -122,7 +122,8 @@
# if defined(__APPLE__) && ((__MAC_OS_X_VERSION_MIN_REQUIRED > 1050) || \
(__IPHONE_OS_VERSION_MIN_REQUIRED > 2000))
# if (!defined(TARGET_OS_EMBEDDED) || (TARGET_OS_EMBEDDED==0)) \
&& (!defined(TARGET_IPHONE_SIMULATOR) || (TARGET_IPHONE_SIMULATOR==0))
&& (!defined(TARGET_IPHONE_SIMULATOR) || (TARGET_IPHONE_SIMULATOR==0))\
&& (!defined(TARGET_OS_MACCATALYST) || (TARGET_OS_MACCATALYST==0))
# undef HAVE_GETHOSTUUID
# define HAVE_GETHOSTUUID 1
# else
@@ -1544,6 +1545,9 @@ static int unixCheckReservedLock(sqlite3_file *id, int *pResOut){
return rc;
}
/* Forward declaration*/
static int unixSleep(sqlite3_vfs*,int);
/*
** Set a posix-advisory-lock.
**
@@ -1573,7 +1577,7 @@ static int osSetPosixAdvisoryLock(
** generic posix, however, there is no such API. So we simply try the
** lock once every millisecond until either the timeout expires, or until
** the lock is obtained. */
usleep(1000);
unixSleep(0,1000);
rc = osFcntl(h,F_SETLK,pLock);
tm--;
}
@@ -2144,6 +2148,7 @@ static int unixClose(sqlite3_file *id){
}
sqlite3_mutex_leave(pInode->pLockMutex);
releaseInodeInfo(pFile);
assert( pFile->pShm==0 );
rc = closeUnixFile(id);
unixLeaveMutex();
return rc;
@@ -4254,6 +4259,7 @@ struct unixShmNode {
char **apRegion; /* Array of mapped shared-memory regions */
int nRef; /* Number of unixShm objects pointing to this */
unixShm *pFirst; /* All unixShm objects pointing to this */
int aLock[SQLITE_SHM_NLOCK]; /* # shared locks on slot, -1==excl lock */
#ifdef SQLITE_DEBUG
u8 exclMask; /* Mask of exclusive locks held */
u8 sharedMask; /* Mask of shared locks held */
@@ -4794,6 +4800,38 @@ shmpage_out:
return rc;
}
/*
** Check that the pShmNode->aLock[] array comports with the locking bitmasks
** held by each client. Return true if it does, or false otherwise. This
** is to be used in an assert(). e.g.
**
** assert( assertLockingArrayOk(pShmNode) );
*/
#ifdef SQLITE_DEBUG
static int assertLockingArrayOk(unixShmNode *pShmNode){
unixShm *pX;
int aLock[SQLITE_SHM_NLOCK];
assert( sqlite3_mutex_held(pShmNode->pShmMutex) );
memset(aLock, 0, sizeof(aLock));
for(pX=pShmNode->pFirst; pX; pX=pX->pNext){
int i;
for(i=0; i<SQLITE_SHM_NLOCK; i++){
if( pX->exclMask & (1<<i) ){
assert( aLock[i]==0 );
aLock[i] = -1;
}else if( pX->sharedMask & (1<<i) ){
assert( aLock[i]>=0 );
aLock[i]++;
}
}
}
assert( 0==memcmp(pShmNode->aLock, aLock, sizeof(aLock)) );
return (memcmp(pShmNode->aLock, aLock, sizeof(aLock))==0);
}
#endif
/*
** Change the lock state for a shared-memory segment.
**
@@ -4810,10 +4848,10 @@ static int unixShmLock(
){
unixFile *pDbFd = (unixFile*)fd; /* Connection holding shared memory */
unixShm *p = pDbFd->pShm; /* The shared memory being locked */
unixShm *pX; /* For looping over all siblings */
unixShmNode *pShmNode = p->pShmNode; /* The underlying file iNode */
int rc = SQLITE_OK; /* Result code */
u16 mask; /* Mask of locks to take or release */
int *aLock = pShmNode->aLock;
assert( pShmNode==pDbFd->pInode->pShmNode );
assert( pShmNode->pInode==pDbFd->pInode );
@@ -4852,78 +4890,76 @@ static int unixShmLock(
mask = (1<<(ofst+n)) - (1<<ofst);
assert( n>1 || mask==(1<<ofst) );
sqlite3_mutex_enter(pShmNode->pShmMutex);
assert( assertLockingArrayOk(pShmNode) );
if( flags & SQLITE_SHM_UNLOCK ){
u16 allMask = 0; /* Mask of locks held by siblings */
if( (p->exclMask|p->sharedMask) & mask ){
int ii;
int bUnlock = 1;
/* See if any siblings hold this same lock */
for(pX=pShmNode->pFirst; pX; pX=pX->pNext){
if( pX==p ) continue;
assert( (pX->exclMask & (p->exclMask|p->sharedMask))==0 );
allMask |= pX->sharedMask;
for(ii=ofst; ii<ofst+n; ii++){
if( aLock[ii]>((p->sharedMask & (1<<ii)) ? 1 : 0) ){
bUnlock = 0;
}
}
if( bUnlock ){
rc = unixShmSystemLock(pDbFd, F_UNLCK, ofst+UNIX_SHM_BASE, n);
if( rc==SQLITE_OK ){
memset(&aLock[ofst], 0, sizeof(int)*n);
}
}else if( p->sharedMask & (1<<ofst) ){
assert( n==1 && aLock[ofst]>1 );
aLock[ofst]--;
}
/* Undo the local locks */
if( rc==SQLITE_OK ){
p->exclMask &= ~mask;
p->sharedMask &= ~mask;
}
}
/* Unlock the system-level locks */
if( (mask & allMask)==0 ){
rc = unixShmSystemLock(pDbFd, F_UNLCK, ofst+UNIX_SHM_BASE, n);
}else{
rc = SQLITE_OK;
}
/* Undo the local locks */
if( rc==SQLITE_OK ){
p->exclMask &= ~mask;
p->sharedMask &= ~mask;
}
}else if( flags & SQLITE_SHM_SHARED ){
u16 allShared = 0; /* Union of locks held by connections other than "p" */
/* Find out which shared locks are already held by sibling connections.
** If any sibling already holds an exclusive lock, go ahead and return
** SQLITE_BUSY.
*/
for(pX=pShmNode->pFirst; pX; pX=pX->pNext){
if( (pX->exclMask & mask)!=0 ){
assert( n==1 );
assert( (p->exclMask & (1<<ofst))==0 );
if( (p->sharedMask & mask)==0 ){
if( aLock[ofst]<0 ){
rc = SQLITE_BUSY;
break;
}
allShared |= pX->sharedMask;
}
/* Get shared locks at the system level, if necessary */
if( rc==SQLITE_OK ){
if( (allShared & mask)==0 ){
}else if( aLock[ofst]==0 ){
rc = unixShmSystemLock(pDbFd, F_RDLCK, ofst+UNIX_SHM_BASE, n);
}else{
rc = SQLITE_OK;
}
}
/* Get the local shared locks */
if( rc==SQLITE_OK ){
p->sharedMask |= mask;
/* Get the local shared locks */
if( rc==SQLITE_OK ){
p->sharedMask |= mask;
aLock[ofst]++;
}
}
}else{
/* Make sure no sibling connections hold locks that will block this
** lock. If any do, return SQLITE_BUSY right away.
*/
for(pX=pShmNode->pFirst; pX; pX=pX->pNext){
if( (pX->exclMask & mask)!=0 || (pX->sharedMask & mask)!=0 ){
** lock. If any do, return SQLITE_BUSY right away. */
int ii;
for(ii=ofst; ii<ofst+n; ii++){
assert( (p->sharedMask & mask)==0 );
if( (p->exclMask & (1<<ii))==0 && aLock[ii] ){
rc = SQLITE_BUSY;
break;
}
}
/* Get the exclusive locks at the system level. Then if successful
** also mark the local connection as being locked.
*/
/* Get the exclusive locks at the system level. Then if successful
** also update the in-memory values. */
if( rc==SQLITE_OK ){
rc = unixShmSystemLock(pDbFd, F_WRLCK, ofst+UNIX_SHM_BASE, n);
if( rc==SQLITE_OK ){
assert( (p->sharedMask & mask)==0 );
p->exclMask |= mask;
for(ii=ofst; ii<ofst+n; ii++){
aLock[ii] = -1;
}
}
}
}
assert( assertLockingArrayOk(pShmNode) );
sqlite3_mutex_leave(pShmNode->pShmMutex);
OSTRACE(("SHM-LOCK shmid-%d, pid-%d got %03x,%03x\n",
p->id, osGetpid(0), p->sharedMask, p->exclMask));
@@ -6543,7 +6579,8 @@ static int unixSleep(sqlite3_vfs *NotUsed, int microseconds){
UNUSED_PARAMETER(NotUsed);
return microseconds;
#elif defined(HAVE_USLEEP) && HAVE_USLEEP
usleep(microseconds);
if( microseconds>=1000000 ) sleep(microseconds/1000000);
if( microseconds%1000000 ) usleep(microseconds%1000000);
UNUSED_PARAMETER(NotUsed);
return microseconds;
#else
@@ -7116,7 +7153,7 @@ static int proxyConchLock(unixFile *pFile, uuid_t myHostID, int lockType){
if( nTries==1 ){
conchModTime = buf.st_mtimespec;
usleep(500000); /* wait 0.5 sec and try the lock again*/
unixSleep(0,500000); /* wait 0.5 sec and try the lock again*/
continue;
}
@@ -7142,7 +7179,7 @@ static int proxyConchLock(unixFile *pFile, uuid_t myHostID, int lockType){
/* don't break the lock on short read or a version mismatch */
return SQLITE_BUSY;
}
usleep(10000000); /* wait 10 sec and try the lock again */
unixSleep(0,10000000); /* wait 10 sec and try the lock again */
continue;
}
+5 -1
View File
@@ -5126,7 +5126,11 @@ static int winOpen(
dwCreationDisposition = OPEN_EXISTING;
}
dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
if( 0==sqlite3_uri_boolean(zName, "exclusive", 0) ){
dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
}else{
dwShareMode = 0;
}
if( isDelete ){
#if SQLITE_OS_WINCE
+14 -8
View File
@@ -1,5 +1,6 @@
%include {
/*
** 2001 September 15
** 2001-09-15
**
** The author disclaims copyright to this source code. In place of
** a legal notice, here is a blessing:
@@ -9,11 +10,16 @@
** May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains SQLite's grammar for SQL. Process this file
** using the lemon parser generator to generate C code that runs
** the parser. Lemon will also generate a header file containing
** numeric codes for all of the tokens.
** This file contains SQLite's SQL parser.
**
** The canonical source code to this file ("parse.y") is a Lemon grammar
** file that specifies the input grammar and actions to take while parsing.
** That input file is processed by Lemon to generate a C-language
** implementation of a parser for the given grammer. You might be reading
** this comment as part of the translated C-code. Edits should be made
** to the original parse.y sources.
*/
}
// All token codes are small integers with #defines that begin with "TK_"
%token_prefix TK_
@@ -366,7 +372,7 @@ ccons ::= PRIMARY KEY sortorder(Z) onconf(R) autoinc(I).
{sqlite3AddPrimaryKey(pParse,0,R,I,Z);}
ccons ::= UNIQUE onconf(R). {sqlite3CreateIndex(pParse,0,0,0,0,R,0,0,0,0,
SQLITE_IDXTYPE_UNIQUE);}
ccons ::= CHECK LP expr(X) RP. {sqlite3AddCheckConstraint(pParse,X);}
ccons ::= CHECK LP(A) expr(X) RP(B). {sqlite3AddCheckConstraint(pParse,X,A.z,B.z);}
ccons ::= REFERENCES nm(T) eidlist_opt(TA) refargs(R).
{sqlite3CreateForeignKey(pParse,0,&T,TA,R);}
ccons ::= defer_subclause(D). {sqlite3DeferForeignKey(pParse,D);}
@@ -420,8 +426,8 @@ tcons ::= PRIMARY KEY LP sortlist(X) autoinc(I) RP onconf(R).
tcons ::= UNIQUE LP sortlist(X) RP onconf(R).
{sqlite3CreateIndex(pParse,0,0,0,X,R,0,0,0,0,
SQLITE_IDXTYPE_UNIQUE);}
tcons ::= CHECK LP expr(E) RP onconf.
{sqlite3AddCheckConstraint(pParse,E);}
tcons ::= CHECK LP(A) expr(E) RP(B) onconf.
{sqlite3AddCheckConstraint(pParse,E,A.z,B.z);}
tcons ::= FOREIGN KEY LP eidlist(FA) RP
REFERENCES nm(T) eidlist_opt(TA) refargs(R) defer_subclause_opt(D). {
sqlite3CreateForeignKey(pParse, FA, &T, TA, R);
+5 -3
View File
@@ -131,7 +131,9 @@ static int getTempStore(const char *z){
static int invalidateTempStorage(Parse *pParse){
sqlite3 *db = pParse->db;
if( db->aDb[1].pBt!=0 ){
if( !db->autoCommit || sqlite3BtreeIsInReadTrans(db->aDb[1].pBt) ){
if( !db->autoCommit
|| sqlite3BtreeTxnState(db->aDb[1].pBt)!=SQLITE_TXN_NONE
){
sqlite3ErrorMsg(pParse, "temporary storage cannot be changed "
"from within a transaction");
return SQLITE_ERROR;
@@ -1451,7 +1453,7 @@ void sqlite3Pragma(
aiCols = 0;
if( pParent ){
x = sqlite3FkLocateIndex(pParse, pParent, pFK, &pIdx, &aiCols);
assert( x==0 );
assert( x==0 || db->mallocFailed );
}
addrOk = sqlite3VdbeMakeLabel(pParse);
@@ -1476,7 +1478,7 @@ void sqlite3Pragma(
int jmp = sqlite3VdbeCurrentAddr(v)+2;
sqlite3VdbeAddOp3(v, OP_SeekRowid, i, jmp, regRow); VdbeCoverage(v);
sqlite3VdbeGoto(v, addrOk);
assert( pFK->nCol==1 );
assert( pFK->nCol==1 || db->mallocFailed );
}
/* Generate code to report an FK violation to the caller. */
+3 -2
View File
@@ -240,7 +240,7 @@ int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg, u32 mFlags){
** on the b-tree database, open one now. If a transaction is opened, it
** will be closed before this function returns. */
sqlite3BtreeEnter(pDb->pBt);
if( !sqlite3BtreeIsInReadTrans(pDb->pBt) ){
if( sqlite3BtreeTxnState(pDb->pBt)==SQLITE_TXN_NONE ){
rc = sqlite3BtreeBeginTrans(pDb->pBt, 0, 0);
if( rc!=SQLITE_OK ){
sqlite3SetString(pzErrMsg, db, sqlite3ErrStr(rc));
@@ -483,7 +483,7 @@ static void schemaIsValid(Parse *pParse){
/* If there is not already a read-only (or read-write) transaction opened
** on the b-tree database, open one now. If a transaction is opened, it
** will be closed immediately after reading the meta-value. */
if( !sqlite3BtreeIsInReadTrans(pBt) ){
if( sqlite3BtreeTxnState(pBt)==SQLITE_TXN_NONE ){
rc = sqlite3BtreeBeginTrans(pBt, 0, 0);
if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ){
sqlite3OomFault(db);
@@ -746,6 +746,7 @@ static int sqlite3LockAndPrepare(
sqlite3BtreeLeaveAll(db);
rc = sqlite3ApiExit(db, rc);
assert( (rc&db->errMask)==rc );
db->busyHandler.nBusy = 0;
sqlite3_mutex_leave(db->mutex);
return rc;
}
+4 -5
View File
@@ -427,11 +427,10 @@ void sqlite3_str_vappendf(
v = va_arg(ap,int);
}
if( v<0 ){
if( v==SMALLEST_INT64 ){
longvalue = ((u64)1)<<63;
}else{
longvalue = -v;
}
testcase( v==SMALLEST_INT64 );
testcase( v==(-1) );
longvalue = ~v;
longvalue++;
prefix = '-';
}else{
longvalue = v;
+1 -1
View File
@@ -1075,7 +1075,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
assert( !ExprHasProperty(pExpr, EP_Reduced) );
/* Handle special cases of "x IS TRUE", "x IS FALSE", "x IS NOT TRUE",
** and "x IS NOT FALSE". */
if( pRight && pRight->op==TK_ID ){
if( pRight && (pRight->op==TK_ID || pRight->op==TK_TRUEFALSE) ){
int rc = resolveExprStep(pWalker, pRight);
if( rc==WRC_Abort ) return WRC_Abort;
if( pRight->op==TK_TRUEFALSE ){
+71 -42
View File
@@ -2340,6 +2340,7 @@ static void generateWithRecursiveQuery(
int nCol = p->pEList->nExpr; /* Number of columns in the recursive table */
Vdbe *v = pParse->pVdbe; /* The prepared statement under construction */
Select *pSetup = p->pPrior; /* The setup query */
Select *pFirstRec; /* Left-most recursive term */
int addrTop; /* Top of the loop */
int addrCont, addrBreak; /* CONTINUE and BREAK addresses */
int iCurrent = 0; /* The Current table */
@@ -2415,7 +2416,25 @@ static void generateWithRecursiveQuery(
/* Detach the ORDER BY clause from the compound SELECT */
p->pOrderBy = 0;
/* Figure out how many elements of the compound SELECT are part of the
** recursive query. Make sure no recursive elements use aggregate
** functions. Mark the recursive elements as UNION ALL even if they
** are really UNION because the distinctness will be enforced by the
** iDistinct table. pFirstRec is left pointing to the left-most
** recursive term of the CTE.
*/
pFirstRec = p;
for(pFirstRec=p; ALWAYS(pFirstRec!=0); pFirstRec=pFirstRec->pPrior){
if( pFirstRec->selFlags & SF_Aggregate ){
sqlite3ErrorMsg(pParse, "recursive aggregate queries not supported");
goto end_of_recursive_query;
}
pFirstRec->op = TK_ALL;
if( (pFirstRec->pPrior->selFlags & SF_Recursive)==0 ) break;
}
/* Store the results of the setup-query in Queue. */
pSetup = pFirstRec->pPrior;
pSetup->pNext = 0;
ExplainQueryPlan((pParse, 1, "SETUP"));
rc = sqlite3Select(pParse, pSetup, &destQueue);
@@ -2448,15 +2467,11 @@ static void generateWithRecursiveQuery(
/* Execute the recursive SELECT taking the single row in Current as
** the value for the recursive-table. Store the results in the Queue.
*/
if( p->selFlags & SF_Aggregate ){
sqlite3ErrorMsg(pParse, "recursive aggregate queries not supported");
}else{
p->pPrior = 0;
ExplainQueryPlan((pParse, 1, "RECURSIVE STEP"));
sqlite3Select(pParse, p, &destQueue);
assert( p->pPrior==0 );
p->pPrior = pSetup;
}
pFirstRec->pPrior = 0;
ExplainQueryPlan((pParse, 1, "RECURSIVE STEP"));
sqlite3Select(pParse, p, &destQueue);
assert( pFirstRec->pPrior==0 );
pFirstRec->pPrior = pSetup;
/* Keep running the loop until the Queue is empty */
sqlite3VdbeGoto(v, addrTop);
@@ -2525,6 +2540,16 @@ static int multiSelectValues(
return rc;
}
/*
** Return true if the SELECT statement which is known to be the recursive
** part of a recursive CTE still has its anchor terms attached. If the
** anchor terms have already been removed, then return false.
*/
static int hasAnchor(Select *p){
while( p && (p->selFlags & SF_Recursive)!=0 ){ p = p->pPrior; }
return p!=0;
}
/*
** This routine is called to process a compound query form from
** two or more separate queries using UNION, UNION ALL, EXCEPT, or
@@ -2610,7 +2635,7 @@ static int multiSelect(
assert( p->pEList->nExpr==pPrior->pEList->nExpr );
#ifndef SQLITE_OMIT_CTE
if( p->selFlags & SF_Recursive ){
if( (p->selFlags & SF_Recursive)!=0 && hasAnchor(p) ){
generateWithRecursiveQuery(pParse, p, &dest);
}else
#endif
@@ -2701,6 +2726,7 @@ static int multiSelect(
findRightmost(p)->selFlags |= SF_UsesEphemeral;
assert( p->pEList );
}
/* Code the SELECT statements to our left
*/
@@ -3506,7 +3532,7 @@ static Expr *substExpr(
ifNullRow.op = TK_IF_NULL_ROW;
ifNullRow.pLeft = pCopy;
ifNullRow.iTable = pSubst->iNewTable;
ifNullRow.flags = EP_Skip;
ifNullRow.flags = EP_IfNullRow;
pCopy = &ifNullRow;
}
testcase( ExprHasProperty(pCopy, EP_Subquery) );
@@ -3515,8 +3541,7 @@ static Expr *substExpr(
ExprSetProperty(pNew, EP_CanBeNull);
}
if( pNew && ExprHasProperty(pExpr,EP_FromJoin) ){
pNew->iRightJoinTable = pExpr->iRightJoinTable;
ExprSetProperty(pNew, EP_FromJoin);
sqlite3SetJoinExpr(pNew, pExpr->iRightJoinTable);
}
sqlite3ExprDelete(db, pExpr);
pExpr = pNew;
@@ -4795,8 +4820,10 @@ static int withExpand(
ExprList *pEList;
Select *pSel;
Select *pLeft; /* Left-most SELECT statement */
Select *pRecTerm; /* Left-most recursive term */
int bMayRecursive; /* True if compound joined by UNION [ALL] */
With *pSavedWith; /* Initial value of pParse->pWith */
int iRecTab = -1; /* Cursor for recursive table */
/* If pCte->zCteErr is non-NULL at this point, then this is an illegal
** recursive reference to CTE pCte. Leave an error in pParse and return
@@ -4821,44 +4848,48 @@ static int withExpand(
assert( pFrom->pSelect );
/* Check if this is a recursive CTE. */
pSel = pFrom->pSelect;
pRecTerm = pSel = pFrom->pSelect;
bMayRecursive = ( pSel->op==TK_ALL || pSel->op==TK_UNION );
if( bMayRecursive ){
while( bMayRecursive && pRecTerm->op==pSel->op ){
int i;
SrcList *pSrc = pFrom->pSelect->pSrc;
SrcList *pSrc = pRecTerm->pSrc;
assert( pRecTerm->pPrior!=0 );
for(i=0; i<pSrc->nSrc; i++){
struct SrcList_item *pItem = &pSrc->a[i];
if( pItem->zDatabase==0
&& pItem->zName!=0
&& 0==sqlite3StrICmp(pItem->zName, pCte->zName)
){
){
pItem->pTab = pTab;
pItem->fg.isRecursive = 1;
pTab->nTabRef++;
pSel->selFlags |= SF_Recursive;
pItem->fg.isRecursive = 1;
if( pRecTerm->selFlags & SF_Recursive ){
sqlite3ErrorMsg(pParse,
"multiple references to recursive table: %s", pCte->zName
);
return SQLITE_ERROR;
}
pRecTerm->selFlags |= SF_Recursive;
if( iRecTab<0 ) iRecTab = pParse->nTab++;
pItem->iCursor = iRecTab;
}
}
if( (pRecTerm->selFlags & SF_Recursive)==0 ) break;
pRecTerm = pRecTerm->pPrior;
}
/* Only one recursive reference is permitted. */
if( pTab->nTabRef>2 ){
sqlite3ErrorMsg(
pParse, "multiple references to recursive table: %s", pCte->zName
);
return SQLITE_ERROR;
}
assert( pTab->nTabRef==1 ||
((pSel->selFlags&SF_Recursive) && pTab->nTabRef==2 ));
pCte->zCteErr = "circular reference: %s";
pSavedWith = pParse->pWith;
pParse->pWith = pWith;
if( bMayRecursive ){
Select *pPrior = pSel->pPrior;
assert( pPrior->pWith==0 );
pPrior->pWith = pSel->pWith;
sqlite3WalkSelect(pWalker, pPrior);
pPrior->pWith = 0;
if( pSel->selFlags & SF_Recursive ){
assert( pRecTerm!=0 );
assert( (pRecTerm->selFlags & SF_Recursive)==0 );
assert( pRecTerm->pNext!=0 );
assert( (pRecTerm->pNext->selFlags & SF_Recursive)!=0 );
assert( pRecTerm->pWith==0 );
pRecTerm->pWith = pSel->pWith;
sqlite3WalkSelect(pWalker, pRecTerm);
pRecTerm->pWith = 0;
}else{
sqlite3WalkSelect(pWalker, pSel);
}
@@ -5808,13 +5839,11 @@ int sqlite3Select(
assert( p->pOrderBy==0 || pDest->eDest!=SRT_Fifo );
assert( p->pOrderBy==0 || pDest->eDest!=SRT_DistQueue );
assert( p->pOrderBy==0 || pDest->eDest!=SRT_Queue );
if( IgnorableOrderby(pDest) ){
assert(pDest->eDest==SRT_Exists || pDest->eDest==SRT_Union ||
pDest->eDest==SRT_Except || pDest->eDest==SRT_Discard ||
pDest->eDest==SRT_Queue || pDest->eDest==SRT_DistFifo ||
pDest->eDest==SRT_DistQueue || pDest->eDest==SRT_Fifo);
/* If ORDER BY makes no difference in the output then neither does
** DISTINCT so it can be removed too. */
if( IgnorableDistinct(pDest) ){
assert(pDest->eDest==SRT_Exists || pDest->eDest==SRT_Union ||
pDest->eDest==SRT_Except || pDest->eDest==SRT_Discard ||
pDest->eDest==SRT_DistQueue || pDest->eDest==SRT_DistFifo );
/* All of these destinations are also able to ignore the ORDER BY clause */
sqlite3ExprListDelete(db, p->pOrderBy);
p->pOrderBy = 0;
p->selFlags &= ~SF_Distinct;
+138 -48
View File
@@ -553,8 +553,6 @@ static void utf8_width_print(FILE *pOut, int w, const char *zUtf){
int i;
int n;
int aw = w<0 ? -w : w;
char zBuf[1000];
if( aw>(int)sizeof(zBuf)/3 ) aw = (int)sizeof(zBuf)/3;
for(i=n=0; zUtf[i]; i++){
if( (zUtf[i]&0xc0)!=0x80 ){
n++;
@@ -1028,6 +1026,7 @@ INCLUDE ../ext/misc/memtrace.c
INCLUDE ../ext/misc/uint.c
INCLUDE ../ext/misc/decimal.c
INCLUDE ../ext/misc/ieee754.c
INCLUDE ../ext/misc/series.c
#ifdef SQLITE_HAVE_ZLIB
INCLUDE ../ext/misc/zipfile.c
INCLUDE ../ext/misc/sqlar.c
@@ -1185,6 +1184,8 @@ struct ShellState {
#define SHFLG_CountChanges 0x00000020 /* .changes setting */
#define SHFLG_Echo 0x00000040 /* .echo or --echo setting */
#define SHFLG_HeaderSet 0x00000080 /* .header has been used */
#define SHFLG_DumpDataOnly 0x00000100 /* .dump show data only */
#define SHFLG_DumpNoSys 0x00000200 /* .dump omits system tables */
/*
** Macros for testing and setting shellFlgs
@@ -3705,19 +3706,25 @@ static int dump_callback(void *pArg, int nArg, char **azArg, char **azNotUsed){
const char *zType;
const char *zSql;
ShellState *p = (ShellState *)pArg;
int dataOnly;
int noSys;
UNUSED_PARAMETER(azNotUsed);
if( nArg!=3 || azArg==0 ) return 0;
zTable = azArg[0];
zType = azArg[1];
zSql = azArg[2];
dataOnly = (p->shellFlgs & SHFLG_DumpDataOnly)!=0;
noSys = (p->shellFlgs & SHFLG_DumpNoSys)!=0;
if( strcmp(zTable, "sqlite_sequence")==0 ){
raw_printf(p->out, "DELETE FROM sqlite_sequence;\n");
}else if( sqlite3_strglob("sqlite_stat?", zTable)==0 ){
raw_printf(p->out, "ANALYZE sqlite_schema;\n");
if( strcmp(zTable, "sqlite_sequence")==0 && !noSys ){
if( !dataOnly ) raw_printf(p->out, "DELETE FROM sqlite_sequence;\n");
}else if( sqlite3_strglob("sqlite_stat?", zTable)==0 && !noSys ){
if( !dataOnly ) raw_printf(p->out, "ANALYZE sqlite_schema;\n");
}else if( strncmp(zTable, "sqlite_", 7)==0 ){
return 0;
}else if( dataOnly ){
/* no-op */
}else if( strncmp(zSql, "CREATE VIRTUAL TABLE", 20)==0 ){
char *zIns;
if( !p->writableSchema ){
@@ -3890,8 +3897,10 @@ static const char *(azHelp[]) = {
".dbinfo ?DB? Show status information about the database",
".dump ?TABLE? Render database content as SQL",
" Options:",
" --preserve-rowids Include ROWID values in the output",
" --data-only Output only INSERT statements",
" --newlines Allow unescaped newline characters in output",
" --nosys Omit system tables (ex: \"sqlite_stat1\")",
" --preserve-rowids Include ROWID values in the output",
" TABLE is a LIKE pattern for the tables to dump",
" Additional LIKE patterns can be given in subsequent arguments",
".echo on|off Turn command echo on or off",
@@ -4016,8 +4025,9 @@ static const char *(azHelp[]) = {
".save FILE Write in-memory database into FILE",
".scanstats on|off Turn sqlite3_stmt_scanstatus() metrics on or off",
".schema ?PATTERN? Show the CREATE statements matching PATTERN",
" Options:",
" --indent Try to pretty-print the schema",
" Options:",
" --indent Try to pretty-print the schema",
" --nosys Omit objects whose names start with \"sqlite_\"",
".selftest ?OPTIONS? Run tests defined in the SELFTEST table",
" Options:",
" --init Create a new SELFTEST table",
@@ -4426,6 +4436,19 @@ static void shellIdQuote(
}
}
/*
** Scalar function "usleep(X)" invokes sqlite3_sleep(X) and returns X.
*/
static void shellUSleepFunc(
sqlite3_context *context,
int argc,
sqlite3_value **argv
){
int sleep = sqlite3_value_int(argv[0]);
sqlite3_sleep(sleep/1000);
sqlite3_result_int(context, sleep);
}
/*
** Scalar function "shell_escape_crnl" used by the .recover command.
** The argument passed to this function is the output of built-in
@@ -4590,6 +4613,7 @@ static void open_db(ShellState *p, int openFlags){
sqlite3_uint_init(p->db, 0, 0);
sqlite3_decimal_init(p->db, 0, 0);
sqlite3_ieee_init(p->db, 0, 0);
sqlite3_series_init(p->db, 0, 0);
#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB)
sqlite3_dbdata_init(p->db, 0, 0);
#endif
@@ -4609,6 +4633,8 @@ static void open_db(ShellState *p, int openFlags){
shellInt32, 0, 0);
sqlite3_create_function(p->db, "shell_idquote", 1, SQLITE_UTF8, 0,
shellIdQuote, 0, 0);
sqlite3_create_function(p->db, "usleep",1,SQLITE_UTF8,0,
shellUSleepFunc, 0, 0);
#ifndef SQLITE_NOHAVE_SYSTEM
sqlite3_create_function(p->db, "edit", 1, SQLITE_UTF8, 0,
editFunc, 0, 0);
@@ -7583,21 +7609,41 @@ static int do_meta_command(char *zLine, ShellState *p){
}else
if( c=='d' && n>1 && strncmp(azArg[0], "databases", n)==0 ){
ShellState data;
char *zErrMsg = 0;
char **azName = 0;
int nName = 0;
sqlite3_stmt *pStmt;
int i;
open_db(p, 0);
memcpy(&data, p, sizeof(data));
data.showHeader = 0;
data.cMode = data.mode = MODE_List;
sqlite3_snprintf(sizeof(data.colSeparator),data.colSeparator,": ");
data.cnt = 0;
sqlite3_exec(p->db, "SELECT name, file FROM pragma_database_list",
callback, &data, &zErrMsg);
if( zErrMsg ){
utf8_printf(stderr,"Error: %s\n", zErrMsg);
sqlite3_free(zErrMsg);
rc = sqlite3_prepare_v2(p->db, "PRAGMA database_list", -1, &pStmt, 0);
if( rc ){
utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
rc = 1;
}else{
while( sqlite3_step(pStmt)==SQLITE_ROW ){
const char *zSchema = (const char *)sqlite3_column_text(pStmt,1);
const char *zFile = (const char*)sqlite3_column_text(pStmt,2);
azName = sqlite3_realloc(azName, (nName+1)*2*sizeof(char*));
if( azName==0 ){ shell_out_of_memory(); /* Does not return */ }
azName[nName*2] = strdup(zSchema);
azName[nName*2+1] = strdup(zFile);
nName++;
}
}
sqlite3_finalize(pStmt);
for(i=0; i<nName; i++){
int eTxn = sqlite3_txn_state(p->db, azName[i*2]);
int bRdonly = sqlite3_db_readonly(p->db, azName[i*2]);
const char *z = azName[i*2+1];
utf8_printf(p->out, "%s: %s %s%s\n",
azName[i*2],
z && z[0] ? z : "\"\"",
bRdonly ? "r/o" : "r/w",
eTxn==SQLITE_TXN_NONE ? "" :
eTxn==SQLITE_TXN_READ ? " read-txn" : " write-txn");
free(azName[i*2]);
free(azName[i*2+1]);
}
sqlite3_free(azName);
}else
if( c=='d' && n>=3 && strncmp(azArg[0], "dbconfig", n)==0 ){
@@ -7656,7 +7702,9 @@ static int do_meta_command(char *zLine, ShellState *p){
int i;
int savedShowHeader = p->showHeader;
int savedShellFlags = p->shellFlgs;
ShellClearFlag(p, SHFLG_PreserveRowid|SHFLG_Newlines|SHFLG_Echo);
ShellClearFlag(p,
SHFLG_PreserveRowid|SHFLG_Newlines|SHFLG_Echo
|SHFLG_DumpDataOnly|SHFLG_DumpNoSys);
for(i=1; i<nArg; i++){
if( azArg[i][0]=='-' ){
const char *z = azArg[i]+1;
@@ -7675,6 +7723,12 @@ static int do_meta_command(char *zLine, ShellState *p){
if( strcmp(z,"newlines")==0 ){
ShellSetFlag(p, SHFLG_Newlines);
}else
if( strcmp(z,"data-only")==0 ){
ShellSetFlag(p, SHFLG_DumpDataOnly);
}else
if( strcmp(z,"nosys")==0 ){
ShellSetFlag(p, SHFLG_DumpNoSys);
}else
{
raw_printf(stderr, "Unknown option \"%s\" on \".dump\"\n", azArg[i]);
rc = 1;
@@ -7691,11 +7745,13 @@ static int do_meta_command(char *zLine, ShellState *p){
open_db(p, 0);
/* When playing back a "dump", the content might appear in an order
** which causes immediate foreign key constraints to be violated.
** So disable foreign-key constraint enforcement to prevent problems. */
raw_printf(p->out, "PRAGMA foreign_keys=OFF;\n");
raw_printf(p->out, "BEGIN TRANSACTION;\n");
if( (p->shellFlgs & SHFLG_DumpDataOnly)==0 ){
/* When playing back a "dump", the content might appear in an order
** which causes immediate foreign key constraints to be violated.
** So disable foreign-key constraint enforcement to prevent problems. */
raw_printf(p->out, "PRAGMA foreign_keys=OFF;\n");
raw_printf(p->out, "BEGIN TRANSACTION;\n");
}
p->writableSchema = 0;
p->showHeader = 0;
/* Set writable_schema=ON since doing so forces SQLite to initialize
@@ -7713,14 +7769,16 @@ static int do_meta_command(char *zLine, ShellState *p){
);
run_schema_dump_query(p,zSql);
sqlite3_free(zSql);
zSql = sqlite3_mprintf(
"SELECT sql FROM sqlite_schema "
"WHERE (%s) AND sql NOT NULL"
" AND type IN ('index','trigger','view')",
zLike
);
run_table_dump_query(p, zSql);
sqlite3_free(zSql);
if( (p->shellFlgs & SHFLG_DumpDataOnly)==0 ){
zSql = sqlite3_mprintf(
"SELECT sql FROM sqlite_schema "
"WHERE (%s) AND sql NOT NULL"
" AND type IN ('index','trigger','view')",
zLike
);
run_table_dump_query(p, zSql);
sqlite3_free(zSql);
}
sqlite3_free(zLike);
if( p->writableSchema ){
raw_printf(p->out, "PRAGMA writable_schema=OFF;\n");
@@ -7728,7 +7786,9 @@ static int do_meta_command(char *zLine, ShellState *p){
}
sqlite3_exec(p->db, "PRAGMA writable_schema=OFF;", 0, 0, 0);
sqlite3_exec(p->db, "RELEASE dump;", 0, 0, 0);
raw_printf(p->out, p->nErr?"ROLLBACK; -- due to errors\n":"COMMIT;\n");
if( (p->shellFlgs & SHFLG_DumpDataOnly)==0 ){
raw_printf(p->out, p->nErr?"ROLLBACK; -- due to errors\n":"COMMIT;\n");
}
p->showHeader = savedShowHeader;
p->shellFlgs = savedShellFlags;
}else
@@ -8167,7 +8227,7 @@ static int do_meta_command(char *zLine, ShellState *p){
while( (nSkip--)>0 ){
while( xRead(&sCtx) && sCtx.cTerm==sCtx.cColSep ){}
}
zSql = sqlite3_mprintf("SELECT * FROM %s", zTable);
zSql = sqlite3_mprintf("SELECT * FROM \"%w\"", zTable);
if( zSql==0 ){
import_cleanup(&sCtx);
shell_out_of_memory();
@@ -8176,7 +8236,7 @@ static int do_meta_command(char *zLine, ShellState *p){
rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
import_append_char(&sCtx, 0); /* To ensure sCtx.z is allocated */
if( rc && sqlite3_strglob("no such table: *", sqlite3_errmsg(p->db))==0 ){
char *zCreate = sqlite3_mprintf("CREATE TABLE %s", zTable);
char *zCreate = sqlite3_mprintf("CREATE TABLE \"%w\"", zTable);
char cSep = '(';
while( xRead(&sCtx) ){
zCreate = sqlite3_mprintf("%z%c\n \"%w\" TEXT", zCreate, cSep, sCtx.z);
@@ -8197,7 +8257,7 @@ static int do_meta_command(char *zLine, ShellState *p){
rc = sqlite3_exec(p->db, zCreate, 0, 0, 0);
sqlite3_free(zCreate);
if( rc ){
utf8_printf(stderr, "CREATE TABLE %s(...) failed: %s\n", zTable,
utf8_printf(stderr, "CREATE TABLE \"%s\"(...) failed: %s\n", zTable,
sqlite3_errmsg(p->db));
import_cleanup(&sCtx);
rc = 1;
@@ -8962,9 +9022,16 @@ static int do_meta_command(char *zLine, ShellState *p){
rc = 1;
goto meta_command_exit;
}
if( notNormalFile(azArg[1])
|| (p->in = fopen(azArg[1], "rb"))==0
){
if( azArg[1][0]=='|' ){
p->in = popen(azArg[1]+1, "r");
if( p->in==0 ){
utf8_printf(stderr, "Error: cannot open \"%s\"\n", azArg[1]);
rc = 1;
}else{
rc = process_input(p);
pclose(p->in);
}
}else if( notNormalFile(azArg[1]) || (p->in = fopen(azArg[1], "rb"))==0 ){
utf8_printf(stderr,"Error: cannot open \"%s\"\n", azArg[1]);
rc = 1;
}else{
@@ -9046,6 +9113,7 @@ static int do_meta_command(char *zLine, ShellState *p){
const char *zName = 0;
int iSchema = 0;
int bDebug = 0;
int bNoSystemTabs = 0;
int ii;
open_db(p, 0);
@@ -9058,10 +9126,16 @@ static int do_meta_command(char *zLine, ShellState *p){
data.cMode = data.mode = MODE_Pretty;
}else if( optionMatch(azArg[ii],"debug") ){
bDebug = 1;
}else if( optionMatch(azArg[ii],"nosys") ){
bNoSystemTabs = 1;
}else if( azArg[ii][0]=='-' ){
utf8_printf(stderr, "Unknown option: \"%s\"\n", azArg[ii]);
rc = 1;
goto meta_command_exit;
}else if( zName==0 ){
zName = azArg[ii];
}else{
raw_printf(stderr, "Usage: .schema ?--indent? ?LIKE-PATTERN?\n");
raw_printf(stderr, "Usage: .schema ?--indent? ?--nosys? ?LIKE-PATTERN?\n");
rc = 1;
goto meta_command_exit;
}
@@ -9147,7 +9221,10 @@ static int do_meta_command(char *zLine, ShellState *p){
appendText(&sSelect, " AND ", 0);
sqlite3_free(zQarg);
}
appendText(&sSelect, "type!='meta' AND sql IS NOT NULL"
if( bNoSystemTabs ){
appendText(&sSelect, "name NOT LIKE 'sqlite_%%' AND ", 0);
}
appendText(&sSelect, "sql IS NOT NULL"
" ORDER BY snum, rowid", 0);
if( bDebug ){
utf8_printf(p->out, "SQL: %s;\n", sSelect.z);
@@ -9844,6 +9921,7 @@ static int do_meta_command(char *zLine, ShellState *p){
{ "prng_restore", SQLITE_TESTCTRL_PRNG_RESTORE, "" },
{ "prng_save", SQLITE_TESTCTRL_PRNG_SAVE, "" },
{ "prng_seed", SQLITE_TESTCTRL_PRNG_SEED, "SEED ?db?" },
{ "seek_count", SQLITE_TESTCTRL_SEEK_COUNT, "" },
};
int testctrl = -1;
int iCtrl = -1;
@@ -9906,7 +9984,6 @@ static int do_meta_command(char *zLine, ShellState *p){
/* sqlite3_test_control(int) */
case SQLITE_TESTCTRL_PRNG_SAVE:
case SQLITE_TESTCTRL_PRNG_RESTORE:
case SQLITE_TESTCTRL_PRNG_RESET:
case SQLITE_TESTCTRL_BYTEORDER:
if( nArg==2 ){
rc2 = sqlite3_test_control(testctrl);
@@ -9980,6 +10057,14 @@ static int do_meta_command(char *zLine, ShellState *p){
}
break;
case SQLITE_TESTCTRL_SEEK_COUNT: {
u64 x = 0;
rc2 = sqlite3_test_control(testctrl, p->db, &x);
utf8_printf(p->out, "%llu\n", x);
isOk = 3;
break;
}
#ifdef YYCOVERAGE
case SQLITE_TESTCTRL_PARSER_COVERAGE:
if( nArg==2 ){
@@ -10875,11 +10960,14 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
(void)cmdline_option_value(argc, argv, ++i);
#endif
}else if( strcmp(z,"-pagecache")==0 ){
int n, sz;
sz = (int)integerValue(cmdline_option_value(argc,argv,++i));
sqlite3_int64 n, sz;
sz = integerValue(cmdline_option_value(argc,argv,++i));
if( sz>70000 ) sz = 70000;
if( sz<0 ) sz = 0;
n = (int)integerValue(cmdline_option_value(argc,argv,++i));
n = integerValue(cmdline_option_value(argc,argv,++i));
if( sz>0 && n>0 && 0xffffffffffffLL/sz<n ){
n = 0xffffffffffffLL/sz;
}
sqlite3_config(SQLITE_CONFIG_PAGECACHE,
(n>0 && sz>0) ? malloc(n*sz) : 0, sz, n);
data.shellFlgs |= SHFLG_Pagecache;
@@ -11015,6 +11103,8 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
data.mode = MODE_List;
}else if( strcmp(z,"-quote")==0 ){
data.mode = MODE_Quote;
sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator, SEP_Comma);
sqlite3_snprintf(sizeof(data.rowSeparator), data.rowSeparator, SEP_Row);
}else if( strcmp(z,"-line")==0 ){
data.mode = MODE_Line;
}else if( strcmp(z,"-column")==0 ){
+66 -4
View File
@@ -6186,6 +6186,57 @@ const char *sqlite3_db_filename(sqlite3 *db, const char *zDbName);
*/
int sqlite3_db_readonly(sqlite3 *db, const char *zDbName);
/*
** CAPI3REF: Determine the transaction state of a database
** METHOD: sqlite3
**
** ^The sqlite3_txn_state(D,S) interface returns the current
** [transaction state] of schema S in database connection D. ^If S is NULL,
** then the highest transaction state of any schema on databse connection D
** is returned. Transaction states are (in order of lowest to highest):
** <ol>
** <li value="0"> SQLITE_TXN_NONE
** <li value="1"> SQLITE_TXN_READ
** <li value="2"> SQLITE_TXN_WRITE
** </ol>
** ^If the S argument to sqlite3_txn_state(D,S) is not the name of
** a valid schema, then -1 is returned.
*/
int sqlite3_txn_state(sqlite3*,const char *zSchema);
/*
** CAPI3REF: Allowed return values from [sqlite3_txn_state()]
** KEYWORDS: {transaction state}
**
** These constants define the current transaction state of a database file.
** ^The [sqlite3_txn_state(D,S)] interface returns one of these
** constants in order to describe the transaction state of schema S
** in [database connection] D.
**
** <dl>
** [[SQLITE_TXN_NONE]] <dt>SQLITE_TXN_NONE</dt>
** <dd>The SQLITE_TXN_NONE state means that no transaction is currently
** pending.</dd>
**
** [[SQLITE_TXN_READ]] <dt>SQLITE_TXN_READ</dt>
** <dd>The SQLITE_TXN_READ state means that the database is currently
** in a read transaction. Content has been read from the database file
** but nothing in the database file has changed. The transaction state
** will advanced to SQLITE_TXN_WRITE if any changes occur and there are
** no other conflicting concurrent write transactions. The transaction
** state will revert to SQLITE_TXN_NONE following a [ROLLBACK] or
** [COMMIT].</dd>
**
** [[SQLITE_TXN_WRITE]] <dt>SQLITE_TXN_WRITE</dt>
** <dd>The SQLITE_TXN_WRITE state means that the database is currently
** in a write transaction. Content has been written to the database file
** but has not yet committed. The transaction state will change to
** to SQLITE_TXN_NONE at the next [ROLLBACK] or [COMMIT].</dd>
*/
#define SQLITE_TXN_NONE 0
#define SQLITE_TXN_READ 1
#define SQLITE_TXN_WRITE 2
/*
** CAPI3REF: Find the next prepared statement
** METHOD: sqlite3
@@ -7688,6 +7739,7 @@ int sqlite3_test_control(int op, ...);
#define SQLITE_TESTCTRL_PRNG_SAVE 5
#define SQLITE_TESTCTRL_PRNG_RESTORE 6
#define SQLITE_TESTCTRL_PRNG_RESET 7 /* NOT USED */
#define SQLITE_TESTCTRL_SEEK_COUNT 7
#define SQLITE_TESTCTRL_BITVEC_TEST 8
#define SQLITE_TESTCTRL_FAULT_INSTALL 9
#define SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS 10
@@ -9192,10 +9244,11 @@ int sqlite3_vtab_on_conflict(sqlite3 *);
** CAPI3REF: Determine If Virtual Table Column Access Is For UPDATE
**
** If the sqlite3_vtab_nochange(X) routine is called within the [xColumn]
** method of a [virtual table], then it returns true if and only if the
** method of a [virtual table], then it might return true if the
** column is being fetched as part of an UPDATE operation during which the
** column value will not change. Applications might use this to substitute
** a return value that is less expensive to compute and that the corresponding
** column value will not change. The virtual table implementation can use
** this hint as permission to substitute a return value that is less
** expensive to compute and that the corresponding
** [xUpdate] method understands as a "no-change" value.
**
** If the [xColumn] method calls sqlite3_vtab_nochange() and finds that
@@ -9204,6 +9257,12 @@ int sqlite3_vtab_on_conflict(sqlite3 *);
** any of the [sqlite3_result_int|sqlite3_result_xxxxx() interfaces].
** In that case, [sqlite3_value_nochange(X)] will return true for the
** same column in the [xUpdate] method.
**
** The sqlite3_vtab_nochange() routine is an optimization. Virtual table
** implementations should continue to give a correct answer even if the
** sqlite3_vtab_nochange() interface were to always return false. In the
** current implementation, the sqlite3_vtab_nochange() interface does always
** returns false for the enhanced [UPDATE FROM] statement.
*/
int sqlite3_vtab_nochange(sqlite3_context*);
@@ -9345,6 +9404,7 @@ void sqlite3_stmt_scanstatus_reset(sqlite3_stmt*);
/*
** CAPI3REF: Flush caches to disk mid-transaction
** METHOD: sqlite3
**
** ^If a write-transaction is open on [database connection] D when the
** [sqlite3_db_cacheflush(D)] interface invoked, any dirty
@@ -9377,6 +9437,7 @@ int sqlite3_db_cacheflush(sqlite3*);
/*
** CAPI3REF: The pre-update hook.
** METHOD: sqlite3
**
** ^These interfaces are only available if SQLite is compiled using the
** [SQLITE_ENABLE_PREUPDATE_HOOK] compile-time option.
@@ -9417,7 +9478,7 @@ int sqlite3_db_cacheflush(sqlite3*);
** seventh parameter is the final rowid value of the row being inserted
** or updated. The value of the seventh parameter passed to the callback
** function is not defined for operations on WITHOUT ROWID tables, or for
** INSERT operations on rowid tables.
** DELETE operations on rowid tables.
**
** The [sqlite3_preupdate_old()], [sqlite3_preupdate_new()],
** [sqlite3_preupdate_count()], and [sqlite3_preupdate_depth()] interfaces
@@ -9479,6 +9540,7 @@ int sqlite3_preupdate_new(sqlite3 *, int, sqlite3_value **);
/*
** CAPI3REF: Low-level system error code
** METHOD: sqlite3
**
** ^Attempt to return the underlying operating system error code or error
** number that caused the most recent I/O error or failure to open a file.
+21 -13
View File
@@ -17,15 +17,16 @@
/* Special Comments:
**
** Some comments have special meaning to the tools that measure test
** coverage:
** Some comments have special meaning to the external tools that measure test
** coverage of conditional brances (MC/DC testing, described in
** https://en.wikipedia.org/wiki/Modified_condition/decision_coverage ).
**
** NO_TEST - The branches on this line are not
** measured by branch coverage. This is
** used on lines of code that actually
** implement parts of coverage testing.
**
** OPTIMIZATION-IF-TRUE - This branch is allowed to alway be false
** OPTIMIZATION-IF-TRUE - This branch is allowed to always be false
** and the correct answer is still obtained,
** though perhaps more slowly.
**
@@ -35,7 +36,11 @@
**
** PREVENTS-HARMLESS-OVERREAD - This branch prevents a buffer overread
** that would be harmless and undetectable
** if it did occur.
** if it did occur.
**
** The OPTIMIZATION-* comments above are for mutation testing as described in
** https://en.wikipedia.org/wiki/Mutation_testing and
** https://www.sqlite.org/testing.html#mutationtests .
**
** In all cases, the special comment must be enclosed in the usual
** slash-asterisk...asterisk-slash comment marks, with no spaces between the
@@ -2187,6 +2192,7 @@ struct Table {
#define TF_OOOHidden 0x0400 /* Out-of-Order hidden columns */
#define TF_HasNotNull 0x0800 /* Contains NOT NULL constraints */
#define TF_Shadow 0x1000 /* True for a shadow table */
#define TF_HasStat4 0x2000 /* STAT4 info available for this table */
/*
** Test to see whether or not a table is a virtual table. This is
@@ -2715,7 +2721,7 @@ struct Expr {
#define EP_TokenOnly 0x004000 /* Expr struct EXPR_TOKENONLYSIZE bytes only */
#define EP_Win 0x008000 /* Contains window functions */
#define EP_MemToken 0x010000 /* Need to sqlite3DbFree() Expr.zToken */
/* 0x020000 // available for reuse */
#define EP_IfNullRow 0x020000 /* The TK_IF_NULL_ROW opcode */
#define EP_Unlikely 0x040000 /* unlikely() or likelihood() function */
#define EP_ConstFunc 0x080000 /* A SQLITE_FUNC_CONSTANT or _SLOCHNG function */
#define EP_CanBeNull 0x100000 /* Can be null despite NOT NULL constraint */
@@ -3152,9 +3158,6 @@ struct Select {
** statements within triggers whose only purpose is
** the side-effects of functions.
**
** All of the above are free to ignore their ORDER BY clause. Those that
** follow must honor the ORDER BY clause.
**
** SRT_Output Generate a row of output (using the OP_ResultRow
** opcode) for each row in the result set.
**
@@ -3211,13 +3214,18 @@ struct Select {
#define SRT_Except 2 /* Remove result from a UNION index */
#define SRT_Exists 3 /* Store 1 if the result is not empty */
#define SRT_Discard 4 /* Do not save the results anywhere */
#define SRT_Fifo 5 /* Store result as data with an automatic rowid */
#define SRT_DistFifo 6 /* Like SRT_Fifo, but unique results only */
#define SRT_DistFifo 5 /* Like SRT_Fifo, but unique results only */
#define SRT_DistQueue 6 /* Like SRT_Queue, but unique results only */
/* The DISTINCT clause is ignored for all of the above. Not that
** IgnorableDistinct() implies IgnorableOrderby() */
#define IgnorableDistinct(X) ((X->eDest)<=SRT_DistQueue)
#define SRT_Queue 7 /* Store result in an queue */
#define SRT_DistQueue 8 /* Like SRT_Queue, but unique results only */
#define SRT_Fifo 8 /* Store result as data with an automatic rowid */
/* The ORDER BY clause is ignored for all of the above */
#define IgnorableOrderby(X) ((X->eDest)<=SRT_DistQueue)
#define IgnorableOrderby(X) ((X->eDest)<=SRT_Fifo)
#define SRT_Output 9 /* Output each row of result */
#define SRT_Mem 10 /* Store result in a memory cell */
@@ -4184,7 +4192,7 @@ void sqlite3StartTable(Parse*,Token*,Token*,int,int,int,int);
void sqlite3AddColumn(Parse*,Token*,Token*);
void sqlite3AddNotNull(Parse*, int);
void sqlite3AddPrimaryKey(Parse*, ExprList*, int, int, int);
void sqlite3AddCheckConstraint(Parse*, Expr*);
void sqlite3AddCheckConstraint(Parse*, Expr*, const char*, const char*);
void sqlite3AddDefaultValue(Parse*,Expr*,const char*,const char*);
void sqlite3AddCollateType(Parse*, Token*);
void sqlite3AddGenerated(Parse*,Expr*,Token*);
+1 -5
View File
@@ -60,11 +60,7 @@
** The maximum depth of an expression tree. This is limited to
** some extent by SQLITE_MAX_SQL_LENGTH. But sometime you might
** want to place more severe limits on the complexity of an
** expression.
**
** A value of 0 used to mean that the limit was not enforced.
** But that is no longer true. The limit is now strictly enforced
** at all times.
** expression. A value of 0 means that there is no limit.
*/
#ifndef SQLITE_MAX_EXPR_DEPTH
# define SQLITE_MAX_EXPR_DEPTH 1000
+28
View File
@@ -7749,6 +7749,33 @@ static int SQLITE_TCLAPI test_sqlite3_db_config(
Tcl_SetObjResult(interp, Tcl_NewIntObj(v));
return TCL_OK;
}
/*
** tclcmd: sqlite3_txn_state DB ?SCHEMA?
**
** Invoke sqlite3_txn_state(DB,SCHEMA) and return the
** numeric value that results. Use NULL for SCHEMA if the 3 argument
** is omitted.
*/
static int SQLITE_TCLAPI test_sqlite3_txn_state(
void *clientData,
Tcl_Interp *interp,
int objc,
Tcl_Obj *CONST objv[]
){
sqlite3 *db;
const char *zSchema;
int iTxn;
if( objc!=2 && objc!=3 ){
Tcl_WrongNumArgs(interp, 1, objv, "DB ?SCHEMA?");
return TCL_ERROR;
}
if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
zSchema = objc==3 ? Tcl_GetString(objv[2]) : 0;
iTxn = sqlite3_txn_state(db, zSchema);
Tcl_SetObjResult(interp, Tcl_NewIntObj(iTxn));
return TCL_OK;
}
/*
** Change the name of the main database schema from "main" to "icecube".
@@ -7985,6 +8012,7 @@ int Sqlitetest1_Init(Tcl_Interp *interp){
void *clientData;
} aObjCmd[] = {
{ "sqlite3_db_config", test_sqlite3_db_config, 0 },
{ "sqlite3_txn_state", test_sqlite3_txn_state, 0 },
{ "bad_behavior", test_bad_behavior, (void*)&iZero },
{ "register_dbstat_vtab", test_register_dbstat_vtab },
{ "sqlite3_connection_pointer", get_sqlite_pointer, 0 },
+8 -4
View File
@@ -550,13 +550,16 @@ static int cfDeviceCharacteristics(sqlite3_file *pFile){
** Pass-throughs for WAL support.
*/
static int cfShmLock(sqlite3_file *pFile, int ofst, int n, int flags){
return sqlite3OsShmLock(((CrashFile*)pFile)->pRealFile, ofst, n, flags);
sqlite3_file *pReal = ((CrashFile*)pFile)->pRealFile;
return pReal->pMethods->xShmLock(pReal, ofst, n, flags);
}
static void cfShmBarrier(sqlite3_file *pFile){
sqlite3OsShmBarrier(((CrashFile*)pFile)->pRealFile);
sqlite3_file *pReal = ((CrashFile*)pFile)->pRealFile;
pReal->pMethods->xShmBarrier(pReal);
}
static int cfShmUnmap(sqlite3_file *pFile, int delFlag){
return sqlite3OsShmUnmap(((CrashFile*)pFile)->pRealFile, delFlag);
sqlite3_file *pReal = ((CrashFile*)pFile)->pRealFile;
return pReal->pMethods->xShmUnmap(pReal, delFlag);
}
static int cfShmMap(
sqlite3_file *pFile, /* Handle open on database file */
@@ -565,7 +568,8 @@ static int cfShmMap(
int w, /* True to extend file if necessary */
void volatile **pp /* OUT: Mapped memory */
){
return sqlite3OsShmMap(((CrashFile*)pFile)->pRealFile, iRegion, sz, w, pp);
sqlite3_file *pReal = ((CrashFile*)pFile)->pRealFile;
return pReal->pMethods->xShmMap(pReal, iRegion, sz, w, pp);
}
static const sqlite3_io_methods CrashFileVtab = {
+4 -4
View File
@@ -191,7 +191,7 @@ static int devsymDeviceCharacteristics(sqlite3_file *pFile){
*/
static int devsymShmLock(sqlite3_file *pFile, int ofst, int n, int flags){
devsym_file *p = (devsym_file *)pFile;
return sqlite3OsShmLock(p->pReal, ofst, n, flags);
return p->pReal->pMethods->xShmLock(p->pReal, ofst, n, flags);
}
static int devsymShmMap(
sqlite3_file *pFile,
@@ -201,15 +201,15 @@ static int devsymShmMap(
void volatile **pp
){
devsym_file *p = (devsym_file *)pFile;
return sqlite3OsShmMap(p->pReal, iRegion, szRegion, isWrite, pp);
return p->pReal->pMethods->xShmMap(p->pReal, iRegion, szRegion, isWrite, pp);
}
static void devsymShmBarrier(sqlite3_file *pFile){
devsym_file *p = (devsym_file *)pFile;
sqlite3OsShmBarrier(p->pReal);
p->pReal->pMethods->xShmBarrier(p->pReal);
}
static int devsymShmUnmap(sqlite3_file *pFile, int delFlag){
devsym_file *p = (devsym_file *)pFile;
return sqlite3OsShmUnmap(p->pReal, delFlag);
return p->pReal->pMethods->xShmUnmap(p->pReal, delFlag);
}
+3 -3
View File
@@ -168,7 +168,7 @@ static int SQLITE_TCLAPI hexio_write(
if( Tcl_GetIntFromObj(interp, objv[2], &offset) ) return TCL_ERROR;
zFile = Tcl_GetString(objv[1]);
zIn = (const unsigned char *)Tcl_GetStringFromObj(objv[3], &nIn);
aOut = sqlite3_malloc( nIn/2 );
aOut = sqlite3_malloc( 1 + nIn/2 );
if( aOut==0 ){
return TCL_ERROR;
}
@@ -213,7 +213,7 @@ static int SQLITE_TCLAPI hexio_get_int(
return TCL_ERROR;
}
zIn = (const unsigned char *)Tcl_GetStringFromObj(objv[1], &nIn);
aOut = sqlite3_malloc( nIn/2 );
aOut = sqlite3_malloc( 1 + nIn/2 );
if( aOut==0 ){
return TCL_ERROR;
}
@@ -309,7 +309,7 @@ static int SQLITE_TCLAPI utf8_to_utf8(
return TCL_ERROR;
}
zOrig = (unsigned char *)Tcl_GetStringFromObj(objv[1], &n);
z = sqlite3_malloc( n+3 );
z = sqlite3_malloc( n+4 );
n = sqlite3TestHexToBin(zOrig, n, z);
z[n] = 0;
nOut = sqlite3Utf8To8(z);
+8 -4
View File
@@ -895,7 +895,8 @@ static int tvfsShmMap(
Testvfs *p = (Testvfs *)(pFd->pVfs->pAppData);
if( p->isFullshm ){
return sqlite3OsShmMap(pFd->pReal, iPage, pgsz, isWrite, pp);
sqlite3_file *pReal = pFd->pReal;
return pReal->pMethods->xShmMap(pReal, iPage, pgsz, isWrite, pp);
}
if( 0==pFd->pShm ){
@@ -945,7 +946,8 @@ static int tvfsShmLock(
char zLock[80];
if( p->isFullshm ){
return sqlite3OsShmLock(pFd->pReal, ofst, n, flags);
sqlite3_file *pReal = pFd->pReal;
return pReal->pMethods->xShmLock(pReal, ofst, n, flags);
}
if( p->pScript && p->mask&TESTVFS_SHMLOCK_MASK ){
@@ -1009,7 +1011,8 @@ static void tvfsShmBarrier(sqlite3_file *pFile){
}
if( p->isFullshm ){
sqlite3OsShmBarrier(pFd->pReal);
sqlite3_file *pReal = pFd->pReal;
pReal->pMethods->xShmBarrier(pReal);
return;
}
}
@@ -1025,7 +1028,8 @@ static int tvfsShmUnmap(
TestvfsFd **ppFd;
if( p->isFullshm ){
return sqlite3OsShmUnmap(pFd->pReal, deleteFlag);
sqlite3_file *pReal = pFd->pReal;
return pReal->pMethods->xShmUnmap(pReal, deleteFlag);
}
if( !pBuffer ) return SQLITE_OK;
+19 -5
View File
@@ -234,7 +234,7 @@ static void updateFromSelect(
#endif
pList = sqlite3ExprListAppend(pParse, pList, pNew);
}
eDest = SRT_Upfrom;
eDest = IsVirtual(pTab) ? SRT_Table : SRT_Upfrom;
}else if( pTab->pSelect ){
for(i=0; i<pTab->nCol; i++){
pList = sqlite3ExprListAppend(pParse, pList, exprRowColumn(pParse, i));
@@ -1187,12 +1187,26 @@ static void updateVirtualTable(
regArg = pParse->nMem + 1;
pParse->nMem += nArg;
if( pSrc->nSrc>1 ){
Index *pPk = 0;
Expr *pRow;
ExprList *pList;
if( pRowid ){
pRow = sqlite3ExprDup(db, pRowid, 0);
if( HasRowid(pTab) ){
if( pRowid ){
pRow = sqlite3ExprDup(db, pRowid, 0);
}else{
pRow = sqlite3PExpr(pParse, TK_ROW, 0, 0);
}
}else{
pRow = sqlite3PExpr(pParse, TK_ROW, 0, 0);
i16 iPk; /* PRIMARY KEY column */
pPk = sqlite3PrimaryKeyIndex(pTab);
assert( pPk!=0 );
assert( pPk->nKeyCol==1 );
iPk = pPk->aiColumn[0];
if( aXRef[iPk]>=0 ){
pRow = sqlite3ExprDup(db, pChanges->a[aXRef[iPk]].pExpr, 0);
}else{
pRow = exprRowColumn(pParse, iPk);
}
}
pList = sqlite3ExprListAppend(pParse, 0, pRow);
@@ -1206,7 +1220,7 @@ static void updateVirtualTable(
}
}
updateFromSelect(pParse, ephemTab, 0, pList, pSrc, pWhere, 0, 0);
updateFromSelect(pParse, ephemTab, pPk, pList, pSrc, pWhere, 0, 0);
sqlite3ExprListDelete(db, pList);
eOnePass = ONEPASS_OFF;
}else{
+1
View File
@@ -681,6 +681,7 @@ int sqlite3Atoi64(const char *zNum, i64 *pNum, int length, u8 enc){
incr = 1;
}else{
incr = 2;
length &= ~1;
assert( SQLITE_UTF16LE==2 && SQLITE_UTF16BE==3 );
for(i=3-enc; i<length && zNum[i]==0; i+=2){}
nonNum = i<length;
+2 -2
View File
@@ -339,8 +339,8 @@ SQLITE_NOINLINE int sqlite3RunVacuum(
BTREE_APPLICATION_ID, 0, /* Preserve the application id */
};
assert( 1==sqlite3BtreeIsInTrans(pTemp) );
assert( pOut!=0 || 1==sqlite3BtreeIsInTrans(pMain) );
assert( SQLITE_TXN_WRITE==sqlite3BtreeTxnState(pTemp) );
assert( pOut!=0 || SQLITE_TXN_WRITE==sqlite3BtreeTxnState(pMain) );
/* Copy Btree meta values */
for(i=0; i<ArraySize(aCopy); i+=2){
+207 -28
View File
@@ -3487,7 +3487,8 @@ case OP_AutoCommit: {
** active.
** If P2 is non-zero, then a write-transaction is started, or if a
** read-transaction is already active, it is upgraded to a write-transaction.
** If P2 is zero, then a read-transaction is started.
** If P2 is zero, then a read-transaction is started. If P2 is 2 or more
** then an exclusive transaction is started.
**
** P1 is the index of the database file on which the transaction is
** started. Index 0 is the main database file and index 1 is the
@@ -3521,6 +3522,7 @@ case OP_Transaction: {
assert( p->bIsReader );
assert( p->readOnly==0 || pOp->p2==0 );
assert( pOp->p2>=0 && pOp->p2<=2 );
assert( pOp->p1>=0 && pOp->p1<db->nDb );
assert( DbMaskTest(p->btreeMask, pOp->p1) );
if( pOp->p2 && (db->flags & SQLITE_QueryOnly)!=0 ){
@@ -3546,7 +3548,7 @@ case OP_Transaction: {
&& pOp->p2
&& (db->autoCommit==0 || db->nVdbeRead>1)
){
assert( sqlite3BtreeIsInTrans(pBt) );
assert( sqlite3BtreeTxnState(pBt)==SQLITE_TXN_WRITE );
if( p->iStatement==0 ){
assert( db->nStatement>=0 && db->nSavepoint>=0 );
db->nStatement++;
@@ -4383,22 +4385,172 @@ seek_not_found:
break;
}
/* Opcode: SeekHit P1 P2 * * *
** Synopsis: seekHit=P2
/* Opcode: SeekScan P1 P2 * * *
** Synopsis: Scan-ahead up to P1 rows
**
** Set the seekHit flag on cursor P1 to the value in P2.
** The seekHit flag is used by the IfNoHope opcode.
** This opcode is a prefix opcode to OP_SeekGE. In other words, this
** opcode must be immediately followed by OP_SeekGE. This constraint is
** checked by assert() statements.
**
** P1 must be a valid b-tree cursor. P2 must be a boolean value,
** either 0 or 1.
** This opcode uses the P1 through P4 operands of the subsequent
** OP_SeekGE. In the text that follows, the operands of the subsequent
** OP_SeekGE opcode are denoted as SeekOP.P1 through SeekOP.P4. Only
** the P1 and P2 operands of this opcode are also used, and are called
** This.P1 and This.P2.
**
** This opcode helps to optimize IN operators on a multi-column index
** where the IN operator is on the later terms of the index by avoiding
** unnecessary seeks on the btree, substituting steps to the next row
** of the b-tree instead. A correct answer is obtained if this opcode
** is omitted or is a no-op.
**
** The SeekGE.P3 and SeekGE.P4 operands identify an unpacked key which
** is the desired entry that we want the cursor SeekGE.P1 to be pointing
** to. Call this SeekGE.P4/P5 row the "target".
**
** If the SeekGE.P1 cursor is not currently pointing to a valid row,
** then this opcode is a no-op and control passes through into the OP_SeekGE.
**
** If the SeekGE.P1 cursor is pointing to a valid row, then that row
** might be the target row, or it might be near and slightly before the
** target row. This opcode attempts to position the cursor on the target
** row by, perhaps by invoking sqlite3BtreeStep() on the cursor
** between 0 and This.P1 times.
**
** There are three possible outcomes from this opcode:<ol>
**
** <li> If after This.P1 steps, the cursor is still point to a place that
** is earlier in the btree than the target row,
** then fall through into the subsquence OP_SeekGE opcode.
**
** <li> If the cursor is successfully moved to the target row by 0 or more
** sqlite3BtreeNext() calls, then jump to This.P2, which will land just
** past the OP_IdxGT opcode that follows the OP_SeekGE.
**
** <li> If the cursor ends up past the target row (indicating the the target
** row does not exist in the btree) then jump to SeekOP.P2.
** </ol>
*/
case OP_SeekScan: {
VdbeCursor *pC;
int res;
int nStep;
UnpackedRecord r;
assert( pOp[1].opcode==OP_SeekGE );
/* pOp->p2 points to the first instruction past the OP_IdxGT that
** follows the OP_SeekGE. */
assert( pOp->p2>=(int)(pOp-aOp)+2 );
assert( aOp[pOp->p2-1].opcode==OP_IdxGT );
assert( pOp[1].p1==aOp[pOp->p2-1].p1 );
assert( pOp[1].p2==aOp[pOp->p2-1].p2 );
assert( pOp[1].p3==aOp[pOp->p2-1].p3 );
assert( pOp->p1>0 );
pC = p->apCsr[pOp[1].p1];
assert( pC!=0 );
assert( pC->eCurType==CURTYPE_BTREE );
assert( !pC->isTable );
if( !sqlite3BtreeCursorIsValidNN(pC->uc.pCursor) ){
#ifdef SQLITE_DEBUG
if( db->flags&SQLITE_VdbeTrace ){
printf("... cursor not valid - fall through\n");
}
#endif
break;
}
nStep = pOp->p1;
assert( nStep>=1 );
r.pKeyInfo = pC->pKeyInfo;
r.nField = (u16)pOp[1].p4.i;
r.default_rc = 0;
r.aMem = &aMem[pOp[1].p3];
#ifdef SQLITE_DEBUG
{
int i;
for(i=0; i<r.nField; i++){
assert( memIsValid(&r.aMem[i]) );
REGISTER_TRACE(pOp[1].p3+i, &aMem[pOp[1].p3+i]);
}
}
#endif
res = 0; /* Not needed. Only used to silence a warning. */
while(1){
rc = sqlite3VdbeIdxKeyCompare(db, pC, &r, &res);
if( rc ) goto abort_due_to_error;
if( res>0 ){
seekscan_search_fail:
#ifdef SQLITE_DEBUG
if( db->flags&SQLITE_VdbeTrace ){
printf("... %d steps and then skip\n", pOp->p1 - nStep);
}
#endif
VdbeBranchTaken(1,3);
pOp++;
goto jump_to_p2;
}
if( res==0 ){
#ifdef SQLITE_DEBUG
if( db->flags&SQLITE_VdbeTrace ){
printf("... %d steps and then success\n", pOp->p1 - nStep);
}
#endif
VdbeBranchTaken(2,3);
goto jump_to_p2;
break;
}
if( nStep<=0 ){
#ifdef SQLITE_DEBUG
if( db->flags&SQLITE_VdbeTrace ){
printf("... fall through after %d steps\n", pOp->p1);
}
#endif
VdbeBranchTaken(0,3);
break;
}
nStep--;
rc = sqlite3BtreeNext(pC->uc.pCursor, 0);
if( rc ){
if( rc==SQLITE_DONE ){
rc = SQLITE_OK;
goto seekscan_search_fail;
}else{
goto abort_due_to_error;
}
}
}
break;
}
/* Opcode: SeekHit P1 P2 P3 * *
** Synopsis: set P2<=seekHit<=P3
**
** Increase or decrease the seekHit value for cursor P1, if necessary,
** so that it is no less than P2 and no greater than P3.
**
** The seekHit integer represents the maximum of terms in an index for which
** there is known to be at least one match. If the seekHit value is smaller
** than the total number of equality terms in an index lookup, then the
** OP_IfNoHope opcode might run to see if the IN loop can be abandoned
** early, thus saving work. This is part of the IN-early-out optimization.
**
** P1 must be a valid b-tree cursor.
*/
case OP_SeekHit: {
VdbeCursor *pC;
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
pC = p->apCsr[pOp->p1];
assert( pC!=0 );
assert( pOp->p2==0 || pOp->p2==1 );
pC->seekHit = pOp->p2 & 1;
assert( pOp->p3>=pOp->p2 );
if( pC->seekHit<pOp->p2 ){
pC->seekHit = pOp->p2;
}else if( pC->seekHit>pOp->p3 ){
pC->seekHit = pOp->p3;
}
break;
}
@@ -4456,16 +4608,20 @@ case OP_IfNotOpen: { /* jump */
** Synopsis: key=r[P3@P4]
**
** Register P3 is the first of P4 registers that form an unpacked
** record.
** record. Cursor P1 is an index btree. P2 is a jump destination.
** In other words, the operands to this opcode are the same as the
** operands to OP_NotFound and OP_IdxGT.
**
** Cursor P1 is on an index btree. If the seekHit flag is set on P1, then
** this opcode is a no-op. But if the seekHit flag of P1 is clear, then
** check to see if there is any entry in P1 that matches the
** prefix identified by P3 and P4. If no entry matches the prefix,
** jump to P2. Otherwise fall through.
** This opcode is an optimization attempt only. If this opcode always
** falls through, the correct answer is still obtained, but extra works
** is performed.
**
** This opcode behaves like OP_NotFound if the seekHit
** flag is clear and it behaves like OP_Noop if the seekHit flag is set.
** A value of N in the seekHit flag of cursor P1 means that there exists
** a key P3:N that will match some record in the index. We want to know
** if it is possible for a record P3:P4 to match some record in the
** index. If it is not possible, we can skips some work. So if seekHit
** is less than P4, attempt to find out if a match is possible by running
** OP_NotFound.
**
** This opcode is used in IN clause processing for a multi-column key.
** If an IN clause is attached to an element of the key other than the
@@ -4507,7 +4663,7 @@ case OP_IfNoHope: { /* jump, in3 */
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
pC = p->apCsr[pOp->p1];
assert( pC!=0 );
if( pC->seekHit ) break;
if( pC->seekHit>=pOp->p4.i ) break;
/* Fall through into OP_NotFound */
/* no break */ deliberate_fall_through
}
@@ -4589,6 +4745,7 @@ case OP_Found: { /* jump, in3 */
}else{
VdbeBranchTaken(takeJump||alreadyExists==0,2);
if( takeJump || !alreadyExists ) goto jump_to_p2;
if( pOp->opcode==OP_IfNoHope ) pC->seekHit = pOp->p4.i;
}
break;
}
@@ -5821,7 +5978,7 @@ case OP_FinishSeek: {
break;
}
/* Opcode: IdxGE P1 P2 P3 P4 P5
/* Opcode: IdxGE P1 P2 P3 P4 *
** Synopsis: key=r[P3@P4]
**
** The P4 register values beginning with P3 form an unpacked index
@@ -5832,7 +5989,7 @@ case OP_FinishSeek: {
** If the P1 index entry is greater than or equal to the key value
** then jump to P2. Otherwise fall through to the next instruction.
*/
/* Opcode: IdxGT P1 P2 P3 P4 P5
/* Opcode: IdxGT P1 P2 P3 P4 *
** Synopsis: key=r[P3@P4]
**
** The P4 register values beginning with P3 form an unpacked index
@@ -5843,7 +6000,7 @@ case OP_FinishSeek: {
** If the P1 index entry is greater than the key value
** then jump to P2. Otherwise fall through to the next instruction.
*/
/* Opcode: IdxLT P1 P2 P3 P4 P5
/* Opcode: IdxLT P1 P2 P3 P4 *
** Synopsis: key=r[P3@P4]
**
** The P4 register values beginning with P3 form an unpacked index
@@ -5854,7 +6011,7 @@ case OP_FinishSeek: {
** If the P1 index entry is less than the key value then jump to P2.
** Otherwise fall through to the next instruction.
*/
/* Opcode: IdxLE P1 P2 P3 P4 P5
/* Opcode: IdxLE P1 P2 P3 P4 *
** Synopsis: key=r[P3@P4]
**
** The P4 register values beginning with P3 form an unpacked index
@@ -5880,7 +6037,6 @@ case OP_IdxGE: { /* jump */
assert( pC->eCurType==CURTYPE_BTREE );
assert( pC->uc.pCursor!=0);
assert( pC->deferredMoveto==0 );
assert( pOp->p5==0 || pOp->p5==1 );
assert( pOp->p4type==P4_INT32 );
r.pKeyInfo = pC->pKeyInfo;
r.nField = (u16)pOp->p4.i;
@@ -5901,8 +6057,31 @@ case OP_IdxGE: { /* jump */
}
}
#endif
res = 0; /* Not needed. Only used to silence a warning. */
rc = sqlite3VdbeIdxKeyCompare(db, pC, &r, &res);
/* Inlined version of sqlite3VdbeIdxKeyCompare() */
{
i64 nCellKey = 0;
BtCursor *pCur;
Mem m;
assert( pC->eCurType==CURTYPE_BTREE );
pCur = pC->uc.pCursor;
assert( sqlite3BtreeCursorIsValid(pCur) );
nCellKey = sqlite3BtreePayloadSize(pCur);
/* nCellKey will always be between 0 and 0xffffffff because of the way
** that btreeParseCellPtr() and sqlite3GetVarint32() are implemented */
if( nCellKey<=0 || nCellKey>0x7fffffff ){
rc = SQLITE_CORRUPT_BKPT;
goto abort_due_to_error;
}
sqlite3VdbeMemInit(&m, db, 0);
rc = sqlite3VdbeMemFromBtreeZeroOffset(pCur, (u32)nCellKey, &m);
if( rc ) goto abort_due_to_error;
res = sqlite3VdbeRecordCompareWithSkip(m.n, m.z, &r, 0);
sqlite3VdbeMemRelease(&m);
}
/* End of inlined sqlite3VdbeIdxKeyCompare() */
assert( (OP_IdxLE&1)==(OP_IdxLT&1) && (OP_IdxGE&1)==(OP_IdxGT&1) );
if( (pOp->opcode&1)==(OP_IdxLT&1) ){
assert( pOp->opcode==OP_IdxLE || pOp->opcode==OP_IdxLT );
@@ -5912,7 +6091,7 @@ case OP_IdxGE: { /* jump */
res++;
}
VdbeBranchTaken(res>0,2);
if( rc ) goto abort_due_to_error;
assert( rc==SQLITE_OK );
if( res>0 ) goto jump_to_p2;
break;
}
@@ -7038,7 +7217,7 @@ case OP_JournalMode: { /* out2 */
/* Open a transaction on the database file. Regardless of the journal
** mode, this transaction always uses a rollback journal.
*/
assert( sqlite3BtreeIsInTrans(pBt)==0 );
assert( sqlite3BtreeTxnState(pBt)!=SQLITE_TXN_WRITE );
if( rc==SQLITE_OK ){
rc = sqlite3BtreeSetVersion(pBt, (eNew==PAGER_JOURNALMODE_WAL ? 2 : 1));
}
+1 -1
View File
@@ -86,7 +86,7 @@ struct VdbeCursor {
Bool isEphemeral:1; /* True for an ephemeral table */
Bool useRandomRowid:1; /* Generate new record numbers semi-randomly */
Bool isOrdered:1; /* True if the table is not BTREE_UNORDERED */
Bool seekHit:1; /* See the OP_SeekHit and OP_IfNoHope opcodes */
u16 seekHit; /* See the OP_SeekHit and OP_IfNoHope opcodes */
Btree *pBtx; /* Separate file holding temporary table */
i64 seqCount; /* Sequence counter */
u32 *aAltMap; /* Mapping from table to index column numbers */
+5 -4
View File
@@ -475,6 +475,7 @@ void sqlite3VdbeAddParseSchemaOp(Vdbe *p, int iDb, char *zWhere){
int j;
sqlite3VdbeAddOp4(p, OP_ParseSchema, iDb, 0, 0, zWhere, P4_DYNAMIC);
for(j=0; j<p->db->nDb; j++) sqlite3VdbeUsesBtree(p, j);
sqlite3MayAbort(p->pParse);
}
/*
@@ -703,7 +704,7 @@ int sqlite3VdbeAssertMayAbort(Vdbe *v, int mayAbort){
if( opcode==OP_Destroy || opcode==OP_VUpdate || opcode==OP_VRename
|| opcode==OP_VDestroy
|| opcode==OP_VCreate
|| (opcode==OP_ParseSchema && pOp->p4.z==0)
|| opcode==OP_ParseSchema
|| ((opcode==OP_Halt || opcode==OP_HaltIfNull)
&& ((pOp->p1)!=SQLITE_OK && pOp->p2==OE_Abort))
){
@@ -1521,7 +1522,7 @@ char *sqlite3VdbeDisplayComment(
sqlite3_str_appendf(&x, "%d", v1);
}else if( pCtx->argc>1 ){
sqlite3_str_appendf(&x, "%d..%d", v1, v1+pCtx->argc-1);
}else{
}else if( x.accError==0 ){
assert( x.nChar>2 );
x.nChar -= 2;
ii++;
@@ -2663,7 +2664,7 @@ static int vdbeCommit(sqlite3 *db, Vdbe *p){
*/
for(i=0; rc==SQLITE_OK && i<db->nDb; i++){
Btree *pBt = db->aDb[i].pBt;
if( sqlite3BtreeIsInTrans(pBt) ){
if( sqlite3BtreeTxnState(pBt)==SQLITE_TXN_WRITE ){
/* Whether or not a database might need a super-journal depends upon
** its journal mode (among other things). This matrix determines which
** journal modes use a super-journal and which do not */
@@ -2798,7 +2799,7 @@ static int vdbeCommit(sqlite3 *db, Vdbe *p){
*/
for(i=0; i<db->nDb; i++){
Btree *pBt = db->aDb[i].pBt;
if( sqlite3BtreeIsInTrans(pBt) ){
if( sqlite3BtreeTxnState(pBt)==SQLITE_TXN_WRITE ){
char const *zFile = sqlite3BtreeGetJournalname(pBt);
if( zFile==0 ){
continue; /* Ignore TEMP and :memory: databases */
+4 -1
View File
@@ -970,13 +970,16 @@ int sqlite3VdbeSorterInit(
if( pSorter==0 ){
rc = SQLITE_NOMEM_BKPT;
}else{
Btree *pBt = db->aDb[0].pBt;
pSorter->pKeyInfo = pKeyInfo = (KeyInfo*)((u8*)pSorter + sz);
memcpy(pKeyInfo, pCsr->pKeyInfo, szKeyInfo);
pKeyInfo->db = 0;
if( nField && nWorker==0 ){
pKeyInfo->nKeyField = nField;
}
pSorter->pgsz = pgsz = sqlite3BtreeGetPageSize(db->aDb[0].pBt);
sqlite3BtreeEnter(pBt);
pSorter->pgsz = pgsz = sqlite3BtreeGetPageSize(pBt);
sqlite3BtreeLeave(pBt);
pSorter->nTask = nWorker + 1;
pSorter->iPrev = (u8)(nWorker - 1);
pSorter->bUseThreads = (pSorter->nTask>1);
+49 -24
View File
@@ -257,7 +257,7 @@ static WhereTerm *whereScanNext(WhereScan *pScan){
do{
for(pTerm=pWC->a+k; k<pWC->nTerm; k++, pTerm++){
if( pTerm->leftCursor==iCur
&& pTerm->u.leftColumn==iColumn
&& pTerm->u.x.leftColumn==iColumn
&& (iColumn!=XN_EXPR
|| sqlite3ExprCompareSkip(pTerm->pExpr->pLeft,
pScan->pIdxExpr,iCur)==0)
@@ -679,8 +679,8 @@ static int termCanDriveIndex(
return 0;
}
if( (pTerm->prereqRight & notReady)!=0 ) return 0;
if( pTerm->u.leftColumn<0 ) return 0;
aff = pSrc->pTab->aCol[pTerm->u.leftColumn].affinity;
if( pTerm->u.x.leftColumn<0 ) return 0;
aff = pSrc->pTab->aCol[pTerm->u.x.leftColumn].affinity;
if( !sqlite3IndexAffinityOk(pTerm->pExpr, aff) ) return 0;
testcase( pTerm->pExpr->op==TK_IS );
return 1;
@@ -751,7 +751,7 @@ static void constructAutomaticIndex(
sqlite3ExprDup(pParse->db, pExpr, 0));
}
if( termCanDriveIndex(pTerm, pSrc, notReady) ){
int iCol = pTerm->u.leftColumn;
int iCol = pTerm->u.x.leftColumn;
Bitmask cMask = iCol>=BMS ? MASKBIT(BMS-1) : MASKBIT(iCol);
testcase( iCol==BMS );
testcase( iCol==BMS-1 );
@@ -804,14 +804,14 @@ static void constructAutomaticIndex(
idxCols = 0;
for(pTerm=pWC->a; pTerm<pWCEnd; pTerm++){
if( termCanDriveIndex(pTerm, pSrc, notReady) ){
int iCol = pTerm->u.leftColumn;
int iCol = pTerm->u.x.leftColumn;
Bitmask cMask = iCol>=BMS ? MASKBIT(BMS-1) : MASKBIT(iCol);
testcase( iCol==BMS-1 );
testcase( iCol==BMS );
if( (idxCols & cMask)==0 ){
Expr *pX = pTerm->pExpr;
idxCols |= cMask;
pIdx->aiColumn[n] = pTerm->u.leftColumn;
pIdx->aiColumn[n] = pTerm->u.x.leftColumn;
pColl = sqlite3ExprCompareCollSeq(pParse, pX);
assert( pColl!=0 || pParse->nErr>0 ); /* TH3 collate01.800 */
pIdx->azColl[n] = pColl ? pColl->zName : sqlite3StrBINARY;
@@ -932,7 +932,7 @@ static sqlite3_index_info *allocateIndexInfo(
testcase( pTerm->eOperator & WO_ALL );
if( (pTerm->eOperator & ~(WO_EQUIV))==0 ) continue;
if( pTerm->wtFlags & TERM_VNULL ) continue;
assert( pTerm->u.leftColumn>=(-1) );
assert( pTerm->u.x.leftColumn>=(-1) );
nTerm++;
}
@@ -992,8 +992,8 @@ static sqlite3_index_info *allocateIndexInfo(
){
continue;
}
assert( pTerm->u.leftColumn>=(-1) );
pIdxCons[j].iColumn = pTerm->u.leftColumn;
assert( pTerm->u.x.leftColumn>=(-1) );
pIdxCons[j].iColumn = pTerm->u.x.leftColumn;
pIdxCons[j].iTermOffset = i;
op = pTerm->eOperator & WO_ALL;
if( op==WO_IN ) op = WO_EQ;
@@ -1756,9 +1756,9 @@ void sqlite3WhereTermPrint(WhereTerm *pTerm, int iTerm){
if( pTerm->wtFlags & TERM_CODED ) zType[3] = 'C';
if( pTerm->eOperator & WO_SINGLE ){
sqlite3_snprintf(sizeof(zLeft),zLeft,"left={%d:%d}",
pTerm->leftCursor, pTerm->u.leftColumn);
pTerm->leftCursor, pTerm->u.x.leftColumn);
}else if( (pTerm->eOperator & WO_OR)!=0 && pTerm->u.pOrInfo!=0 ){
sqlite3_snprintf(sizeof(zLeft),zLeft,"indexable=0x%lld",
sqlite3_snprintf(sizeof(zLeft),zLeft,"indexable=0x%llx",
pTerm->u.pOrInfo->indexable);
}else{
sqlite3_snprintf(sizeof(zLeft),zLeft,"left=%d", pTerm->leftCursor);
@@ -1772,8 +1772,8 @@ void sqlite3WhereTermPrint(WhereTerm *pTerm, int iTerm){
sqlite3DebugPrintf(" prob=%-3d prereq=%llx,%llx",
pTerm->truthProb, (u64)pTerm->prereqAll, (u64)pTerm->prereqRight);
}
if( pTerm->iField ){
sqlite3DebugPrintf(" iField=%d", pTerm->iField);
if( pTerm->u.x.iField ){
sqlite3DebugPrintf(" iField=%d", pTerm->u.x.iField);
}
if( pTerm->iParent>=0 ){
sqlite3DebugPrintf(" iParent=%d", pTerm->iParent);
@@ -2536,7 +2536,7 @@ static int whereLoopAddBtreeIndex(
/* "x IN (value, value, ...)" */
nIn = sqlite3LogEst(pExpr->x.pList->nExpr);
}
if( pProbe->hasStat1 ){
if( pProbe->hasStat1 && rLogSize>=10 ){
LogEst M, logK, safetyMargin;
/* Let:
** N = the total number of rows in the table
@@ -2555,7 +2555,8 @@ static int whereLoopAddBtreeIndex(
** a safety margin of 2 (LogEst: 10) that favors using the IN operator
** with the index, as using an index has better worst-case behavior.
** If we do not have real sqlite_stat1 data, always prefer to use
** the index.
** the index. Do not bother with this optimization on very small
** tables (less than 2 rows) as it is pointless in that case.
*/
M = pProbe->aiRowLogEst[saved_nEq];
logK = estLog(nIn);
@@ -2564,7 +2565,7 @@ static int whereLoopAddBtreeIndex(
WHERETRACE(0x40,
("Scan preferred over IN operator on column %d of \"%s\" (%d<%d)\n",
saved_nEq, pProbe->zName, M+logK+10, nIn+rLogSize));
continue;
pNew->wsFlags |= WHERE_IN_SEEKSCAN;
}else{
WHERETRACE(0x40,
("IN operator preferred on column %d of \"%s\" (%d>=%d)\n",
@@ -3041,8 +3042,23 @@ static int whereLoopAddBtree(
/* Full table scan */
pNew->iSortIdx = b ? iSortIdx : 0;
/* TUNING: Cost of full table scan is (N*3.0). */
/* TUNING: Cost of full table scan is 3.0*N. The 3.0 factor is an
** extra cost designed to discourage the use of full table scans,
** since index lookups have better worst-case performance if our
** stat guesses are wrong. Reduce the 3.0 penalty slightly
** (to 2.75) if we have valid STAT4 information for the table.
** At 2.75, a full table scan is preferred over using an index on
** a column with just two distinct values where each value has about
** an equal number of appearances. Without STAT4 data, we still want
** to use an index in that case, since the constraint might be for
** the scarcer of the two values, and in that case an index lookup is
** better.
*/
#ifdef SQLITE_ENABLE_STAT4
pNew->rRun = rSize + 16 - 2*((pTab->tabFlags & TF_HasStat4)!=0);
#else
pNew->rRun = rSize + 16;
#endif
ApplyCostMultiplier(pNew->rRun, pTab->costMult);
whereLoopOutputAdjust(pWC, pNew, rSize);
rc = whereLoopInsert(pBuilder, pNew);
@@ -4053,16 +4069,24 @@ static LogEst whereSortingCost(
** cost = (3.0 * N * log(N)) * (Y/X)
**
** The (Y/X) term is implemented using stack variable rScale
** below. */
** below.
*/
LogEst rScale, rSortCost;
assert( nOrderBy>0 && 66==sqlite3LogEst(100) );
rScale = sqlite3LogEst((nOrderBy-nSorted)*100/nOrderBy) - 66;
rSortCost = nRow + rScale + 16;
/* Multiple by log(M) where M is the number of output rows.
** Use the LIMIT for M if it is smaller */
** Use the LIMIT for M if it is smaller. Or if this sort is for
** a DISTINT operator, M will be the number of distinct output
** rows, so fudge it downwards a bit.
*/
if( (pWInfo->wctrlFlags & WHERE_USE_LIMIT)!=0 && pWInfo->iLimit<nRow ){
nRow = pWInfo->iLimit;
}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) );
}
rSortCost += estLog(nRow);
return rSortCost;
@@ -5189,6 +5213,7 @@ WhereInfo *sqlite3WhereBegin(
if( (pLoop->wsFlags & WHERE_CONSTRAINT)!=0
&& (pLoop->wsFlags & (WHERE_COLUMN_RANGE|WHERE_SKIPSCAN))==0
&& (pLoop->wsFlags & WHERE_BIGNULL_SORT)==0
&& (pLoop->wsFlags & WHERE_IN_SEEKSCAN)==0
&& (pWInfo->wctrlFlags&WHERE_ORDERBY_MIN)==0
&& pWInfo->eDistinct!=WHERE_DISTINCT_ORDERED
){
@@ -5351,7 +5376,9 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){
sqlite3VdbeJumpHere(v, pIn->addrInTop+1);
if( pIn->eEndLoopOp!=OP_Noop ){
if( pIn->nPrefix ){
assert( pLoop->wsFlags & WHERE_IN_EARLYOUT );
int bEarlyOut =
(pLoop->wsFlags & WHERE_VIRTUALTABLE)==0
&& (pLoop->wsFlags & WHERE_IN_EARLYOUT)!=0;
if( pLevel->iLeftJoin ){
/* For LEFT JOIN queries, cursor pIn->iCur may not have been
** opened yet. This occurs for WHERE clauses such as
@@ -5362,12 +5389,10 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){
** jump over the OP_Next or OP_Prev instruction about to
** be coded. */
sqlite3VdbeAddOp2(v, OP_IfNotOpen, pIn->iCur,
sqlite3VdbeCurrentAddr(v) + 2 +
((pLoop->wsFlags & WHERE_VIRTUALTABLE)==0)
);
sqlite3VdbeCurrentAddr(v) + 2 + bEarlyOut);
VdbeCoverage(v);
}
if( (pLoop->wsFlags & WHERE_VIRTUALTABLE)==0 ){
if( bEarlyOut ){
sqlite3VdbeAddOp4Int(v, OP_IfNoHope, pLevel->iIdxCur,
sqlite3VdbeCurrentAddr(v)+2,
pIn->iBase, pIn->nPrefix);
+5 -2
View File
@@ -261,9 +261,11 @@ struct WhereTerm {
u8 eMatchOp; /* Op for vtab MATCH/LIKE/GLOB/REGEXP terms */
int iParent; /* Disable pWC->a[iParent] when this term disabled */
int leftCursor; /* Cursor number of X in "X <op> <expr>" */
int iField; /* Field in (?,?,?) IN (SELECT...) vector */
union {
int leftColumn; /* Column number of X in "X <op> <expr>" */
struct {
int leftColumn; /* Column number of X in "X <op> <expr>" */
int iField; /* Field in (?,?,?) IN (SELECT...) vector */
} x; /* Opcode other than OP_OR or OP_AND */
WhereOrInfo *pOrInfo; /* Extra information if (eOperator & WO_OR)!=0 */
WhereAndInfo *pAndInfo; /* Extra information if (eOperator& WO_AND)!=0 */
} u;
@@ -617,5 +619,6 @@ void sqlite3WhereTabFuncArgs(Parse*, struct SrcList_item*, WhereClause*);
#define WHERE_PARTIALIDX 0x00020000 /* The automatic index is partial */
#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 */
#endif /* !defined(SQLITE_WHEREINT_H) */
+34 -8
View File
@@ -427,7 +427,7 @@ static Expr *removeUnindexableInClauseTerms(
for(i=iEq; i<pLoop->nLTerm; i++){
if( pLoop->aLTerm[i]->pExpr==pX ){
int iField = pLoop->aLTerm[i]->iField - 1;
int iField = pLoop->aLTerm[i]->u.x.iField - 1;
if( pOrigRhs->a[iField].pExpr==0 ) continue; /* Duplicate PK column */
pRhs = sqlite3ExprListAppend(pParse, pRhs, pOrigRhs->a[iField].pExpr);
pOrigRhs->a[iField].pExpr = 0;
@@ -570,6 +570,9 @@ static int codeEqualityTerm(
if( pLevel->u.in.nIn==0 ){
pLevel->addrNxt = sqlite3VdbeMakeLabel(pParse);
}
if( iEq>0 && (pLoop->wsFlags & WHERE_IN_SEEKSCAN)==0 ){
pLoop->wsFlags |= WHERE_IN_EARLYOUT;
}
i = pLevel->u.in.nIn;
pLevel->u.in.nIn += nEq;
@@ -596,7 +599,6 @@ static int codeEqualityTerm(
if( iEq>0 ){
pIn->iBase = iReg - i;
pIn->nPrefix = i;
pLoop->wsFlags |= WHERE_IN_EARLYOUT;
}else{
pIn->nPrefix = 0;
}
@@ -606,6 +608,14 @@ static int codeEqualityTerm(
pIn++;
}
}
testcase( iEq>0
&& (pLoop->wsFlags & WHERE_IN_SEEKSCAN)==0
&& (pLoop->wsFlags & WHERE_VIRTUALTABLE)!=0 );
if( iEq>0
&& (pLoop->wsFlags & (WHERE_IN_SEEKSCAN|WHERE_VIRTUALTABLE))==0
){
sqlite3VdbeAddOp3(v, OP_SeekHit, pLevel->iIdxCur, 0, iEq);
}
}else{
pLevel->u.in.nIn = 0;
}
@@ -1392,6 +1402,9 @@ Bitmask sqlite3WhereCodeOneLoopStart(
pLoop->u.vtab.needFree ? P4_DYNAMIC : P4_STATIC);
VdbeCoverage(v);
pLoop->u.vtab.needFree = 0;
/* An OOM inside of AddOp4(OP_VFilter) instruction above might have freed
** the u.vtab.idxStr. NULL it out to prevent a use-after-free */
if( db->mallocFailed ) pLoop->u.vtab.idxStr = 0;
pLevel->p1 = iCur;
pLevel->op = pWInfo->eOnePass ? OP_Noop : OP_VNext;
pLevel->p2 = sqlite3VdbeCurrentAddr(v);
@@ -1650,6 +1663,7 @@ Bitmask sqlite3WhereCodeOneLoopStart(
u8 bStopAtNull = 0; /* Add condition to terminate at NULLs */
int omitTable; /* True if we use the index only */
int regBignull = 0; /* big-null flag register */
int addrSeekScan = 0; /* Opcode of the OP_SeekScan, if any */
pIdx = pLoop->u.btree.pIndex;
iIdxCur = pLevel->iIdxCur;
@@ -1788,9 +1802,6 @@ Bitmask sqlite3WhereCodeOneLoopStart(
** above has already left the cursor sitting on the correct row,
** so no further seeking is needed */
}else{
if( pLoop->wsFlags & WHERE_IN_EARLYOUT ){
sqlite3VdbeAddOp1(v, OP_SeekHit, iIdxCur);
}
if( regBignull ){
sqlite3VdbeAddOp2(v, OP_Integer, 1, regBignull);
VdbeComment((v, "NULL-scan pass ctr"));
@@ -1798,6 +1809,20 @@ Bitmask sqlite3WhereCodeOneLoopStart(
op = aStartOp[(start_constraints<<2) + (startEq<<1) + bRev];
assert( op!=0 );
if( (pLoop->wsFlags & WHERE_IN_SEEKSCAN)!=0 && op==OP_SeekGE ){
assert( regBignull==0 );
/* TUNING: The OP_SeekScan opcode seeks to reduce the number
** of expensive seek operations by replacing a single seek with
** 1 or more step operations. The question is, how many steps
** should we try before giving up and going with a seek. The cost
** of a seek is proportional to the logarithm of the of the number
** of entries in the tree, so basing the number of steps to try
** on the estimated number of rows in the btree seems like a good
** guess. */
addrSeekScan = sqlite3VdbeAddOp1(v, OP_SeekScan,
(pIdx->aiRowLogEst[0]+9)/10);
VdbeCoverage(v);
}
sqlite3VdbeAddOp4Int(v, op, iIdxCur, addrNxt, regBase, nConstraint);
VdbeCoverage(v);
VdbeCoverageIf(v, op==OP_Rewind); testcase( op==OP_Rewind );
@@ -1880,6 +1905,7 @@ Bitmask sqlite3WhereCodeOneLoopStart(
testcase( op==OP_IdxGE ); VdbeCoverageIf(v, op==OP_IdxGE );
testcase( op==OP_IdxLT ); VdbeCoverageIf(v, op==OP_IdxLT );
testcase( op==OP_IdxLE ); VdbeCoverageIf(v, op==OP_IdxLE );
if( addrSeekScan ) sqlite3VdbeJumpHere(v, addrSeekScan);
}
if( regBignull ){
/* During a NULL-scan, check to see if we have reached the end of
@@ -1899,8 +1925,8 @@ Bitmask sqlite3WhereCodeOneLoopStart(
testcase( op==OP_IdxLE ); VdbeCoverageIf(v, op==OP_IdxLE );
}
if( pLoop->wsFlags & WHERE_IN_EARLYOUT ){
sqlite3VdbeAddOp2(v, OP_SeekHit, iIdxCur, 1);
if( (pLoop->wsFlags & WHERE_IN_EARLYOUT)!=0 ){
sqlite3VdbeAddOp3(v, OP_SeekHit, iIdxCur, nEq, nEq);
}
/* Seek the table cursor, if required */
@@ -2407,7 +2433,7 @@ Bitmask sqlite3WhereCodeOneLoopStart(
#endif
assert( !ExprHasProperty(pE, EP_FromJoin) );
assert( (pTerm->prereqRight & pLevel->notReady)!=0 );
pAlt = sqlite3WhereFindTerm(pWC, iCur, pTerm->u.leftColumn, notReady,
pAlt = sqlite3WhereFindTerm(pWC, iCur, pTerm->u.x.leftColumn, notReady,
WO_EQ|WO_IN|WO_IS, 0);
if( pAlt==0 ) continue;
if( pAlt->wtFlags & (TERM_CODED) ) continue;
+13 -13
View File
@@ -798,7 +798,7 @@ static void exprAnalyzeOrTerm(
assert( pOrTerm->wtFlags & (TERM_COPIED|TERM_VIRTUAL) );
continue;
}
iColumn = pOrTerm->u.leftColumn;
iColumn = pOrTerm->u.x.leftColumn;
iCursor = pOrTerm->leftCursor;
pLeft = pOrTerm->pExpr->pLeft;
break;
@@ -820,7 +820,7 @@ static void exprAnalyzeOrTerm(
assert( pOrTerm->eOperator & WO_EQ );
if( pOrTerm->leftCursor!=iCursor ){
pOrTerm->wtFlags &= ~TERM_OR_OK;
}else if( pOrTerm->u.leftColumn!=iColumn || (iColumn==XN_EXPR
}else if( pOrTerm->u.x.leftColumn!=iColumn || (iColumn==XN_EXPR
&& sqlite3ExprCompare(pParse, pOrTerm->pExpr->pLeft, pLeft, -1)
)){
okToChngToIN = 0;
@@ -855,7 +855,7 @@ static void exprAnalyzeOrTerm(
if( (pOrTerm->wtFlags & TERM_OR_OK)==0 ) continue;
assert( pOrTerm->eOperator & WO_EQ );
assert( pOrTerm->leftCursor==iCursor );
assert( pOrTerm->u.leftColumn==iColumn );
assert( pOrTerm->u.x.leftColumn==iColumn );
pDup = sqlite3ExprDup(db, pOrTerm->pExpr->pRight, 0);
pList = sqlite3ExprListAppend(pWInfo->pParse, pList, pDup);
pLeft = pOrTerm->pExpr->pLeft;
@@ -1091,15 +1091,15 @@ static void exprAnalyze(
Expr *pRight = sqlite3ExprSkipCollate(pExpr->pRight);
u16 opMask = (pTerm->prereqRight & prereqLeft)==0 ? WO_ALL : WO_EQUIV;
if( pTerm->iField>0 ){
if( pTerm->u.x.iField>0 ){
assert( op==TK_IN );
assert( pLeft->op==TK_VECTOR );
pLeft = pLeft->x.pList->a[pTerm->iField-1].pExpr;
pLeft = pLeft->x.pList->a[pTerm->u.x.iField-1].pExpr;
}
if( exprMightBeIndexed(pSrc, prereqLeft, aiCurCol, pLeft, op) ){
pTerm->leftCursor = aiCurCol[0];
pTerm->u.leftColumn = aiCurCol[1];
pTerm->u.x.leftColumn = aiCurCol[1];
pTerm->eOperator = operatorMask(op) & opMask;
}
if( op==TK_IS ) pTerm->wtFlags |= TERM_IS;
@@ -1109,7 +1109,7 @@ static void exprAnalyze(
WhereTerm *pNew;
Expr *pDup;
u16 eExtraOp = 0; /* Extra bits for pNew->eOperator */
assert( pTerm->iField==0 );
assert( pTerm->u.x.iField==0 );
if( pTerm->leftCursor>=0 ){
int idxNew;
pDup = sqlite3ExprDup(db, pExpr, 0);
@@ -1135,7 +1135,7 @@ static void exprAnalyze(
}
pNew->wtFlags |= exprCommute(pParse, pDup);
pNew->leftCursor = aiCurCol[0];
pNew->u.leftColumn = aiCurCol[1];
pNew->u.x.leftColumn = aiCurCol[1];
testcase( (prereqLeft | extraRight) != prereqLeft );
pNew->prereqRight = prereqLeft | extraRight;
pNew->prereqAll = prereqAll;
@@ -1309,7 +1309,7 @@ static void exprAnalyze(
pNewTerm = &pWC->a[idxNew];
pNewTerm->prereqRight = prereqExpr;
pNewTerm->leftCursor = pLeft->iTable;
pNewTerm->u.leftColumn = pLeft->iColumn;
pNewTerm->u.x.leftColumn = pLeft->iColumn;
pNewTerm->eOperator = WO_AUX;
pNewTerm->eMatchOp = eOp2;
markTermAsChild(pWC, idxNew, idxTerm);
@@ -1356,13 +1356,13 @@ static void exprAnalyze(
/* If there is a vector IN term - e.g. "(a, b) IN (SELECT ...)" - create
** a virtual term for each vector component. The expression object
** used by each such virtual term is pExpr (the full vector IN(...)
** expression). The WhereTerm.iField variable identifies the index within
** expression). The WhereTerm.u.x.iField variable identifies the index within
** the vector on the LHS that the virtual term represents.
**
** This only works if the RHS is a simple SELECT (not a compound) that does
** not use window functions.
*/
if( pWC->op==TK_AND && pExpr->op==TK_IN && pTerm->iField==0
if( pWC->op==TK_AND && pExpr->op==TK_IN && pTerm->u.x.iField==0
&& pExpr->pLeft->op==TK_VECTOR
&& pExpr->x.pSelect->pPrior==0
#ifndef SQLITE_OMIT_WINDOWFUNC
@@ -1373,7 +1373,7 @@ static void exprAnalyze(
for(i=0; i<sqlite3ExprVectorSize(pExpr->pLeft); i++){
int idxNew;
idxNew = whereClauseInsert(pWC, pExpr, TERM_VIRTUAL);
pWC->a[idxNew].iField = i+1;
pWC->a[idxNew].u.x.iField = i+1;
exprAnalyze(pSrc, pWC, idxNew);
markTermAsChild(pWC, idxNew, idxTerm);
}
@@ -1408,7 +1408,7 @@ static void exprAnalyze(
pNewTerm = &pWC->a[idxNew];
pNewTerm->prereqRight = 0;
pNewTerm->leftCursor = pLeft->iTable;
pNewTerm->u.leftColumn = pLeft->iColumn;
pNewTerm->u.x.leftColumn = pLeft->iColumn;
pNewTerm->eOperator = WO_GT;
markTermAsChild(pWC, idxNew, idxTerm);
pTerm = &pWC->a[idxTerm];
+4 -4
View File
@@ -72,10 +72,10 @@ do_execsql_test affinity3-200 {
CREATE TABLE mzed AS SELECT * FROM idmap;
}
do_execsql_test affinity3-210 {
PRAGMA automatic_index=ON;
SELECT * FROM data JOIN idmap USING(id);
} {1 abc a 4 xyz e}
#do_execsql_test affinity3-210 {
#PRAGMA automatic_index=ON;
#SELECT * FROM data JOIN idmap USING(id);
#} {1 abc a 4 xyz e}
do_execsql_test affinity3-220 {
SELECT * FROM data JOIN mzed USING(id);
} {1 abc a 4 xyz e}
+35
View File
@@ -677,4 +677,39 @@ do_execsql_test 22.1 {
SELECT * FROM t1;
} {1 2 78 a b 78}
#-------------------------------------------------------------------------
reset_db
db collate compare64 compare64
do_execsql_test 23.1 {
CREATE TABLE gigo(a text);
CREATE TABLE idx(x text COLLATE compare64);
CREATE VIEW v1 AS SELECT * FROM idx WHERE x='abc';
}
db close
sqlite3 db test.db
do_execsql_test 23.2 {
alter table gigo rename to ggiiggoo;
alter table idx rename to idx2;
}
do_execsql_test 23.3 {
SELECT sql FROM sqlite_master;
} {
{CREATE TABLE "ggiiggoo"(a text)}
{CREATE TABLE "idx2"(x text COLLATE compare64)}
{CREATE VIEW v1 AS SELECT * FROM "idx2" WHERE x='abc'}
}
do_execsql_test 23.4 {
ALTER TABLE idx2 RENAME x TO y;
SELECT sql FROM sqlite_master;
} {
{CREATE TABLE "ggiiggoo"(a text)}
{CREATE TABLE "idx2"(y text COLLATE compare64)}
{CREATE VIEW v1 AS SELECT * FROM "idx2" WHERE y='abc'}
}
finish_test
+10
View File
@@ -23,6 +23,16 @@ ifcapable !stat4 {
return
}
# This test cannot be run with the sqlite3_prepare() permutation, as it
# tests that stat4 data can be used to influence the plans of queries
# based on bound variable values. And this is not possible when using
# sqlite3_prepare() - as queries cannot be internally re-prepared after
# binding values are available.
if {[permutation]=="prepare"} {
finish_test
return
}
#----------------------------------------------------------------------
# Test Organization:
#
+4 -4
View File
@@ -75,10 +75,10 @@ do_execsql_test atof1-2.30 {
CREATE INDEX i1 ON t1(a);
SELECT count(*) FROM t1 WHERE substr(a,',');
} {1}
# 2020-08-27 OSSFuzz find related to the above.
do_execsql_test atof1-2.40 {
SELECT randomblob(0) - 1;
} {-1}
finish_test
+1 -1
View File
@@ -95,7 +95,7 @@ for {set i 0} {$i < 9} {incr i} {
" [string map {"\n " "\n"} "
QUERY PLAN
|--SCAN TABLE t$t AS o USING COVERING INDEX sqlite_autoindex_t${t}_1
`--CORRELATED SCALAR SUBQUERY
`--CORRELATED SCALAR SUBQUERY xxxxxx
`--SEARCH TABLE t$t AS i USING INTEGER PRIMARY KEY (rowid=?)
"]
}
+36
View File
@@ -131,5 +131,41 @@ do_multiclient_test tn {
}
}
#-------------------------------------------------------------------------
# Check that even if the busy-handler fails (returns zero) within a
# call to sqlite3_prepare() (or _v2(), or _v3()), it is still invoked
# the next time an SQLITE_BUSY is encountered.
#
do_multiclient_test tn {
code1 {
set ::busy_called 0
proc busy {args} {
if {$::busy_called} { return 1 }
set ::busy_called 1
return 0
}
db busy busy
}
do_test 3.$tn.1 {
sql2 {
CREATE TABLE t1(x);
BEGIN EXCLUSIVE;
INSERT INTO t1 VALUES('x');
}
} {}
do_test 3.$tn.2 {
set ::busy_called 0
list [catch { sql1 { SELECT * FROM t1 } } msg] $msg $::busy_called
} {1 {database is locked} 1}
do_test 3.$tn.3 {
set ::busy_called 0
list [catch { sql1 { SELECT * FROM t1 } } msg] $msg $::busy_called
} {1 {database is locked} 1}
}
finish_test
+9
View File
@@ -474,5 +474,14 @@ ifcapable utf16 {
} 1
}
reset_db
do_execsql_test cast-9.0 {
CREATE TABLE t0(c0);
INSERT INTO t0(c0) VALUES (0);
CREATE VIEW v1(c0, c1) AS
SELECT CAST(0.0 AS NUMERIC), COUNT(*) OVER () FROM t0;
SELECT v1.c0 FROM v1, t0 WHERE v1.c0=0;
} {0.0}
finish_test
+25 -19
View File
@@ -40,7 +40,7 @@ do_test check-1.3 {
catchsql {
INSERT INTO t1 VALUES(6,7);
}
} {1 {CHECK constraint failed: t1}}
} {1 {CHECK constraint failed: x<5}}
do_test check-1.4 {
execsql {
SELECT * FROM t1;
@@ -50,7 +50,7 @@ do_test check-1.5 {
catchsql {
INSERT INTO t1 VALUES(4,3);
}
} {1 {CHECK constraint failed: t1}}
} {1 {CHECK constraint failed: y>x}}
do_test check-1.6 {
execsql {
SELECT * FROM t1;
@@ -87,7 +87,7 @@ do_test check-1.12 {
catchsql {
UPDATE t1 SET x=7 WHERE x==2
}
} {1 {CHECK constraint failed: t1}}
} {1 {CHECK constraint failed: x<5}}
do_test check-1.13 {
execsql {
SELECT * FROM t1;
@@ -97,7 +97,7 @@ do_test check-1.14 {
catchsql {
UPDATE t1 SET x=5 WHERE x==2
}
} {1 {CHECK constraint failed: t1}}
} {1 {CHECK constraint failed: x<5}}
do_test check-1.15 {
execsql {
SELECT * FROM t1;
@@ -186,7 +186,7 @@ do_test check-2.11 {
catchsql {
INSERT INTO t2b VALUES('xyzzy','hi',5);
}
} {1 {CHECK constraint failed: t2b}}
} {1 {CHECK constraint failed: typeof(coalesce(x,0))=='integer'}}
do_test check-2.12 {
execsql {
CREATE TABLE t2c(
@@ -271,7 +271,7 @@ do_test check-3.9 {
catchsql {
INSERT INTO t3 VALUES(111,222,333);
}
} {1 {CHECK constraint failed: t3}}
} {1 {CHECK constraint failed: t3.x<25}}
do_test check-4.1 {
execsql {
@@ -313,7 +313,10 @@ do_test check-4.6 {
catchsql {
UPDATE t4 SET x=0, y=1;
}
} {1 {CHECK constraint failed: t4}}
} {1 {CHECK constraint failed: x+y==11
OR x*y==12
OR x/y BETWEEN 5 AND 8
OR -x==y+10}}
do_test check-4.7 {
execsql {
SELECT * FROM t4;
@@ -335,7 +338,10 @@ do_test check-4.9 {
catchsql {
UPDATE t4 SET x=0, y=2;
}
} {1 {CHECK constraint failed: t4}}
} {1 {CHECK constraint failed: x+y==11
OR x*y==12
OR x/y BETWEEN 5 AND 8
OR -x==y+10}}
ifcapable vacuum {
do_test check_4.10 {
catchsql {
@@ -386,7 +392,7 @@ do_test check-6.5 {
catchsql {
UPDATE OR FAIL t1 SET x=7-x, y=y+1;
}
} {1 {CHECK constraint failed: t1}}
} {1 {CHECK constraint failed: x<5}}
do_test check-6.6 {
execsql {
SELECT * FROM t1;
@@ -398,7 +404,7 @@ do_test check-6.7 {
INSERT INTO t1 VALUES(1,30.0);
INSERT OR ROLLBACK INTO t1 VALUES(8,40.0);
}
} {1 {CHECK constraint failed: t1}}
} {1 {CHECK constraint failed: x<5}}
do_test check-6.8 {
catchsql {
COMMIT;
@@ -417,7 +423,7 @@ do_test check-6.12 {
catchsql {
REPLACE INTO t1 VALUES(6,7);
}
} {1 {CHECK constraint failed: t1}}
} {1 {CHECK constraint failed: x<5}}
do_test check-6.13 {
execsql {SELECT * FROM t1}
} {3 12.0 2 20.0}
@@ -446,7 +452,7 @@ db func myfunc -deterministic myfunc
do_execsql_test 7.1 { CREATE TABLE t6(a CHECK (myfunc(a))) }
do_execsql_test 7.2 { INSERT INTO t6 VALUES(9) }
do_catchsql_test 7.3 { INSERT INTO t6 VALUES(11) } \
{1 {CHECK constraint failed: t6}}
{1 {CHECK constraint failed: myfunc(a)}}
do_test 7.4 {
sqlite3 db2 test.db
@@ -469,7 +475,7 @@ do_test 7.7 {
do_test 7.8 {
db2 func myfunc myfunc
catchsql { INSERT INTO t6 VALUES(12) } db2
} {1 {CHECK constraint failed: t6}}
} {1 {CHECK constraint failed: myfunc(a)}}
# 2013-08-02: Silently ignore database name qualifiers in CHECK constraints.
#
@@ -550,10 +556,10 @@ do_execsql_test 12.20 {
} {}
do_catchsql_test 12.21 {
INSERT INTO t1(a) VALUES('xyz');
} {1 {CHECK constraint failed: t1}}
} {1 {CHECK constraint failed: a<>+a}}
do_catchsql_test 12.22 {
INSERT INTO t1(a) VALUES(123);
} {1 {CHECK constraint failed: t1}}
} {1 {CHECK constraint failed: a<>+a}}
do_execsql_test 12.30 {
DROP TABLE t1;
CREATE TABLE t1(a TEXT, CHECK(NOT(a=+a)));
@@ -561,10 +567,10 @@ do_execsql_test 12.30 {
} {}
do_catchsql_test 12.31 {
INSERT INTO t1(a) VALUES('xyz');
} {1 {CHECK constraint failed: t1}}
} {1 {CHECK constraint failed: NOT(a=+a)}}
do_catchsql_test 12.32 {
INSERT INTO t1(a) VALUES(123);
} {1 {CHECK constraint failed: t1}}
} {1 {CHECK constraint failed: NOT(a=+a)}}
do_execsql_test 12.40 {
DROP TABLE t1;
CREATE TABLE t1(a TEXT, CHECK(NOT(a<>+a)));
@@ -585,7 +591,7 @@ do_execsql_test 12.60 {
} {NULL}
do_catchsql_test 12.61 {
INSERT INTO t1(a) VALUES(456);
} {1 {CHECK constraint failed: t1}}
} {1 {CHECK constraint failed: a NOT BETWEEN 0 AND +a}}
do_execsql_test 12.70 {
DROP TABLE t1;
CREATE TABLE t1(a TEXT, CHECK(a BETWEEN +a AND 999999));
@@ -600,6 +606,6 @@ do_execsql_test 12.80 {
} {NULL}
do_catchsql_test 12.81 {
INSERT INTO t1(a) VALUES(456);
} {1 {CHECK constraint failed: t1}}
} {1 {CHECK constraint failed: a NOT BETWEEN +a AND 999999}}
finish_test
+1 -1
View File
@@ -813,7 +813,7 @@ do_test conflict-13.1 {
catchsql {
REPLACE INTO t13 VALUES(2);
}
} {1 {CHECK constraint failed: t13}}
} {1 {CHECK constraint failed: a!=2}}
verify_ex_errcode conflict-13.1b SQLITE_CONSTRAINT_CHECK
do_test conflict-13.2 {
execsql {
+1 -1
View File
@@ -811,7 +811,7 @@ do_test conflict2-13.1 {
catchsql {
REPLACE INTO t13 VALUES(2);
}
} {1 {CHECK constraint failed: t13}}
} {1 {CHECK constraint failed: a!=2}}
verify_ex_errcode conflict2-13.1b SQLITE_CONSTRAINT_CHECK
do_test conflict2-13.2 {
execsql {
+2 -2
View File
@@ -36,7 +36,7 @@ do_execsql_test date2-120 {
} {2017-07-20 one}
do_catchsql_test date2-130 {
INSERT INTO t1(x,y) VALUES('2017-08-01','two');
} {1 {CHECK constraint failed: t1}}
} {1 {CHECK constraint failed: date(x) BETWEEN '2017-07-01' AND '2017-07-31'}}
do_execsql_test date2-200 {
CREATE TABLE t2(x,y);
@@ -138,7 +138,7 @@ do_catchsql_test date2-601 {
} {0 {}}
do_catchsql_test date2-602 {
INSERT INTO t601(a,b) VALUES(1e100, '1970-01-01');
} {1 {CHECK constraint failed: t601}}
} {1 {CHECK constraint failed: a<julianday(b)}}
do_catchsql_test date2-603 {
INSERT INTO t601(a,b) VALUES(10, 'now');
} {1 {non-deterministic use of julianday() in a CHECK constraint}}
+1 -1
View File
@@ -266,7 +266,7 @@ do_execsql_test 2030 {
ANALYZE;
}
do_execsql_test 2040 {
SELECT DISTINCT a, b, x FROM t3 CROSS JOIN t2 ORDER BY a;
SELECT DISTINCT a, b, x FROM t3 CROSS JOIN t2 ORDER BY a, +b;
} {
one 0 1
one 1 1
+11 -11
View File
@@ -1433,20 +1433,20 @@ do_execsql_test 4.11 {
}
do_createtable_tests 4.11 -error {CHECK constraint failed: %s} {
1a "INSERT INTO x1 VALUES('one', 0)" {x1}
1b "INSERT INTO t1 VALUES('one', -4.0)" {t1}
1a "INSERT INTO x1 VALUES('one', 0)" {b>0}
1b "INSERT INTO t1 VALUES('one', -4.0)" {b>0}
2a "INSERT INTO x2 VALUES('abc', 1)" {x2}
2b "INSERT INTO t2 VALUES('abc', 1)" {t2}
2a "INSERT INTO x2 VALUES('abc', 1)" {a||b}
2b "INSERT INTO t2 VALUES('abc', 1)" {a||b}
3a "INSERT INTO x2 VALUES(0, 'abc')" {x2}
3b "INSERT INTO t2 VALUES(0, 'abc')" {t2}
3a "INSERT INTO x2 VALUES(0, 'abc')" {a||b}
3b "INSERT INTO t2 VALUES(0, 'abc')" {a||b}
4a "UPDATE t1 SET b=-1 WHERE rowid=1" {t1}
4b "UPDATE x1 SET b=-1 WHERE rowid=1" {x1}
4a "UPDATE t1 SET b=-1 WHERE rowid=1" {b>0}
4b "UPDATE x1 SET b=-1 WHERE rowid=1" {b>0}
4a "UPDATE x2 SET a='' WHERE rowid=1" {x2}
4b "UPDATE t2 SET a='' WHERE rowid=1" {t2}
4a "UPDATE x2 SET a='' WHERE rowid=1" {a||b}
4b "UPDATE t2 SET a='' WHERE rowid=1" {a||b}
}
# EVIDENCE-OF: R-34109-39108 If the CHECK expression evaluates to NULL,
@@ -1639,7 +1639,7 @@ do_execsql_test 4.18.1 {
do_execsql_test 4.18.2 { BEGIN; INSERT INTO t4 VALUES(5, 6) }
do_catchsql_test 4.18.3 {
INSERT INTO t4 SELECT a+4, b+4 FROM t4
} {1 {CHECK constraint failed: t4}}
} {1 {CHECK constraint failed: b!=10}}
do_test e_createtable-4.18.4 { sqlite3_get_autocommit db } 0
do_execsql_test 4.18.5 { SELECT * FROM t4 } {1 2 3 4 5 6}
+2 -2
View File
@@ -417,14 +417,14 @@ do_test fkey2-3.1.2 {
} {}
do_test fkey2-3.1.3 {
catchsql { UPDATE ab SET a = 5 }
} {1 {CHECK constraint failed: ef}}
} {1 {CHECK constraint failed: e!=5}}
do_test fkey2-3.1.4 {
execsql { SELECT * FROM ab }
} {1 b}
do_test fkey2-3.1.4 {
execsql BEGIN;
catchsql { UPDATE ab SET a = 5 }
} {1 {CHECK constraint failed: ef}}
} {1 {CHECK constraint failed: e!=5}}
do_test fkey2-3.1.5 {
execsql COMMIT;
execsql { SELECT * FROM ab; SELECT * FROM cd; SELECT * FROM ef }
+23 -23
View File
@@ -381,32 +381,32 @@ ifcapable check {
catchsql {
INSERT INTO t1 (x) VALUES (NULL);
}
} {1 {CHECK constraint failed: t1}}
} {1 {CHECK constraint failed: tointeger(x) IS NOT NULL}}
do_test func4-3.3 {
catchsql {
INSERT INTO t1 (x) VALUES (NULL);
}
} {1 {CHECK constraint failed: t1}}
} {1 {CHECK constraint failed: tointeger(x) IS NOT NULL}}
do_test func4-3.4 {
catchsql {
INSERT INTO t1 (x) VALUES ('');
}
} {1 {CHECK constraint failed: t1}}
} {1 {CHECK constraint failed: tointeger(x) IS NOT NULL}}
do_test func4-3.5 {
catchsql {
INSERT INTO t1 (x) VALUES ('bad');
}
} {1 {CHECK constraint failed: t1}}
} {1 {CHECK constraint failed: tointeger(x) IS NOT NULL}}
do_test func4-3.6 {
catchsql {
INSERT INTO t1 (x) VALUES ('1234bad');
}
} {1 {CHECK constraint failed: t1}}
} {1 {CHECK constraint failed: tointeger(x) IS NOT NULL}}
do_test func4-3.7 {
catchsql {
INSERT INTO t1 (x) VALUES ('1234.56bad');
}
} {1 {CHECK constraint failed: t1}}
} {1 {CHECK constraint failed: tointeger(x) IS NOT NULL}}
do_test func4-3.8 {
catchsql {
INSERT INTO t1 (x) VALUES (1234);
@@ -416,7 +416,7 @@ ifcapable check {
catchsql {
INSERT INTO t1 (x) VALUES (1234.56);
}
} {1 {CHECK constraint failed: t1}}
} {1 {CHECK constraint failed: tointeger(x) IS NOT NULL}}
do_test func4-3.10 {
catchsql {
INSERT INTO t1 (x) VALUES ('1234');
@@ -426,27 +426,27 @@ ifcapable check {
catchsql {
INSERT INTO t1 (x) VALUES ('1234.56');
}
} {1 {CHECK constraint failed: t1}}
} {1 {CHECK constraint failed: tointeger(x) IS NOT NULL}}
do_test func4-3.12 {
catchsql {
INSERT INTO t1 (x) VALUES (ZEROBLOB(4));
}
} {1 {CHECK constraint failed: t1}}
} {1 {CHECK constraint failed: tointeger(x) IS NOT NULL}}
do_test func4-3.13 {
catchsql {
INSERT INTO t1 (x) VALUES (X'');
}
} {1 {CHECK constraint failed: t1}}
} {1 {CHECK constraint failed: tointeger(x) IS NOT NULL}}
do_test func4-3.14 {
catchsql {
INSERT INTO t1 (x) VALUES (X'1234');
}
} {1 {CHECK constraint failed: t1}}
} {1 {CHECK constraint failed: tointeger(x) IS NOT NULL}}
do_test func4-3.15 {
catchsql {
INSERT INTO t1 (x) VALUES (X'12345678');
}
} {1 {CHECK constraint failed: t1}}
} {1 {CHECK constraint failed: tointeger(x) IS NOT NULL}}
do_test func4-3.16 {
catchsql {
INSERT INTO t1 (x) VALUES ('1234.00');
@@ -467,7 +467,7 @@ ifcapable check {
catchsql {
INSERT INTO t1 (x) VALUES (9223372036854775808);
}
} {1 {CHECK constraint failed: t1}}
} {1 {CHECK constraint failed: tointeger(x) IS NOT NULL}}
}
do_execsql_test func4-3.20 {
SELECT x FROM t1 WHERE x>0 ORDER BY x;
@@ -483,32 +483,32 @@ ifcapable check {
catchsql {
INSERT INTO t2 (x) VALUES (NULL);
}
} {1 {CHECK constraint failed: t2}}
} {1 {CHECK constraint failed: toreal(x) IS NOT NULL}}
do_test func4-4.3 {
catchsql {
INSERT INTO t2 (x) VALUES (NULL);
}
} {1 {CHECK constraint failed: t2}}
} {1 {CHECK constraint failed: toreal(x) IS NOT NULL}}
do_test func4-4.4 {
catchsql {
INSERT INTO t2 (x) VALUES ('');
}
} {1 {CHECK constraint failed: t2}}
} {1 {CHECK constraint failed: toreal(x) IS NOT NULL}}
do_test func4-4.5 {
catchsql {
INSERT INTO t2 (x) VALUES ('bad');
}
} {1 {CHECK constraint failed: t2}}
} {1 {CHECK constraint failed: toreal(x) IS NOT NULL}}
do_test func4-4.6 {
catchsql {
INSERT INTO t2 (x) VALUES ('1234bad');
}
} {1 {CHECK constraint failed: t2}}
} {1 {CHECK constraint failed: toreal(x) IS NOT NULL}}
do_test func4-4.7 {
catchsql {
INSERT INTO t2 (x) VALUES ('1234.56bad');
}
} {1 {CHECK constraint failed: t2}}
} {1 {CHECK constraint failed: toreal(x) IS NOT NULL}}
do_test func4-4.8 {
catchsql {
INSERT INTO t2 (x) VALUES (1234);
@@ -533,22 +533,22 @@ ifcapable check {
catchsql {
INSERT INTO t2 (x) VALUES (ZEROBLOB(4));
}
} {1 {CHECK constraint failed: t2}}
} {1 {CHECK constraint failed: toreal(x) IS NOT NULL}}
do_test func4-4.13 {
catchsql {
INSERT INTO t2 (x) VALUES (X'');
}
} {1 {CHECK constraint failed: t2}}
} {1 {CHECK constraint failed: toreal(x) IS NOT NULL}}
do_test func4-4.14 {
catchsql {
INSERT INTO t2 (x) VALUES (X'1234');
}
} {1 {CHECK constraint failed: t2}}
} {1 {CHECK constraint failed: toreal(x) IS NOT NULL}}
do_test func4-4.15 {
catchsql {
INSERT INTO t2 (x) VALUES (X'12345678');
}
} {1 {CHECK constraint failed: t2}}
} {1 {CHECK constraint failed: toreal(x) IS NOT NULL}}
do_execsql_test func4-4.16 {
SELECT x FROM t2 ORDER BY x;
} {1234.0 1234.0 1234.56 1234.56}
+33 -9
View File
@@ -627,7 +627,7 @@ static int decodeDatabase(
unsigned char **paDecode, /* OUT: decoded database file */
int *pnDecode /* OUT: Size of decoded database */
){
unsigned char *a; /* Database under construction */
unsigned char *a, *aNew; /* Database under construction */
int mx = 0; /* Current size of the database */
sqlite3_uint64 nAlloc = 4096; /* Space allocated in a[] */
unsigned int i; /* Next byte of zIn[] to read */
@@ -673,11 +673,12 @@ static int decodeDatabase(
}
newSize = MX_FILE_SZ;
}
a = sqlite3_realloc64( a, newSize );
if( a==0 ){
fprintf(stderr, "Out of memory!\n");
exit(1);
aNew = sqlite3_realloc64( a, newSize );
if( aNew==0 ){
sqlite3_free(a);
return -1;
}
a = aNew;
assert( newSize > nAlloc );
memset(a+nAlloc, 0, (size_t)(newSize - nAlloc));
nAlloc = newSize;
@@ -851,7 +852,8 @@ int runCombinedDbSqlInput(const uint8_t *aData, size_t nByte){
int nAlloc = 0;
int nNotUsed = 0;
sqlite3_status(SQLITE_STATUS_MALLOC_COUNT, &nAlloc, &nNotUsed, 0);
fprintf(stderr,"Memory leak in mutator: %lld bytes in %d allocations\n",
fprintf(stderr,"memory leak prior to test start:"
" %lld bytes in %d allocations\n",
sqlite3_memory_used(), nAlloc);
exit(1);
}
@@ -866,7 +868,10 @@ int runCombinedDbSqlInput(const uint8_t *aData, size_t nByte){
fflush(stdout);
}
rc = sqlite3_open(0, &cx.db);
if( rc ) return 1;
if( rc ){
sqlite3_free(aDb);
return 1;
}
if( bVdbeDebug ){
sqlite3_exec(cx.db, "PRAGMA vdbe_debug=ON", 0, 0, 0);
}
@@ -1410,7 +1415,8 @@ static void showHelp(void){
" --export-sql DIR Write SQL to file(s) in DIR. Also works with --sqlid\n"
" --help Show this help text\n"
" --info Show information about SOURCE-DB w/o running tests\n"
" --limit-depth N Limit expression depth to N\n"
" --limit-depth N Limit expression depth to N. Default: 500\n"
" --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"
@@ -1424,6 +1430,7 @@ static void showHelp(void){
" -q|--quiet Reduced output\n"
" --rebuild Rebuild and vacuum the database file\n"
" --result-trace Show the results of each SQL command\n"
" --skip N Skip the first N test cases\n"
" --spinner Use a spinner to show progress\n"
" --sqlid N Use only SQL where sqlid=N\n"
" --timeout N Abort if any single test needs more than N seconds\n"
@@ -1451,6 +1458,7 @@ int main(int argc, char **argv){
int rebuildFlag = 0; /* --rebuild */
int vdbeLimitFlag = 0; /* --limit-vdbe */
int infoFlag = 0; /* --info */
int nSkip = 0; /* --skip */
int bSpinner = 0; /* True for --spinner */
int timeoutTest = 0; /* undocumented --timeout-test flag */
int runFlags = 0; /* Flags sent to runSql() */
@@ -1520,6 +1528,10 @@ int main(int argc, char **argv){
if( i>=argc-1 ) fatalError("missing arguments on %s", argv[i]);
depthLimit = integerValue(argv[++i]);
}else
if( strcmp(z,"limit-heap")==0 ){
if( i>=argc-1 ) fatalError("missing arguments on %s", argv[i]);
heapLimit = integerValue(argv[++i]);
}else
if( strcmp(z,"limit-mem")==0 ){
if( i>=argc-1 ) fatalError("missing arguments on %s", argv[i]);
nMem = integerValue(argv[++i]);
@@ -1578,6 +1590,10 @@ int main(int argc, char **argv){
if( strcmp(z,"result-trace")==0 ){
runFlags |= SQL_OUTPUT;
}else
if( strcmp(z,"skip")==0 ){
if( i>=argc-1 ) fatalError("missing arguments on %s", argv[i]);
nSkip = atoi(argv[++i]);
}else
if( strcmp(z,"spinner")==0 ){
bSpinner = 1;
}else
@@ -1898,7 +1914,11 @@ int main(int argc, char **argv){
prevAmt = amt;
}
}
runCombinedDbSqlInput(pSql->a, pSql->sz);
if( nSkip>0 ){
nSkip--;
}else{
runCombinedDbSqlInput(pSql->a, pSql->sz);
}
nTest++;
g.zTestName[0] = 0;
disableOom();
@@ -1927,6 +1947,10 @@ int main(int argc, char **argv){
prevAmt = amt;
}
}
if( nSkip>0 ){
nSkip--;
continue;
}
createVFile("main.db", pDb->sz, pDb->a);
sqlite3_randomness(0,0);
if( ossFuzzThisDb ){
BIN
View File
Binary file not shown.
+7 -1
View File
@@ -332,7 +332,7 @@ do_test in-10.2 {
catchsql {
INSERT INTO t5 VALUES(4);
}
} {1 {CHECK constraint failed: t5}}
} {1 {CHECK constraint failed: a IN (111,222,333)}}
# Ticket #1821
#
@@ -791,4 +791,10 @@ do_execsql_test in-19.40 {
PRAGMA integrity_check;
} {ok}
# Ticket f3ff1472887
#
do_execsql_test in-20.1 {
SELECT (1 IN (2 IS TRUE));
} {1}
finish_test
+5 -5
View File
@@ -55,7 +55,7 @@ do_test insert4-1.1 {
catchsql {
INSERT INTO t1 SELECT * FROM t2;
}
} {1 {CHECK constraint failed: t1}}
} {1 {CHECK constraint failed: b>a}}
xferopt_test insert4-1.2 0
do_test insert4-1.3 {
execsql {
@@ -102,7 +102,7 @@ do_test insert4-2.3.3 {
INSERT INTO t1 SELECT * FROM t2 LIMIT 1;
SELECT * FROM t1;
}
} {1 {CHECK constraint failed: t1}}
} {1 {CHECK constraint failed: b>a}}
xferopt_test insert4-2.3.4 0
# Do not run the transfer optimization if there is a DISTINCT
@@ -120,7 +120,7 @@ do_test insert4-2.4.3 {
DELETE FROM t1;
INSERT INTO t1 SELECT DISTINCT * FROM t2;
}
} {1 {CHECK constraint failed: t1}}
} {1 {CHECK constraint failed: b>a}}
xferopt_test insert4-2.4.4 0
# The following procedure constructs two tables then tries to transfer
@@ -316,7 +316,7 @@ do_test insert4-6.6 {
catchsql {
INSERT INTO t6b SELECT * FROM t6a;
}
} {1 {CHECK constraint failed: t6b}}
} {1 {CHECK constraint failed: x<>'abc' COLLATE nocase}}
do_test insert4-6.7 {
execsql {
DROP TABLE t6b;
@@ -325,7 +325,7 @@ do_test insert4-6.7 {
catchsql {
INSERT INTO t6b SELECT * FROM t6a;
}
} {1 {CHECK constraint failed: t6b}}
} {1 {CHECK constraint failed: x COLLATE nocase <>'abc'}}
# Ticket [6284df89debdfa61db8073e062908af0c9b6118e]
# Disable the xfer optimization if the destination table contains
+5 -5
View File
@@ -112,16 +112,16 @@ do_execsql_test istrue-520 {
} {1 1 0 {} {}}
do_catchsql_test istrue-521 {
INSERT INTO t2 VALUES(2,false,false,null,null);
} {1 {CHECK constraint failed: t2}}
} {1 {CHECK constraint failed: b IS TRUE}}
do_catchsql_test istrue-522 {
INSERT INTO t2 VALUES(2,true,true,null,null);
} {1 {CHECK constraint failed: t2}}
} {1 {CHECK constraint failed: c IS FALSE}}
do_catchsql_test istrue-523 {
INSERT INTO t2 VALUES(2,true,false,true,null);
} {1 {CHECK constraint failed: t2}}
} {1 {CHECK constraint failed: d IS NOT TRUE}}
do_catchsql_test istrue-524 {
INSERT INTO t2 VALUES(2,true,false,null,false);
} {1 {CHECK constraint failed: t2}}
} {1 {CHECK constraint failed: e IS NOT FALSE}}
foreach {tn val} [list 1 NaN 2 -NaN 3 NaN0 4 -NaN0 5 Inf 6 -Inf] {
do_execsql_test istrue-600.$tn.1 {
@@ -193,7 +193,7 @@ do_execsql_test istrue-840 {
} {}
do_catchsql_test istrue-841 {
INSERT INTO False VALUES(5,6,7);
} {1 {CHECK constraint failed: false}}
} {1 {CHECK constraint failed: 5 IN (false.false)}}
do_execsql_test istrue-850 {
SELECT 9 IN (false.false) FROM false;
} {0}
+14 -1
View File
@@ -1025,5 +1025,18 @@ do_execsql_test join-24.2 {
SELECT * FROM t2 LEFT JOIN t1 ON a=0 WHERE (x='x' OR x IS NULL);
} {1 {} {}}
finish_test
# 2020-09-30 ticket 66e4b0e271c47145
# The query flattener inserts an "expr AND expr" expression as a substitution
# for the column of a view where that view column is part of an ON expression
# of a LEFT JOIN.
#
reset_db
do_execsql_test join-25.1 {
CREATE TABLE t0(c0 INT);
CREATE VIEW v0 AS SELECT (NULL AND 5) as c0 FROM t0;
INSERT INTO t0(c0) VALUES (NULL);
SELECT count(*) FROM v0 LEFT JOIN t0 ON v0.c0;
} {1}
finish_test
+16 -1
View File
@@ -294,7 +294,10 @@ do_execsql_test 8.1 {
}
#-------------------------------------------------------------------------
# Ticket [45f4bf4eb].
# Ticket [45f4bf4eb] reported by Manuel Rigger (2020-04-25)
#
# Follow up error reported by Eric Speckman on the SQLite forum
# https://sqlite.org/forum/info/c49496d24d35bd7c (2020-08-19)
#
reset_db
do_execsql_test 9.0 {
@@ -324,5 +327,17 @@ do_execsql_test 9.5 {
UNION SELECT 0,0 WHERE 0;
} {0 0}
do_execsql_test 9.10 {
CREATE TABLE t1 (aaa);
INSERT INTO t1 VALUES(23456);
CREATE TABLE t2(bbb);
CREATE VIEW v2(ccc) AS SELECT bbb IS 1234 FROM t2;
SELECT ccc, ccc IS NULL AS ddd FROM t1 LEFT JOIN v2;
} {{} 1}
optimization_control db query-flattener 0
do_execsql_test 9.11 {
SELECT ccc, ccc IS NULL AS ddd FROM t1 LEFT JOIN v2;
} {{} 1}
finish_test
+16
View File
@@ -147,6 +147,22 @@ ifcapable compound {
} {1 91 92 3 93 5}
}
do_execsql_test join6-5.1 {
CREATE TABLE tx(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o PRIMARY KEY)
WITHOUT ROWID;
INSERT INTO tx VALUES(
1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
);
} {}
do_execsql_test joint6-5.2 {
SELECT o FROM tx NATURAL JOIN tx;
} {15}
do_execsql_test join6-5.3 {
CREATE TABLE ty(a,Ñ,x6,x7,x8,Q,I,v,x1,L,E,x2,x3,x4,x5,s,g PRIMARY KEY,b,c)
WITHOUT ROWID;
SELECT a FROM ty NATURAL JOIN ty;
}
+7
View File
@@ -296,5 +296,12 @@ do_execsql_test null-9.3 {
SELECT * FROM t5 WHERE a IS NULL AND b = 'x';
} {{} x two {} x ii}
# 2020-09-30 ticket 5c4e7aa793943803
reset_db
do_execsql_test null-10.1 {
CREATE TABLE t0(c0 PRIMARY KEY DESC);
INSERT INTO t0(c0) VALUES (0);
SELECT * FROM t0 WHERE t0.c0 > NULL;
} {}
finish_test
+1 -1
View File
@@ -276,7 +276,7 @@ do_execsql_test pager1-3.1.2 {
} {3 0}
do_catchsql_test pager1-3.1.3 {
INSERT INTO t1 SELECT a+3, randomblob(1500) FROM t1
} {1 {CHECK constraint failed: counter}}
} {1 {CHECK constraint failed: i<5}}
do_execsql_test pager1-3.4 { SELECT * FROM counter } {3 0}
do_execsql_test pager1-3.5 { SELECT a FROM t1 } {1 2 3}
do_execsql_test pager1-3.6 { COMMIT } {}
+1 -1
View File
@@ -122,7 +122,7 @@ do_execsql_test 2.3.1 {
}
do_catchsql_test 2.3.2 {
INSERT INTO xyz VALUES(1, 2, 'null');
} {1 {CHECK constraint failed: xyz}}
} {1 {CHECK constraint failed: c!="null"}}
do_execsql_test 2.4 {
INSERT INTO t1 VALUES(1, 2, 3);
+11 -3
View File
@@ -54,9 +54,10 @@ array set ::Configs [strip_comments {
-DSQLITE_ENABLE_DESERIALIZE
}
"Sanitize" {
CC=clang -fsanitize=undefined
CC=clang -fsanitize=address,undefined
-DSQLITE_ENABLE_STAT4
--enable-session
--enable-debug
--enable-all
}
"Stdcall" {
-DUSE_STDCALL=1
@@ -135,6 +136,11 @@ array set ::Configs [strip_comments {
-DSQLITE_MUTATION_TEST
--enable-fts5 --enable-json1
}
"Debug-Two" {
-DSQLITE_DEFAULT_MEMSTATUS=0
-DSQLITE_MAX_EXPR_DEPTH=0
--enable-debug
}
"Fast-One" {
-O6
-DSQLITE_ENABLE_FTS4=1
@@ -142,6 +148,7 @@ array set ::Configs [strip_comments {
-DSQLITE_ENABLE_STAT4
-DSQLITE_ENABLE_RBU
-DSQLITE_MAX_ATTACHED=125
-DSQLITE_MAX_MMAP_SIZE=12884901888
-DLONGDOUBLE_TYPE=double
--enable-session
}
@@ -284,6 +291,7 @@ array set ::Platforms [strip_comments {
"Check-Symbols*" checksymbols
"Fast-One" "fuzztest test"
"Debug-One" "mptest test"
"Debug-Two" "test"
"Have-Not" test
"Secure-Delete" test
"Unlock-Notify" "QUICKTEST_INCLUDE=notify2.test test"
@@ -294,7 +302,7 @@ array set ::Platforms [strip_comments {
"No-lookaside" test
"Devkit" test
"Apple" test
"Sanitize" {QUICKTEST_OMIT=func4.test,nan.test test}
"Sanitize" {QUICKTEST_OMIT=crash*,shell*,sqldiff*,sessionB.test test}
"Device-One" fulltest
"Default" "threadtest fulltest"
"Valgrind*" valgrindtest

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