Compare commits

...

185 Commits

Author SHA1 Message Date
drh d63c76fb31 Version 3.32.1
FossilOrigin-Name: 0c1fcf4711a2e66c813aed38cf41cd3e2123ee8eb6db98118086764c4ba83350
2020-05-25 16:19:56 +00:00
drh b6907e2993 Extra assert() statements in the printf() logic.
FossilOrigin-Name: b1b182be2ab34cec1d94c5570bc361331a34f727eb9fa4aadfabb7f1ef79f83e
2020-05-25 15:41:03 +00:00
drh 0934d64045 Defensive code that tries to prevent a recurrence of problems like the
one described in ticket [7a5279a25c57adf1]

FossilOrigin-Name: 572105de1d44bca4f18c99d373458889163611384eebbc9659474874ee1701f4
2020-05-25 15:19:52 +00:00
drh efc752b131 Fix minor compile issues with optional extensions.
FossilOrigin-Name: 3261ee9ec26bbeaa64190c12556a1d8146270b6660c70004830bd38c1b5b63f4
2020-05-25 12:49:58 +00:00
drh 91960aa53f Make sure variable declarations are at start of scope even when
SQLITE_ENABLE_SNAPSHOT is used.

FossilOrigin-Name: a77ceaf6ba934b1d73c90b8980191a65d02ad6ce1e11e6baf573b3a132685545
2020-05-25 12:02:12 +00:00
drh e859e43bb8 Version number to 3.32.1.
FossilOrigin-Name: 56e5063c326ffbfd3e3cb6f2b05718412aca2cb183274bfe11f5666effdd04b9
2020-05-24 12:36:20 +00:00
drh c37577bb2d When rewriting a query for window functions, if the rewrite changes the
depth of TK_AGG_FUNCTION nodes, be sure to adjust the Expr.op2 field
appropriately.  Fix for ticket [7a5279a25c57adf1]

FossilOrigin-Name: ad7bb70af9bb68d192137188bb2528f1e9e43ad164c925174ca1dafc9e1f5339
2020-05-24 03:38:37 +00:00
drh e40cc16b47 Move some utility Walker callbacks into the walker.c source file, as they
seem to belong there better.

FossilOrigin-Name: dac438236f7c5419d4e7e094e8b3f19f83cd3b1a18bc8acb14aee90d4514fa3c
2020-05-24 03:01:36 +00:00
drh ca74fbf6f1 Improvements to parse-tree tracing logic. No changes in deliverable code.
FossilOrigin-Name: f7e5a68a7ebbb97a5beb050a75b3b4cf2fd6adc54653da993a8950fb3a5799f7
2020-05-24 02:05:04 +00:00
drh 16dc07f756 Minor fix to a comment. No code changes.
FossilOrigin-Name: efdbb2b499bda8ffcfe54f5d6ece08a2c58fe7a490d9550785d806bd404abb8c
2020-05-24 00:30:38 +00:00
drh dd6c33d372 Limit the "precision" of floating-point to text conversions in the printf()
function to 100,000,000.  Fix for ticket [23439ea582241138].

FossilOrigin-Name: d08d3405878d394e08e5d3af281246edfbd81ca74cc8d16458808591512fb93d
2020-05-23 19:58:07 +00:00
drh 8e50d65aaf Improved bytecode comment.
FossilOrigin-Name: 9224f1543b51a674ad6d7db8e90d97e1b0d1abe68bed3417820ebd09d27270f9
2020-05-23 17:56:49 +00:00
drh 0b0274a90c Version 3.32.0
FossilOrigin-Name: 5998789c9c744bce92e4cff7636bba800a75574243d6977e1fc8281e360f8d5a
2020-05-22 17:46:16 +00:00
drh f25f8d5834 Change a NEVER macro into a NO_TEST comment, as the conditional is reachable,
but only when compiling for Windows 32-bit.

FossilOrigin-Name: ce36b6d1331edba5a921fef32553e2470a79bdb1f62d2cfd81190691c83d5b06
2020-05-21 20:38:39 +00:00
dan 23e3c340b5 Avoid another potential OOB read in sqlite3expert.c.
FossilOrigin-Name: 0ccea80092f16e7f17f4c4de4f8be3fdef217199fcc08ace37e179c1b22c1294
2020-05-21 19:13:46 +00:00
drh 4f1315a432 Back out the change from [7fab1393c2b22b1f] that tries to convert invalid
surrogate characters in UTF16 into the replacement character 0xfffd, as we
find that this breaks some software.

FossilOrigin-Name: 4218c7b71fb6b227dbe4b852718584c150164af2d84e067cb810aa602554a609
2020-05-20 15:02:04 +00:00
drh 5a8cd2e40c Add compiler hints to disable TSAN for the routines that access the -shm
file header in WAL mode using a double-read with memory barrier.

FossilOrigin-Name: 3117c1b5a9e348fd8d16ba9d03fdafaad8514567fb3403f72b86d6162ad40bde
2020-05-19 15:51:10 +00:00
dan 10757ed0ca In os_win.c, avoid calling sqlite3_uri_boolean() on anything other than a main-db filename.
FossilOrigin-Name: cb0a18e64f8d81c2ada9f698faaf5ca68a0666687bf6f3abc860324cb1997463
2020-05-19 15:40:07 +00:00
drh 1a7feefac5 User-suggested improvement to the README.txt for the ICU extension.
FossilOrigin-Name: 1d1293c25abdd4b0fca64e5b1d0a118e2f339635dbc89422c0c2463fbf9ee27f
2020-05-19 12:29:56 +00:00
drh f16cf653f4 In wal.c, improved comments on concurrency issues. More use of
AtomicLoad() and AtomicStore().

FossilOrigin-Name: 4bf566feca3a8fbe5e386533aac30e0ac25836cfc820a3abd91e156bd6198b4a
2020-05-19 12:27:29 +00:00
dan a5ee67d5b3 Add vdbevtab.lo to build of libsqlite3.lib in Makefile.msc.
FossilOrigin-Name: f64d054b799c0af8d582fd9aff9bcbfa380ef08026ba5db8c5f89f6f56dfdad9
2020-05-18 18:02:37 +00:00
drh c795e3df7a Avoid harmless UB in memcpy() in the JSON extension.
FossilOrigin-Name: 69e149f76853d196c8855fedfc98848b60fb116ac36bc08824b1a122469f8ece
2020-05-17 13:47:28 +00:00
drh d924e7bc78 Use the sqlite3Realloc() interface internally, rather than the public
sqlite3_realloc64() equivalent, to avoid unnecessary calls to
sqlite3_initialize().

FossilOrigin-Name: 1313557b512297e7b75ed748894379b2022aecf696d5a58318e46a668321c1ff
2020-05-17 00:26:44 +00:00
drh b2eb7e46eb Performance optimization for the sqlite3FindTable() subroutine.
FossilOrigin-Name: 55910b9a7287be92af9f95e0af54af822055d15b7eabbcc81d61410d0bf67726
2020-05-16 21:01:00 +00:00
drh 8c1febb2f9 The OP_RealAffinity opcode is not necessary after reading values from
a virtual table (such as rtree).  It is harmless, but it does use CPU
cycles.  Might as well leave it off.

FossilOrigin-Name: dc18d89354cffcb726722c234a0271ab628a71277b22887eea2bf118028193a6
2020-05-16 18:01:02 +00:00
dan becd68ba0d Fix a use-after-free bug in the fts3 snippet() function.
FossilOrigin-Name: 0d69f76f0865f9626078bee087a22fb826407279e78cf9d5382e1c985c9f64a9
2020-05-16 17:26:58 +00:00
drh c48428899d Extra memory barrier during initialization.
FossilOrigin-Name: 043a7e142dfc2b0da5fbc0b025d005ccad4886f0b0ff65426ba9155ca40394ca
2020-05-16 16:23:48 +00:00
dan 62c94d0afe Add sqlite3BeginBenignMalloc() and EndBenignMalloc() calls to debugging function sqlite3VdbePrintOp().
FossilOrigin-Name: 6f857d0e9e0893524c2f828a1a1600fefb6efeff12ecbc9bb1da106a5aff9c1c
2020-05-16 15:18:27 +00:00
dan b2c6fe225a Update code in sqlite3expert.c to account for the fact that "-- TRIGGER xyz" VM comments are now omitted for some builds.
FossilOrigin-Name: 7cf93dc55c48c68731a1fe3ae3517fcfeb5c252bfa87e715a333c6194bcc0ace
2020-05-15 18:48:31 +00:00
dan d48eafb984 Fix another build problem for SQLITE_OMIT_VIRTUALTABLE builds.
FossilOrigin-Name: 5e1eb0fa3afd74251bc8f484e3edfa81b15610479431af205bd952c91eecd21f
2020-05-15 16:19:35 +00:00
drh cc1d9109c4 Fix a documentation typo. No changes to code.
FossilOrigin-Name: 758353c72627a847ba027ca44a750bbf057827dafd05811f56e4765dfc77623b
2020-05-15 16:05:31 +00:00
drh bbf6d4328e Adjust some requirement marks. No changes to code.
FossilOrigin-Name: 7285ae2ce8fb1439e1acea2ec321abbc76aab0a2e84b58683fddb0a7bf74fb1b
2020-05-15 15:03:51 +00:00
dan 2629adc7b2 Update test file e_fkey.test to account for the fact that new columns with REFERENCE clauses and non-NULL default values may now be added using ALTER TABLE if the table is empty.
FossilOrigin-Name: 4087fce97252beda2456164afe9508f952fc9fe4be68ad0e9b330569a78e42f2
2020-05-15 13:52:33 +00:00
dan 34d1566763 Fix SQLITE_OMIT_VIRTUALTABLE testfixture builds.
FossilOrigin-Name: 3d9780c5f6095ea35bc731a51eb34d7cf8bd5dcece825b686b94fd50131626e2
2020-05-15 11:36:16 +00:00
dan a796de8300 Test script changes to account for the fact that the "p5" column in the EXPLAIN output is now an integer, not a text values containing a 2-digit hex value.
FossilOrigin-Name: 102126d80872fdb7469233611cab28100c8455aab4ce25702b83398394559185
2020-05-15 11:26:31 +00:00
mistachkin a8e41ecaca Enhancements to long-path support in the Win32 VFS.
FossilOrigin-Name: 0119d96decd344ae711388ac8475b92464a6d018ecf73862170f137410036dac
2020-05-15 01:18:07 +00:00
drh 043c8f60a8 Move some new test cases from fts3snippet.test into fts3snippet2.test.
FossilOrigin-Name: fa203999944133941a38e5c858f1f66fc1ef4d2f33222ab81cbf4e3fc1539f1c
2020-05-15 01:13:46 +00:00
drh 856408abf4 Add the SQLITE_ENABLE_FTS3_PARENTHESIS option to fuzzcheck. Add a new
test case that uses that option.

FossilOrigin-Name: c49a33db954f1a3fbc1889bbe9f3f3fdb8fb00e31aafb91cd6f5d1602db5c2b9
2020-05-15 01:02:00 +00:00
drh 219b8e7e75 Fix a null pointer deference that can occur on a strange matchinfo()
query.

FossilOrigin-Name: a4dd148928ea65bd4e1654dfacc3d8057d1f85b8c9939416991d50722e5a720e
2020-05-14 23:59:24 +00:00
drh 3d863b5e4e Do not allow a virtual table to be renamed into the name of one of its
shadows.

FossilOrigin-Name: eca0ba2cf4c0fdf757bae19c6397a48245adb99e8017ddc28f01804072a30b2c
2020-05-14 21:16:52 +00:00
drh 3c0e606bba Implement the IIF(x,y,z) SQL function that is short-hand for
"CASE WHEN x THEN y ELSE z END".  For compatibility with SQL Server.

FossilOrigin-Name: fce173cd211b15867369b6a54fad48168352fc83981a722ce98e57299b88608a
2020-05-13 18:03:34 +00:00
drh ffe421c76a Remove unused constant SQLITE_FUNC_COALESCE.
FossilOrigin-Name: a116b20f863e9732cd08fbfbb1aa48204a17d611c9c1edde85dcf59310bde782
2020-05-13 17:26:38 +00:00
dan 8b4f231c47 Use AtomicStore() and AtomicLoad() in a few more places to avoid a theoretically undefined behaviour. This is not actually problem on any known hardware.
FossilOrigin-Name: fda57d4d2f1499c861d43026aa9362d1a30d67c9c002ebf5b0cdc25251537fbb
2020-05-13 13:33:30 +00:00
drh 2493dcdd07 New test case in test/fuzzdata8.db.
FossilOrigin-Name: fa11230135610f01c56d6f436f30a8b57a50b430fe7397ea3a0b6642986b3a39
2020-05-11 11:11:25 +00:00
dan efa78884a8 Fix a problem handling constant integer expressions with collation sequences in PARTITION BY clauses.
FossilOrigin-Name: 155e6649efe8614718be7ac6c3cccf5b073ae57496dc220db5e4313621f5188e
2020-05-11 10:55:24 +00:00
drh 9e5fdc41c1 Release some restrictions on columns added by ALTER TABLE so that they
only apply if the table contains one or more rows.

FossilOrigin-Name: 3a16c0ce4d8851f79f670d94786032c8007619154ece44647dc9cc5b1f9654ff
2020-05-08 19:02:21 +00:00
drh 98aa1d735e Fix the count-optimization so that it honors the NOT INDEXED clause.
FossilOrigin-Name: 0d23a0b209900f4d7c6c13f75d4364f19afc23db72f9cfdb11e05b81502e8040
2020-05-08 18:22:00 +00:00
drh 91d4c374e2 New test cases added to test/fuzzdata8.db.
FossilOrigin-Name: 3fce9711a47329811cd333ae2f1d1384a96d73b9a5d6f9d08454a57a3fd24fc8
2020-05-08 15:28:07 +00:00
drh acc175215a Do not retry on a failed realloc() unless SQLITE_ENABLE_MEMORY_MANAGEMENT
is available, meaning that the retry has some possibility of success.

FossilOrigin-Name: e9a8f910b5e2b84dd77364783f0610bca970cc88aa037c88636c72145b99f411
2020-05-08 10:44:23 +00:00
dan 2d3ed22a3f Fix a failing assert() in fts3 triggered by a corrupt database.
FossilOrigin-Name: cb299a090c81cdc5c116c4e15ab38fce112916f8b0fad0c7f2ab127e79238a94
2020-05-07 19:55:40 +00:00
dan b28f44eba2 Changes to avoid deadlock in SQLITE_ENABLE_SETLK_TIMEOUT builds.
FossilOrigin-Name: 652e4b23fffbff128b177697d7217b7d5aad8baf2364df1646b268ce6774e0fb
2020-05-07 14:39:56 +00:00
dan 11a8182e5c Fix an error that could occur if the first transaction executed by a connection configured to use blocking locks is a write-transaction for which the WRITER lock cannot be obtained.
FossilOrigin-Name: 49e4dc72f7a4b28e4b49d7b91030bc986aea3ff44dac38cb6e68305800cd1de5
2020-05-07 14:26:40 +00:00
dan 4cbe5d3588 Merge trunk changes into this branch.
FossilOrigin-Name: ac4ee69664278a828e0a64c5be3b96fdb6eb6acc95646a9425c667aea328791c
2020-05-07 14:05:08 +00:00
drh e937df81f0 Fix the handling of reserve-bytes so that the maximum value of 255 can be used.
FossilOrigin-Name: 99749d4fd4930ccf15227f67c732266af9e09dd3cabdc0834fb450ef98196441
2020-05-07 01:56:57 +00:00
dan a8aae52391 Avoid leaking a file-handle in test file walsetlk.test.
FossilOrigin-Name: 3cfc675e2e917b69108feb3a75728b573abe8e44f0890a7d20d307b0b6784c0e
2020-05-06 21:25:39 +00:00
dan bc9fc18e45 Fix an assert() failure that could follow an IO error.
FossilOrigin-Name: e89c864299024cdce395a15c19b000b976142b9eed267901a288adaa695f9e65
2020-05-06 21:24:29 +00:00
drh 783e159e48 Fix harmless compiler warnings.
FossilOrigin-Name: 92dc59132f8547635d73c61c21ea29b380c401ddc84a6d01412808e00386b9e8
2020-05-06 20:55:38 +00:00
dan 7a623e1d25 Fix a problem preventing building without SQLITE_ENABLE_SETLK_TIMEOUT defined.
FossilOrigin-Name: 98eb54c6d83992886f17a00b6fc8998df230e3b5f45bafc6fae0d15a9ee5a4c6
2020-05-06 20:45:11 +00:00
dan 7bb8b8a4f7 Add error code SQLITE_BUSY_TIMEOUT, used internally by the OS layer to indicate that a call to xShmLock() has failed due to timeout of a blocking lock.
FossilOrigin-Name: f3ef9c7c2b4ba3de1057ad569f068b241d5f23e6629d8e0dacf85e57fd13b8aa
2020-05-06 20:27:18 +00:00
dan fc87ab8c4a Fix compiler warnings in non-SQLITE_ENABLE_SETLK_TIMEOUT builds.
FossilOrigin-Name: 22de99ef410ba2a540871f3e61157d8dc4b969416f14808aeca73971b17fcd51
2020-05-06 19:22:59 +00:00
dan 861fb1e9dc Block on the WRITER lock when attempting to run recovery.
FossilOrigin-Name: 105d6c9bbcadc64faa2b24e315cb13227b17cfc6bf1b3512713f80ce56976a3d
2020-05-06 19:14:41 +00:00
drh e0a8b712c1 Provide the SQLITE_DEFAULT_LEGACY_ALTER_TABLE compile-time option.
FossilOrigin-Name: 63e659d9a793227604aa95685a8d83cd08305f1d01e135407a3ffc6d54482ab8
2020-05-06 18:43:57 +00:00
dan d0e6d13301 Add tests for running recovery when opening a write transaction or performing a checkpoint with blocking locks enabled. Fix some failing assert() statements.
FossilOrigin-Name: d096ea3fe20f8af90f9e3f798fd0a69527b32ac8e208ade58b9d0af0e831f41b
2020-05-06 17:18:57 +00:00
dan 293e9f5d6c Merge latest trunk changes into this branch.
FossilOrigin-Name: a3727dba10b476f414f0a049b35f2a5c169a408eccefa6833821560684e07f8b
2020-05-06 15:07:25 +00:00
dan 58021b237a Unless upgrading an existing read transaction, have ENABLE_SETLK_TIMEOUT builds attempt to use a blocking lock when opening a write transaction on a wal mode database.
FossilOrigin-Name: d6f819a9e6b35f3fd558bd93255a6a24ad690a0fa15a82b009ca9c641db983c6
2020-05-05 20:30:07 +00:00
drh fde2592503 The only known path to a corruption detection branch was cut off by the
previous commit implementing earlier index corruption.  So make the branch
NEVER.  Maybe a fuzzer will find a new path.

FossilOrigin-Name: 9a84d8eb44b12ddea921baa73ac3bffa8c8d23a852605dc1dbde37907360bd79
2020-05-05 19:54:02 +00:00
drh 85bd353ac2 Earlier detection of index corruption caused by missing index entries.
FossilOrigin-Name: f339f31f9e9a856b576f99c5230fdf6d60fdc2873e48cb5aa0a4ab1d04e3c930
2020-05-05 18:42:49 +00:00
drh eb8305bbc7 Fix a compiler warning in cksumvfs.c.
FossilOrigin-Name: 68033bcade87e6046f4c0a49936d63ce531c680c1def98fae02afa0c79db2c7f
2020-05-05 13:41:40 +00:00
drh 3d42fb788a Fix harmless compiler warnings.
FossilOrigin-Name: 8eee591d3cb9fadfd5cac5543bd66ef9cb371a72d3ad3241fb3bfd67fb216eda
2020-05-04 19:52:00 +00:00
dan 8714de97c0 Changes to avoid deadlock in SQLITE_ENABLE_SETLK_TIMEOUT builds.
FossilOrigin-Name: 553423c23142cf0ec219192315d57ce8a0e10c3d8678d28bc110a1a9a7c17cee
2020-05-04 19:42:35 +00:00
drh 44a5c86c6c Minor change to the sqlite_stmt virtual table, for test coverage.
FossilOrigin-Name: 838987b2097c4b7acaa65aea99cfdaf199f04d76bcf6ef12743c60b338a965f7
2020-05-04 19:04:23 +00:00
drh 20e34f9110 Simplify the initialization of built-in extensions.
FossilOrigin-Name: 729f2397358d0382e255ba0058bf70bc9ed410b7621a67466da13de437d3ba5c
2020-05-04 17:15:21 +00:00
drh 995e1af9fa Ensure that the master-journal name is in a form suitable to be passed
into sqlite3_uri_parameter().

FossilOrigin-Name: d1ba026d882f070b351280028e2fa88a3cca59b46d4683302e24c6677e0951b9
2020-05-04 11:47:38 +00:00
drh 278b0517d8 Add the SQLITE_FCNTL_CKPT_START file-control and use it to optimize
the cksumvfs extension.

FossilOrigin-Name: efdecb13091316aeac2722f58577cb0314e008e857f2816a2a222bac0a83e9e1
2020-05-02 04:08:23 +00:00
drh 477a357278 Add support for PRAGMA analyze_limit and approximate analysis.
FossilOrigin-Name: 812547525d35df975f40cbbeb604cc9cd2dec809c1ca083cbb139fe59ffa1d73
2020-05-02 03:46:32 +00:00
drh f72981f2d9 Add a missing VdbeCoverage() macro.
FossilOrigin-Name: 77a55c394d2c313a5710229bee9262457dcfc6620e6500f9f526c5f6acf87cef
2020-05-02 03:29:21 +00:00
drh c75921ac4e Merge the bytecode and tables_used table-valued functions. Requires
-DSQLITE_ENABLE_BYTECODE_VTAB at compile-time.

FossilOrigin-Name: d09bcce37f1eaf084e3b07eb4a23653ea1f370cdd290ce3875408186adf87022
2020-05-02 00:31:00 +00:00
drh 7e088a6c0a Corner-case changes to the bytecode virtual table for testability and
correctness.

FossilOrigin-Name: baa720e4a88f268ed95337daab5f434fd3263b00f09101cddc6424765bf3b722
2020-05-02 00:01:39 +00:00
drh 51f1c6f3ec Merge recent enhancements from trunk.
FossilOrigin-Name: 96dfc71ea599702ef38b60952d03e95dce5a8c534cd943e076e9c76b00e61e65
2020-05-01 18:58:21 +00:00
drh fcf31b28ff Add the SQLITE_FCNTL_CKPT_START file-control. Use it to optimize the
cksumvfs extension.

FossilOrigin-Name: b40f5aa344ae10cf4da83b3aa9e4866d6f6ffb06ba7e34ec1ce80c92468cf3bf
2020-05-01 18:37:34 +00:00
drh e754830eae Merge recent trunk enhancements.
FossilOrigin-Name: 2100b2c8f339e9778723fa0c91e479bab8675cf6fbea1664b6af49f40db6d27b
2020-05-01 15:04:13 +00:00
drh 5051194270 Clarification to the sqlite3_uri() family of interfaces. Documentation
enhancement only - no changes to code.

FossilOrigin-Name: 853703cd6d44d6dd48ef5eda6523e374b8ebdf7c338ddaad31c15a40a8b3fd9b
2020-05-01 13:45:12 +00:00
drh 8b2d8de3e2 Update documentation for sqlite3_close_v2() for clarity. No functional
changes.

FossilOrigin-Name: 80498b69ea489e8816c80a52c9e55a62699116fcbfdcbfd922ef23c2d9938871
2020-05-01 13:32:19 +00:00
drh cdb6ce980b Add the new SQLITE_IOERR_DATA result code and use it in cksumvfs.
Also enhance cksumvfs to emit an sqlite3_log() message whenever it finds
an invalid checksum.

FossilOrigin-Name: a094e8bfdef10d9e5d97f5a9f7c15b0fc547358b83367762ba5c2dfd2c9d0117
2020-05-01 11:31:43 +00:00
drh 95063d8c90 Do not allow page_size changes on an active cksumvfs database.
FossilOrigin-Name: 2c17cdce26fd935e6d81ff828f4670291fc014013c93b2a1578506598345ee86
2020-04-29 01:09:46 +00:00
drh 451f89a896 Fix incorrect error message when something goes wrong with the
sqlite3_dbpage() table-valued function in the .dbinfo command of the CLI.

FossilOrigin-Name: 0dcf002463f5931c3875d2038d2b97298f1800b1cdfa70485d6430ab758f3b25
2020-04-28 23:09:56 +00:00
drh 065e4a8d29 Add the cksumvfs extension.
FossilOrigin-Name: 237c10f941cc6cb775693ae87513ff1b816f12b5e9c3d57b057421204d2d02cf
2020-04-28 20:47:40 +00:00
drh 23bef340be Use AtomicStore() when setting the mem0.nearlyFull boolean to avoid
harmless TSAN warnings and to forestall doubts about threadsafety.

FossilOrigin-Name: ce980af65a9b528f112baa22a95020a98ac5340155a0b53b09c46f99aad9b12b
2020-04-28 14:01:31 +00:00
drh 9f603fcefd Use an AtomicLoad() macro in sqlite3HeapNearlyFull().
FossilOrigin-Name: 7556bc632e271d8a1e4fd836ce91e28213768ac09c90857b91171e9cd1009884
2020-04-28 11:45:41 +00:00
drh e238e31413 Yet another attempt to enhance sqlite3_load_extension() so that it works
with Window-style pathnames using a backslash separator character.

FossilOrigin-Name: b73d9a7d6f7fec0ffc9640902a849289c305f8651e891388c01255c4da7a6c4b
2020-04-26 22:04:48 +00:00
drh ec9a25c7c7 Fix an issue with check-in [bc3bf7c6681a96bc] when compiling on Windows.
FossilOrigin-Name: 57b16d8ca3d1ede3b411389256bec6686433aae716f47bca309ee7c8e5fe3128
2020-04-26 14:33:54 +00:00
drh 7d9ad75a56 Fix the sqlite3_load_extension() interface so that it tolerates backslashes
in place of forward-slashes in pathnames on Windows.

FossilOrigin-Name: bc3bf7c6681a96bc18a1ed02f0ccced4731d5dab45f60c347dd1841706e6b62a
2020-04-25 21:05:51 +00:00
dan 07f9e8f4f3 Ensure affinity is not discarded from a view column if the view appears on the rhs of a LEFT JOIN. Fix for [45f4bf4e].
FossilOrigin-Name: ac31edd3eeafcef46164a4506bbc32c711bb7cd78378aeaa4c9bb12524ac5ea1
2020-04-25 15:01:53 +00:00
drh ab2172e69f The new sqlite3_database_file_object() interface requires that the pager
never invoke xOpen with SQLITE_OPEN_MAIN_JOURNAL unless it is using
a pointer to the journal name found in the Pager structure itself.   Make
this the case when processing a master-journal.

FossilOrigin-Name: b4987a5ced0c0f2c606c040e0c1b8ee11175f40ae35a7446308a43e77b1f1db2
2020-04-24 18:20:30 +00:00
drh 742efb6749 New test case for ticket [1dcb4d44964846ad].
FossilOrigin-Name: 9e9f1e96c9aac60fcbbcda6923e01e350ca4dd88acefb9d400979419ba4e1e4d
2020-04-24 17:55:52 +00:00
drh 5415ab49b4 Fix an uninitialized variable in the newly enhanced ".output" command of
the CLI.

FossilOrigin-Name: 65c6c26bb48d5347ce53bb3607de3a03a5a03946b232d35e46a20533f86750f8
2020-04-23 20:45:46 +00:00
drh 542bd6521e Fix an off-by-one error in the "calculated" page count output from the
sqlite3_analyzer utility for databases that are more than 1GB in size.

FossilOrigin-Name: 8789368b91fb5b7477bdba3a953412fc3839b4894443b65186f7b8f79f6369c9
2020-04-22 13:49:25 +00:00
dan fc7f31742d Fix an integer overflow in fts3 causing a usan error.
FossilOrigin-Name: e256f85289a78e629acdf83e5bf1f8df2a0ffb3d559738eb9e49db6c228dc8c0
2020-04-22 11:11:17 +00:00
drh 4d34766f4e Clarify the comment on the sqlite3BtreeGetRequestedReserve() routine.
No changes to code.

FossilOrigin-Name: 52a6acca6d5d376308d354c02f4d676d9375c34c3841d7b1941196ee8b4e2511
2020-04-22 00:50:21 +00:00
drh 6ef2dc137d Add the sqlite3_database_file_object() interface.
FossilOrigin-Name: f534ebeaaf34f825550138f09f9a40221dfa7cd5c6537ef9f86dce5249025ec3
2020-04-21 20:19:25 +00:00
drh 9a1bb3f616 Add the sqlite3_database_file_object() interface to sqlite3ext.h.
FossilOrigin-Name: 3cabe06b6e9433cbfb4bf7bd72a425f43b54f57d84a205adbaa6a1147bbe46bf
2020-04-21 19:27:08 +00:00
drh 480620c713 Experimental API: sqlite3_database_file_object().
FossilOrigin-Name: ae697b152d22737169892411a0c4d908895ff5fb249cce9bdb1ba0bbe32806f0
2020-04-21 01:06:35 +00:00
drh 3b9f154bb7 Do not use O_NOFOLLOW when opening a directory just to call fsync() on
that directory.

FossilOrigin-Name: 2fc80ef16ce5878311ab88a0c64631813572ffbb71f75363b4619c9667e0926b
2020-04-20 17:35:32 +00:00
drh 541ef2c36c Enhance the ".filectrl" command in the CLI to support the --schema option.
FossilOrigin-Name: 698d40db58b76f4094687d46b5c6292702a62168054f9e6a70ee86650a6635f7
2020-04-20 16:21:30 +00:00
drh 45248de39a The SQLITE_TESTCTRL_RESERVE operator is removed. In its place is the
more generate SQLITE_FCNTL_RESERVE_BYTES which is an API and which can
operator on more than just the main schema.

FossilOrigin-Name: abc1aad74f7b6a1e72fb09936239f2224aa942d16296c6a3de0b8daef4bc8471
2020-04-20 15:18:43 +00:00
drh 871f45441c Remove an obsolete comment. No changes to code.
FossilOrigin-Name: 4135cb024456288d9c85aef5fb572dbb591527dd33d9a60ca5946b712c269941
2020-04-20 14:05:54 +00:00
drh 7a43100afb Add the --bom option to the ".excel", ".once", and ".output" commands
of the CLI.  Also fix the "--all" option on ".help" so that it works with
two dashes in addition to just one.

FossilOrigin-Name: d5b0def96ba6d90f47bc96fab1ccf9c501d84885d086744035b16fd96f3e248c
2020-04-18 14:12:00 +00:00
drh 1d9ea27f7e Fix the ".excel" command and the ".open -x" and ".open -e" command so that
they work better when running from an in-memory database and on Windows
and when running from a script.

FossilOrigin-Name: 07752164c2bf00b6885808533bbdb2cefbf1bf281a887b0b4f6316649a6cb810
2020-04-17 23:46:54 +00:00
dan 054a081555 Merge accidentally created fork.
FossilOrigin-Name: cb772b7a8fb53694cb267e74c11f49d2b9fd6920821c4e232f90ec35739c8904
2020-04-16 15:56:03 +00:00
dan 7576a68c8c Improve corruption detection in fts3 shadow tables earlier in order to prevent an assert() from failing.
FossilOrigin-Name: a9ec8c8f80a59badabb0afdb4189f0fd2934f936530d4151de395b3a7e7c1f1f
2020-04-16 11:35:27 +00:00
drh c39b121a95 Clarification of the byte-order determination for UTF16 inputs to routines
like sqlite3_bind_text16() and sqlite3_result_text16() and others that
accept UTF16 input strings.

FossilOrigin-Name: a42fdcf54bcbd72a301dad4a040346dc48e67cacab43479ec618f5c32108c55f
2020-04-15 17:39:39 +00:00
drh f05dd03a6e Build the UINT collating sequence extension into the CLI.
FossilOrigin-Name: 2b8c6b035a276029850de02651712a5fd69f4dfee45083d24b9d1f998004829b
2020-04-14 15:53:58 +00:00
drh e6a85962e7 Add the UINT collating sequence extension. The implementation is copied out
of the "natsort" branch.

FossilOrigin-Name: 6f46c6e3e3c471ca864d7596e0211ee90316b784c8fe22c7ae177c9d29731dc7
2020-04-14 15:48:55 +00:00
mistachkin 43e862723e When compiling the shell for WinRT, avoid using Win32 APIs that are unavailable.
FossilOrigin-Name: 85d3dc8c50d8dbb8eac1956e8976e861d3b671e03355ca9257060fa3dca51cc4
2020-04-09 15:31:22 +00:00
drh 75b5f22c01 Merge recent trunk enhancements into the bytecode-function branch.
FossilOrigin-Name: 7e6576ec00fde277c5c7abac264f7ec7e531de00c4e112bf733a07fe703fadcc
2020-04-09 15:07:22 +00:00
drh ad996da0f6 Merge trunk enhancements into the approximate-analyze branch.
FossilOrigin-Name: 17901ea6a1951b8c55671408841901c6660e3f8099378204f080b171a684d718
2020-04-09 15:01:09 +00:00
drh 4b3282d8a0 Limit LIKE/GLOB pattern length to 100 bytes (default is 50K) when running
dbsql cases in the fuzzcheck utility.

FossilOrigin-Name: 10306118e8591e727af477a1a15d136852d21170e645bd0e75f7c88346b037d7
2020-04-07 15:07:11 +00:00
drh aa0696ee9a Add the --spinner option to the fuzzcheck test program.
FossilOrigin-Name: b1eae2686f03a6e20a49ca2b3a654b3019506d4941708ee3919c339cd093a57d
2020-04-07 13:08:56 +00:00
drh 2d99f95721 The ALTER TABLE fix of check-in [7e5ad8e0ab7ee91a] is no longer needed due
to the changes at check-in [4cf8721f5ceb1fda].  But, we keep the defense
in place as an assert() for extra safety.

FossilOrigin-Name: 230556e859536bbadf0daf8133a9a01ef4f03148b3296723e37bad66e3fc3d82
2020-04-07 01:18:23 +00:00
drh b3120fdf5b Remove dead code that was added during initial development of RENAME COLUMN
but never actually served a purpose.

FossilOrigin-Name: c95c4cda4640f05d61b13b4e60494dec07d4483734fc41ffcce73fb5163cbb0d
2020-04-07 00:54:09 +00:00
drh 4047bdfd2c Performance improvement in sqlite3ResolveExprNameList().
FossilOrigin-Name: 7e170e67f24c7cdef7e7ceac4e0b81a75382618e4abe9e604f3d7f6db9dc6396
2020-04-06 20:35:52 +00:00
drh d44390c8c5 Performance improvement for column name lookup.
FossilOrigin-Name: 1e4b6a93987cdfbf829e2ff35ef417c290625f2894ad11949e301af518f1fb44
2020-04-06 18:16:31 +00:00
dan 85f2c76cf9 When running ALTER TABLE, avoid adding some internally generated tokens to the token map to improve performance on schemas with nested views.
FossilOrigin-Name: 4cf8721f5ceb1fdaefdc355b3211f75c53c4cdf9d2582ca70fc96777a9b057c2
2020-04-06 16:37:05 +00:00
drh 47f8ef32a0 Remove a NEVER() that could be true in sqlite3MatchEName().
FossilOrigin-Name: 921448f0e24a3753374b32be9d7bf36a9ca5d8522eff9f0b51dc243f08652419
2020-04-04 11:58:22 +00:00
drh 2e52a9c611 In the push-down optimization, do not substitute columns that have previously
been identified as being constant by the propagate-constants optimization.
Fix for ticket [51166be0159fd2ce]

FossilOrigin-Name: 70c44811d12f540d4ec1c29dedbe999cf79b82e326a8712ae2fa0725d6bd8a65
2020-04-04 00:15:54 +00:00
dan c59b4acf5d Avoid factoring out constant expressions on the LHS of an IN(...) operator, as the IN(...) operation may affect the affinity of these values.
FossilOrigin-Name: 98d56b4a34fddcbaecd953a045ae0270b4d78c1edf34cc73522fb4e12743af80
2020-04-03 19:37:14 +00:00
drh a96a69b7db Add a test case to fuzzdata8.db for the recent Henry Liu bugs.
FossilOrigin-Name: 42b02454b146ca1b04c0a5321465326435fc5b995f5498d3b1cf69c558a20f95
2020-04-03 16:11:32 +00:00
drh eb110d9687 Merge updates from trunk.
FossilOrigin-Name: 348c40136c8ec20f36ccdd4c8a6d4ec2d8274328b86b25b385813e3aae31ea8b
2020-04-03 15:48:05 +00:00
drh c415d91007 In the event of a semantic error in an aggregate query, early-out the
resetAccumulator() function to prevent problems due to incomplete or
incorrect initialization of the AggInfo object.
Fix for ticket [af4556bb5c285c08].

FossilOrigin-Name: 4a302b42c7bf5e11ddb5522ca999f74aba397d3a7eb91b1844bb02852f772441
2020-04-03 13:19:03 +00:00
dan 4db7ab53f9 Do not suppress errors when resolving references in an ORDER BY clause belonging to a compound SELECT within a view or trigger within ALTER TABLE. Fix for ticket [a10a14e9b4ba2].
FossilOrigin-Name: 684293882c302600e112cf52553c19d84fdb31663d96e5dd7f8ac17dda00a026
2020-04-03 11:52:59 +00:00
dan fb99e388ec Fix a case when a pointer might be used after being freed in the ALTER TABLE code. Fix for [4722bdab08cb1].
FossilOrigin-Name: d09f8c3621d5f7f8c6d99d7d82bcaa8421855b3f470bea2b26c858106382b906
2020-04-03 11:20:40 +00:00
drh 49d01abaac Fix a minor problem with EXPLAIN QUERY PLAN for triggers.
FossilOrigin-Name: 6e11c03f84efa93b218b07e39b6b56b1d872639f39c18498ee54d8cd8364d4f5
2020-04-02 19:58:31 +00:00
drh e1cd73f671 Minor changes for better test coverage.
FossilOrigin-Name: ae3ac297d2deee2a687ae2e9cf98aaf3e1b41196363238101a19d38092aebec6
2020-04-02 17:21:51 +00:00
drh 91654b2016 Fix an obsolete comment in the parameter binding logic of the CLI.
No changes to code.

FossilOrigin-Name: c9c735e201d7900d8c2b766463a6c90f547d9844352719dc650734e25e635fad
2020-04-02 13:21:10 +00:00
drh c004bd54e3 Fix another harmless compiler warning.
FossilOrigin-Name: 949eec2530bbe7f48daddfb3022d60ea5d7a43f0f5d120e71c682054feb721db
2020-04-02 13:08:54 +00:00
drh e0ef4e2b47 Add a missing #ifdef to avoid a harmless compiler warning.
FossilOrigin-Name: cc54de354317ebc080d4d1ee25427b31a49c4a75e01cb5d9966f1aaeb2ad098d
2020-04-02 12:53:17 +00:00
drh e065a18a4b Merge enhancements from trunk.
FossilOrigin-Name: d1731385c077f298b0cf654d6183ed40f7e5c07e4e2ab7f69109cf951ce99d9e
2020-04-02 12:24:08 +00:00
drh 31e3744ecb Simple fixes to PRAGMA analysis_limit.
FossilOrigin-Name: c20d4fdee21409ebc9c65c9540af8ac48d1f4425499a6674ef9319655c192612
2020-04-01 01:15:16 +00:00
drh 49a76a8fe5 Add "PRAGMA analysis_limit=N;" to limit the number of rows visited by
ANALYZE when N is positive.  Positive N also disables collecting stat4.

FossilOrigin-Name: a279b151c1623807774daf4975175c62ea252eefb71f9820ced6773769b392c5
2020-03-31 20:57:06 +00:00
drh dcdd707a9c Merge recent enhancements from trunk.
FossilOrigin-Name: c705ce266ad25af71791035590875f0ea9f2c72826b3eda17f065d2bf091de92
2020-03-31 18:41:21 +00:00
dan 892edb69c4 Use __atomic_load_n() and __atomic_store_n() for a few more things where they are available.
FossilOrigin-Name: a49f8ec552bede7da731e0571ccf49de1a30e7be3a5673150436c8b411ba6ffc
2020-03-30 13:35:05 +00:00
dan 3e42b99175 Fix "GCC_VESRION" typo in wal.c.
FossilOrigin-Name: fbd9378727141848ba2f5a8eee3076ecbd315e4a87b264c6d890103d56b2e4bc
2020-03-30 11:17:37 +00:00
drh 218da8c6f1 Enhancements to the SQLITE_ENABLE_SETLK_TIMEOUT compile-time option to avoid
rare deadlocks on recovery.

FossilOrigin-Name: 06885e9aa4e430d10f4b32105bcf405c65fd6f7b4cd451baf56fb4f12f408963
2020-03-28 19:02:39 +00:00
drh b1243a6d9c MSVC does not allow constant expressions as initializers for
constants with /fp:strict.

FossilOrigin-Name: 076658e5d21d9284448f41312b83a6c3d25394c2bfa088ef6cdfe1dc60277856
2020-03-28 12:01:25 +00:00
dan 97ccc1bd11 Modifications to the way blocking locks are used in SQLITE_ENABLE_SETLK_TIMEOUT builds so that multiple processes or threads may not deadlock when operating on a single database.
FossilOrigin-Name: c516027d5fd876b7d0bf566435667d554db29ded30ad6fc1165caa4a93d015a0
2020-03-27 17:23:17 +00:00
drh 8f78a528d5 Add the tables_used() table-valued function as a variation on bytecode().
FossilOrigin-Name: 6283c677d57220e54375a6463f453c6d068e042263558df16cff1055d1b0d3f5
2020-03-26 16:48:18 +00:00
drh c5eeacd58b Merge updates from trunk.
FossilOrigin-Name: d7db09101878102e192ee7a81437e8f6f2e317ddf110852673a2e81d1f80ae0e
2020-03-26 15:28:46 +00:00
drh 95b395901a Reinstate the optimization that converts "x IN (y)" into "x==y".
FossilOrigin-Name: 27936e6884e77093533719c7955a17f051cfb359872e51a6d1481152e6256443
2020-03-26 00:29:50 +00:00
drh cdbb28154e For the LIKE pattern in the .dump command of the CLI, accept backslash as
an escape character.

FossilOrigin-Name: 029ceea612f5c7a1420939d8a772eefcc6f9550d24d57b52ae1729ea9d85fae9
2020-03-25 20:31:45 +00:00
drh 8e9297fb79 Enhance the ".dump" command in the CLI so that it accepts multiple LIKE
pattern arguments and shows the union of all matching tables.

FossilOrigin-Name: 45fba3d7055f90f67005ca740687f060a2311db40c8f6a161bfea0424e6ebf6d
2020-03-25 12:50:13 +00:00
drh 7797207554 Optimize the "subprog IS NULL" constraint.
FossilOrigin-Name: ca8c5f028b9f6f32639c8bc9df5dc02537e21385fcbe7e1ae600c640977ea0d5
2020-03-24 18:41:58 +00:00
drh cf08f08d2c Fix a memory leak.
FossilOrigin-Name: c9f3405eeac8aff171b5d76bae954f3b51b353d16286a3d2af43ef942c212abc
2020-03-24 17:52:31 +00:00
drh 0518d06117 Provide content for the bytecode.subprog column.
FossilOrigin-Name: df893364b7cea07ff2b15b80cb294dccaffe701d51452264599b55304a36fa7c
2020-03-24 13:27:53 +00:00
drh eeb55d8694 Fix the build so that it works even without SQLITE_ENABLE_EXPLAIN_COMMENTS.
FossilOrigin-Name: 5896cbf4d0c7854c29c96d2ea2cea4adaedaa027a0fe4a3f0ac4dfbeaabb8dec
2020-03-23 23:17:38 +00:00
drh 8c5163a697 The bytecode() function now runs and sometimes works, but it untested and
there are known problems.

FossilOrigin-Name: 6819b86eb2de516c445655a83f9b2ba5ae0bff660cffaf84f1345d9be79b051e
2020-03-23 20:58:55 +00:00
drh cb49f5468e Further simplification and modularization of the EXPLAIN logic.
FossilOrigin-Name: aee1c12f4227cea9e8c6295cee3ec11797422c31b48c9468f176eb52f8261fe8
2020-03-23 19:14:11 +00:00
drh 356cd76aa8 Begin breaking appear the sqlite3VdbeList() routine into subroutines that
can be reused by the bytecode() table.

FossilOrigin-Name: 2c4dd79fbd4b9f72634a732abb9ed833cd8c9b05fe1e10af8f23e6d6ec023c7c
2020-03-23 17:24:46 +00:00
drh 691b5c54b8 Infrastructure for the bytecode() table-valued function. The function itself
is not yet implemented.

FossilOrigin-Name: 2795f0d633577e0de66b389d9e8e44c55e85975bdc62f1a0b8f93959d19b22bf
2020-03-23 15:49:22 +00:00
drh 74a07986ce Fix to the recomputation of the colUsed field added by check-in
[a9bb71ba708ba722].  This fixes ticket [5829597ac43811e3].

FossilOrigin-Name: 5d14a1c4f2fc17de98ad685ad1422cdfda89dfccb00afcaf32ee416b6f84f525
2020-03-21 23:10:38 +00:00
drh f7f6dbf501 Enhance the treeview system to show the SrcList_item.colUsed field for
FROM clause elements.

FossilOrigin-Name: 8a5c539b77aa174c048a504d211c56902075f9b42b654e1f8cc5767739e5fcc9
2020-03-21 22:03:32 +00:00
dan 7d76fad8eb Simplify some of the code modified by the previous commit.
FossilOrigin-Name: 04abadb545d1b34bdd74d62becb3bfd83aceee373fd6b4b708d5ad53f41d9464
2020-03-21 20:58:05 +00:00
dan 31f170f396 Ensure that "main" can always be used to refer to the main database, even if it has been renamed using SQLITE_DBCONFIG_MAINDBNAME.
FossilOrigin-Name: 682b426f5658254e63dff02c960b557fb33cb3e944fdd14faa0aa9988af7269a
2020-03-21 15:41:55 +00:00
dan 465c2b8964 Consolidate some code on this branch.
FossilOrigin-Name: a85c63daa640e02fdfd891a05a1a09e848c9621a5dd6e112338451008623ecbb
2020-03-21 15:10:40 +00:00
drh 2c3629e1c9 Change a bitfield in sqlite3_stmt into an unsigned character, for slightly
smaller code and better performance.

FossilOrigin-Name: 0d4d3c642494ad494b4ec937215eaf833158e62e5ae59ed981d6b546220c13b8
2020-03-21 15:07:27 +00:00
drh 62b6e1d042 Performance optimization in sqlite3VdbeMakeReady().
FossilOrigin-Name: aa92f9b95f95d40cc58910da87168a5bd440f71deb072dc651bb15936315786c
2020-03-21 14:22:27 +00:00
drh 2aee514b4c Recompute the set of columns used for each table when the table is
involved in query flattening.

FossilOrigin-Name: a9bb71ba708ba72255ba8d18c9856e38ddf53eae2d61c8435149354fb2b2459e
2020-03-21 00:05:53 +00:00
dan 00bd55e1ae Allow "main" to be used to refer to the main database even after SQLITE_DBCONFIG_MAINDBNAME has been used to assign another alias.
FossilOrigin-Name: 75c85ca32f9ae4a28fd8f8ff2f7639599413d22af706e9799a0e76cc560d14eb
2020-03-20 20:54:28 +00:00
dan ec8e689a20 Avoid an undefined integer overflow in fts3 by detecting data structure corruption earlier.
FossilOrigin-Name: 86e98ddc19470410ccc6d2cf4ad56ef0bc5a23b7fbe6331b8cae374689f54529
2020-03-20 20:18:49 +00:00
drh 589c787620 Chagnes the ESCAPE clause on the LIKE operator to overwrite wildcard
characters, in order ot match the behavior of PosgreSQL.

FossilOrigin-Name: 11e0844f71e8f2d27ce9363fb505e02fd7795c61dae0b3886cf0d8df4484dd97
2020-03-19 18:13:28 +00:00
drh f0a2172d1d Fix an integer overflow problem with the dbstat virtual table that comes up
when trying to analyze a corrupt database.

FossilOrigin-Name: 1d64f4a8af81fe1235fffa54884d8f842a48ff6a33d6172f0cd65bf42fe8b2a1
2020-03-19 17:27:52 +00:00
drh 91a23dc299 Fix a typo in a comment. No changes to code.
FossilOrigin-Name: 3a51919ac23ae7312d78905334dc97742b517a7476052a85aa07945d9c77697b
2020-03-19 15:57:03 +00:00
drh 78a50d7280 Fix the build for when SQLITE_ENABLE_STAT4 is defined.
FossilOrigin-Name: 8f0a8c2aa45f7cf7339094d83893aeb046b010b5b97bb4dae99ac07a8ebf2fa6
2020-03-18 15:58:13 +00:00
drh 59a8cb7931 Add the SQLITE_ANALYZE_LIMIT compile-time option (expected to be temporary)
that sets a threshold at which ANALYZE starts to use approximations during
the analysis process.

FossilOrigin-Name: a773fd4698d474fda5e57bc77ed66a79cf74efee2706f43f6def6f450bfd1fc0
2020-03-18 14:43:05 +00:00
drh 9f27463684 Provide an estimated row count to stat_init() for STAT1 analysis.
FossilOrigin-Name: 714419fe85cfdad22979183a94e4569c87740652758ab76b646753cf2b013b54
2020-03-17 17:11:23 +00:00
drh e50478d727 Remove the SQLITE_OMIT_BTREECOUNT option. Btree count is required.
FossilOrigin-Name: a9bfa47aeea27e91611ba913d33e6635d2016e2c2ab78f9b0657f1bd8933e1a8
2020-03-17 13:41:51 +00:00
drh dc4a1687b8 Improved bytecode comments for the ANALYZE command.
FossilOrigin-Name: c38ea4139d87535b789f43eb1e38b2dc4b8312352a721035283e67cf0f3d5067
2020-03-17 13:07:04 +00:00
drh 9d8c287309 Merge changes from trunk.
FossilOrigin-Name: 93d710262eb046e2370660b1096ac634373755f92a2e9b1220df3b2bda5f9eeb
2020-03-17 12:37:27 +00:00
dan 553948e514 Fix handling of window functions in aggregate queries that have no GROUP BY clause. Also remove a faulty assert causing the error reported in [618156e3].
FossilOrigin-Name: 38e3dd389d142e520c71139ec84aa3c7722992af28a5f93a7f16e0ea176b74bb
2020-03-16 18:52:53 +00:00
drh 14c98a4f40 At the end of the right-hand table loop of a LEFT JOIN that uses an IN
operator in the ON clause, put the OP_IfNoHope operator after the
OP_IfNotOpen operator, not before, to avoid a (harmless) uninitialized
register reference.  Ticket [82b588d342d515d1]

FossilOrigin-Name: 8b437b47266ec2d80d85eafcfdd6949556d6c28d9d67d5f43d89799f0f5b7bd0
2020-03-16 03:07:53 +00:00
drh ba25c7e29f Remove stray comment characters at the end of an #ifdef that were
accidently left in the previous check-in.

FossilOrigin-Name: ea914bec81c49625072fc9d23faa048300f3a0421e069d303b7203edcdfb3743
2020-03-12 17:54:39 +00:00
drh 576d0a9fd9 Fix comments and strengthen assert() statements associated with the
OPFLAG_SEEKEQ and BTREE_SEEK_EQ flags.

FossilOrigin-Name: 231749213854756b599b33413b17b35186f17889b0c73f109fa9db726b415558
2020-03-12 17:28:27 +00:00
drh e31f00bbef Merge enhancements from trunk.
FossilOrigin-Name: 4945a66237fa3861bc691d5fbef0d40286b596a0902b4f4c032d1d6528bb1a1b
2020-03-11 20:03:22 +00:00
drh 2267a7fa87 Do not factor out constant functions into the initialization section of a
prepared statement, because even though they are constant, they can still
throw exceptions.  Instead, put such functions in an OP_Once block.  This
fixes ticket [3c9eadd2a6ba0aa5] and causes COALESCE() and CASE...END to
be short-circuit.

FossilOrigin-Name: c5f96a085db9688a09793f52ce1ecf033c2e6e2e5873a19fe0fb374b242b317f
2020-03-11 19:56:26 +00:00
drh 2e51dc6c9b Merge updates from trunk.
FossilOrigin-Name: e05f743f619a6b60d0782ee85c73f6866696962954d7cb3eceb03af79c6a6189
2020-03-10 22:55:51 +00:00
drh 9d33d9e7ac Background work for experiments trying to enhance ANALYZE so that it runs
off of samples of the entire index and does not need to read the entire
index.

FossilOrigin-Name: 29d1cc5c3619a88229f18c3c8131228f8a2d151ac3d9203f0c7fc538a996ecec
2020-03-10 01:24:13 +00:00
125 changed files with 4582 additions and 1317 deletions
+13 -1
View File
@@ -190,7 +190,8 @@ LIBOBJS0 = alter.lo analyze.lo attach.lo auth.lo \
table.lo threads.lo tokenize.lo treeview.lo trigger.lo \
update.lo userauth.lo upsert.lo util.lo vacuum.lo \
vdbe.lo vdbeapi.lo vdbeaux.lo vdbeblob.lo vdbemem.lo vdbesort.lo \
vdbetrace.lo wal.lo walker.lo where.lo wherecode.lo whereexpr.lo \
vdbetrace.lo vdbevtab.lo \
wal.lo walker.lo where.lo wherecode.lo whereexpr.lo \
window.lo utf.lo vtab.lo
# Object files for the amalgamation.
@@ -296,6 +297,7 @@ SRC = \
$(TOP)/src/vdbemem.c \
$(TOP)/src/vdbesort.c \
$(TOP)/src/vdbetrace.c \
$(TOP)/src/vdbevtab.c \
$(TOP)/src/vdbeInt.h \
$(TOP)/src/vtab.c \
$(TOP)/src/vxworks.h \
@@ -502,6 +504,7 @@ TESTSRC2 = \
$(TOP)/src/vdbe.c \
$(TOP)/src/vdbemem.c \
$(TOP)/src/vdbetrace.c \
$(TOP)/src/vdbevtab.c \
$(TOP)/src/where.c \
$(TOP)/src/wherecode.c \
$(TOP)/src/whereexpr.c \
@@ -607,6 +610,7 @@ SHELL_OPT += -DSQLITE_ENABLE_UNKNOWN_SQL_FUNCTION
SHELL_OPT += -DSQLITE_ENABLE_STMTVTAB
SHELL_OPT += -DSQLITE_ENABLE_DBPAGE_VTAB
SHELL_OPT += -DSQLITE_ENABLE_DBSTAT_VTAB
SHELL_OPT += -DSQLITE_ENABLE_BYTECODE_VTAB
SHELL_OPT += -DSQLITE_ENABLE_OFFSET_SQL_FUNC
SHELL_OPT += -DSQLITE_ENABLE_DESERIALIZE
FUZZERSHELL_OPT = -DSQLITE_ENABLE_JSON1
@@ -615,10 +619,12 @@ FUZZCHECK_OPT += -DSQLITE_MAX_MEMORY=50000000
FUZZCHECK_OPT += -DSQLITE_PRINTF_PRECISION_LIMIT=1000
FUZZCHECK_OPT += -DSQLITE_ENABLE_DESERIALIZE
FUZZCHECK_OPT += -DSQLITE_ENABLE_FTS4
FUZZCHECK_OPT += -DSQLITE_ENABLE_FTS3_PARENTHESIS
#FUZZCHECK_OPT += -DSQLITE_ENABLE_FTS5
FUZZCHECK_OPT += -DSQLITE_ENABLE_RTREE
FUZZCHECK_OPT += -DSQLITE_ENABLE_GEOPOLY
FUZZCHECK_OPT += -DSQLITE_ENABLE_DBSTAT_VTAB
FUZZCHECK_OPT += -DSQLITE_ENABLE_BYTECODE_VTAB
FUZZCHECK_SRC = $(TOP)/test/fuzzcheck.c $(TOP)/test/ossfuzz.c
DBFUZZ_OPT =
@@ -688,6 +694,7 @@ DBFUZZ2_OPTS = \
-DSQLITE_ENABLE_DESERIALIZE \
-DSQLITE_DEBUG \
-DSQLITE_ENABLE_DBSTAT_VTAB \
-DSQLITE_ENABLE_BYTECODE_VTAB \
-DSQLITE_ENABLE_RTREE \
-DSQLITE_ENABLE_FTS4 \
-DSQLITE_ENABLE_FTS5
@@ -1004,6 +1011,9 @@ vdbesort.lo: $(TOP)/src/vdbesort.c $(HDR)
vdbetrace.lo: $(TOP)/src/vdbetrace.c $(HDR)
$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/vdbetrace.c
vdbevtab.lo: $(TOP)/src/vdbevtab.c $(HDR)
$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/vdbevtab.c
vtab.lo: $(TOP)/src/vtab.c $(HDR)
$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/vtab.c
@@ -1069,6 +1079,7 @@ SHELL_SRC = \
$(TOP)/ext/misc/fileio.c \
$(TOP)/ext/misc/completion.c \
$(TOP)/ext/misc/sqlar.c \
$(TOP)/ext/misc/uint.c \
$(TOP)/ext/expert/sqlite3expert.c \
$(TOP)/ext/expert/sqlite3expert.h \
$(TOP)/ext/misc/zipfile.c \
@@ -1210,6 +1221,7 @@ TESTFIXTURE_FLAGS += -DSQLITE_SERIES_CONSTRAINT_VERIFY=1
TESTFIXTURE_FLAGS += -DSQLITE_DEFAULT_PAGE_SIZE=1024
TESTFIXTURE_FLAGS += -DSQLITE_ENABLE_STMTVTAB
TESTFIXTURE_FLAGS += -DSQLITE_ENABLE_DBPAGE_VTAB
TESTFIXTURE_FLAGS += -DSQLITE_ENABLE_BYTECODE_VTAB
TESTFIXTURE_FLAGS += -DSQLITE_ENABLE_DESERIALIZE
TESTFIXTURE_SRC0 = $(TESTSRC2) libsqlite3.la
+20 -2
View File
@@ -234,6 +234,15 @@ OSTRACE = 0
DEBUG = 0
!ENDIF
# <<mark>>
# Disable use of the --linemacros argument to the mksqlite3c.tcl tool, which
# is used to build the amalgamation.
#
!IFNDEF NO_LINEMACROS
NO_LINEMACROS = 0
!ENDIF
# <</mark>>
# Enable use of available compiler optimizations? Normally, this should be
# non-zero. Setting this to zero, thus disabling all compiler optimizations,
# can be useful for testing.
@@ -357,6 +366,7 @@ OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_JSON1=1
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_STMTVTAB=1
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_DBPAGE_VTAB=1
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_DBSTAT_VTAB=1
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_BYTECODE_VTAB=1
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_DESERIALIZE=1
!ENDIF
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_COLUMN_METADATA=1
@@ -775,7 +785,7 @@ MKSQLITE3C_TOOL = $(TOP)\tool\mksqlite3c.tcl
!ENDIF
!IFNDEF MKSQLITE3C_ARGS
!IF $(DEBUG)>1
!IF $(DEBUG)>1 && $(NO_LINEMACROS)==0
MKSQLITE3C_ARGS = --linemacros
!ELSE
MKSQLITE3C_ARGS =
@@ -1246,7 +1256,8 @@ LIBOBJS0 = vdbe.lo parse.lo alter.lo analyze.lo attach.lo auth.lo \
table.lo threads.lo tokenize.lo treeview.lo trigger.lo \
update.lo upsert.lo util.lo vacuum.lo \
vdbeapi.lo vdbeaux.lo vdbeblob.lo vdbemem.lo vdbesort.lo \
vdbetrace.lo wal.lo walker.lo where.lo wherecode.lo whereexpr.lo \
vdbetrace.lo vdbevtab.lo wal.lo walker.lo where.lo wherecode.lo \
whereexpr.lo \
window.lo utf.lo vtab.lo
# <</mark>>
@@ -1353,6 +1364,7 @@ SRC01 = \
$(TOP)\src\vdbemem.c \
$(TOP)\src\vdbesort.c \
$(TOP)\src\vdbetrace.c \
$(TOP)\src\vdbevtab.c \
$(TOP)\src\vtab.c \
$(TOP)\src\wal.c \
$(TOP)\src\walker.c \
@@ -1684,6 +1696,7 @@ FUZZCHECK_OPTS = $(FUZZCHECK_OPTS) -DSQLITE_ENABLE_FTS4
FUZZCHECK_OPTS = $(FUZZCHECK_OPTS) -DSQLITE_ENABLE_RTREE
FUZZCHECK_OPTS = $(FUZZCHECK_OPTS) -DSQLITE_ENABLE_GEOPOLY
FUZZCHECK_OPTS = $(FUZZCHECK_OPTS) -DSQLITE_ENABLE_DBSTAT_VTAB
FUZZCHECK_OPTS = $(FUZZCHECK_OPTS) -DSQLITE_ENABLE_BYTECODE_VTAB
FUZZCHECK_SRC = $(TOP)\test\fuzzcheck.c $(TOP)\test\ossfuzz.c
OSSSHELL_SRC = $(TOP)\test\ossshell.c $(TOP)\test\ossfuzz.c
@@ -2109,6 +2122,9 @@ vdbesort.lo: $(TOP)\src\vdbesort.c $(HDR)
vdbetrace.lo: $(TOP)\src\vdbetrace.c $(HDR)
$(LTCOMPILE) $(CORE_COMPILE_OPTS) -c $(TOP)\src\vdbetrace.c
vdbevtab.lo: $(TOP)\src\vdbevtab.c $(HDR)
$(LTCOMPILE) $(CORE_COMPILE_OPTS) -c $(TOP)\src\vdbevtab.c
vtab.lo: $(TOP)\src\vtab.c $(HDR)
$(LTCOMPILE) $(CORE_COMPILE_OPTS) -c $(TOP)\src\vtab.c
@@ -2182,6 +2198,7 @@ SHELL_SRC = \
$(TOP)\ext\misc\shathree.c \
$(TOP)\ext\misc\fileio.c \
$(TOP)\ext\misc\completion.c \
$(TOP)\ext\misc\uint.c \
$(TOP)\ext\expert\sqlite3expert.c \
$(TOP)\ext\expert\sqlite3expert.h \
$(TOP)\ext\misc\memtrace.c \
@@ -2352,6 +2369,7 @@ TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_SERIES_CONSTRAINT_VERIFY=1
TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_DEFAULT_PAGE_SIZE=1024
TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_ENABLE_STMTVTAB=1
TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_ENABLE_DBPAGE_VTAB=1
TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_ENABLE_BYTECODE_VTAB=1
TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_ENABLE_JSON1=1
TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_ENABLE_DESERIALIZE=1
TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) $(TEST_CCONV_OPTS)
+1 -1
View File
@@ -1 +1 @@
3.32.0
3.32.1
+2
View File
@@ -196,6 +196,7 @@ OSTRACE = 0
DEBUG = 0
!ENDIF
# Enable use of available compiler optimizations? Normally, this should be
# non-zero. Setting this to zero, thus disabling all compiler optimizations,
# can be useful for testing.
@@ -288,6 +289,7 @@ OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_JSON1=1
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_STMTVTAB=1
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_DBPAGE_VTAB=1
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_DBSTAT_VTAB=1
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_BYTECODE_VTAB=1
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_DESERIALIZE=1
!ENDIF
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_COLUMN_METADATA=1
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.32.0.
# Generated by GNU Autoconf 2.69 for sqlite 3.32.1.
#
#
# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
@@ -726,8 +726,8 @@ MAKEFLAGS=
# Identity of this package.
PACKAGE_NAME='sqlite'
PACKAGE_TARNAME='sqlite'
PACKAGE_VERSION='3.32.0'
PACKAGE_STRING='sqlite 3.32.0'
PACKAGE_VERSION='3.32.1'
PACKAGE_STRING='sqlite 3.32.1'
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.32.0 to adapt to many kinds of systems.
\`configure' configures sqlite 3.32.1 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.32.0:";;
short | recursive ) echo "Configuration of sqlite 3.32.1:";;
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.32.0
sqlite configure 3.32.1
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.32.0, which was
It was created by sqlite $as_me 3.32.1, 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.32.0, which was
This file was extended by sqlite $as_me 3.32.1, 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.32.0
sqlite config.status 3.32.1
configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\"
+11 -4
View File
@@ -37,6 +37,9 @@ proc squish {txt} {
proc do_setup_rec_test {tn setup sql res} {
reset_db
if {[info exists ::set_main_db_name]} {
dbconfig_maindbname_icecube db
}
db eval $setup
uplevel [list do_rec_test $tn $sql $res]
}
@@ -76,6 +79,10 @@ foreach {tn setup} {
}
}
3 {
if {[info commands sqlite3_expert_new]==""} { continue }
set ::set_main_db_name 1
}
4 {
if {![file executable $CLI]} { continue }
proc do_rec_test {tn sql res} {
@@ -336,7 +343,7 @@ proc do_candidates_test {tn sql res} {
reset_db
do_execsql_test 4.0 {
do_execsql_test 5.0 {
CREATE TABLE t1(a, b);
CREATE TABLE t2(c, d);
@@ -346,7 +353,7 @@ do_execsql_test 4.0 {
WITH s(i) AS ( VALUES(1) UNION ALL SELECT i+1 FROM s WHERE i<100)
INSERT INTO t2 SELECT (i-1)/20, (i-1)/5 FROM s;
}
do_candidates_test 4.1 {
do_candidates_test 5.1 {
SELECT * FROM t1,t2 WHERE (b=? OR a=?) AND (c=? OR d=?)
} {
CREATE INDEX t1_idx_00000062 ON t1(b); -- stat1: 100 20
@@ -355,14 +362,14 @@ do_candidates_test 4.1 {
CREATE INDEX t2_idx_00000064 ON t2(d); -- stat1: 100 5
}
do_candidates_test 4.2 {
do_candidates_test 5.2 {
SELECT * FROM t1,t2 WHERE a=? AND b=? AND c=? AND d=?
} {
CREATE INDEX t1_idx_000123a7 ON t1(a, b); -- stat1: 100 50 17
CREATE INDEX t2_idx_0001295b ON t2(c, d); -- stat1: 100 20 5
}
do_execsql_test 4.3 {
do_execsql_test 5.3 {
CREATE INDEX t1_idx_00000061 ON t1(a); -- stat1: 100 50
CREATE INDEX t1_idx_00000062 ON t1(b); -- stat1: 100 20
CREATE INDEX t1_idx_000123a7 ON t1(a, b); -- stat1: 100 50 16
+9 -4
View File
@@ -1128,14 +1128,19 @@ int idxFindIndexes(
/* int iParent = sqlite3_column_int(pExplain, 1); */
/* int iNotUsed = sqlite3_column_int(pExplain, 2); */
const char *zDetail = (const char*)sqlite3_column_text(pExplain, 3);
int nDetail = STRLEN(zDetail);
int nDetail;
int i;
if( !zDetail ) continue;
nDetail = STRLEN(zDetail);
for(i=0; i<nDetail; i++){
const char *zIdx = 0;
if( memcmp(&zDetail[i], " USING INDEX ", 13)==0 ){
if( i+13<nDetail && memcmp(&zDetail[i], " USING INDEX ", 13)==0 ){
zIdx = &zDetail[i+13];
}else if( memcmp(&zDetail[i], " USING COVERING INDEX ", 22)==0 ){
}else if( i+22<nDetail
&& memcmp(&zDetail[i], " USING COVERING INDEX ", 22)==0
){
zIdx = &zDetail[i+22];
}
if( zIdx ){
@@ -1950,4 +1955,4 @@ void sqlite3_expert_destroy(sqlite3expert *p){
}
}
#endif /* ifndef SQLITE_OMIT_VIRTUAL_TABLE */
#endif /* ifndef SQLITE_OMIT_VIRTUALTABLE */
+28 -11
View File
@@ -962,6 +962,22 @@ static char *fts3WriteExprList(Fts3Table *p, const char *zFunc, int *pRc){
return zRet;
}
/*
** Buffer z contains a positive integer value encoded as utf-8 text.
** Decode this value and store it in *pnOut, returning the number of bytes
** consumed. If an overflow error occurs return a negative value.
*/
int sqlite3Fts3ReadInt(const char *z, int *pnOut){
u64 iVal = 0;
int i;
for(i=0; z[i]>='0' && z[i]<='9'; i++){
iVal = iVal*10 + (z[i] - '0');
if( iVal>0x7FFFFFFF ) return -1;
}
*pnOut = (int)iVal;
return i;
}
/*
** This function interprets the string at (*pp) as a non-negative integer
** value. It reads the integer and sets *pnOut to the value read, then
@@ -977,19 +993,17 @@ static char *fts3WriteExprList(Fts3Table *p, const char *zFunc, int *pRc){
*/
static int fts3GobbleInt(const char **pp, int *pnOut){
const int MAX_NPREFIX = 10000000;
const char *p; /* Iterator pointer */
int nInt = 0; /* Output value */
for(p=*pp; p[0]>='0' && p[0]<='9'; p++){
nInt = nInt * 10 + (p[0] - '0');
if( nInt>MAX_NPREFIX ){
nInt = 0;
break;
}
int nByte;
nByte = sqlite3Fts3ReadInt(*pp, &nInt);
if( nInt>MAX_NPREFIX ){
nInt = 0;
}
if( nByte==0 ){
return SQLITE_ERROR;
}
if( p==*pp ) return SQLITE_ERROR;
*pnOut = nInt;
*pp = p;
*pp += nByte;
return SQLITE_OK;
}
@@ -2171,7 +2185,9 @@ static void fts3ReadNextPos(
sqlite3_int64 *pi /* IN/OUT: Value read from position-list */
){
if( (**pp)&0xFE ){
fts3GetDeltaVarint(pp, pi);
int iVal;
*pp += fts3GetVarint32((*pp), &iVal);
*pi += iVal;
*pi -= 2;
}else{
*pi = POSITION_LIST_END;
@@ -5301,6 +5317,7 @@ static void fts3EvalNextRow(
fts3EvalNextRow(pCsr, pLeft, pRc);
}
}
pRight->bEof = pLeft->bEof = 1;
}
}
break;
+1
View File
@@ -591,6 +591,7 @@ int sqlite3Fts3EvalPhraseStats(Fts3Cursor *, Fts3Expr *, u32 *);
int sqlite3Fts3FirstFilter(sqlite3_int64, char *, int, char *);
void sqlite3Fts3CreateStatTable(int*, Fts3Table*);
int sqlite3Fts3EvalTestDeferred(Fts3Cursor *pCsr, int *pRc);
int sqlite3Fts3ReadInt(const char *z, int *pnOut);
/* fts3_tokenizer.c */
const char *sqlite3Fts3NextToken(const char *, int *);
+1 -4
View File
@@ -446,10 +446,7 @@ static int getNextNode(
if( pKey->eType==FTSQUERY_NEAR ){
assert( nKey==4 );
if( zInput[4]=='/' && zInput[5]>='0' && zInput[5]<='9' ){
nNear = 0;
for(nKey=5; zInput[nKey]>='0' && zInput[nKey]<='9'; nKey++){
nNear = nNear * 10 + (zInput[nKey] - '0');
}
nKey += 1+sqlite3Fts3ReadInt(&zInput[nKey+1], &nNear);
}
}
+1 -1
View File
@@ -876,7 +876,7 @@ static int fts3ExprLHits(
iStart = pExpr->iPhrase * ((p->nCol + 31) / 32);
}
while( 1 ){
if( pIter ) while( 1 ){
int nHit = fts3ColumnlistCount(&pIter);
if( (pPhrase->iColumn>=pTab->nColumn || pPhrase->iColumn==iCol) ){
if( p->flag==FTS3_MATCHINFO_LHITS ){
+10 -3
View File
@@ -1415,6 +1415,7 @@ static int fts3SegReaderNext(
*/
if( pReader->nDoclist > pReader->nNode-(pReader->aDoclist-pReader->aNode)
|| (pReader->nPopulate==0 && pReader->aDoclist[pReader->nDoclist-1])
|| pReader->nDoclist==0
){
return FTS_CORRUPT_VTAB;
}
@@ -3068,11 +3069,11 @@ static void fts3ReadEndBlockField(
if( zText ){
int i;
int iMul = 1;
i64 iVal = 0;
u64 iVal = 0;
for(i=0; zText[i]>='0' && zText[i]<='9'; i++){
iVal = iVal*10 + (zText[i] - '0');
}
*piEndBlock = iVal;
*piEndBlock = (i64)iVal;
while( zText[i]==' ' ) i++;
iVal = 0;
if( zText[i]=='-' ){
@@ -3082,7 +3083,7 @@ static void fts3ReadEndBlockField(
for(/* no-op */; zText[i]>='0' && zText[i]<='9'; i++){
iVal = iVal*10 + (zText[i] - '0');
}
*pnByte = (iVal * (i64)iMul);
*pnByte = ((i64)iVal * (i64)iMul);
}
}
@@ -4953,6 +4954,12 @@ int sqlite3Fts3Incrmerge(Fts3Table *p, int nMerge, int nMin){
** Exit early in this case. */
if( nSeg<=0 ) break;
assert( nMod<=0x7FFFFFFF );
if( iAbsLevel<0 || iAbsLevel>(nMod<<32) ){
rc = FTS_CORRUPT_VTAB;
break;
}
/* Open a cursor to iterate through the contents of the oldest nSeg
** indexes of absolute level iAbsLevel. If this cursor is opened using
** the 'hint' parameters, it is possible that there are less than nSeg
+2 -1
View File
@@ -116,7 +116,8 @@ SQLite. Documentation follows.
and use it as a dynamically loadable SQLite extension. To do this
using gcc on *nix:
gcc -shared icu.c `icu-config --ldflags` -o libSqliteIcu.so
gcc -fPIC -shared icu.c `pkg-config --libs --cflags icu-uc icu-io` \
-o libSqliteIcu.so
You may need to add "-I" flags so that gcc can find sqlite3ext.h
and sqlite3.h. The resulting shared lib, libSqliteIcu.so, may be
+3 -3
View File
@@ -143,7 +143,7 @@ static int icuLikeCompare(
** 3. uPattern is an unescaped escape character, or
** 4. uPattern is to be handled as an ordinary character
*/
if( !prevEscape && uPattern==MATCH_ALL ){
if( uPattern==MATCH_ALL && !prevEscape && uPattern!=(uint32_t)uEsc ){
/* Case 1. */
uint8_t c;
@@ -169,12 +169,12 @@ static int icuLikeCompare(
}
return 0;
}else if( !prevEscape && uPattern==MATCH_ONE ){
}else if( uPattern==MATCH_ONE && !prevEscape && uPattern!=(uint32_t)uEsc ){
/* Case 2. */
if( *zString==0 ) return 0;
SQLITE_ICU_SKIP_UTF8(zString);
}else if( !prevEscape && uPattern==(uint32_t)uEsc){
}else if( uPattern==(uint32_t)uEsc && !prevEscape ){
/* Case 3. */
prevEscape = 1;
+797
View File
@@ -0,0 +1,797 @@
/*
** 2020-04-20
**
** The author disclaims copyright to this source code. In place of
** a legal notice, here is a blessing:
**
** May you do good and not evil.
** May you find forgiveness for yourself and forgive others.
** May you share freely, never taking more than you give.
**
******************************************************************************
**
** This file implements a VFS shim that writes a checksum on each page
** of an SQLite database file. When reading pages, the checksum is verified
** and an error is raised if the checksum is incorrect.
**
** COMPILING
**
** This extension requires SQLite 3.32.0 or later. It uses the
** sqlite3_database_file_object() interface which was added in
** version 3.32.0, so it will not link with an earlier version of
** SQLite.
**
** To build this extension as a separately loaded shared library or
** DLL, use compiler command-lines similar to the following:
**
** (linux) gcc -fPIC -shared cksumvfs.c -o cksumvfs.so
** (mac) clang -fPIC -dynamiclib cksumvfs.c -o cksumvfs.dylib
** (windows) cl cksumvfs.c -link -dll -out:cksumvfs.dll
**
** You may want to add additional compiler options, of course,
** according to the needs of your project.
**
** If you want to statically link this extension with your product,
** then compile it like any other C-language module but add the
** "-DSQLITE_CKSUMVFS_STATIC" option so that this module knows that
** it is being statically linked rather than dynamically linked
**
** LOADING
**
** To load this extension as a shared library, you first have to
** bring up a dummy SQLite database connection to use as the argument
** to the sqlite3_load_extension() API call. Then you invoke the
** sqlite3_load_extension() API and shutdown the dummy database
** connection. All subsequent database connections that are opened
** will include this extension. For example:
**
** sqlite3 *db;
** sqlite3_open(":memory:", &db);
** sqlite3_load_extention(db, "./cksumvfs");
** sqlite3_close(db);
**
** If this extension is compiled with -DSQLITE_CKSUMVFS_STATIC and
** statically linked against the application, initialize it using
** a single API call as follows:
**
** sqlite3_cksumvfs_init();
**
** 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
** 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
** Shim stack in the right order.
**
** USING
**
** Open database connections using the sqlite3_open() or
** sqlite3_open_v2() interfaces, as normal. Ordinary database files
** (without a checksum) will operate normally. Databases with
** checksums will return an SQLITE_IOERR_DATA error if a page is
** encountered that contains an invalid checksum.
**
** Checksumming only works on databases that have a reserve-bytes
** value of exactly 8. The default value for reserve-bytes is 0.
** Hence, newly created database files will omit the checksum by
** default. To create a database that includes a checksum, change
** the reserve-bytes value to 8 by runing:
**
** int n = 8;
** sqlite3_file_control(db, 0, SQLITE_FCNTL_RESERVED_BYTES, &n);
**
** If you do this immediately after creating a new database file,
** before anything else has been written into the file, then that
** might be all that you need to do. Otherwise, the API call
** above should be followed by:
**
** sqlite3_exec(db, "VACUUM", 0, 0, 0);
**
** It never hurts to run the VACUUM, even if you don't need it.
** If the database is in WAL mode, you should shutdown and
** reopen all database connections before continuing.
**
** From the CLI, use the ".filectrl reserve_bytes 8" command,
** followed by "VACUUM;".
**
** Note that SQLite allows the number of reserve-bytes to be
** increased but not decreased. So if a database file already
** has a reserve-bytes value greater than 8, there is no way to
** activate checksumming on that database, other than to dump
** and restore the database file. Note also that other extensions
** might also make use of the reserve-bytes. Checksumming will
** be incompatible with those other extensions.
**
** VERIFICATION OF CHECKSUMS
**
** If any checksum is incorrect, the "PRAGMA quick_check" command
** will find it. To verify that checksums are actually enabled
** and running, use the following query:
**
** SELECT count(*), verify_checksum(data)
** FROM sqlite_dbpage
** GROUP BY 2;
**
** There are three possible outputs form the verify_checksum()
** function: 1, 0, and NULL. 1 is returned if the checksum is
** correct. 0 is returned if the checksum is incorrect. NULL
** is returned if the page is unreadable. If checksumming is
** enabled, the read will fail if the checksum is wrong, so the
** usual result from verify_checksum() on a bad checksum is NULL.
**
** If everything is OK, the query above should return a single
** row where the second column is 1. Any other result indicates
** either that there is a checksum error, or checksum validation
** is disabled.
**
** CONTROLLING CHECKSUM VERIFICATION
**
** The cksumvfs extension implements a new PRAGMA statement that can
** be used to disable, re-enable, or query the status of checksum
** verification:
**
** PRAGMA checksum_verification; -- query status
** PRAGMA checksum_verification=OFF; -- disable verification
** PRAGMA checksum_verification=ON; -- re-enable verification
**
** The "checksum_verification" pragma will return "1" (true) or "0"
** (false) if checksum verification is enabled or disabled, respectively.
** "Verification" in this context means the feature that causes
** SQLITE_IOERR_DATA errors if a checksum mismatch is detected while
** reading. Checksums are always kept up-to-date as long as the
** reserve-bytes value of the database is 8, regardless of the setting
** of this pragma. Checksum verification can be disabled (for example)
** to do forensic analysis of a database that has previously reported
** a checksum error.
**
** The "checksum_verification" pragma will always respond with "0" if
** the database file does not have a reserve-bytes value of 8. The
** pragma will return no rows at all if the cksumvfs extension is
** not loaded.
**
** IMPLEMENTATION NOTES
**
** The checksum is stored in the last 8 bytes of each page. This
** module only operates if the "bytes of reserved space on each page"
** value at offset 20 the SQLite database header is exactly 8. If
** the reserved-space value is not 8, this module is a no-op.
*/
#ifdef SQLITE_CKSUMVFS_STATIC
# include "sqlite3.h"
#else
# include "sqlite3ext.h"
SQLITE_EXTENSION_INIT1
#endif
#include <string.h>
#include <assert.h>
/*
** Forward declaration of objects used by this utility
*/
typedef struct sqlite3_vfs CksmVfs;
typedef struct CksmFile CksmFile;
/*
** Useful datatype abbreviations
*/
#if !defined(SQLITE_CORE)
typedef unsigned char u8;
typedef unsigned int u32;
#endif
/* Access to a lower-level VFS that (might) implement dynamic loading,
** access to randomness, etc.
*/
#define ORIGVFS(p) ((sqlite3_vfs*)((p)->pAppData))
#define ORIGFILE(p) ((sqlite3_file*)(((CksmFile*)(p))+1))
/* An open file */
struct CksmFile {
sqlite3_file base; /* IO methods */
const char *zFName; /* Original name of the file */
char computeCksm; /* True to compute checksums.
** Always true if reserve size is 8. */
char verifyCksm; /* True to verify checksums */
char isWal; /* True if processing a WAL file */
char inCkpt; /* Currently doing a checkpoint */
CksmFile *pPartner; /* Ptr from WAL to main-db, or from main-db to WAL */
};
/*
** Methods for CksmFile
*/
static int cksmClose(sqlite3_file*);
static int cksmRead(sqlite3_file*, void*, int iAmt, sqlite3_int64 iOfst);
static int cksmWrite(sqlite3_file*,const void*,int iAmt, sqlite3_int64 iOfst);
static int cksmTruncate(sqlite3_file*, sqlite3_int64 size);
static int cksmSync(sqlite3_file*, int flags);
static int cksmFileSize(sqlite3_file*, sqlite3_int64 *pSize);
static int cksmLock(sqlite3_file*, int);
static int cksmUnlock(sqlite3_file*, int);
static int cksmCheckReservedLock(sqlite3_file*, int *pResOut);
static int cksmFileControl(sqlite3_file*, int op, void *pArg);
static int cksmSectorSize(sqlite3_file*);
static int cksmDeviceCharacteristics(sqlite3_file*);
static int cksmShmMap(sqlite3_file*, int iPg, int pgsz, int, void volatile**);
static int cksmShmLock(sqlite3_file*, int offset, int n, int flags);
static void cksmShmBarrier(sqlite3_file*);
static int cksmShmUnmap(sqlite3_file*, int deleteFlag);
static int cksmFetch(sqlite3_file*, sqlite3_int64 iOfst, int iAmt, void **pp);
static int cksmUnfetch(sqlite3_file*, sqlite3_int64 iOfst, void *p);
/*
** Methods for CksmVfs
*/
static int cksmOpen(sqlite3_vfs*, const char *, sqlite3_file*, int , int *);
static int cksmDelete(sqlite3_vfs*, const char *zName, int syncDir);
static int cksmAccess(sqlite3_vfs*, const char *zName, int flags, int *);
static int cksmFullPathname(sqlite3_vfs*, const char *zName, int, char *zOut);
static void *cksmDlOpen(sqlite3_vfs*, const char *zFilename);
static void cksmDlError(sqlite3_vfs*, int nByte, char *zErrMsg);
static void (*cksmDlSym(sqlite3_vfs *pVfs, void *p, const char*zSym))(void);
static void cksmDlClose(sqlite3_vfs*, void*);
static int cksmRandomness(sqlite3_vfs*, int nByte, char *zOut);
static int cksmSleep(sqlite3_vfs*, int microseconds);
static int cksmCurrentTime(sqlite3_vfs*, double*);
static int cksmGetLastError(sqlite3_vfs*, int, char *);
static int cksmCurrentTimeInt64(sqlite3_vfs*, sqlite3_int64*);
static int cksmSetSystemCall(sqlite3_vfs*, const char*,sqlite3_syscall_ptr);
static sqlite3_syscall_ptr cksmGetSystemCall(sqlite3_vfs*, const char *z);
static const char *cksmNextSystemCall(sqlite3_vfs*, const char *zName);
static sqlite3_vfs cksm_vfs = {
3, /* iVersion (set when registered) */
0, /* szOsFile (set when registered) */
1024, /* mxPathname */
0, /* pNext */
"cksmvfs", /* zName */
0, /* pAppData (set when registered) */
cksmOpen, /* xOpen */
cksmDelete, /* xDelete */
cksmAccess, /* xAccess */
cksmFullPathname, /* xFullPathname */
cksmDlOpen, /* xDlOpen */
cksmDlError, /* xDlError */
cksmDlSym, /* xDlSym */
cksmDlClose, /* xDlClose */
cksmRandomness, /* xRandomness */
cksmSleep, /* xSleep */
cksmCurrentTime, /* xCurrentTime */
cksmGetLastError, /* xGetLastError */
cksmCurrentTimeInt64, /* xCurrentTimeInt64 */
cksmSetSystemCall, /* xSetSystemCall */
cksmGetSystemCall, /* xGetSystemCall */
cksmNextSystemCall /* xNextSystemCall */
};
static const sqlite3_io_methods cksm_io_methods = {
3, /* iVersion */
cksmClose, /* xClose */
cksmRead, /* xRead */
cksmWrite, /* xWrite */
cksmTruncate, /* xTruncate */
cksmSync, /* xSync */
cksmFileSize, /* xFileSize */
cksmLock, /* xLock */
cksmUnlock, /* xUnlock */
cksmCheckReservedLock, /* xCheckReservedLock */
cksmFileControl, /* xFileControl */
cksmSectorSize, /* xSectorSize */
cksmDeviceCharacteristics, /* xDeviceCharacteristics */
cksmShmMap, /* xShmMap */
cksmShmLock, /* xShmLock */
cksmShmBarrier, /* xShmBarrier */
cksmShmUnmap, /* xShmUnmap */
cksmFetch, /* xFetch */
cksmUnfetch /* xUnfetch */
};
/* Do byte swapping on a unsigned 32-bit integer */
#define BYTESWAP32(x) ( \
(((x)&0x000000FF)<<24) + (((x)&0x0000FF00)<<8) \
+ (((x)&0x00FF0000)>>8) + (((x)&0xFF000000)>>24) \
)
/* Compute a checksum on a buffer */
static void cksmCompute(
u8 *a, /* Content to be checksummed */
int nByte, /* Bytes of content in a[]. Must be a multiple of 8. */
u8 *aOut /* OUT: Final 8-byte checksum value output */
){
u32 s1 = 0, s2 = 0;
u32 *aData = (u32*)a;
u32 *aEnd = (u32*)&a[nByte];
u32 x = 1;
assert( nByte>=8 );
assert( (nByte&0x00000007)==0 );
assert( nByte<=65536 );
if( 1 == *(u8*)&x ){
/* Little-endian */
do {
s1 += *aData++ + s2;
s2 += *aData++ + s1;
}while( aData<aEnd );
}else{
/* Big-endian */
do {
s1 += BYTESWAP32(aData[0]) + s2;
s2 += BYTESWAP32(aData[1]) + s1;
aData += 2;
}while( aData<aEnd );
s1 = BYTESWAP32(s1);
s2 = BYTESWAP32(s2);
}
memcpy(aOut, &s1, 4);
memcpy(aOut+4, &s2, 4);
}
/*
** SQL function: verify_checksum(BLOB)
**
** Return 0 or 1 if the checksum is invalid or valid. Or return
** NULL if the input is not a BLOB that is the right size for a
** database page.
*/
static void cksmVerifyFunc(
sqlite3_context *context,
int argc,
sqlite3_value **argv
){
int nByte;
u8 *data;
u8 cksum[8];
data = (u8*)sqlite3_value_blob(argv[0]);
if( data==0 ) return;
if( sqlite3_value_type(argv[0])!=SQLITE_BLOB ) return;
nByte = sqlite3_value_bytes(argv[0]);
if( nByte<512 || nByte>65536 || (nByte & (nByte-1))!=0 ) return;
cksmCompute(data, nByte-8, cksum);
sqlite3_result_int(context, memcmp(data+nByte-8,cksum,8)==0);
}
/*
** Close a cksm-file.
*/
static int cksmClose(sqlite3_file *pFile){
CksmFile *p = (CksmFile *)pFile;
if( p->pPartner ){
assert( p->pPartner->pPartner==p );
p->pPartner->pPartner = 0;
p->pPartner = 0;
}
pFile = ORIGFILE(pFile);
return pFile->pMethods->xClose(pFile);
}
/*
** Set the computeCkSm and verifyCksm flags, if they need to be
** changed.
*/
static void cksmSetFlags(CksmFile *p, int hasCorrectReserveSize){
if( hasCorrectReserveSize!=p->computeCksm ){
p->computeCksm = p->verifyCksm = hasCorrectReserveSize;
if( p->pPartner ){
p->pPartner->verifyCksm = hasCorrectReserveSize;
p->pPartner->computeCksm = hasCorrectReserveSize;
}
}
}
/*
** Read data from a cksm-file.
*/
static int cksmRead(
sqlite3_file *pFile,
void *zBuf,
int iAmt,
sqlite_int64 iOfst
){
int rc;
CksmFile *p = (CksmFile *)pFile;
pFile = ORIGFILE(pFile);
rc = pFile->pMethods->xRead(pFile, zBuf, iAmt, iOfst);
if( rc==SQLITE_OK ){
if( iOfst==0 && iAmt>=100 && memcmp(zBuf,"SQLite format 3",16)==0 ){
u8 *d = (u8*)zBuf;
char hasCorrectReserveSize = (d[20]==8);
cksmSetFlags(p, hasCorrectReserveSize);
}
/* Verify the checksum if
** (1) the size indicates that we are dealing with a complete
** database page
** (2) checksum verification is enabled
** (3) we are not in the middle of checkpoint
*/
if( iAmt>=512 /* (1) */
&& p->verifyCksm /* (2) */
&& !p->inCkpt /* (3) */
){
u8 cksum[8];
cksmCompute((u8*)zBuf, iAmt-8, cksum);
if( memcmp((u8*)zBuf+iAmt-8, cksum, 8)!=0 ){
sqlite3_log(SQLITE_IOERR_DATA,
"checksum fault offset %lld of \"%s\"",
iOfst, p->zFName);
rc = SQLITE_IOERR_DATA;
}
}
}
return rc;
}
/*
** Write data to a cksm-file.
*/
static int cksmWrite(
sqlite3_file *pFile,
const void *zBuf,
int iAmt,
sqlite_int64 iOfst
){
CksmFile *p = (CksmFile *)pFile;
pFile = ORIGFILE(pFile);
if( iOfst==0 && iAmt>=100 && memcmp(zBuf,"SQLite format 3",16)==0 ){
u8 *d = (u8*)zBuf;
char hasCorrectReserveSize = (d[20]==8);
cksmSetFlags(p, hasCorrectReserveSize);
}
/* If the write size is appropriate for a database page and if
** checksums where ever enabled, then it will be safe to compute
** the checksums. The reserve byte size might have increased, but
** it will never decrease. And because it cannot decrease, the
** checksum will not overwrite anything.
*/
if( iAmt>=512
&& p->computeCksm
&& !p->inCkpt
){
cksmCompute((u8*)zBuf, iAmt-8, ((u8*)zBuf)+iAmt-8);
}
return pFile->pMethods->xWrite(pFile, zBuf, iAmt, iOfst);
}
/*
** Truncate a cksm-file.
*/
static int cksmTruncate(sqlite3_file *pFile, sqlite_int64 size){
pFile = ORIGFILE(pFile);
return pFile->pMethods->xTruncate(pFile, size);
}
/*
** Sync a cksm-file.
*/
static int cksmSync(sqlite3_file *pFile, int flags){
pFile = ORIGFILE(pFile);
return pFile->pMethods->xSync(pFile, flags);
}
/*
** Return the current file-size of a cksm-file.
*/
static int cksmFileSize(sqlite3_file *pFile, sqlite_int64 *pSize){
CksmFile *p = (CksmFile *)pFile;
pFile = ORIGFILE(p);
return pFile->pMethods->xFileSize(pFile, pSize);
}
/*
** Lock a cksm-file.
*/
static int cksmLock(sqlite3_file *pFile, int eLock){
pFile = ORIGFILE(pFile);
return pFile->pMethods->xLock(pFile, eLock);
}
/*
** Unlock a cksm-file.
*/
static int cksmUnlock(sqlite3_file *pFile, int eLock){
pFile = ORIGFILE(pFile);
return pFile->pMethods->xUnlock(pFile, eLock);
}
/*
** Check if another file-handle holds a RESERVED lock on a cksm-file.
*/
static int cksmCheckReservedLock(sqlite3_file *pFile, int *pResOut){
pFile = ORIGFILE(pFile);
return pFile->pMethods->xCheckReservedLock(pFile, pResOut);
}
/*
** File control method. For custom operations on a cksm-file.
*/
static int cksmFileControl(sqlite3_file *pFile, int op, void *pArg){
int rc;
CksmFile *p = (CksmFile*)pFile;
pFile = ORIGFILE(pFile);
if( op==SQLITE_FCNTL_PRAGMA ){
char **azArg = (char**)pArg;
assert( azArg[1]!=0 );
if( sqlite3_stricmp(azArg[1],"checksum_verification")==0 ){
char *zArg = azArg[2];
if( zArg!=0 ){
if( (zArg[0]>='1' && zArg[0]<='9')
|| sqlite3_strlike("enable%",zArg,0)==0
|| sqlite3_stricmp("yes",zArg)==0
|| sqlite3_stricmp("on",zArg)==0
){
p->verifyCksm = p->computeCksm;
}else{
p->verifyCksm = 0;
}
if( p->pPartner ) p->pPartner->verifyCksm = p->verifyCksm;
}
azArg[0] = sqlite3_mprintf("%d",p->verifyCksm);
return SQLITE_OK;
}else if( p->computeCksm && azArg[2]!=0
&& sqlite3_stricmp(azArg[1], "page_size")==0 ){
/* Do not allow page size changes on a checksum database */
return SQLITE_OK;
}
}else if( op==SQLITE_FCNTL_CKPT_START || op==SQLITE_FCNTL_CKPT_DONE ){
p->inCkpt = op==SQLITE_FCNTL_CKPT_START;
if( p->pPartner ) p->pPartner->inCkpt = p->inCkpt;
}
rc = pFile->pMethods->xFileControl(pFile, op, pArg);
if( rc==SQLITE_OK && op==SQLITE_FCNTL_VFSNAME ){
*(char**)pArg = sqlite3_mprintf("cksm/%z", *(char**)pArg);
}
return rc;
}
/*
** Return the sector-size in bytes for a cksm-file.
*/
static int cksmSectorSize(sqlite3_file *pFile){
pFile = ORIGFILE(pFile);
return pFile->pMethods->xSectorSize(pFile);
}
/*
** Return the device characteristic flags supported by a cksm-file.
*/
static int cksmDeviceCharacteristics(sqlite3_file *pFile){
pFile = ORIGFILE(pFile);
return pFile->pMethods->xDeviceCharacteristics(pFile);
}
/* Create a shared memory file mapping */
static int cksmShmMap(
sqlite3_file *pFile,
int iPg,
int pgsz,
int bExtend,
void volatile **pp
){
pFile = ORIGFILE(pFile);
return pFile->pMethods->xShmMap(pFile,iPg,pgsz,bExtend,pp);
}
/* Perform locking on a shared-memory segment */
static int cksmShmLock(sqlite3_file *pFile, int offset, int n, int flags){
pFile = ORIGFILE(pFile);
return pFile->pMethods->xShmLock(pFile,offset,n,flags);
}
/* Memory barrier operation on shared memory */
static void cksmShmBarrier(sqlite3_file *pFile){
pFile = ORIGFILE(pFile);
pFile->pMethods->xShmBarrier(pFile);
}
/* Unmap a shared memory segment */
static int cksmShmUnmap(sqlite3_file *pFile, int deleteFlag){
pFile = ORIGFILE(pFile);
return pFile->pMethods->xShmUnmap(pFile,deleteFlag);
}
/* Fetch a page of a memory-mapped file */
static int cksmFetch(
sqlite3_file *pFile,
sqlite3_int64 iOfst,
int iAmt,
void **pp
){
CksmFile *p = (CksmFile *)pFile;
if( p->computeCksm ){
*pp = 0;
return SQLITE_OK;
}
pFile = ORIGFILE(pFile);
return pFile->pMethods->xFetch(pFile, iOfst, iAmt, pp);
}
/* Release a memory-mapped page */
static int cksmUnfetch(sqlite3_file *pFile, sqlite3_int64 iOfst, void *pPage){
pFile = ORIGFILE(pFile);
return pFile->pMethods->xUnfetch(pFile, iOfst, pPage);
}
/*
** Open a cksm file handle.
*/
static int cksmOpen(
sqlite3_vfs *pVfs,
const char *zName,
sqlite3_file *pFile,
int flags,
int *pOutFlags
){
CksmFile *p;
sqlite3_file *pSubFile;
sqlite3_vfs *pSubVfs;
int rc;
pSubVfs = ORIGVFS(pVfs);
if( (flags & (SQLITE_OPEN_MAIN_DB|SQLITE_OPEN_WAL))==0 ){
return pSubVfs->xOpen(pSubVfs, zName, pFile, flags, pOutFlags);
}
p = (CksmFile*)pFile;
memset(p, 0, sizeof(*p));
pSubFile = ORIGFILE(pFile);
p->base.pMethods = &cksm_io_methods;
rc = pSubVfs->xOpen(pSubVfs, zName, pSubFile, flags, pOutFlags);
if( rc ) goto cksm_open_done;
if( flags & SQLITE_OPEN_WAL ){
sqlite3_file *pDb = sqlite3_database_file_object(zName);
p->pPartner = (CksmFile*)pDb;
assert( p->pPartner->pPartner==0 );
p->pPartner->pPartner = p;
p->isWal = 1;
p->computeCksm = p->pPartner->computeCksm;
}else{
p->isWal = 0;
p->computeCksm = 0;
}
p->zFName = zName;
cksm_open_done:
if( rc ) pFile->pMethods = 0;
return rc;
}
/*
** All other VFS methods are pass-thrus.
*/
static int cksmDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){
return ORIGVFS(pVfs)->xDelete(ORIGVFS(pVfs), zPath, dirSync);
}
static int cksmAccess(
sqlite3_vfs *pVfs,
const char *zPath,
int flags,
int *pResOut
){
return ORIGVFS(pVfs)->xAccess(ORIGVFS(pVfs), zPath, flags, pResOut);
}
static int cksmFullPathname(
sqlite3_vfs *pVfs,
const char *zPath,
int nOut,
char *zOut
){
return ORIGVFS(pVfs)->xFullPathname(ORIGVFS(pVfs),zPath,nOut,zOut);
}
static void *cksmDlOpen(sqlite3_vfs *pVfs, const char *zPath){
return ORIGVFS(pVfs)->xDlOpen(ORIGVFS(pVfs), zPath);
}
static void cksmDlError(sqlite3_vfs *pVfs, int nByte, char *zErrMsg){
ORIGVFS(pVfs)->xDlError(ORIGVFS(pVfs), nByte, zErrMsg);
}
static void (*cksmDlSym(sqlite3_vfs *pVfs, void *p, const char *zSym))(void){
return ORIGVFS(pVfs)->xDlSym(ORIGVFS(pVfs), p, zSym);
}
static void cksmDlClose(sqlite3_vfs *pVfs, void *pHandle){
ORIGVFS(pVfs)->xDlClose(ORIGVFS(pVfs), pHandle);
}
static int cksmRandomness(sqlite3_vfs *pVfs, int nByte, char *zBufOut){
return ORIGVFS(pVfs)->xRandomness(ORIGVFS(pVfs), nByte, zBufOut);
}
static int cksmSleep(sqlite3_vfs *pVfs, int nMicro){
return ORIGVFS(pVfs)->xSleep(ORIGVFS(pVfs), nMicro);
}
static int cksmCurrentTime(sqlite3_vfs *pVfs, double *pTimeOut){
return ORIGVFS(pVfs)->xCurrentTime(ORIGVFS(pVfs), pTimeOut);
}
static int cksmGetLastError(sqlite3_vfs *pVfs, int a, char *b){
return ORIGVFS(pVfs)->xGetLastError(ORIGVFS(pVfs), a, b);
}
static int cksmCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *p){
return ORIGVFS(pVfs)->xCurrentTimeInt64(ORIGVFS(pVfs), p);
}
static int cksmSetSystemCall(
sqlite3_vfs *pVfs,
const char *zName,
sqlite3_syscall_ptr pCall
){
return ORIGVFS(pVfs)->xSetSystemCall(ORIGVFS(pVfs),zName,pCall);
}
static sqlite3_syscall_ptr cksmGetSystemCall(
sqlite3_vfs *pVfs,
const char *zName
){
return ORIGVFS(pVfs)->xGetSystemCall(ORIGVFS(pVfs),zName);
}
static const char *cksmNextSystemCall(sqlite3_vfs *pVfs, const char *zName){
return ORIGVFS(pVfs)->xNextSystemCall(ORIGVFS(pVfs), zName);
}
/* Register the verify_checksum() SQL function.
*/
static int cksmRegisterFunc(
sqlite3 *db,
char **pzErrMsg,
const sqlite3_api_routines *pApi
){
int rc;
if( db==0 ) return SQLITE_OK;
rc = sqlite3_create_function(db, "verify_checksum", 1,
SQLITE_UTF8|SQLITE_INNOCUOUS|SQLITE_DETERMINISTIC,
0, cksmVerifyFunc, 0, 0);
return rc;
}
/*
** Register the cksum VFS as the default VFS for the system.
** Also make arrangements to automatically register the "verify_checksum()"
** SQL function on each new database connection.
*/
static int cksmRegisterVfs(void){
int rc = SQLITE_OK;
sqlite3_vfs *pOrig;
if( sqlite3_vfs_find("cksum")!=0 ) return SQLITE_OK;
pOrig = sqlite3_vfs_find(0);
cksm_vfs.iVersion = pOrig->iVersion;
cksm_vfs.pAppData = pOrig;
cksm_vfs.szOsFile = pOrig->szOsFile + sizeof(CksmFile);
rc = sqlite3_vfs_register(&cksm_vfs, 1);
if( rc==SQLITE_OK ){
rc = sqlite3_auto_extension((void(*)(void))cksmRegisterFunc);
}
return rc;
}
#if defined(SQLITE_CKSUMVFS_STATIC)
/* This variant of the initializer runs when the extension is
** statically linked.
*/
int sqlite3_register_cksumvfs(const char *NotUsed){
(void)NotUsed;
return cksmRegisterVfs();
}
#endif /* defined(SQLITE_CKSUMVFS_STATIC */
#if !defined(SQLITE_CKSUMVFS_STATIC)
/* This variant of the initializer function is used when the
** extension is shared library to be loaded at run-time.
*/
#ifdef _WIN32
__declspec(dllexport)
#endif
/*
** This routine is called by sqlite3_load_extension() when the
** extension is first loaded.
***/
int sqlite3_cksumvfs_init(
sqlite3 *db,
char **pzErrMsg,
const sqlite3_api_routines *pApi
){
int rc;
SQLITE_EXTENSION_INIT2(pApi);
(void)pzErrMsg; /* not used */
rc = cksmRegisterFunc(db, 0, 0);
if( rc==SQLITE_OK ){
}
if( rc==SQLITE_OK ){
rc = cksmRegisterVfs();
}
if( rc==SQLITE_OK ) rc = SQLITE_OK_LOAD_PERMANENTLY;
return rc;
}
#endif /* !defined(SQLITE_CKSUMVFS_STATIC) */
+2
View File
@@ -394,6 +394,7 @@ static int writeFile(
if( mtime>=0 ){
#if defined(_WIN32)
#if !SQLITE_OS_WINRT
/* Windows */
FILETIME lastAccess;
FILETIME lastWrite;
@@ -424,6 +425,7 @@ static int writeFile(
}else{
return 1;
}
#endif
#elif defined(AT_FDCWD) && 0 /* utimensat() is not universally available */
/* Recent unix */
struct timespec times[2];
+1
View File
@@ -254,6 +254,7 @@ static int jsonGrow(JsonString *p, u32 N){
/* Append N bytes from zIn onto the end of the JsonString string.
*/
static void jsonAppendRaw(JsonString *p, const char *zIn, u32 N){
if( N==0 ) return;
if( (N+p->nUsed >= p->nAlloc) && jsonGrow(p,N)!=0 ) return;
memcpy(p->zBuf+p->nUsed, zIn, N);
p->nUsed += N;
+1
View File
@@ -17,6 +17,7 @@
#include "sqlite3ext.h"
SQLITE_EXTENSION_INIT1
#include <zlib.h>
#include <assert.h>
/*
** Implementation of the "sqlar_compress(X)" SQL function.
+2 -1
View File
@@ -168,7 +168,8 @@ static int stmtColumn(
sqlite3_result_int(ctx, sqlite3_stmt_busy(pCur->pStmt));
break;
}
case STMT_COLUMN_MEM: {
default: {
assert( i==STMT_COLUMN_MEM );
i = SQLITE_STMTSTATUS_MEMUSED +
STMT_COLUMN_NSCAN - SQLITE_STMTSTATUS_FULLSCAN_STEP;
/* Fall thru */
+92
View File
@@ -0,0 +1,92 @@
/*
** 2020-04-14
**
** 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 SQLite extension implements the UINT collating sequence.
**
** UINT works like BINARY for text, except that embedded strings
** of digits compare in numeric order.
**
** * Leading zeros are handled properly, in the sense that
** they do not mess of the maginitude comparison of embedded
** strings of digits. "x00123y" is equal to "x123y".
**
** * Only unsigned integers are recognized. Plus and minus
** signs are ignored. Decimal points and exponential notation
** are ignored.
**
** * Embedded integers can be of arbitrary length. Comparison
** is *not* limited integers that can be expressed as a
** 64-bit machine integer.
*/
#include "sqlite3ext.h"
SQLITE_EXTENSION_INIT1
#include <assert.h>
#include <string.h>
#include <ctype.h>
/*
** Compare text in lexicographic order, except strings of digits
** compare in numeric order.
*/
static int uintCollFunc(
void *notUsed,
int nKey1, const void *pKey1,
int nKey2, const void *pKey2
){
const unsigned char *zA = (const unsigned char*)pKey1;
const unsigned char *zB = (const unsigned char*)pKey2;
int i=0, j=0, x;
(void)notUsed;
while( i<nKey1 && j<nKey2 ){
x = zA[i] - zB[j];
if( isdigit(zA[i]) ){
int k;
if( !isdigit(zB[j]) ) return x;
while( i<nKey1 && zA[i]=='0' ){ i++; }
while( j<nKey2 && zB[j]=='0' ){ j++; }
k = 0;
while( i+k<nKey1 && isdigit(zA[i+k])
&& j+k<nKey2 && isdigit(zB[j+k]) ){
k++;
}
if( i+k<nKey1 && isdigit(zA[i+k]) ){
return +1;
}else if( j+k<nKey2 && isdigit(zB[j+k]) ){
return -1;
}else{
x = memcmp(zA+i, zB+j, k);
if( x ) return x;
i += k;
j += k;
}
}else if( x ){
return x;
}else{
i++;
j++;
}
}
return (nKey1 - i) - (nKey2 - j);
}
#ifdef _WIN32
__declspec(dllexport)
#endif
int sqlite3_uint_init(
sqlite3 *db,
char **pzErrMsg,
const sqlite3_api_routines *pApi
){
SQLITE_EXTENSION_INIT2(pApi);
(void)pzErrMsg; /* Unused parameter */
return sqlite3_create_collation(db, "uint", SQLITE_UTF8, 0, uintCollFunc);
}
+1 -1
View File
@@ -811,7 +811,7 @@ int sqlite3_vfsstat_init(
if( rc==SQLITE_OK ){
rc = vstatRegister(db, pzErrMsg, pApi);
if( rc==SQLITE_OK ){
rc = sqlite3_auto_extension(vstatRegister);
rc = sqlite3_auto_extension((void(*)(void))vstatRegister);
}
}
if( rc==SQLITE_OK ) rc = SQLITE_OK_LOAD_PERMANENTLY;
+9 -1
View File
@@ -74,7 +74,8 @@ LIBOBJ+= vdbe.o parse.o \
table.o threads.o tokenize.o treeview.o trigger.o \
update.o upsert.o userauth.o util.o vacuum.o \
vdbeapi.o vdbeaux.o vdbeblob.o vdbemem.o vdbesort.o \
vdbetrace.o wal.o walker.o where.o wherecode.o whereexpr.o \
vdbetrace.o vdbevtab.o \
wal.o walker.o where.o wherecode.o whereexpr.o \
utf.o vtab.o window.o
LIBOBJ += sqlite3session.o
@@ -173,6 +174,7 @@ SRC = \
$(TOP)/src/vdbemem.c \
$(TOP)/src/vdbesort.c \
$(TOP)/src/vdbetrace.c \
$(TOP)/src/vdbevtab.c \
$(TOP)/src/vdbeInt.h \
$(TOP)/src/vtab.c \
$(TOP)/src/vxworks.h \
@@ -421,6 +423,7 @@ TESTSRC2 = \
$(TOP)/src/vdbeaux.c \
$(TOP)/src/vdbe.c \
$(TOP)/src/vdbemem.c \
$(TOP)/src/vdbevtab.c \
$(TOP)/src/where.c \
$(TOP)/src/wherecode.c \
$(TOP)/src/whereexpr.c \
@@ -526,6 +529,7 @@ SHELL_OPT += -DSQLITE_ENABLE_UNKNOWN_SQL_FUNCTION
SHELL_OPT += -DSQLITE_ENABLE_STMTVTAB
SHELL_OPT += -DSQLITE_ENABLE_DBPAGE_VTAB
SHELL_OPT += -DSQLITE_ENABLE_DBSTAT_VTAB
SHELL_OPT += -DSQLITE_ENABLE_BYTECODE_VTAB
SHELL_OPT += -DSQLITE_ENABLE_OFFSET_SQL_FUNC
FUZZERSHELL_OPT = -DSQLITE_ENABLE_JSON1
FUZZCHECK_OPT = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_MEMSYS5
@@ -536,6 +540,7 @@ FUZZCHECK_OPT += -DSQLITE_ENABLE_FTS4
FUZZCHECK_OPT += -DSQLITE_ENABLE_RTREE
FUZZCHECK_OPT += -DSQLITE_ENABLE_GEOPOLY
FUZZCHECK_OPT += -DSQLITE_ENABLE_DBSTAT_VTAB
FUZZCHECK_OPT += -DSQLITE_ENABLE_BYTECODE_VTAB
DBFUZZ_OPT =
KV_OPT = -DSQLITE_THREADSAFE=0 -DSQLITE_DIRECT_OVERFLOW_READ
ST_OPT = -DSQLITE_THREADSAFE=0
@@ -586,6 +591,7 @@ DBFUZZ2_OPTS = \
-DSQLITE_ENABLE_DESERIALIZE \
-DSQLITE_DEBUG \
-DSQLITE_ENABLE_DBSTAT_VTAB \
-DSQLITE_ENABLE_BYTECODE_VTAB \
-DSQLITE_ENABLE_RTREE \
-DSQLITE_ENABLE_FTS4 \
-DSQLITE_ENABLE_FTS5
@@ -733,6 +739,7 @@ SHELL_SRC = \
$(TOP)/ext/misc/fileio.c \
$(TOP)/ext/misc/completion.c \
$(TOP)/ext/misc/sqlar.c \
$(TOP)/ext/misc/uint.c \
$(TOP)/ext/expert/sqlite3expert.c \
$(TOP)/ext/expert/sqlite3expert.h \
$(TOP)/ext/misc/zipfile.c \
@@ -894,6 +901,7 @@ TESTFIXTURE_FLAGS += -DSQLITE_SERIES_CONSTRAINT_VERIFY=1
TESTFIXTURE_FLAGS += -DSQLITE_DEFAULT_PAGE_SIZE=1024
TESTFIXTURE_FLAGS += -DSQLITE_ENABLE_STMTVTAB
TESTFIXTURE_FLAGS += -DSQLITE_ENABLE_DBPAGE_VTAB
TESTFIXTURE_FLAGS += -DSQLITE_ENABLE_BYTECODE_VTAB
TESTFIXTURE_FLAGS += -DTCLSH_INIT_PROC=sqlite3TestInit
testfixture$(EXE): $(TESTSRC2) libsqlite3.a $(TESTSRC) $(TOP)/src/tclsqlite.c
+131 -122
View File
@@ -1,13 +1,13 @@
C Rename\ssqlite3ExprCodeAtInit()\sto\ssqlite3ExprCodeRunJustOnce().\nOther\schanges\sto\smake\sthe\snew\scode\scleaner.\s\sTest\scases\sadded.
D 2020-03-11T19:41:49.390
C Version\s3.32.1
D 2020-05-25T16:19:56.155
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
F Makefile.in 9dfc7936f675785309b74d09202bb656732325e65df889e5aaa18cc8932e5b0c
F Makefile.in 376f53999defeb32b7ad2626fd58aae8f3694c38ab7ee30c2289e0d0525a9238
F Makefile.linux-gcc f609543700659711fbd230eced1f01353117621dccae7b9fb70daa64236c5241
F Makefile.msc fab23c6b10cb6f06a7e9c407fc2e35cb184a6d653f1b793bda87fcee2eafa4f6
F Makefile.msc 8d00aeba2609bb498dded5eead2890126321f02e292573bf29bf2d18487d37bd
F README.md 1514a365ffca3c138e00c5cc839906108a01011a6b082bad19b09781e3aa498a
F VERSION 980d78a2ce04a1fd0ebefbaabd665f7f9186563820629ee29c6e350e96f19b52
F VERSION 7d1da8465e06354a9ffb67a9ef3f933552767d8e239b507cb2a08ba417048322
F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50
F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2
F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90
@@ -15,7 +15,7 @@ F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2
F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903
F autoconf/Makefile.am e14b629addaa1ce372b72043f28f40de2e32b7e211b6e0fc18dbb87989197e40
F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac
F autoconf/Makefile.msc 1d1e4af61289c62b94aa65a93afcd3dfa4b53e4195908980e0b138203e71e1c9
F autoconf/Makefile.msc e0f1dafc48d000fd6ddfdb01815271528db55cbc7299ca888df5b93367f0d5a4
F autoconf/README.first 6c4f34fe115ff55d4e8dbfa3cecf04a0188292f7
F autoconf/README.txt 4f04b0819303aabaa35fff5f7b257fb0c1ef95f1
F autoconf/configure.ac 3cd933b959fe514eebd1ca1717dfddbf2c9b825b6bc2c5f744deaf5d63af9288
@@ -34,7 +34,7 @@ F autoconf/tea/win/rules.vc c511f222b80064096b705dbeb97060ee1d6b6d63
F config.guess 883205ddf25b46f10c181818bf42c09da9888884af96f79e1719264345053bd6
F config.h.in 6376abec766e9a0785178b1823b5a587e9f1ccbc
F config.sub c2d0260f17f3e4bc0b6808fccf1b291cb5e9126c14fc5890efc77b9fd0175559
F configure 4bbb5f13998f2faf929b9ae708aea9fbcb08a46cb6dd3150e36c3f09c0a05a75 x
F configure 4705718305e176b707e65047b69dca834fe7bc5475584e30fe1f63c8e33751b8 x
F configure.ac 798a24cee2879325ca5b688a618199eb32cc77ed8136edbaa43d9137b470d54e
F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad
F doc/F2FS.txt c1d4a0ae9711cfe0e1d8b019d154f1c29e0d3abfe820787ba1e9ed7691160fcd
@@ -48,8 +48,8 @@ F ext/async/sqlite3async.c 0f3070cc3f5ede78f2b9361fb3b629ce200d7d74
F ext/async/sqlite3async.h f489b080af7e72aec0e1ee6f1d98ab6cf2e4dcef
F ext/expert/README.md b321c2762bb93c18ea102d5a5f7753a4b8bac646cb392b3b437f633caf2020c3
F ext/expert/expert.c d548d603a4cc9e61f446cc179c120c6713511c413f82a4a32b1e1e69d3f086a4
F ext/expert/expert1.test e2afc53a27610e8251e44c7f961806607a5490ff204b3db342740d558e052662
F ext/expert/sqlite3expert.c 3da865f2286433588260f41e796422c611bceaca3a0bbf9139a619cf7d062c19
F ext/expert/expert1.test 2e10ff875c31c9e6fc5e324767624181273859771fe34c5daeeadf3f2974a4f7
F ext/expert/sqlite3expert.c ac008c72c00e6ded0f5116914d22ebd57f415fc0a7ea04738f4e9766dbdd3117
F ext/expert/sqlite3expert.h ca81efc2679a92373a13a3e76a6138d0310e32be53d6c3bfaedabd158ea8969b
F ext/expert/test_expert.c d56c194b769bdc90cf829a14c9ecbc1edca9c850b837a4d0b13be14095c32a72
F ext/fts1/README.txt 20ac73b006a70bcfd80069bdaf59214b6cf1db5e
@@ -82,16 +82,16 @@ F ext/fts3/README.content fdc666a70d5257a64fee209f97cf89e0e6e32b51
F ext/fts3/README.syntax a19711dc5458c20734b8e485e75fb1981ec2427a
F ext/fts3/README.tokenizers b92bdeb8b46503f0dd301d364efc5ef59ef9fa8e2758b8e742f39fa93a2e422d
F ext/fts3/README.txt 8c18f41574404623b76917b9da66fcb0ab38328d
F ext/fts3/fts3.c 2a9dd452003a143248e68449302da80dd0c43df72195b56577e3562e43c408a0
F ext/fts3/fts3.c 45f5774987a68d36355799503b6d02dbff5286ffb42bec14d928b295d2b93c1b
F ext/fts3/fts3.h 3a10a0af180d502cecc50df77b1b22df142817fe
F ext/fts3/fts3Int.h f091030b976045e7df91af2337935952b477cdbd9f48058c44c965684484cb50
F ext/fts3/fts3Int.h 2c59cc46aefde134c1782e89a6a5384710ddcd4e783071337aa5d43d07269be3
F ext/fts3/fts3_aux.c 96708c8b3a7d9b8ca1b68ea2b7e503e283f20e95f145becadedfad096dbd0f34
F ext/fts3/fts3_expr.c b132af223e90e35b9f9efa9fe63d6ae737d34153a3b6066736086df8abc78a1f
F ext/fts3/fts3_expr.c f081e38da641724cd72c20e23b71db2bf4d0c9517c14637442f6910259f11a34
F ext/fts3/fts3_hash.c 8b6e31bfb0844c27dc6092c2620bdb1fca17ed613072db057d96952c6bdb48b7
F ext/fts3/fts3_hash.h 39cf6874dc239d6b4e30479b1975fe5b22a3caaf
F ext/fts3/fts3_icu.c 305ce7fb6036484085b5556a9c8e62acdc7763f0f4cdf5fd538212a9f3720116
F ext/fts3/fts3_porter.c 3565faf04b626cddf85f03825e86056a4562c009
F ext/fts3/fts3_snippet.c 052b35ad746349ffb53820379bacdb23ff3ac60d3cc13d986e56d42822ef5a9a
F ext/fts3/fts3_snippet.c 86e7e947a176f0f005720b3ca17631aca2fd2f9daa6729d4adbf2d16ab1b9613
F ext/fts3/fts3_term.c f45a1e7c6ef464abb1231245d123dae12266b69e05cc56e14045b76591ae92d1
F ext/fts3/fts3_test.c 73b16e229e517c1b1f0fb8e1046182a4e5dbc8dbe6eea8a5d4353fcce7dbbf39
F ext/fts3/fts3_tokenize_vtab.c cb792f59212f7799bf2891c7d4579bbf568f124ce8fbb0a9902aa5bd577e8b75
@@ -100,7 +100,7 @@ F ext/fts3/fts3_tokenizer.h 64c6ef6c5272c51ebe60fc607a896e84288fcbc3
F ext/fts3/fts3_tokenizer1.c 5c98225a53705e5ee34824087478cf477bdb7004
F ext/fts3/fts3_unicode.c 4b9af6151c29b35ed09574937083cece7c31e911f69615e168a39677569b684d
F ext/fts3/fts3_unicode2.c 416eb7e1e81142703520d284b768ca2751d40e31fa912cae24ba74860532bf0f
F ext/fts3/fts3_write.c ddf34315b6c3dce79a28d966981cc76919b18f645d82c6132133a7c65b8ed283
F ext/fts3/fts3_write.c ed869b24d074f2498bdbef915d6db1f88c604ca5811502112061932a0bed5133
F ext/fts3/fts3speed.tcl b54caf6a18d38174f1a6e84219950d85e98bb1e9
F ext/fts3/mkfts3amal.tcl 252ecb7fe6467854f2aa237bf2c390b74e71f100
F ext/fts3/tool/fts3cov.sh c331d006359456cf6f8f953e37f2b9c7d568f3863f00bb5f7eb87fea4ac01b73
@@ -230,8 +230,8 @@ F ext/fts5/tool/fts5txt2db.tcl 526a9979c963f1c54fd50976a05a502e533a4c59
F ext/fts5/tool/loadfts5.tcl 95b03429ee6b138645703c6ca192c3ac96eaf093
F ext/fts5/tool/mkfts5c.tcl d1c2a9ab8e0ec690a52316f33dd9b1d379942f45
F ext/fts5/tool/showfts5.tcl d54da0e067306663e2d5d523965ca487698e722c
F ext/icu/README.txt a295e91db742b153e8dce8f7efd31d28ad1eea4df31ef4daa3eedc85be2f5138
F ext/icu/icu.c 7adfe8a72dd4f54b47684dc9b88523399c6ef119d733b73e17371445f7428dd1
F ext/icu/README.txt 1c48ffaf7f255bd73d00a35f68f6de357c2a6594f16cb00506a151be23694706
F ext/icu/icu.c 91c021c7e3e8bbba286960810fa303295c622e323567b2e6def4ce58e4466e60
F ext/icu/sqliteicu.h 728867a802baa5a96de7495e9689a8e01715ef37
F ext/lsm1/Makefile a553b728bba6c11201b795188c5708915cc4290f02b7df6ba7e8c4c943fd5cd9
F ext/lsm1/Makefile.msc f8c878b467232226de288da320e1ac71c131f5ec91e08b21f502303347260013
@@ -285,6 +285,7 @@ F ext/misc/appendvfs.c 3777f22ec1057dc4e5fd89f2fbddcc7a29fbeef1ad038c736c54411bb
F ext/misc/blobio.c a867c4c4617f6ec223a307ebfe0eabb45e0992f74dd47722b96f3e631c0edb2a
F ext/misc/btreeinfo.c 26004b7a6be320ec08fc20ca8d0f01fccb00a98cbe0f3197446794ff2a506aa3
F ext/misc/carray.c 91e9a7f512fda934894bed30464552fffa7d3073b5be04189ae0bd0c59f26bfd
F ext/misc/cksumvfs.c b0d07f2e1bb08f8b6f311f4e454360b6a7f0021912c326428d74900020f29c31
F ext/misc/closure.c dbfd8543b2a017ae6b1a5843986b22ddf99ff126ec9634a2f4047cd14c85c243
F ext/misc/completion.c a0efe03edfdc4f717c61e6c9b0bfe2708ff7878010dae3174980a68fdf76aabc
F ext/misc/compress.c 3354c77a7c8e86e07d849916000cdac451ed96500bfb5bd83b20eb61eee012c9
@@ -293,11 +294,11 @@ F ext/misc/dbdata.c e316fba936571584e55abd5b974a32a191727a6b746053a0c9d439bd2cf9
F ext/misc/dbdump.c baf6e37447c9d6968417b1cd34cbedb0b0ab3f91b5329501d8a8d5be3287c336
F ext/misc/eval.c 04bc9aada78c888394204b4ed996ab834b99726fb59603b0ee3ed6e049755dc1
F ext/misc/explain.c d5c12962d79913ef774b297006872af1fccda388f61a11d37758f9179a09551f
F ext/misc/fileio.c bfa11a207da4eed8e5f84a1e3954608492f25f8850f9f00d0d2076f4648d7608
F ext/misc/fileio.c 9b69e25da3b51d4a1d905a464ccb96709792ad627a742ba09215bc0d1447e7bd
F ext/misc/fossildelta.c 1240b2d3e52eab1d50c160c7fe1902a9bd210e052dc209200a750bbf885402d5
F ext/misc/fuzzer.c eae560134f66333e9e1ca4c8ffea75df42056e2ce8456734565dbe1c2a92bf3d
F ext/misc/ieee754.c eaffd9b364d7c8371727e9c43fc8bec38cdacc4d11fc26beffaa3ca05a0ea9d6
F ext/misc/json1.c 2d44e3fa37f958b42cbcd41651f9f0a0eaaf3bac3f1f4b8eb456431623cb3bd8
F ext/misc/json1.c 3a42e3231d716516a8ae33b0a052d3ed5f52943e3d627b68744a427a6e552ae3
F ext/misc/memstat.c 3017a0832c645c0f8c773435620d663855f04690172316bd127270d1a7523d4d
F ext/misc/memtrace.c 7c0d115d2ef716ad0ba632c91e05bd119cb16c1aedf3bec9f06196ead2d5537b
F ext/misc/memvfs.c ab36f49e02ebcdf85a1e08dc4d8599ea8f343e073ac9e0bca18a98b7e1ec9567
@@ -316,15 +317,16 @@ F ext/misc/sha1.c c8f2253c8792ffab9517695ea7d88c079f0395a5505eefef5c8198fe184ed5
F ext/misc/shathree.c 135b7c145db4a09b1650c3e7aff9cb538763a9a361e834c015dd1aaf8d5c9a00
F ext/misc/showauth.c 732578f0fe4ce42d577e1c86dc89dd14a006ab52
F ext/misc/spellfix.c 94df9bbfa514a563c1484f684a2df3d128a2f7209a84ca3ca100c68a0163e29f
F ext/misc/sqlar.c c9e5d58544e1506135806a1e0f525f92d4bb6bb125348dce469d778fb334fbce
F ext/misc/stmt.c 8a8dc4675042e4551e4afe99b8d0cc7a4a2fc1a8dacc0a9ce1b1bbff145da93d
F ext/misc/sqlar.c 0ace5d3c10fe736dc584bf1159a36b8e2e60fab309d310cd8a0eecd9036621b6
F ext/misc/stmt.c 35063044a388ead95557e4b84b89c1b93accc2f1c6ddea3f9710e8486a7af94a
F ext/misc/templatevtab.c 8a16a91a5ceaccfcbd6aaaa56d46828806e460dd194965b3f77bf38f14b942c4
F ext/misc/totype.c fa4aedeb07f66169005dffa8de3b0a2b621779fd44f85c103228a42afa71853b
F ext/misc/uint.c 053fed3bce2e89583afcd4bf804d75d659879bbcedac74d0fa9ed548839a030b
F ext/misc/unionvtab.c 36237f0607ca954ac13a4a0e2d2ac40c33bc6e032a5f55f431713061ef1625f9
F ext/misc/urifuncs.c f71360d14fa9e7626b563f1f781c6148109462741c5235ac63ae0f8917b9c751
F ext/misc/uuid.c 5bb2264c1b64d163efa46509544fd7500cb8769cb7c16dd52052da8d961505cf
F ext/misc/vfslog.c 3b25c2f56ba60788db247287be6ab024b53c4afffd412b4876db563389be0d35
F ext/misc/vfsstat.c 77b5b4235c9f7f11eddf82487c0a422944ac2f132dafd5af3be7a68a057b1cdb
F ext/misc/vfsstat.c 389ea13983d3af926504c314f06a83cc858d5adc24b40af74aaed1fece00c118
F ext/misc/vtablog.c 5538acd0c8ddaae372331bee11608d76973436b77d6a91e8635cfc9432fba5ae
F ext/misc/vtshim.c 1976e6dd68dd0d64508c91a6dfab8e75f8aaf6cd
F ext/misc/wholenumber.c 520f34c3099e5b7d546f13708607dc2fa173c46b68952eecf0d19cd675fec85e
@@ -453,7 +455,7 @@ F ext/userauth/userauth.c 7f00cded7dcaa5d47f54539b290a43d2e59f4b1eb5f447545fa865
F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x
F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8
F magic.txt 8273bf49ba3b0c8559cb2774495390c31fd61c60
F main.mk 7ce055f3df31a4f7d21e38f493f907c21db1f673863a573e231f55e2ab005023
F main.mk addd0a300e90ad090dc4a934df8a6f1b6c52c057a1aebb93682aed29fb68a345
F mkso.sh fd21c06b063bb16a5d25deea1752c2da6ac3ed83
F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271
F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504
@@ -465,44 +467,44 @@ F spec.template 86a4a43b99ebb3e75e6b9a735d5fd293a24e90ca
F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b
F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786
F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a
F src/alter.c f48a4423c8f198d7f1ae4940f74b606707d05384ac79fb219be8e3323af2a2de
F src/analyze.c 831bb090988477a00d3b4c000746e1b0454dcc93b10b793e6ebe1c47f25d193a
F src/attach.c fa5addce233a2bb2dfdefeee3b37000e154c47214d3269cab1bb331416e330db
F src/alter.c 826bc4561456094cf758f095776026f25892a2bb3a7cd86742323267dc9bdb5f
F src/analyze.c 953a6c43870ccaf080597244e1eeb4dc2ff6cb84f9501b24e46323de36970b61
F src/attach.c ff2daea0fe62080192e3f262670e4f61f5a86c1e7bea9cec34e960fe79852aa1
F src/auth.c a3d5bfdba83d25abed1013a8c7a5f204e2e29b0c25242a56bc02bb0c07bf1e06
F src/backup.c 5e617c087f1c2d6005c2ec694ce80d6e16bc68d906e1b1c556d7c7c2228b636b
F src/backup.c b1c90cd4110248c8e1273ff4578d3a84c0c34725e1b96dacd4a6294a908702de
F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33
F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6
F src/btree.c 7271a120a66dfd12edcee942443fcd7b3860514a5621cb26a374781af1462117
F src/btree.h 6111552f19ed7a40f029cf4b33badc6fef9880314fffd80a945f0b7f43ab7471
F src/btreeInt.h dee1a1d0c621524e006bb260bd6b66d5d1867da6fe38cba9ad7b6a9bb9c0c175
F src/build.c 406645db37154920075d90a4ea3c47f33d5f5b6e0769010a54ea8247ee433c1a
F src/btree.c f14e415fcfd0b52b4e4ebd193ba5fadac5e8252c30f023389af682813af44025
F src/btree.h 989ef3c33413549e3e148f3dcb46c030f317dac130dc86809ba6b9aa4b16c72a
F src/btreeInt.h 5c8b8749805787313ecf49eb5be3ced1e94bbf8ef54bb01470ce6bd0d5185c67
F src/build.c ca9e7a33b74f1bf2eb3a5f37f9d07dfed335469f2d70c0bd350e0dd42a50183a
F src/callback.c d0b853dd413255d2e337b34545e54d888ea02f20da5ad0e63585b389624c4a6c
F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e
F src/ctime.c 6a77ec9e0eb87aea929e002c816298907e337094a7b556898ae2d1e6be209f90
F src/date.c 6c408fdd2e9ddf6e8431aba76315a2d061bea2cec8fbb75e25d7c1ba08274712
F src/ctime.c e98518d2d3d4029a13c805e07313fb60c877be56db76e90dd5f3af73085d0ce6
F src/date.c b29b349d277e3d579dcc295b24c0a2caed83fd8f090a9f7cbe6070c0fd662384
F src/dbpage.c 8a01e865bf8bc6d7b1844b4314443a6436c07c3efe1d488ed89e81719047833a
F src/dbstat.c 0f55297469d4244ab7df395849e1af98eb5e95816af7c661e7d2d8402dea23da
F src/delete.c 11000121c4281c0bce4e41db29addfaea0038eaa127ece02557c9207bc3e541d
F src/expr.c ed718ee2206166c9c2fc4fe89eadb1f369318aeb8645e06033566b387970fb9a
F src/dbstat.c 793deaf88a0904f88285d93d6713c636d55ede0ffd9f08d10f4ea825531d367f
F src/delete.c 88047c8e59878c920fce14582bc1dde4d81157d1ca5ffdf36c2907e6d41996c4
F src/expr.c b46669d9fc9e0361dba6cc289901a013789e0b1dc629c4c1bc88ec9403633b38
F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007
F src/fkey.c 4b575423b0a5d4898b1a7868ce985cf1a8ad91c741c9abbb108ff02536d20f41
F src/func.c 108577cebe8a50c86d849a93b99493a54e348dd0b846f00d13b52ca973d5baf4
F src/func.c 2333eb4277f55a5efdc12ef754e7d7ec9105d257b2fd00301d23ce1e8fa67dc0
F src/global.c 79a988b56b06ce2d08ebefe1d35da9aa25b3851faa47ea5233361c4827185a64
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 8e4211d04eb460c0694d486c6ba1c068d468c6f653c3f237869a802ad82854de
F src/insert.c 92b07a7f7e682114948ce59fd6511ffec7672b508cc343a804ef6afee21b6c11
F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa
F src/loadext.c b179df50e6e8bb0c36c149e95d958d49bd8c6c7469e59c01b53d164360bc6c32
F src/main.c b11eec03807a038b4075d310936dc33ce597078ab78c35dacdf5f05446ed53de
F src/malloc.c eaa4dc9602ce28b077f7de2eb275db2be270c5cc56d7fec5466301bd9b80e2f5
F src/loadext.c 421310045bd78afefb772294a99e50f37d87ae578786a6169074e6291e30d969
F src/main.c 97d962ab1f830540043042e41085c5b85636a60e6ed95002c1a56b64f7eb6a0b
F src/malloc.c d0400b0366e1a3a2414ca4534b4a7406df34732835f37a15cb4642eb7df1a363
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
F src/mem1.c c12a42539b1ba105e3707d0e628ad70e611040d8f5e38cf942cee30c867083de
F src/mem2.c f1940d9e91948dd6a908fbb9ce3835c36b5d83c3
F src/mem3.c 8768ac94694f31ffaf8b4d0ea5dc08af7010a35a
F src/mem5.c 9bf955937b07f8c32541c8a9991f33ce3173d944
F src/memdb.c 02a5fcec19b9d40dd449ca802dc1b2e8f93f255fbf2a886277a3c3800d8d35db
F src/memdb.c 252137ca122acb8f54a99b48cf9f96a31d5130f19d174381a53294446d8b64a3
F src/memjournal.c 7561c01c90958f3ba9bc6cb2d857123d932bdfa5539ea34427a0957b2e35154d
F src/msvc.h 3a15918220367a8876be3fa4f2abe423a861491e84b864fb2b7426bf022a28f8
F src/mutex.c 5e3409715552348732e97b9194abe92fdfcd934cfb681df4ba0ab87ac6c18d25
@@ -515,32 +517,32 @@ F src/os.c 669cc3839cc35d20f81faf0be1ab6d4581cea35e9d8f3a9d48a98d6571f7c285
F src/os.h 48388821692e87da174ea198bf96b1b2d9d83be5dfc908f673ee21fafbe0d432
F src/os_common.h b2f4707a603e36811d9b1a13278bffd757857b85
F src/os_setup.h 0dbaea40a7d36bf311613d31342e0b99e2536586
F src/os_unix.c 238ad16109b4160d0fba2597ef71459995ab5e304b3d8bbe290a8d5d6d6000e0
F src/os_win.c 035a813cbd17f355bdcad7ab894af214a9c13a1db8aeac902365350b98cd45a7
F src/os_unix.c 13f983da988b6460ef3c4c22099c67ab0938291e543644ac4d99eccc8ba604f1
F src/os_win.c e832e21e830c1f9409c9c54053939b6dcb14c1e92128b756204ce1e3e331d678
F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a
F src/pager.c a71ffd145f55e28cbdc1bdabb5e6bef063da428a6c0de3c3a36e9a0c41d4c8c0
F src/pager.h 3b33619a90180e0874c7eca31d6f6ceb464d9322c6fb4e9a7bbb318c8a17bdb3
F src/parse.y 8575183809cf30f8c9d1fbea65ca34d1de78b659792bc7c42681e01fc596b520
F src/pager.c 96436cb1920074d4ade120a1a8a9d0ae3f52df06651e21b7eccc5eae2f02b111
F src/pager.h 8d1dc9a2c3fc5eb6eeed75f48a076f425e77706f8935f05817fa05a308f587b5
F src/parse.y c8eff38606f443d5ba245263fa7abc05e4116d95656e050c4b78e9bfbf931add
F src/pcache.c 385ff064bca69789d199a98e2169445dc16e4291fa807babd61d4890c3b34177
F src/pcache.h 4f87acd914cef5016fae3030343540d75f5b85a1877eed1a2a19b9f284248586
F src/pcache1.c 6596e10baf3d8f84cc1585d226cf1ab26564a5f5caf85a15757a281ff977d51a
F src/pragma.c 5fd004b89c77319008ddff6d65dcc83ccca9584d3048f4f66b108b5906a20dba
F src/pragma.h 9473160d220416456b40f27323bb4b316d4e4e08ffbf8bf88c5f7045d49c38e5
F src/pragma.c 1b0db48177e52b256c003b8dc6ac708b1079a82cded944a23820574586a4731f
F src/pragma.h 8168e588536bffd95319451f34e9a754dc37d205ebe433031a7813c5b286beae
F src/prepare.c 8d4d6c8aa6afefc48027c54b41cdf134b4d6bc2fc4badbe483ad7fd9e1728a28
F src/printf.c 9be6945837c839ba57837b4bc3af349eba630920fa5532aa518816defe42a7d4
F src/printf.c 94b5419ad0a17269f76a9e968ca19cf9fa37617abed2e246fc48844e511b6bc6
F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384
F src/resolve.c 38e3a5636f5bdc92e3683e4cafbba6418c0aa15e0d89ca5b28bd0b621dbb80bf
F src/resolve.c c2008519a0654f1e7490e9281ed0397d0f14bb840d81f0b96946248afcbdb25d
F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92
F src/select.c c94eec317c8ba929bc228392eb3cac8124f2d0fbe3fc1bddecb44dfc7057bc78
F src/shell.c.in f76590931c0cbbfef347f44f81ade6b335f80c46bc6e59b8b6114383a8df30e0
F src/sqlite.h.in 802957feeb249ede54f8dfe99b72aa19e70a0b7737969c46e625dc2f9f2d42b0
F src/select.c e2a59548681bf1c407132863ae87bf2444aca5543867c21d9d09aa07f44aef5d
F src/shell.c.in cf2d24f54412c06e5fb34af7fabc748651125e1dceac29b740e91f06d23447b6
F src/sqlite.h.in 74342b41e9d68ff9e56b192009046f8dd0aa2bd76ce1a588f330de614ba61de7
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
F src/sqlite3ext.h 9c5269260409eb3275324ccace6a13a96f4ad330c708415f70ca6097901ff4ee
F src/sqliteInt.h 5f74c1c52b152259ee07f241821620f11736e4f590936cfaf1cbbff9a2f563d3
F src/sqlite3ext.h 2d1af80082edffd71c6f96f70ad1ce6a4fb46615ad10291fc77fe0dea9ff0197
F src/sqliteInt.h 37f74544c8e2f59a16d1b13e6847bc02fb3fcbbfae4d6e6342c7a94c3a3984a5
F src/sqliteLimit.h 95cb8479ca459496d9c1c6a9f76b38aee12203a56ce1092fe13e50ae2454c032
F src/status.c 9ff2210207c6c3b4d9631a8241a7d45ab1b26a0e9c84cb07a9b5ce2de9a3b278
F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34
F src/tclsqlite.c d0aa320416efe88c4dbb0156ed6c494f2f9958871a940e46984ee57b3e7fcc50
F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1
F src/tclsqlite.c 986b6391f02cd9b53c1d688be55899f6ffddeb8e8014cd83c1b73ff912579a71
F src/test1.c 5e8b8cc54e8c88906ea8a084387aa79bad245e539f4cee73149e5c0527e1db16
F src/test2.c 3efb99ab7f1fc8d154933e02ae1378bac9637da5
F src/test3.c 61798bb0d38b915067a8c8e03f5a534b431181f802659a6616f9b4ff7d872644
@@ -595,33 +597,34 @@ F src/test_windirent.h 90dfbe95442c9762357fe128dc7ae3dc199d006de93eb33ba3972e0a9
F src/test_window.c cdae419fdcea5bad6dcd9368c685abdad6deb59e9fc8b84b153de513d394ba3f
F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9
F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c
F src/tokenize.c 7b17f6e2f20f6cbcb0b215025a86b7457c38451fc7622f705e553d7a488c572d
F src/treeview.c f78cd9cd79a889e70cd98bd6edd4a464c421452da833e65e987d97d8c41f71fe
F src/trigger.c a40d50e88bd3355f1d2a73f0a3b2d6b42eae26ca4219001b82ef0d064439badc
F src/update.c 3eb778c42155d944377a4ee5e440b04520f07094804ed6ce63d2528f619614d9
F src/tokenize.c eee7bae3ec0bc4abee951554bf46a8ba567c0f7752ac90c820ed8afff4c612dc
F src/treeview.c 9df54af6e5830fd527496e62ae0148e1ba33197205d8e232c2826537d42d4063
F src/trigger.c 4ada1037cc99777f647a882cdacbd1a4deb6567b69daf02946286401b88cdc04
F src/update.c 3199098455830fc2d8c8fc4ae3ec2ea513eef64339ae9a7048db62b21169bc7a
F src/upsert.c 2920de71b20f04fe25eb00b655d086f0ba60ea133c59d7fa3325c49838818e78
F src/utf.c 95fb6e03a5ca679045c5adccd05380f0addccabef5911abddcb06af069500ab7
F src/util.c a285c1e026907b69fa2592bd05047a565a1d8a1aef2b73c924b6a8ffe772871a
F src/vacuum.c 813b510ba887fee6492bcb11f2bf77d7eb58b232b83649136372e0a2fc17f4b9
F src/vdbe.c 6d0cf7ac2d54f78ff2fb55cbef970199695319c0a95bf862c6561d7d2c9f7134
F src/vdbe.h 51282fbe819ee0e8eeeaab176240860d334c20a12b14f3b363e7f1a4e05d60b9
F src/vdbeInt.h a17146053a1aa438474012998fe07e314f3df274a61491ad838ad85d848ac051
F src/vdbeapi.c 1252d80c548711e47a6d84dae88ed4e95d3fbb4e7bd0eaa1347299af7efddf02
F src/vdbeaux.c 1ca2d4b3f913ecc4759becfab72952f25493390d674714586ab356c9f06ac279
F src/utf.c d7a61c1dfdac3eb091d43341a674032dca5a34e122f78ef0b5bd2d5a31967dde
F src/util.c 3b6cedf7a0c69bd6e1acce832873952d416212d6293b18d03064e07d7a9b5118
F src/vacuum.c de9780b89fa4ee74c3534f60b94820e3179aca759ffc1338ee53cb4ea7693dd3
F src/vdbe.c e3dba0dee25bc92e871c13cac655260912b3be4abcc85b439259c9934b208da3
F src/vdbe.h 07b8c636a87df8b6e58f29d6badd7f10d5844353deff1d7c88ed1c2bfe3bbd35
F src/vdbeInt.h 571413068b5ac07e2ed8ca7a02fa529622fd5455ae6981498376e5e492d2e5ef
F src/vdbeapi.c e467b75a710ea099f8d2d022abf601d2ccd05e28f63b44b12d93000b6a75f4a8
F src/vdbeaux.c 80626786d21296d9e7936186850343afe5fc6368ad9724a172e151788425a063
F src/vdbeblob.c 253ed82894924c362a7fa3079551d3554cd1cdace39aa833da77d3bc67e7c1b1
F src/vdbemem.c 39b942ecca179f4f30a32b54579a85d74ccaefa5af2a0ad2700abe5ef0768b22
F src/vdbesort.c 2be76d26998ce2b3324cdcc9f6443728e54b6c7677c553ad909c7d7cfab587df
F src/vdbetrace.c fa3bf238002f0bbbdfb66cc8afb0cea284ff9f148d6439bc1f6f2b4c3b7143f0
F src/vtab.c 7b704a90515a239c6cdba6a66b1bb3a385e62326cceb5ecb05ec7a091d6b8515
F src/vdbevtab.c ee5b4c902fdda2230f9503ac7b84c6d614c91e8f6f4dc1633e2e8dfef8ffb144
F src/vtab.c 7b452592ed2ee95dedb1f323d557cebede5a6f3b4558b21a5dca527e6ae9b12c
F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9
F src/wal.c 697424314e40d99f93f548c7bfa526c10e87f4bdf64d5a76a96b999dd7133ebc
F src/wal.h 606292549f5a7be50b6227bd685fa76e3a4affad71bb8ac5ce4cb5c79f6a176a
F src/walker.c a137468bf36c92e64d2275caa80c83902e3a0fc59273591b96c6416d3253d05d
F src/where.c 3b8c9bd013eb0736e16f60bdc109e83337ef99513a3aff5f16ddac036e6c277e
F src/wal.c 04c3d2a673192016a671eb051a1900945a8c7331f4378636a8bfb70e8e596c84
F src/wal.h c3aa7825bfa2fe0d85bef2db94655f99870a285778baa36307c0a16da32b226a
F src/walker.c 3df26a33dc4f54e8771600fb7fdebe1ece0896c2ad68c30ab40b017aa4395049
F src/where.c 9546c82056e8cdb27291f98cf1adca5d271240b399bb97b32f77fc2bea6146c9
F src/whereInt.h 6b874aa15f94e43a2cec1080be64d955b04deeafeac90ffb5d6975c0d511be3c
F src/wherecode.c 7b939de85d65cc4b4bfa197513136b9e0ae03167e3b82842ca5a0ba1055ba65d
F src/whereexpr.c 264d58971eaf8256eb5b0917bcd7fc7a1f1109fdda183a8382308a1b18a2dce7
F src/window.c 0b824edbab94e473d0ade203645798ce80358d0c89ff6ac0ba0f7e2768543319
F src/window.c 66c5fd1e48af7581cf90b97700268294f4da4037f120f367715f912e1148d3f9
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
F test/affinity2.test ce1aafc86e110685b324e9a763eab4f2a73f737842ec3b687bd965867de90627
F test/affinity3.test 6a101af2fc945ce2912f6fe54dd646018551710d
@@ -629,17 +632,17 @@ F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
F test/aggnested.test 12106f0748e8e9bfc1a8e6840e203e051eae06a26ed13fc9fd5db108a8d6db54
F test/alias.test 4529fbc152f190268a15f9384a5651bbbabc9d87
F test/all.test 2ecb8bbd52416642e41c9081182a8df05d42c75637afd4488aace78cc4b69e13
F test/alter.test 77f0092d137dd9470fc683b64ed92868e188462e713e52f48deae8902ea60b96
F test/alter.test 25e109787dc5e631e117eb6e1c57f96a572bb51228db3b4f8b5f41d665e2ccaa
F test/alter2.test a966ccfcddf9ce0a4e0e6ff1aca9e6e7948e0e242cd7e43fc091948521807687
F test/alter3.test 9351a9f0c59ff9dddecccaaa2f777ffee5369870c63d30d3a74add815254ec0f
F test/alter4.test 74b22251c5e9c48093cfc4921ed9c11b59df84634aeeb00e501773320beb8424
F test/alter3.test e487958dec7932453e0b83baf21d6b1e71d5e7d9a55bc20eadfa62a51ddffc29
F test/alter4.test dfd6086faf461b27ca2d2999848dcd207edf23352fc1592d0005c0844f3f08cf
F test/alterauth.test 63442ba61ceb0c1eeb63aac1f4f5cebfa509d352276059d27106ae256bafc959
F test/alterauth2.test c0a1ddf5b93d93cb0d15ba7acaf0c5c6fb515bbe861ede75b2d3fabad33b6499
F test/altercol.test 1d6a6fe698b81e626baea4881f5717f9bc53d7d07f1cd23ee7ad1b931f117ddf
F test/alterlegacy.test 82022721ce0de29cedc9a7af63bc9fcc078b0ee000f8283b4b6ea9c3eab2f44b
F test/altermalloc.test 167a47de41b5c638f5f5c6efb59784002b196fff70f98d9b4ed3cd74a3fb80c9
F test/altermalloc2.test fa7b1c1139ea39b8dec407cf1feb032ca8e0076bd429574969b619175ad0174b
F test/altertab.test 89735fee876427c3f25dc76d887295fbe3659a91bab92468de9f0e622d48bb57
F test/altertab.test 523ba6368e0da19f462f7c05563c569675736d946724cac1c4ae848f76783434
F test/altertab2.test b0d62f323ca5dab42b0bc028c52e310ebdd13e655e8fac070fe622bad7852c2b
F test/altertab3.test 155b8dc225ce484454a7fb4c8ba745680b6fa0fc3e08919cbbc19f9309d128ff
F test/amatch1.test b5ae7065f042b7f4c1c922933f4700add50cdb9f
@@ -666,7 +669,7 @@ F test/atof1.test 1ccfc96a6888566597b83d882c81b3c04258dc39317e8c1cec89ba481eaa2f
F test/atomic.test 065a453dde33c77ff586d91ccaa6ed419829d492dbb1a5694b8a09f3f9d7d061
F test/atomic2.test b6863b4aa552543874f80b42fb3063f1c8c2e3d8e56b6562f00a3cc347b5c1da
F test/atrc.c ec92d56d8fbed9eb3e11aaf1ab98cf7dd59e69dae31f128013f1d97e54e7dfed
F test/attach.test 21bce8681f780a8d631a5ec7ecd0d849bfe84611257b038ae4ffeccc609d8a4e
F test/attach.test d42862c72fef3d54367d962d41dcfb5363442a4a1bd898c22ae950cea1aa0dd3
F test/attach2.test 256bd240da1835fb8408dd59fb7ef71f8358c7a756c46662434d11d07ba3a0ce
F test/attach3.test c59d92791070c59272e00183b7353eeb94915976
F test/attach4.test aa05b1d8218b24eba5a7cccf4f224f514ba57ba705c9267f09d2bb63fed0eea1
@@ -780,7 +783,7 @@ F test/corruptK.test 5b4212fe346699831c5ad559a62c54e11c0611bdde1ea8423a091f9c01a
F test/corruptL.test 13ef74a93223af25015d223add0df4c2d375f0b958b546a2a72033f2fdab7a70
F test/corruptM.test 7d574320e08c1b36caa3e47262061f186367d593a7e305d35f15289cc2c3e067
F test/cost.test 51f4fcaae6e78ad5a57096831259ed6c760e2ac6876836e91c00030fad385b34
F test/count.test cb2e0f934c6eb33670044520748d2ecccd46259c
F test/count.test e0699a15712bc2a4679d60e408921c2cce7f6365a30340e790c98e0f334a9c77
F test/countofview.test e17d6e6688cf74f22783c9ec6e788c0790ee4fbbaee713affd00b1ac0bb39b86
F test/coveridxscan.test 5ec98719a2e2914e8908dc75f7247d9b54a26df04625f846ac7900d5483f7296
F test/crash.test fb9dc4a02dcba30d4aa5c2c226f98b220b2b959f
@@ -794,10 +797,10 @@ F test/crash8.test 64366e459c28dd62edfb7ad87253a409c7533b92d16fcc479a6a8131bdcc3
F test/crashM.test d95f59046fa749b0d0822edf18a717788c8f318d
F test/crashtest1.c 09c1c7d728ccf4feb9e481671e29dda5669bbcc2
F test/createtab.test 85cdfdae5c3de331cd888d6c66e1aba575b47c2e3c3cc4a1d6f54140699f5165
F test/cse.test 277350a26264495e86b1785f34d2d0c8600e021c
F test/cse.test 00b3aea44b16828833c94fbe92475fd6977583fcb064ae0bc590986812b38d0c
F test/csv01.test c9c3af0d58c34e9ac970c5875a77939edb958762c8aafb95409e19a3f088b6cd
F test/ctime.test 78749e6c9a5f0010d67985be80788f841e3cd2da18114e2ed6010399a7d807f3
F test/cursorhint.test 7bc346788390475e77a345da2b92270d04d35856
F test/cursorhint.test 0175e4404181ace3ceca8b114eb0a98eae600d565aa4e2705abbe6614c7fe201
F test/cursorhint2.test 6f3aa9cb19e7418967a10ec6905209bcbb5968054da855fc36c8beee9ae9c42f
F test/dataversion1.test 6e5e86ac681f0782e766ebcb56c019ae001522d114e0e111e5ebf68ccf2a7bb8
F test/date.test 9b73bbeb1b82d9c1f44dec5cf563bf7da58d2373
@@ -820,7 +823,7 @@ F test/descidx1.test edc8adee58d491b06c7157c50364eaf1c3605c9c19f8093cb1ea2b6184f
F test/descidx2.test a0ba347037ff3b811f4c6ceca5fd0f9d5d72e74e59f2d9de346a9d2f6ad78298
F test/descidx3.test 953c831df7ea219c73826dfbf2f6ee02d95040725aa88ccb4fa43d1a1999b926
F test/diskfull.test 106391384780753ea6896b7b4f005d10e9866b6e
F test/distinct.test 8b6c652f0b2d477f0830884736f2a1cd2e8f7fc10a04aa6d571a401fa13ed88b
F test/distinct.test e7d0cf371944dd0cbedff86420744e2f1ea2b528156451c97eb6ff41a99b9236
F test/distinct2.test 11b0594c932098e969d084ba45ab81d5040f4d4e766db65d49146705a305ed98
F test/distinctagg.test 1a6ef9c87a58669438fc771450d7a72577417376
F test/e_blobbytes.test 439a945953b35cb6948a552edaec4dc31fd70a05
@@ -828,12 +831,12 @@ 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 1c602347e73ab80b11b9fa083f47155861aaafcff8054aac9e0b76d0df33b0a7
F test/e_createtable.test ea27082d6f84df61e1d9e383f3fd79220418856a4a8afc41af75d458b8e7ac33
F test/e_delete.test ab39084f26ae1f033c940b70ebdbbd523dc4962e
F test/e_droptrigger.test 3cd080807622c13e5bbb61fc9a57bd7754da2412
F test/e_dropview.test 21ce09c361227ddbc9819a5608ee2700c276bdd5
F test/e_expr.test 328d2d7c84f8e53e942a13eac771b337bcdfcf4c3569324001868b5639f3c857
F test/e_fkey.test 2febb2084aef9b0186782421c07bc9d377abf067c9cb4efd49d9647ae31f5afe
F test/e_dropview.test 74e405df7fa0f762e0c9445b166fe03955856532e2bb234c372f7c51228d75e7
F test/e_expr.test 62000e6675d5bcf4b09276fe011a27779629ff8f6678ba5937fb6f1b78d645ff
F test/e_fkey.test b497feb7c436693e16a36cdaba8d81ffe12f23659d139ee71dfa57c0c52d1e5b
F test/e_fts3.test 17ba7c373aba4d4f5696ba147ee23fd1a1ef70782af050e03e262ca187c5ee07
F test/e_insert.test f02f7f17852b2163732c6611d193f84fc67bc641fb4882c77a464076e5eba80e
F test/e_reindex.test 2b0e29344497d9a8a999453a003cb476b6b1d2eef2d6c120f83c2d3a429f3164
@@ -872,7 +875,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 65c86b11127c11f80c0f450b3480321e0f087edea3031b9daa1978e3c020c91b
F test/fkey2.test b1b6a8c5556dc0ccf31291b1fed8aa57e404b38f3236110e19ab4dc6aa93edf2
F test/fkey3.test 76d475c80b84ee7a5d062e56ccb6ea68882e2b49
F test/fkey4.test 86446017011273aad8f9a99c1a65019e7bd9ca9d
F test/fkey5.test 24dd28eb3d9f1b5a174f47e9899ace5facb08373a4223593c8c631e6cf9f7d5a
@@ -880,7 +883,7 @@ F test/fkey6.test d078a1e323a740062bed38df32b8a736fd320dc0
F test/fkey7.test 64fb28da03da5dfe3cdef5967aa7e832c2507bf7fb8f0780cacbca1f2338d031
F test/fkey8.test 48ef829d63f5f7b37aabd4df9363ac05f65539d1da8c4a44251631769d920579
F test/fkey_malloc.test 594a7ea1fbab553c036c70813cd8bd9407d63749
F test/fordelete.test eb93a2f34137bb87bdab88fcab06c0bd92719aff
F test/fordelete.test ba98f14446b310f9c9d935b97ec748753d0144a28b356ba30d1f4f6958fdde5c
F test/format4.test eeae341953db8b6bda7f549044797c3278a6cc345d11ada81471671b654f8ef4
F test/fts-9fd058691.test 78b887e30ae6816df0e1fed6259de4b5a64ad33c
F test/fts1a.test 46090311f85da51bb33bd5ce84f7948359c6d8d7
@@ -945,7 +948,7 @@ F test/fts3conf.test c84bbaec81281c1788aa545ac6e78a6bd6cde2bdbbce2da261690e3659f
F test/fts3corrupt.test 79a32ffdcd5254e2f7fa121d9656e61949ad049c3c6554229911b7ceac37c9c6
F test/fts3corrupt2.test bf55c3fa0b0dc8ea1c0fe5543623bd27714585da6a129038fd6999fe3b0d25f3
F test/fts3corrupt3.test 0d5b69a0998b4adf868cc301fc78f3d0707745f1d984ce044c205cdb764b491f
F test/fts3corrupt4.test e8ad49403179cbf714b6b669d2e0f9234ae95f4ca258a253b0f29ce28c1b027c
F test/fts3corrupt4.test fde292a4712753c7ef235a199273c5d196e18a56bd2c4d2db7ccaf59b7027a0a
F test/fts3corrupt5.test 0549f85ec4bd22e992f645f13c59b99d652f2f5e643dac75568bfd23a6db7ed5
F test/fts3cov.test 7eacdbefd756cfa4dc2241974e3db2834e9b372ca215880e00032222f32194cf
F test/fts3d.test 2bd8c97bcb9975f2334147173b4872505b6a41359a4f9068960a36afe07a679f
@@ -966,7 +969,8 @@ F test/fts3fuzz001.test e3c7b0ce9b04cc02281dcc96812a277f02df03cd7dc082055d87e11e
F test/fts3join.test 949b4f5ae3ae9cc2423cb865d711e32476bdb205ab2be923fdf48246e4a44166
F test/fts3malloc.test b0e4c133b8d61d4f6d112d8110f8320e9e453ef6
F test/fts3matchinfo.test aa66cc50615578b30f6df9984819ae5b702511cf8a94251ec7c594096a703a4a
F test/fts3misc.test c47d2c1ea1351c51c32c688545b02c8180a3f22156d1aedc206a8c09b9d95905
F test/fts3matchinfo2.test 00144e841704b8debfcdf6097969cd9f2a1cf759e2203cda42583648f2e6bf58
F test/fts3misc.test 9ec15e7c0b5831a6353bd4c46bf3acdf1360eda5d9f396f667db4d05bcf92ecf
F test/fts3near.test 7e3354d46f155a822b59c0e957fd2a70c1d7e905
F test/fts3offsets.test b85fd382abdc78ebce721d8117bd552dfb75094c
F test/fts3prefix.test fa794eaab0bdae466494947b0b153d7844478ab2
@@ -975,12 +979,13 @@ F test/fts3query.test ca033ff2ebcc22c69d89032fb0bc1850997d31e7e60ecd26440796ba16
F test/fts3rank.test cd99bc83a3c923c8d52afd90d86979cf05fc41849f892faeac3988055ef37b99
F test/fts3rnd.test 1320d8826a845e38a96e769562bf83d7a92a15d0
F test/fts3shared.test 57e26a801f21027b7530da77db54286a6fe4997e
F test/fts3snippet.test d9b9f4b717584040fb56df1dacab53acd474958e9c1d00b073d10726695cea0c
F test/fts3snippet.test 0887196d67cffbe365edde535b95ecc642a532ce8551ccd9a73aab5999c3ffae
F test/fts3snippet2.test 2dabb5889eda4c9980aad325e688b470781f97ce7c0fca0db125616fae0a2cdd
F test/fts3sort.test ed34c716a11cc2009a35210e84ad5f9c102362ca
F test/fts3tok1.test a663f4cac22a9505400bc22aacb818d7055240409c28729669ea7d4cc2120d15
F test/fts3tok_err.test 52273cd193b9036282f7bacb43da78c6be87418d
F test/fts3varint.test 0b84a3fd4eba8a39f3687523804d18f3b322e6d4539a55bf342079c3614f2ada
F test/fts4aa.test 9857f939f5aeb6cc4c143e74cf1cfe07ac87972240ac26d3a0100e36d02f4359
F test/fts4aa.test 0e6bfd6a81695a39b23e448dda25d864e63dda75bde6949c45ddc95426c6c3f5
F test/fts4check.test 6259f856604445d7b684c9b306b2efb6346834c3f50e8fc4a59a2ca6d5319ad0
F test/fts4content.test 73bbb123420d2c46ef2fb3b24761e9acdb78b0877179d3a5d7d57aada08066f6
F test/fts4docid.test e33c383cfbdff0284685604d256f347a18fdbf01
@@ -1016,7 +1021,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 cdd94f1710957b8b907019b25c6cf4f7b63815a08b19021e8b215bc2419bb7f9
F test/fuzzcheck.c 656ee850f331872a784e7d6a10649efe2af123bdaacb728b5a03e4faee8b959c
F test/fuzzdata1.db d36e88741b4f23bcbaaf55b006290669d03c6c891cf13c7b3a53bc1b097b693f
F test/fuzzdata2.db 128b3feeb78918d075c9b14b48610145a0dd4c8d6f1ca7c2870c7e425f5bf31f
F test/fuzzdata3.db c6586d3e3cef0fbc18108f9bb649aa77bfc38aba
@@ -1024,7 +1029,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 00cd360c354083d69572e82e1da9f582a2ed60760baf9c04558ebadd885d390b
F test/fuzzdata8.db 209623791b0ad72ab39110c867af2080a79004e493c4da14ad661e790b5d1ed8
F test/fuzzer1.test 3d4c4b7e547aba5e5511a2991e3e3d07166cfbb8
F test/fuzzer2.test a85ef814ce071293bce1ad8dffa217cbbaad4c14
F test/fuzzerfault.test 8792cd77fd5bce765b05d0c8e01b9edcf8af8536
@@ -1036,7 +1041,7 @@ F test/hexlit.test 4a6a5f46e3c65c4bf1fa06f5dd5a9507a5627751
F test/hidden.test 23c1393a79e846d68fd902d72c85d5e5dcf98711
F test/hook.test 1604b3b2f5931430087540404555c1b6be3618600b81558657c66b533ed70b13
F test/hook2.test b9ff3b8c6519fb67f33192f1afe86e7782ee4ac8
F test/icu.test 41aa8847745a879b897a7febea0f8f9efc8e67fe8bf680589b6e07c7b0a1569a
F test/icu.test 716a6b89fbabe5cc63e0cd4c260befb08fd7b9d761f04d43669233292f0753b1
F test/ieee754.test 806fc0ce7f305f57e3331eaceeddcfec9339e607
F test/imposter1.test c3f1db2d3db2c24611a6596a3fc0ffc14f1466c8
F test/in.test ae4ba0fe3232fdd84ef1090a68c5cd6ccd93f1f8774d5c967dd0c1b301492eed
@@ -1044,7 +1049,7 @@ F test/in2.test 5d4c61d17493c832f7d2d32bef785119e87bde75
F test/in3.test 3cbf58c87f4052cee3a58b37b6389777505aa0c0
F test/in4.test 65460600d48933adba4283c6ebd089aae173d16136ab9d01f74c89089090c5a5
F test/in5.test b32ce7f4a93f44c5dee94af16886d922cc16ebe33c8e1765c73d4049d0f4b40f
F test/in6.test 62d943a02f722948f4410ee0b53c3cb39acd7c41afb083df8d7004238fe90a20
F test/in6.test 8562d0945195cab3cc4ab3794e9118e72cb44c43f785c2b04d48a9d06ca6b4ec
F test/incrblob.test c9b96afc292aeff43d6687bcb09b0280aa599822
F test/incrblob2.test a494c9e848560039a23974b9119cfc2cf3ad3bd15cc2694ee6367ae537ef8f1f
F test/incrblob3.test d8d036fde015d4a159cd3cbae9d29003b37227a4
@@ -1092,7 +1097,7 @@ F test/ioerr5.test 2edfa4fb0f896f733071303b42224df8bedd9da4
F test/ioerr6.test a395a6ab144b26a9e3e21059a1ab6a7149cca65b
F test/istrue.test 75327829744e65cc8700e69340b8e6c192e10e39dfae7ccb0e970d3c4f49090a
F test/join.test bca044589e94bb466e4c1e91fb6fecdc3f3326ca6b3f590f555f1958156eb321
F test/join2.test 659bc6193f5c3fe20fa444dd2c91713db8c33e376b098b860644e175e87b8dbc
F test/join2.test 7d24d095ab88d3910228d53a3b548b7baf2e0e7d8aac6731a273e300e1b34b61
F test/join3.test 6f0c774ff1ba0489e6c88a3e77b9d3528fb4fda0
F test/join4.test 1a352e4e267114444c29266ce79e941af5885916
F test/join5.test 3a96dc62f0b45402d7207e22d1993fe0c2fce1c57644a11439891dd62b990eb7
@@ -1113,9 +1118,9 @@ F test/kvtest.c 94da54bb66aae7a54e47cf7e4ea4acecc0f217560f79ad3abfcc0361d6d557ba
F test/lastinsert.test 42e948fd6442f07d60acbd15d33fb86473e0ef63
F test/laststmtchanges.test ae613f53819206b3222771828d024154d51db200
F test/lemon-test01.y 58b764610fd934e189ffbb0bbfa33d171b9cb06019b55bdc04d090d6767e11d7
F test/like.test 3d702d79bf871fa32985b1ce334294c587e3948d3ab972001e811a58577e8b3c
F test/like.test 47b81d5de2ff19d996d49a65d50ec9754246aacbe0e950b48d186d9d8171eaf0
F test/like2.test 3b2ee13149ba4a8a60b59756f4e5d345573852da
F test/like3.test 4f940ad275c006319950054a7a65661f476772171b82b6fdf795e4dda36f246f
F test/like3.test 03d1bdf848483b78d2cfd1db283d75c4ec2e37c8b8eccc006813f3978d78fbbd
F test/limit.test 0c99a27a87b14c646a9d583c7c89fd06c352663e
F test/limit2.test 9409b033284642a859fafc95f29a5a6a557bd57c1f0d7c3f554bd64ed69df77e
F test/loadext.test faa4f6eed07a5aac35d57fdd7bc07f8fc82464cfd327567c10cf0ba3c86cde04
@@ -1173,7 +1178,7 @@ F test/misc4.test 10cd6addb2fa9093df4751a1b92b50440175dd5468a6ec84d0386e78f087db
F test/misc5.test c4aeaa0fa28faa08f2485309c38db4719e6cd1364215d5687a5b96d340a3fa58
F test/misc6.test 953cc693924d88e6117aeba16f46f0bf5abede91
F test/misc7.test 4f21954012e4eb0a923c54a311f38c81bf6798ccdd7b51584db46d4007f63daa
F test/misc8.test 8fb0f31d7a8aed484d759773ab8ad12ec746a477f4a67394a4af0e677494c3ca
F test/misc8.test 8782708f4c8a459591c3e8fe1215bd2048bffb4024b3df249e9b9ed407dc61ed
F test/misuse.test 9e7f78402005e833af71dcab32d048003869eca5abcaccc985d4f8dc1d86bcc7
F test/mjournal.test 28a08d5cb5fb5b5702a46e19176e45e964e0800d1f894677169e79f34030e152
F test/mmap1.test fb04e0c10492455007624ade884ca0c8852ff3e4e11d95408f9709ca2ef7f626
@@ -1232,7 +1237,7 @@ F test/parser1.test 6ccdf5e459a5dc4673d3273dc311a7e9742ca952dd0551a6a6320d27035c
F test/pcache.test c8acbedd3b6fd0f9a7ca887a83b11d24a007972b
F test/pcache2.test af7f3deb1a819f77a6d0d81534e97d1cf62cd442
F test/percentile.test 4243af26b8f3f4555abe166f723715a1f74c77ff
F test/permutations.test 8587800fe1a0eb01456a3f4500b821e54e3347e78acf11dbf05f4990530f6cee
F test/permutations.test c83339862d72b6272f957905205f874e6eefdbad2823380452c4f0128fd3d906
F test/pg_common.tcl 222a1bad1c41c308fa366313cd7b51b3be7e9b21c8736a421b974ac941693b54
F test/pragma.test 59becdfd720b80d463ab750f69f7118fde10dfd556aa5d554f3bf6b7e5ea7533
F test/pragma2.test e5d5c176360c321344249354c0c16aec46214c9f
@@ -1241,7 +1246,7 @@ F test/pragma4.test 10c624e45a83c0096a82a7579a5ff658542391d3b77355192da6572c8c17
F test/pragma5.test 7b33fc43e2e41abf17f35fb73f71b49671a380ea92a6c94b6ce530a25f8d9102
F test/pragmafault.test 275edaf3161771d37de60e5c2b412627ac94cef11739236bec12ed1258b240f8
F test/prefixes.test b524a1c44bffec225b9aec98bd728480352aa8532ac4c15771fb85e8beef65d9
F test/printf.test 0300699733e53101b2ce48800518427249edd4053bb50fa0621c6607482f0fdb
F test/printf.test 1e0e469f5f8a09afa8a182f34647e3d9b8c01978cbbe2313a194ccc3a8471506
F test/printf2.test 30b5dd0b4b992dc5626496846ecce17ff592cacbcb11c3e589f3ac4d7e129dae
F test/progress.test ebab27f670bd0d4eb9d20d49cef96e68141d92fb
F test/ptrchng.test ef1aa72d6cf35a2bbd0869a649b744e9d84977fc
@@ -1304,7 +1309,7 @@ F test/securedel2.test 2d54c28e46eb1fd6902089958b20b1b056c6f1c5
F test/select1.test 009a6d8eacd9684d046302b8d13b50846a87e39d6f08e92178aa13e95ea29a2d
F test/select2.test 352480e0e9c66eda9c3044e412abdf5be0215b56
F test/select3.test ddd1bc6d0c8dece136321c11bd26d0d8ad17f2b27c72935fdd6574d8cb99d1d4
F test/select4.test 5389d9895968d1196c457d59b3ee6515d771d328
F test/select4.test e8a2502e3623f3058871030599a48abb35789d2244d5b380ecf3696873fdd4a4
F test/select5.test df9ec0d218cedceb4fe7b63262025b547b50a55e59148c6f40b60ca25f1d4546
F test/select6.test 319d45e414cdd321bf17cfacedaf19e3935ad64dac357c53f1492338c6e9b801
F test/select7.test f659f231489349e8c5734e610803d7654207318f
@@ -1333,7 +1338,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 43e12c7d4ff65f041803ad24a93fd3818deb2cb83e721810f27d0fde61d64a13
F test/shell1.test 5bd10014ec494744f5e966a1521334e9d612119a0afcfa5251684a4e1f2ffc66
F test/shell2.test e242a9912f44f4c23c3d1d802a83e934e84c853b
F test/shell3.test ac8c2b744014c3e9a0e26bfd829ab65f00923dc1a91ffd044863e9423cc91494
F test/shell4.test 1c6aef11daaa2d6830acaba3ac9cbec93fbc1c3d5530743a637f39b3987d08ce
@@ -1415,7 +1420,7 @@ F test/temptable.test d2c9b87a54147161bcd1822e30c1d1cd891e5b30
F test/temptable2.test d2940417496e2b9548e01d09990763fbe88c316504033256d51493e1f1a5ce6a
F test/temptable3.test d11a0974e52b347e45ee54ef1923c91ed91e4637
F test/temptrigger.test 38f0ca479b1822d3117069e014daabcaacefffcc
F test/tester.tcl abba168acd7f01dbfa3ffdbf402d151eb97e8a824d9208e845ab34c194441483
F test/tester.tcl fd9d134a7cc4e31b307ad028a195f51cdcf556fc620d74b680515562f0137f25
F test/thread001.test b61a29dd87cf669f5f6ac96124a7c97d71b0c80d9012746072055877055cf9ef
F test/thread002.test e630504f8a06c00bf8bbe68528774dd96aeb2e58
F test/thread003.test ee4c9efc3b86a6a2767516a37bd64251272560a7
@@ -1441,7 +1446,7 @@ F test/tkt-385a5b56b9.test 5204a7cba0e28c99df0acbf95af5e1af4d32965a7a14de6eccebf
F test/tkt-38cb5df375.test f3cc8671f1eb604d4ae9cf886ed4366bec656678
F test/tkt-3998683a16.test 6d1d04d551ed1704eb3396ca87bb9ccc8c5c1eb7
F test/tkt-3a77c9714e.test 90e3e8455ee945a4076d4c44062b8845708af24a880355328fe7008f2047c9f0
F test/tkt-3fe897352e.test 6849fde0a87165ff83f54f5047af7c743d72af26908fadb90174f3294450b3f4
F test/tkt-3fe897352e.test 27e26eb0f1811aeba4d65aba43a4c52e99da5e70
F test/tkt-4a03edc4c8.test 91c0e135888cdc3d4eea82406a44b05c8c1648d0
F test/tkt-4c86b126f2.test cbcc611becd0396890169ab23102dd70048bbc9a
F test/tkt-4dd95f6943.test 3d0ce415d2ee15d3d564121960016b9c7be79407
@@ -1655,7 +1660,7 @@ F test/vtab_alter.test 736e66fb5ec7b4fee58229aa3ada2f27ec58bc58c00edae4836890c37
F test/vtab_err.test dcc8b7b9cb67522b3fe7a272c73856829dae4ab7fdb30399aea1b6981bda2b65
F test/vtab_shared.test 5253bff2355a9a3f014c15337da7e177ab0ef8ad
F test/vtabdrop.test 65d4cf6722972e5499bdaf0c0d70ee3b8133944a4e4bc31862563f32a7edca12
F test/wal.test cdf0ca6cc0447520d19ef1c83287824ebeb3e82d75af856511ba96841a79fc9b
F test/wal.test 16180bc4becda176428ad02eaea437b4b8f5ae099314de443a4e12b2dcc007a2
F test/wal2.test 537f59e5c5932e3b45bf3591ae3e48a2601360c2e52821b633e222fe6ebd5b09
F test/wal3.test 2a93004bc0fb2b5c29888964024695bade278ab2
F test/wal4.test 4744e155cd6299c6bd99d3eab1c82f77db9cdb3c
@@ -1686,6 +1691,7 @@ F test/walprotocol2.test 7d3b6b4bf0b12f8007121b1e6ef714bc99101fb3b48e46371df1db8
F test/walro.test cb438d05ba0d191f10b688e39c4f0cd5b71569a1d1f4440e5bdf3c6880e08c20
F test/walro2.test 0e79dd15cbdb4f482c01ea248373669c732414a726b357d04846a816afafb768
F test/walrofault.test c70cb6e308c443867701856cce92ad8288cd99488fa52afab77cca6cfd51af68
F test/walsetlk.test 11f7fe792fdce54cf09874dab824e0627f2eedecfb9f7983e325606ec5184e0c
F test/walshared.test 0befc811dcf0b287efae21612304d15576e35417
F test/walslow.test c05c68d4dc2700a982f89133ce103a1a84cc285f
F test/walthread.test 14b20fcfa6ae152f5d8e12f5dc8a8a724b7ef189f5d8ef1e2ceab79f2af51747
@@ -1712,29 +1718,29 @@ F test/whereH.test e4b07f7a3c2f5d31195cd33710054c78667573b2
F test/whereI.test a2874062140ed4aba9ffae76e6190a3df6fc73d1373fdfa8fd632945082a5364
F test/whereJ.test 88287550f6ee604422403b053455b1ad894eeaa5c35d348532dfa1439286cb9a
F test/whereK.test f8e3cf26a8513ecc7f514f54df9f0572c046c42b
F test/whereL.test d19499a39c9e3e5a74460778b009558d328c8a230c0e6825c9996c9adff89058
F test/whereL.test e05cedc9389c6f09ad55bd5999a3fddccebec90672fb989433c145dcdaf26996
F test/wherefault.test 1374c3aa198388925246475f84ad4cd5f9528864
F test/wherelfault.test 9012e4ef5259058b771606616bd007af5d154e64cc25fa9fd4170f6411db44e3
F test/wherelimit.test 592081800806d297dd7449b1030c863d2883d6d42901837ccd2e5a9bd962edb0
F test/wherelimit2.test 9bf0aa56cca40ea0e4c5e2915341355a2bbc0859ec4ce1589197fe2a9d94635f
F test/win32heap.test 10fd891266bd00af68671e702317726375e5407561d859be1aa04696f2aeee74
F test/win32lock.test fbf107c91d8f5512be5a5b87c4c42ab9fdd54972
F test/win32longpath.test 169c75a3b2e43481f4a62122510210c67b08f26d
F test/win32longpath.test 4baffc3acb2e5188a5e3a895b2b543ed09e62f7c72d713c1feebf76222fe9976
F test/win32nolock.test ac4f08811a562e45a5755e661f45ca85892bdbbc
F test/window1.test 879a1928c9a6b4f7abdad1a4f31fe1e6c7fe36422935606367fecfdee8b4d5b5
F test/window1.test 502a3e72fce895aaaa633bbe709f6de3c24eed3ecb8098ab9fb8b47584b4452c
F test/window2.tcl 492c125fa550cda1dd3555768a2303b3effbeceee215293adf8871efc25f1476
F test/window2.test e466a88bd626d66edc3d352d7d7e1d5531e0079b549ba44efb029d1fbff9fd3c
F test/window3.tcl acea6e86a4324a210fd608d06741010ca83ded9fde438341cb978c49928faf03
F test/window3.test e9959a993c8a71e96433be8daaa1827d78b8921e4f12debd7bdbeb3c856ef3cb
F test/window4.tcl d732df0e81beedc0ba8a563ade68611d322d27303ad0c0c8e4444107c39e84ec
F test/window4.test 807f3e6b15f9338e5b9742b87c5c7ca825b42b9657fde6096e890119370848e0
F test/window4.tcl 6f85307eb67242b654d051f7da32a996a66aee039a09c5ae358541aa61720742
F test/window4.test fbead87f681400ac07ef3555e0488b544a47d35491f8bf09a7474b6f76ce9b4e
F test/window5.test d328dd18221217c49c144181975eea17339eaeaf0e9aa558cee3afb84652821e
F test/window6.test f8d674254b23289cc17c84d79dec7eda7caa1dfb7836c43122cfdf3640d1df32
F test/window7.tcl 6a1210f05d40ec89c22960213a22cd3f98d4e2f2eb20646c83c8c30d4d76108f
F test/window7.test 1d31276961ae7801edc72173edaf7593e3cbc79c06d1f1f09e20d8418af403cd
F test/window8.tcl f2711aa3571e4e6b0dad98db8d95fd6cb8d9db0c92bbdf535f153b07606a1ce2
F test/window8.test c4331b27a6f66d69fa8f8bab10cc731db1a81d293ae108a68f7c3487fa94e65b
F test/window9.test b63f6f74d730547e63e78946f951f5d1a7d4e99f91f6d5906305469043d92a15
F test/window9.test c22c25377c820613e1842fe7ad4af7c03df625f6a7caee99e6fdb4fcd52e0a8b
F test/windowA.test 6d63dc1260daa17141a55007600581778523a8b420629f1282d2acfc36af23be
F test/windowB.test 7a983ea1cc1cf72be7f378e4b32f6cb2d73014c5cd8b25aaee825164cd4269e5
F test/windowerr.tcl f5acd6fbc210d7b5546c0e879d157888455cd4a17a1d3f28f07c1c8a387019e0
@@ -1747,7 +1753,7 @@ F test/with4.test 257be66c0c67fee1defbbac0f685c3465e2cad037f21ce65f23f86084f1982
F test/withM.test 693b61765f2b387b5e3e24a4536e2e82de15ff64
F test/without_rowid1.test 9cfb83705c506e3849fa7efc88a3c9a15f9a50bf9b1516b41757a7cef9bba8c3
F test/without_rowid2.test af260339f79d13cb220288b67cd287fbcf81ad99
F test/without_rowid3.test 392e6e12f275d11d931a8bc4580e573342f391639c87ffb631010a7b3cedfdc0
F test/without_rowid3.test f8e6b9f7cb32a3570bab743dd4f28d2000e2107808d57585e776f5c3eb076241
F test/without_rowid4.test 4e08bcbaee0399f35d58b5581881e7a6243d458a
F test/without_rowid5.test 89b1c587bd92a0590e440da33e7666bf4891572a
F test/without_rowid6.test 8463b20098e9f75a501a9f17dfb42fffc79068eac0b2775fe56ef2281d2df45e
@@ -1793,12 +1799,12 @@ F tool/mkmsvcmin.tcl 6ecab9fe22c2c8de4d82d4c46797bda3d2deac8e763885f5a38d0c44a89
F tool/mkopcodec.tcl d1b6362bd3aa80d5520d4d6f3765badf01f6c43c
F tool/mkopcodeh.tcl 352a4319c0ad869eb26442bf7c3b015aa15594c21f1cce5a6420dbe999367c21
F tool/mkopts.tcl 680f785fdb09729fd9ac50632413da4eadbdf9071535e3f26d03795828ab07fa
F tool/mkpragmatab.tcl 62663c65d9191aada624a787e1ee3420f268a3c27999ad0ffb77a6918ddc1e52
F tool/mkpragmatab.tcl d348a4bf71ac068bddf89326562071cbbd962273d88f9b5e5d622f3e73b78bdf
F tool/mkshellc.tcl 70a9978e363b0f3280ca9ce1c46d72563ff479c1930a12a7375e3881b7325712
F tool/mksourceid.c 36aa8020014aed0836fd13c51d6dc9219b0df1761d6b5f58ff5b616211b079b9
F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97
F tool/mksqlite3c-noext.tcl 4f7cfef5152b0c91920355cbfc1d608a4ad242cb819f1aea07f6d0274f584a7f
F tool/mksqlite3c.tcl 5fed3d75069d8f66f202d3b5200b0cea4aa7108481acd06732a06fdd42eb83a2
F tool/mksqlite3c.tcl 3ab95bcf7b765f9d6d99cbeb8c4f150b38b0bb1f001ffac688f2ad02ebce2123
F tool/mksqlite3h.tcl 080873e3856eceb9d289a08a00c4b30f875ea3feadcbece796bd509b1532792c
F tool/mksqlite3internalh.tcl eb994013e833359137eb53a55acdad0b5ae1049b
F tool/mkvsix.tcl b9e0777a213c23156b6542842c238479e496ebf5
@@ -1817,7 +1823,7 @@ F tool/showshm.c a0ab6ec32dd1f11218ca2a4018f8fb875b59414801ab8ceed8b2e69b7b45a80
F tool/showstat4.c 0682ebea7abf4d3657f53c4a243f2e7eab48eab344ed36a94bb75dcd19a5c2a1
F tool/showwal.c ad9d768f96ca6199ad3a8c9562d679680bd032dd01204ea3e5ea6fb931d81847
F tool/soak1.tcl 8d407956e1a45b485a8e072470a3e629a27037fe
F tool/spaceanal.tcl 4bfd19aad7eb3ce0372ef0255f58035e0bba4ff5e9acfd763a10c6fb365c8dec
F tool/spaceanal.tcl c161d838825d0242317c7cc13b1eb2126f8cec031950ef31114d42732cb2674e
F tool/speed-check.sh 2b042d703a9472f08c3b13be27afac658426f8e4fc87cd2d575953fda86f08d1
F tool/speedtest.tcl 06c76698485ccf597b9e7dbb1ac70706eb873355
F tool/speedtest16.c ecb6542862151c3e6509bbc00509b234562ae81e
@@ -1860,7 +1866,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
P 97a18a5cd701848a9660385e31bffe2c397e3cfe57ccdb876f44d08c00d1d39a
R bb18f5b4c4c1d8067c8d33e0ad339acb
P b1b182be2ab34cec1d94c5570bc361331a34f727eb9fa4aadfabb7f1ef79f83e
R 060d4022d9a6a2267bacd2bd89abcc90
T +bgcolor * #d0c0ff
T +sym-release *
T +sym-version-3.32.1 *
U drh
Z 791b16818e473b4676673e9f9494706b
Z 2dade396208e30c3681b79baa530525b
+1 -1
View File
@@ -1 +1 @@
d7f18489978fdbbe3ab317485518cac91a75416ccef55898301afdd76d3b415b
0c1fcf4711a2e66c813aed38cf41cd3e2123ee8eb6db98118086764c4ba83350
+47 -11
View File
@@ -123,7 +123,10 @@ void sqlite3AlterRenameTable(
/* Check that a table or index named 'zName' does not already exist
** in database iDb. If so, this is an error.
*/
if( sqlite3FindTable(db, zName, zDb) || sqlite3FindIndex(db, zName, zDb) ){
if( sqlite3FindTable(db, zName, zDb)
|| sqlite3FindIndex(db, zName, zDb)
|| sqlite3IsShadowTableOf(db, pTab, zName)
){
sqlite3ErrorMsg(pParse,
"there is already another table or index with this name: %s", zName);
goto exit_rename_table;
@@ -255,6 +258,22 @@ exit_rename_table:
db->mDbFlags = savedDbFlags;
}
/*
** Write code that will raise an error if the table described by
** zDb and zTab is not empty.
*/
static void sqlite3ErrorIfNotEmpty(
Parse *pParse, /* Parsing context */
const char *zDb, /* Schema holding the table */
const char *zTab, /* Table to check for empty */
const char *zErr /* Error message text */
){
sqlite3NestedParse(pParse,
"SELECT raise(ABORT,%Q) FROM \"%w\".\"%w\"",
zErr, zDb, zTab
);
}
/*
** This function is called after an "ALTER TABLE ... ADD" statement
** has been parsed. Argument pColDef contains the text of the new
@@ -307,7 +326,8 @@ void sqlite3AlterFinishAddColumn(Parse *pParse, Token *pColDef){
return;
}
if( pNew->pIndex ){
sqlite3ErrorMsg(pParse, "Cannot add a UNIQUE column");
sqlite3ErrorMsg(pParse,
"Cannot add a UNIQUE column");
return;
}
if( (pCol->colFlags & COLFLAG_GENERATED)==0 ){
@@ -320,16 +340,15 @@ void sqlite3AlterFinishAddColumn(Parse *pParse, Token *pColDef){
pDflt = 0;
}
if( (db->flags&SQLITE_ForeignKeys) && pNew->pFKey && pDflt ){
sqlite3ErrorMsg(pParse,
sqlite3ErrorIfNotEmpty(pParse, zDb, zTab,
"Cannot add a REFERENCES column with non-NULL default value");
return;
}
if( pCol->notNull && !pDflt ){
sqlite3ErrorMsg(pParse,
sqlite3ErrorIfNotEmpty(pParse, zDb, zTab,
"Cannot add a NOT NULL column with default value NULL");
return;
}
/* Ensure the default expression is something that sqlite3ValueFromExpr()
** can handle (i.e. not CURRENT_TIME etc.)
*/
@@ -343,14 +362,13 @@ void sqlite3AlterFinishAddColumn(Parse *pParse, Token *pColDef){
return;
}
if( !pVal ){
sqlite3ErrorMsg(pParse,"Cannot add a column with non-constant default");
return;
sqlite3ErrorIfNotEmpty(pParse, zDb, zTab,
"Cannot add a column with non-constant default");
}
sqlite3ValueFree(pVal);
}
}else if( pCol->colFlags & COLFLAG_STORED ){
sqlite3ErrorMsg(pParse, "cannot add a STORED column");
return;
sqlite3ErrorIfNotEmpty(pParse, zDb, zTab, "cannot add a STORED column");
}
@@ -469,6 +487,7 @@ void sqlite3AlterBeginAddColumn(Parse *pParse, SrcList *pSrc){
for(i=0; i<pNew->nCol; i++){
Column *pCol = &pNew->aCol[i];
pCol->zName = sqlite3DbStrDup(db, pCol->zName);
pCol->hName = sqlite3StrIHash(pCol->zName);
pCol->zColl = 0;
pCol->pDflt = 0;
}
@@ -697,7 +716,7 @@ void *sqlite3RenameTokenMap(Parse *pParse, void *pPtr, Token *pToken){
RenameToken *pNew;
assert( pPtr || pParse->db->mallocFailed );
renameTokenCheckAll(pParse, pPtr);
if( pParse->eParseMode!=PARSE_MODE_UNMAP ){
if( ALWAYS(pParse->eParseMode!=PARSE_MODE_UNMAP) ){
pNew = sqlite3DbMallocZero(pParse->db, sizeof(RenameToken));
if( pNew ){
pNew->p = pPtr;
@@ -755,6 +774,21 @@ static void renameWalkWith(Walker *pWalker, Select *pSelect){
}
}
/*
** Unmap all tokens in the IdList object passed as the second argument.
*/
static void unmapColumnIdlistNames(
Parse *pParse,
IdList *pIdList
){
if( pIdList ){
int ii;
for(ii=0; ii<pIdList->nId; ii++){
sqlite3RenameTokenRemap(pParse, 0, (void*)pIdList->a[ii].zName);
}
}
}
/*
** Walker callback used by sqlite3RenameExprUnmap().
*/
@@ -776,6 +810,7 @@ static int renameUnmapSelectCb(Walker *pWalker, Select *p){
for(i=0; i<pSrc->nSrc; i++){
sqlite3RenameTokenRemap(pParse, 0, (void*)pSrc->a[i].zName);
if( sqlite3WalkExpr(pWalker, pSrc->a[i].pOn) ) return WRC_Abort;
unmapColumnIdlistNames(pParse, pSrc->a[i].pUsing);
}
}
@@ -984,6 +1019,7 @@ static void renameColumnIdlistNames(
}
}
/*
** Parse the SQL statement zSql using Parse object (*p). The Parse object
** is initialized by this function before it is used.
+131 -84
View File
@@ -188,6 +188,11 @@ static void openStatTable(
Vdbe *v = sqlite3GetVdbe(pParse);
int aRoot[ArraySize(aTable)];
u8 aCreateTbl[ArraySize(aTable)];
#ifdef SQLITE_ENABLE_STAT4
const int nToOpen = OptimizationEnabled(db,SQLITE_Stat4) ? 2 : 1;
#else
const int nToOpen = 1;
#endif
if( v==0 ) return;
assert( sqlite3BtreeHoldsAllMutexes(db) );
@@ -200,8 +205,9 @@ static void openStatTable(
for(i=0; i<ArraySize(aTable); i++){
const char *zTab = aTable[i].zName;
Table *pStat;
aCreateTbl[i] = 0;
if( (pStat = sqlite3FindTable(db, zTab, pDb->zDbSName))==0 ){
if( aTable[i].zCols ){
if( i<nToOpen ){
/* The sqlite_statN table does not exist. Create it. Note that a
** side-effect of the CREATE TABLE statement is to leave the rootpage
** of the new table in register pParse->regRoot. This is important
@@ -217,7 +223,6 @@ static void openStatTable(
** associated with the table zWhere. If zWhere is NULL, delete the
** entire contents of the table. */
aRoot[i] = pStat->tnum;
aCreateTbl[i] = 0;
sqlite3TableLock(pParse, iDb, aRoot[i], 1, zTab);
if( zWhere ){
sqlite3NestedParse(pParse,
@@ -236,7 +241,7 @@ static void openStatTable(
}
/* Open the sqlite_stat[134] tables for writing. */
for(i=0; aTable[i].zCols; i++){
for(i=0; i<nToOpen; i++){
assert( i<ArraySize(aTable) );
sqlite3VdbeAddOp4Int(v, OP_OpenWrite, iStatCur+i, aRoot[i], iDb, 3);
sqlite3VdbeChangeP5(v, aCreateTbl[i]);
@@ -275,9 +280,12 @@ struct StatSample {
};
struct StatAccum {
sqlite3 *db; /* Database connection, for malloc() */
tRowcnt nRow; /* Number of rows in the entire table */
tRowcnt nEst; /* Estimated number of rows */
tRowcnt nRow; /* Number of rows visited so far */
int nLimit; /* Analysis row-scan limit */
int nCol; /* Number of columns in index + pk/rowid */
int nKeyCol; /* Number of index columns w/o the pk/rowid */
u8 nSkipAhead; /* Number of times of skip-ahead */
StatSample current; /* Current row as a StatSample */
#ifdef SQLITE_ENABLE_STAT4
tRowcnt nPSample; /* How often to do a periodic sample */
@@ -357,27 +365,28 @@ static void sampleCopy(StatAccum *p, StatSample *pTo, StatSample *pFrom){
static void statAccumDestructor(void *pOld){
StatAccum *p = (StatAccum*)pOld;
#ifdef SQLITE_ENABLE_STAT4
int i;
for(i=0; i<p->nCol; i++) sampleClear(p->db, p->aBest+i);
for(i=0; i<p->mxSample; i++) sampleClear(p->db, p->a+i);
sampleClear(p->db, &p->current);
if( p->mxSample ){
int i;
for(i=0; i<p->nCol; i++) sampleClear(p->db, p->aBest+i);
for(i=0; i<p->mxSample; i++) sampleClear(p->db, p->a+i);
sampleClear(p->db, &p->current);
}
#endif
sqlite3DbFree(p->db, p);
}
/*
** Implementation of the stat_init(N,K,C) SQL function. The three parameters
** Implementation of the stat_init(N,K,C,L) SQL function. The four parameters
** are:
** N: The number of columns in the index including the rowid/pk (note 1)
** K: The number of columns in the index excluding the rowid/pk.
** C: The number of rows in the index (note 2)
** C: Estimated number of rows in the index
** L: A limit on the number of rows to scan, or 0 for no-limit
**
** Note 1: In the special case of the covering index that implements a
** WITHOUT ROWID table, N is the number of PRIMARY KEY columns, not the
** total number of columns in the table.
**
** Note 2: C is only used for STAT4.
**
** For indexes on ordinary rowid tables, N==K+1. But for indexes on
** WITHOUT ROWID tables, N=K+P where P is the number of columns in the
** PRIMARY KEY of the table. The covering index that implements the
@@ -398,9 +407,10 @@ static void statInit(
int nKeyCol; /* Number of key columns */
int nColUp; /* nCol rounded up for alignment */
int n; /* Bytes of space to allocate */
sqlite3 *db; /* Database connection */
sqlite3 *db = sqlite3_context_db_handle(context); /* Database connection */
#ifdef SQLITE_ENABLE_STAT4
int mxSample = SQLITE_STAT4_SAMPLES;
/* Maximum number of samples. 0 if STAT4 data is not collected */
int mxSample = OptimizationEnabled(db,SQLITE_Stat4) ?SQLITE_STAT4_SAMPLES :0;
#endif
/* Decode the three function arguments */
@@ -415,13 +425,14 @@ static void statInit(
/* Allocate the space required for the StatAccum object */
n = sizeof(*p)
+ sizeof(tRowcnt)*nColUp /* StatAccum.anEq */
+ sizeof(tRowcnt)*nColUp /* StatAccum.anDLt */
+ sizeof(tRowcnt)*nColUp; /* StatAccum.anDLt */
#ifdef SQLITE_ENABLE_STAT4
+ sizeof(tRowcnt)*nColUp /* StatAccum.anLt */
+ sizeof(StatSample)*(nCol+mxSample) /* StatAccum.aBest[], a[] */
+ sizeof(tRowcnt)*3*nColUp*(nCol+mxSample)
if( mxSample ){
n += sizeof(tRowcnt)*nColUp /* StatAccum.anLt */
+ sizeof(StatSample)*(nCol+mxSample) /* StatAccum.aBest[], a[] */
+ sizeof(tRowcnt)*3*nColUp*(nCol+mxSample);
}
#endif
;
db = sqlite3_context_db_handle(context);
p = sqlite3DbMallocZero(db, n);
if( p==0 ){
@@ -430,20 +441,23 @@ static void statInit(
}
p->db = db;
p->nEst = sqlite3_value_int64(argv[2]);
p->nRow = 0;
p->nLimit = sqlite3_value_int64(argv[3]);
p->nCol = nCol;
p->nKeyCol = nKeyCol;
p->nSkipAhead = 0;
p->current.anDLt = (tRowcnt*)&p[1];
p->current.anEq = &p->current.anDLt[nColUp];
#ifdef SQLITE_ENABLE_STAT4
{
p->mxSample = p->nLimit==0 ? mxSample : 0;
if( mxSample ){
u8 *pSpace; /* Allocated space not yet assigned */
int i; /* Used to iterate through p->aSample[] */
p->iGet = -1;
p->mxSample = mxSample;
p->nPSample = (tRowcnt)(sqlite3_value_int64(argv[2])/(mxSample/3+1) + 1);
p->nPSample = (tRowcnt)(p->nEst/(mxSample/3+1) + 1);
p->current.anLt = &p->current.anEq[nColUp];
p->iPrn = 0x689e962d*(u32)nCol ^ 0xd0944565*(u32)sqlite3_value_int(argv[2]);
@@ -471,7 +485,7 @@ static void statInit(
sqlite3_result_blob(context, p, sizeof(*p), statAccumDestructor);
}
static const FuncDef statInitFuncdef = {
2+IsStat4, /* nArg */
4, /* nArg */
SQLITE_UTF8, /* funcFlags */
0, /* pUserData */
0, /* pNext */
@@ -675,10 +689,13 @@ static void samplePushPrevious(StatAccum *p, int iChng){
** R Rowid for the current row. Might be a key record for
** WITHOUT ROWID tables.
**
** This SQL function always returns NULL. It's purpose it to accumulate
** statistical data and/or samples in the StatAccum object about the
** index being analyzed. The stat_get() SQL function will later be used to
** extract relevant information for constructing the sqlite_statN tables.
** The purpose of this routine is to collect statistical data and/or
** samples from the index being analyzed into the StatAccum object.
** The stat_get() SQL function will be used afterwards to
** retrieve the information gathered.
**
** This SQL function usually returns NULL, but might return an integer
** if it wants the byte-code to do special processing.
**
** The R parameter is only used for STAT4
*/
@@ -704,7 +721,7 @@ static void statPush(
}else{
/* Second and subsequent calls get processed here */
#ifdef SQLITE_ENABLE_STAT4
samplePushPrevious(p, iChng);
if( p->mxSample ) samplePushPrevious(p, iChng);
#endif
/* Update anDLt[], anLt[] and anEq[] to reflect the values that apply
@@ -715,26 +732,25 @@ static void statPush(
for(i=iChng; i<p->nCol; i++){
p->current.anDLt[i]++;
#ifdef SQLITE_ENABLE_STAT4
p->current.anLt[i] += p->current.anEq[i];
if( p->mxSample ) p->current.anLt[i] += p->current.anEq[i];
#endif
p->current.anEq[i] = 1;
}
}
p->nRow++;
#ifdef SQLITE_ENABLE_STAT4
if( sqlite3_value_type(argv[2])==SQLITE_INTEGER ){
sampleSetRowidInt64(p->db, &p->current, sqlite3_value_int64(argv[2]));
}else{
sampleSetRowid(p->db, &p->current, sqlite3_value_bytes(argv[2]),
sqlite3_value_blob(argv[2]));
}
p->current.iHash = p->iPrn = p->iPrn*1103515245 + 12345;
#endif
#ifdef SQLITE_ENABLE_STAT4
{
tRowcnt nLt = p->current.anLt[p->nCol-1];
if( p->mxSample ){
tRowcnt nLt;
if( sqlite3_value_type(argv[2])==SQLITE_INTEGER ){
sampleSetRowidInt64(p->db, &p->current, sqlite3_value_int64(argv[2]));
}else{
sampleSetRowid(p->db, &p->current, sqlite3_value_bytes(argv[2]),
sqlite3_value_blob(argv[2]));
}
p->current.iHash = p->iPrn = p->iPrn*1103515245 + 12345;
nLt = p->current.anLt[p->nCol-1];
/* Check if this is to be a periodic sample. If so, add it. */
if( (nLt/p->nPSample)!=(nLt+1)/p->nPSample ){
p->current.isPSample = 1;
@@ -750,9 +766,14 @@ static void statPush(
sampleCopy(p, &p->aBest[i], &p->current);
}
}
}
}else
#endif
if( p->nLimit && p->nRow>(tRowcnt)p->nLimit*(p->nSkipAhead+1) ){
p->nSkipAhead++;
sqlite3_result_int(context, p->current.anDLt[0]>0);
}
}
static const FuncDef statPushFuncdef = {
2+IsStat4, /* nArg */
SQLITE_UTF8, /* funcFlags */
@@ -804,6 +825,7 @@ static void statGet(
|| eCall==STAT_GET_ROWID || eCall==STAT_GET_NLT
|| eCall==STAT_GET_NDLT
);
assert( eCall==STAT_GET_STAT1 || p->mxSample );
if( eCall==STAT_GET_STAT1 )
#else
assert( argc==1 );
@@ -839,7 +861,8 @@ static void statGet(
return;
}
sqlite3_snprintf(24, zRet, "%llu", (u64)p->nRow);
sqlite3_snprintf(24, zRet, "%llu",
p->nSkipAhead ? (u64)p->nEst : (u64)p->nRow);
z = zRet + sqlite3Strlen30(zRet);
for(i=0; i<p->nKeyCol; i++){
u64 nDistinct = p->current.anDLt[i] + 1;
@@ -915,16 +938,16 @@ static const FuncDef statGetFuncdef = {
{0}
};
static void callStatGet(Parse *pParse, int regStat4, int iParam, int regOut){
static void callStatGet(Parse *pParse, int regStat, int iParam, int regOut){
#ifdef SQLITE_ENABLE_STAT4
sqlite3VdbeAddOp2(pParse->pVdbe, OP_Integer, iParam, regStat4+1);
sqlite3VdbeAddOp2(pParse->pVdbe, OP_Integer, iParam, regStat+1);
#elif SQLITE_DEBUG
assert( iParam==STAT_GET_STAT1 );
#else
UNUSED_PARAMETER( iParam );
#endif
assert( regOut!=regStat4 && regOut!=regStat4+1 );
sqlite3VdbeAddFunctionCall(pParse, 0, regStat4, regOut, 1+IsStat4,
assert( regOut!=regStat && regOut!=regStat+1 );
sqlite3VdbeAddFunctionCall(pParse, 0, regStat, regOut, 1+IsStat4,
&statGetFuncdef, 0);
}
@@ -950,12 +973,11 @@ static void analyzeOneTable(
int iDb; /* Index of database containing pTab */
u8 needTableCnt = 1; /* True to count the table */
int regNewRowid = iMem++; /* Rowid for the inserted record */
int regStat4 = iMem++; /* Register to hold StatAccum object */
int regStat = iMem++; /* Register to hold StatAccum object */
int regChng = iMem++; /* Index of changed index field */
#ifdef SQLITE_ENABLE_STAT4
int regRowid = iMem++; /* Rowid argument passed to stat_push() */
#endif
int regTemp = iMem++; /* Temporary use register */
int regTemp2 = iMem++; /* Second temporary use register */
int regTabname = iMem++; /* Register containing table name */
int regIdxname = iMem++; /* Register containing index name */
int regStat1 = iMem++; /* Value for the stat column of sqlite_stat1 */
@@ -1083,17 +1105,26 @@ static void analyzeOneTable(
** (1) the number of columns in the index including the rowid
** (or for a WITHOUT ROWID table, the number of PK columns),
** (2) the number of columns in the key without the rowid/pk
** (3) the number of rows in the index,
**
**
** The third argument is only used for STAT4
** (3) estimated number of rows in the index,
*/
sqlite3VdbeAddOp2(v, OP_Integer, nCol, regStat+1);
assert( regRowid==regStat+2 );
sqlite3VdbeAddOp2(v, OP_Integer, pIdx->nKeyCol, regRowid);
#ifdef SQLITE_ENABLE_STAT4
sqlite3VdbeAddOp2(v, OP_Count, iIdxCur, regStat4+3);
if( OptimizationEnabled(db, SQLITE_Stat4) ){
sqlite3VdbeAddOp2(v, OP_Count, iIdxCur, regTemp);
addrRewind = sqlite3VdbeAddOp1(v, OP_Rewind, iIdxCur);
VdbeCoverage(v);
}else
#endif
sqlite3VdbeAddOp2(v, OP_Integer, nCol, regStat4+1);
sqlite3VdbeAddOp2(v, OP_Integer, pIdx->nKeyCol, regStat4+2);
sqlite3VdbeAddFunctionCall(pParse, 0, regStat4+1, regStat4, 2+IsStat4,
{
addrRewind = sqlite3VdbeAddOp1(v, OP_Rewind, iIdxCur);
VdbeCoverage(v);
sqlite3VdbeAddOp3(v, OP_Count, iIdxCur, regTemp, 1);
}
assert( regTemp2==regStat+4 );
sqlite3VdbeAddOp2(v, OP_Integer, db->nAnalysisLimit, regTemp2);
sqlite3VdbeAddFunctionCall(pParse, 0, regStat+1, regStat, 4,
&statInitFuncdef, 0);
/* Implementation of the following:
@@ -1104,8 +1135,6 @@ static void analyzeOneTable(
** goto next_push_0;
**
*/
addrRewind = sqlite3VdbeAddOp1(v, OP_Rewind, iIdxCur);
VdbeCoverage(v);
sqlite3VdbeAddOp2(v, OP_Integer, 0, regChng);
addrNextRow = sqlite3VdbeCurrentAddr(v);
@@ -1138,6 +1167,7 @@ static void analyzeOneTable(
char *pColl = (char*)sqlite3LocateCollSeq(pParse, pIdx->azColl[i]);
sqlite3VdbeAddOp2(v, OP_Integer, i, regChng);
sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, i, regTemp);
VdbeComment((v, "%s.column(%d)", pIdx->zName, i));
aGotoChng[i] =
sqlite3VdbeAddOp4(v, OP_Ne, regTemp, 0, regPrev+i, pColl, P4_COLLSEQ);
sqlite3VdbeChangeP5(v, SQLITE_NULLEQ);
@@ -1158,6 +1188,7 @@ static void analyzeOneTable(
for(i=0; i<nColTest; i++){
sqlite3VdbeJumpHere(v, aGotoChng[i]);
sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, i, regPrev+i);
VdbeComment((v, "%s.column(%d)", pIdx->zName, i));
}
sqlite3VdbeResolveLabel(v, endDistinctTest);
sqlite3DbFree(db, aGotoChng);
@@ -1171,30 +1202,46 @@ static void analyzeOneTable(
** if !eof(csr) goto next_row;
*/
#ifdef SQLITE_ENABLE_STAT4
assert( regRowid==(regStat4+2) );
if( HasRowid(pTab) ){
sqlite3VdbeAddOp2(v, OP_IdxRowid, iIdxCur, regRowid);
}else{
Index *pPk = sqlite3PrimaryKeyIndex(pIdx->pTable);
int j, k, regKey;
regKey = sqlite3GetTempRange(pParse, pPk->nKeyCol);
for(j=0; j<pPk->nKeyCol; j++){
k = sqlite3TableColumnToIndex(pIdx, pPk->aiColumn[j]);
assert( k>=0 && k<pIdx->nColumn );
sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, k, regKey+j);
VdbeComment((v, "%s", pTab->aCol[pPk->aiColumn[j]].zName));
if( OptimizationEnabled(db, SQLITE_Stat4) ){
assert( regRowid==(regStat+2) );
if( HasRowid(pTab) ){
sqlite3VdbeAddOp2(v, OP_IdxRowid, iIdxCur, regRowid);
}else{
Index *pPk = sqlite3PrimaryKeyIndex(pIdx->pTable);
int j, k, regKey;
regKey = sqlite3GetTempRange(pParse, pPk->nKeyCol);
for(j=0; j<pPk->nKeyCol; j++){
k = sqlite3TableColumnToIndex(pIdx, pPk->aiColumn[j]);
assert( k>=0 && k<pIdx->nColumn );
sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, k, regKey+j);
VdbeComment((v, "%s.column(%d)", pIdx->zName, i));
}
sqlite3VdbeAddOp3(v, OP_MakeRecord, regKey, pPk->nKeyCol, regRowid);
sqlite3ReleaseTempRange(pParse, regKey, pPk->nKeyCol);
}
sqlite3VdbeAddOp3(v, OP_MakeRecord, regKey, pPk->nKeyCol, regRowid);
sqlite3ReleaseTempRange(pParse, regKey, pPk->nKeyCol);
}
#endif
assert( regChng==(regStat4+1) );
sqlite3VdbeAddFunctionCall(pParse, 1, regStat4, regTemp, 2+IsStat4,
&statPushFuncdef, 0);
sqlite3VdbeAddOp2(v, OP_Next, iIdxCur, addrNextRow); VdbeCoverage(v);
assert( regChng==(regStat+1) );
{
sqlite3VdbeAddFunctionCall(pParse, 1, regStat, regTemp, 2+IsStat4,
&statPushFuncdef, 0);
if( db->nAnalysisLimit ){
int j1, j2, j3;
j1 = sqlite3VdbeAddOp1(v, OP_IsNull, regTemp); VdbeCoverage(v);
j2 = sqlite3VdbeAddOp1(v, OP_If, regTemp); VdbeCoverage(v);
j3 = sqlite3VdbeAddOp4Int(v, OP_SeekGT, iIdxCur, 0, regPrev, 1);
VdbeCoverage(v);
sqlite3VdbeJumpHere(v, j1);
sqlite3VdbeAddOp2(v, OP_Next, iIdxCur, addrNextRow); VdbeCoverage(v);
sqlite3VdbeJumpHere(v, j2);
sqlite3VdbeJumpHere(v, j3);
}else{
sqlite3VdbeAddOp2(v, OP_Next, iIdxCur, addrNextRow); VdbeCoverage(v);
}
}
/* Add the entry to the stat1 table. */
callStatGet(pParse, regStat4, STAT_GET_STAT1, regStat1);
callStatGet(pParse, regStat, STAT_GET_STAT1, regStat1);
assert( "BBB"[0]==SQLITE_AFF_TEXT );
sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 3, regTemp, "BBB", 0);
sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur, regNewRowid);
@@ -1206,7 +1253,7 @@ static void analyzeOneTable(
/* Add the entries to the stat4 table. */
#ifdef SQLITE_ENABLE_STAT4
{
if( OptimizationEnabled(db, SQLITE_Stat4) && db->nAnalysisLimit==0 ){
int regEq = regStat1;
int regLt = regStat1+1;
int regDLt = regStat1+2;
@@ -1220,12 +1267,12 @@ static void analyzeOneTable(
pParse->nMem = MAX(pParse->nMem, regCol+nCol);
addrNext = sqlite3VdbeCurrentAddr(v);
callStatGet(pParse, regStat4, STAT_GET_ROWID, regSampleRowid);
callStatGet(pParse, regStat, STAT_GET_ROWID, regSampleRowid);
addrIsNull = sqlite3VdbeAddOp1(v, OP_IsNull, regSampleRowid);
VdbeCoverage(v);
callStatGet(pParse, regStat4, STAT_GET_NEQ, regEq);
callStatGet(pParse, regStat4, STAT_GET_NLT, regLt);
callStatGet(pParse, regStat4, STAT_GET_NDLT, regDLt);
callStatGet(pParse, regStat, STAT_GET_NEQ, regEq);
callStatGet(pParse, regStat, STAT_GET_NLT, regLt);
callStatGet(pParse, regStat, STAT_GET_NDLT, regDLt);
sqlite3VdbeAddOp4Int(v, seekOp, iTabCur, addrNext, regSampleRowid, 0);
VdbeCoverage(v);
for(i=0; i<nCol; i++){
+19 -8
View File
@@ -45,6 +45,17 @@ static int resolveAttachExpr(NameContext *pName, Expr *pExpr)
return rc;
}
/*
** Return true if zName points to a name that may be used to refer to
** database iDb attached to handle db.
*/
int sqlite3DbIsNamed(sqlite3 *db, int iDb, const char *zName){
return (
sqlite3StrICmp(db->aDb[iDb].zDbSName, zName)==0
|| (iDb==0 && sqlite3StrICmp("main", zName)==0)
);
}
/*
** An SQL user-function registered to do the work of an ATTACH statement. The
** three arguments to the function come directly from an attach statement:
@@ -117,9 +128,8 @@ static void attachFunc(
goto attach_error;
}
for(i=0; i<db->nDb; i++){
char *z = db->aDb[i].zDbSName;
assert( z && zName );
if( sqlite3StrICmp(z, zName)==0 ){
assert( zName );
if( sqlite3DbIsNamed(db, i, zName) ){
zErrDyn = sqlite3MPrintf(db, "database %s is already in use", zName);
goto attach_error;
}
@@ -272,7 +282,7 @@ static void detachFunc(
for(i=0; i<db->nDb; i++){
pDb = &db->aDb[i];
if( pDb->pBt==0 ) continue;
if( sqlite3StrICmp(pDb->zDbSName, zName)==0 ) break;
if( sqlite3DbIsNamed(db, i, zName) ) break;
}
if( i>=db->nDb ){
@@ -463,20 +473,21 @@ int sqlite3FixSrcList(
SrcList *pList /* The Source list to check and modify */
){
int i;
const char *zDb;
struct SrcList_item *pItem;
sqlite3 *db = pFix->pParse->db;
int iDb = sqlite3FindDbName(db, pFix->zDb);
if( NEVER(pList==0) ) return 0;
zDb = pFix->zDb;
for(i=0, pItem=pList->a; i<pList->nSrc; i++, pItem++){
if( pFix->bTemp==0 ){
if( pItem->zDatabase && sqlite3StrICmp(pItem->zDatabase, zDb) ){
if( pItem->zDatabase && iDb!=sqlite3FindDbName(db, pItem->zDatabase) ){
sqlite3ErrorMsg(pFix->pParse,
"%s %T cannot reference objects in database %s",
pFix->zType, pFix->pName, pItem->zDatabase);
return 1;
}
sqlite3DbFree(pFix->pParse->db, pItem->zDatabase);
sqlite3DbFree(db, pItem->zDatabase);
pItem->zDatabase = 0;
pItem->pSchema = pFix->pSchema;
pItem->fg.fromDDL = 1;
+1 -1
View File
@@ -112,7 +112,7 @@ static Btree *findBtree(sqlite3 *pErrorDb, sqlite3 *pDb, const char *zDb){
*/
static int setDestPgsz(sqlite3_backup *p){
int rc;
rc = sqlite3BtreeSetPageSize(p->pDest,sqlite3BtreeGetPageSize(p->pSrc),-1,0);
rc = sqlite3BtreeSetPageSize(p->pDest,sqlite3BtreeGetPageSize(p->pSrc),0,0);
return rc;
}
+38 -22
View File
@@ -2304,8 +2304,7 @@ static int btreeInvokeBusyHandler(void *pArg){
BtShared *pBt = (BtShared*)pArg;
assert( pBt->db );
assert( sqlite3_mutex_held(pBt->db->mutex) );
return sqlite3InvokeBusyHandler(&pBt->db->busyHandler,
sqlite3PagerFile(pBt->pPager));
return sqlite3InvokeBusyHandler(&pBt->db->busyHandler);
}
/*
@@ -2856,16 +2855,17 @@ int sqlite3BtreeSetPagerFlags(
*/
int sqlite3BtreeSetPageSize(Btree *p, int pageSize, int nReserve, int iFix){
int rc = SQLITE_OK;
int x;
BtShared *pBt = p->pBt;
assert( nReserve>=-1 && nReserve<=255 );
assert( nReserve>=0 && nReserve<=255 );
sqlite3BtreeEnter(p);
pBt->nReserveWanted = nReserve;
x = pBt->pageSize - pBt->usableSize;
if( nReserve<x ) nReserve = x;
if( pBt->btsFlags & BTS_PAGESIZE_FIXED ){
sqlite3BtreeLeave(p);
return SQLITE_READONLY;
}
if( nReserve<0 ){
nReserve = pBt->pageSize - pBt->usableSize;
}
assert( nReserve>=0 && nReserve<=255 );
if( pageSize>=512 && pageSize<=SQLITE_MAX_PAGE_SIZE &&
((pageSize-1)&pageSize)==0 ){
@@ -2911,16 +2911,17 @@ int sqlite3BtreeGetReserveNoMutex(Btree *p){
** are intentually left unused. This is the "reserved" space that is
** sometimes used by extensions.
**
** If SQLITE_HAS_MUTEX is defined then the number returned is the
** greater of the current reserved space and the maximum requested
** reserve space.
** The value returned is the larger of the current reserve size and
** the latest reserve size requested by SQLITE_FILECTRL_RESERVE_BYTES.
** The amount of reserve can only grow - never shrink.
*/
int sqlite3BtreeGetOptimalReserve(Btree *p){
int n;
int sqlite3BtreeGetRequestedReserve(Btree *p){
int n1, n2;
sqlite3BtreeEnter(p);
n = sqlite3BtreeGetReserveNoMutex(p);
n1 = (int)p->pBt->nReserveWanted;
n2 = sqlite3BtreeGetReserveNoMutex(p);
sqlite3BtreeLeave(p);
return n;
return n1>n2 ? n1 : n2;
}
@@ -3370,6 +3371,7 @@ int sqlite3BtreeNewDb(Btree *p){
*/
int sqlite3BtreeBeginTrans(Btree *p, int wrflag, int *pSchemaVersion){
BtShared *pBt = p->pBt;
Pager *pPager = pBt->pPager;
int rc = SQLITE_OK;
sqlite3BtreeEnter(p);
@@ -3385,7 +3387,7 @@ int sqlite3BtreeBeginTrans(Btree *p, int wrflag, int *pSchemaVersion){
assert( pBt->inTransaction==TRANS_WRITE || IfNotOmitAV(pBt->bDoTruncate)==0 );
if( (p->db->flags & SQLITE_ResetDatabase)
&& sqlite3PagerIsreadonly(pBt->pPager)==0
&& sqlite3PagerIsreadonly(pPager)==0
){
pBt->btsFlags &= ~BTS_READ_ONLY;
}
@@ -3433,6 +3435,18 @@ int sqlite3BtreeBeginTrans(Btree *p, int wrflag, int *pSchemaVersion){
pBt->btsFlags &= ~BTS_INITIALLY_EMPTY;
if( pBt->nPage==0 ) pBt->btsFlags |= BTS_INITIALLY_EMPTY;
do {
sqlite3PagerWalDb(pPager, p->db);
#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
/* If transitioning from no transaction directly to a write transaction,
** block for the WRITER lock first if possible. */
if( pBt->pPage1==0 && wrflag ){
assert( pBt->inTransaction==TRANS_NONE );
rc = sqlite3PagerWalWriteLock(pPager, 1);
if( rc!=SQLITE_BUSY && rc!=SQLITE_OK ) break;
}
#endif
/* Call lockBtree() until either pBt->pPage1 is populated or
** lockBtree() returns something other than SQLITE_OK. lockBtree()
** may return SQLITE_OK but leave pBt->pPage1 set to 0 if after
@@ -3446,7 +3460,7 @@ int sqlite3BtreeBeginTrans(Btree *p, int wrflag, int *pSchemaVersion){
if( (pBt->btsFlags & BTS_READ_ONLY)!=0 ){
rc = SQLITE_READONLY;
}else{
rc = sqlite3PagerBegin(pBt->pPager,wrflag>1,sqlite3TempInMemory(p->db));
rc = sqlite3PagerBegin(pPager, wrflag>1, sqlite3TempInMemory(p->db));
if( rc==SQLITE_OK ){
rc = newDatabase(pBt);
}else if( rc==SQLITE_BUSY_SNAPSHOT && pBt->inTransaction==TRANS_NONE ){
@@ -3459,11 +3473,15 @@ int sqlite3BtreeBeginTrans(Btree *p, int wrflag, int *pSchemaVersion){
}
if( rc!=SQLITE_OK ){
(void)sqlite3PagerWalWriteLock(pPager, 0);
unlockBtreeIfUnused(pBt);
}
}while( (rc&0xFF)==SQLITE_BUSY && pBt->inTransaction==TRANS_NONE &&
btreeInvokeBusyHandler(pBt) );
sqlite3PagerResetLockTimeout(pBt->pPager);
sqlite3PagerWalDb(pPager, 0);
#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
if( rc==SQLITE_BUSY_TIMEOUT ) rc = SQLITE_BUSY;
#endif
if( rc==SQLITE_OK ){
if( p->inTrans==TRANS_NONE ){
@@ -3515,7 +3533,7 @@ trans_begun:
** open savepoints. If the second parameter is greater than 0 and
** the sub-journal is not already open, then it will be opened here.
*/
rc = sqlite3PagerOpenSavepoint(pBt->pPager, p->db->nSavepoint);
rc = sqlite3PagerOpenSavepoint(pPager, p->db->nSavepoint);
}
}
@@ -7151,7 +7169,7 @@ static int editPage(
assert( nCell>=0 );
if( iOld<iNew ){
int nShift = pageFreeArray(pPg, iOld, iNew-iOld, pCArray);
if( nShift>nCell ) return SQLITE_CORRUPT_BKPT;
if( NEVER(nShift>nCell) ) return SQLITE_CORRUPT_BKPT;
memmove(pPg->aCellIdx, &pPg->aCellIdx[nShift*2], nCell*2);
nCell -= nShift;
}
@@ -9508,7 +9526,6 @@ int sqlite3BtreeUpdateMeta(Btree *p, int idx, u32 iMeta){
return rc;
}
#ifndef SQLITE_OMIT_BTREECOUNT
/*
** The first argument, pCur, is a cursor opened on some b-tree. Count the
** number of entries in the b-tree and write the result to *pnEntry.
@@ -9530,7 +9547,7 @@ int sqlite3BtreeCount(sqlite3 *db, BtCursor *pCur, i64 *pnEntry){
/* Unless an error occurs, the following loop runs one iteration for each
** page in the B-Tree structure (not including overflow pages).
*/
while( rc==SQLITE_OK && !db->u1.isInterrupted ){
while( rc==SQLITE_OK && !AtomicLoad(&db->u1.isInterrupted) ){
int iIdx; /* Index of child node in parent */
MemPage *pPage; /* Current page of the b-tree */
@@ -9581,7 +9598,6 @@ int sqlite3BtreeCount(sqlite3 *db, BtCursor *pCur, i64 *pnEntry){
/* An error has occurred. Return an error code. */
return rc;
}
#endif
/*
** Return the pager associated with a BTree. This routine is used for
@@ -9656,7 +9672,7 @@ static int checkRef(IntegrityCk *pCheck, Pgno iPage){
checkAppendMsg(pCheck, "2nd reference to page %d", iPage);
return 1;
}
if( pCheck->db->u1.isInterrupted ) return 1;
if( AtomicLoad(&pCheck->db->u1.isInterrupted) ) return 1;
setPageReferenced(pCheck, iPage);
return 0;
}
+1 -3
View File
@@ -74,7 +74,7 @@ int sqlite3BtreeGetPageSize(Btree*);
int sqlite3BtreeMaxPageCount(Btree*,int);
u32 sqlite3BtreeLastPage(Btree*);
int sqlite3BtreeSecureDelete(Btree*,int);
int sqlite3BtreeGetOptimalReserve(Btree*);
int sqlite3BtreeGetRequestedReserve(Btree*);
int sqlite3BtreeGetReserveNoMutex(Btree *p);
int sqlite3BtreeSetAutoVacuum(Btree *, int);
int sqlite3BtreeGetAutoVacuum(Btree *);
@@ -336,9 +336,7 @@ int sqlite3BtreeCursorIsValid(BtCursor*);
#endif
int sqlite3BtreeCursorIsValidNN(BtCursor*);
#ifndef SQLITE_OMIT_BTREECOUNT
int sqlite3BtreeCount(sqlite3*, BtCursor*, i64*);
#endif
#ifdef SQLITE_TEST
int sqlite3BtreeCursorInfo(BtCursor*, int*, int);
+1
View File
@@ -417,6 +417,7 @@ struct BtShared {
#endif
u8 inTransaction; /* Transaction state */
u8 max1bytePayload; /* Maximum first byte of cell for a 1-byte payload */
u8 nReserveWanted; /* Desired number of extra bytes per page */
u16 btsFlags; /* Boolean parameters. See BTS_* macros below */
u16 maxLocal; /* Maximum local payload in non-LEAFDATA tables */
u16 minLocal; /* Minimum local payload in non-LEAFDATA tables */
+59 -23
View File
@@ -312,22 +312,39 @@ Table *sqlite3FindTable(sqlite3 *db, const char *zName, const char *zDatabase){
return 0;
}
#endif
while(1){
for(i=OMIT_TEMPDB; i<db->nDb; i++){
int j = (i<2) ? i^1 : i; /* Search TEMP before MAIN */
if( zDatabase==0 || sqlite3StrICmp(zDatabase, db->aDb[j].zDbSName)==0 ){
assert( sqlite3SchemaMutexHeld(db, j, 0) );
p = sqlite3HashFind(&db->aDb[j].pSchema->tblHash, zName);
if( p ) return p;
if( zDatabase ){
for(i=0; i<db->nDb; i++){
if( sqlite3StrICmp(zDatabase, db->aDb[i].zDbSName)==0 ) break;
}
if( i>=db->nDb ){
/* No match against the official names. But always match "main"
** to schema 0 as a legacy fallback. */
if( sqlite3StrICmp(zDatabase,"main")==0 ){
i = 0;
}else{
return 0;
}
}
/* Not found. If the name we were looking for was temp.sqlite_master
** then change the name to sqlite_temp_master and try again. */
if( sqlite3StrICmp(zName, MASTER_NAME)!=0 ) break;
if( sqlite3_stricmp(zDatabase, db->aDb[1].zDbSName)!=0 ) break;
zName = TEMP_MASTER_NAME;
p = sqlite3HashFind(&db->aDb[i].pSchema->tblHash, zName);
if( p==0 && i==1 && sqlite3StrICmp(zName, MASTER_NAME)==0 ){
/* All temp.sqlite_master to be an alias for sqlite_temp_master */
p = sqlite3HashFind(&db->aDb[1].pSchema->tblHash, TEMP_MASTER_NAME);
}
}else{
/* Match against TEMP first */
p = sqlite3HashFind(&db->aDb[1].pSchema->tblHash, zName);
if( p ) return p;
/* The main database is second */
p = sqlite3HashFind(&db->aDb[0].pSchema->tblHash, zName);
if( p ) return p;
/* Attached databases are in order of attachment */
for(i=2; i<db->nDb; i++){
assert( sqlite3SchemaMutexHeld(db, i, 0) );
p = sqlite3HashFind(&db->aDb[i].pSchema->tblHash, zName);
if( p ) break;
}
}
return 0;
return p;
}
/*
@@ -437,7 +454,7 @@ Index *sqlite3FindIndex(sqlite3 *db, const char *zName, const char *zDb){
int j = (i<2) ? i^1 : i; /* Search TEMP before MAIN */
Schema *pSchema = db->aDb[j].pSchema;
assert( pSchema );
if( zDb && sqlite3StrICmp(zDb, db->aDb[j].zDbSName) ) continue;
if( zDb && sqlite3DbIsNamed(db, j, zDb)==0 ) continue;
assert( sqlite3SchemaMutexHeld(db, j, 0) );
p = sqlite3HashFind(&pSchema->idxHash, zName);
if( p ) break;
@@ -590,6 +607,7 @@ void sqlite3DeleteColumnNames(sqlite3 *db, Table *pTable){
assert( pTable!=0 );
if( (pCol = pTable->aCol)!=0 ){
for(i=0; i<pTable->nCol; i++, pCol++){
assert( pCol->zName==0 || pCol->hName==sqlite3StrIHash(pCol->zName) );
sqlite3DbFree(db, pCol->zName);
sqlite3ExprDelete(db, pCol->pDflt);
sqlite3DbFree(db, pCol->zColl);
@@ -1238,6 +1256,7 @@ void sqlite3AddColumn(Parse *pParse, Token *pName, Token *pType){
pCol = &p->aCol[p->nCol];
memset(pCol, 0, sizeof(p->aCol[0]));
pCol->zName = z;
pCol->hName = sqlite3StrIHash(z);
sqlite3ColumnPropertiesFromName(p, pCol);
if( pType->n==0 ){
@@ -2129,6 +2148,28 @@ static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){
recomputeColumnsNotIndexed(pPk);
}
#ifndef SQLITE_OMIT_VIRTUALTABLE
/*
** Return true if pTab is a virtual table and zName is a shadow table name
** for that virtual table.
*/
int sqlite3IsShadowTableOf(sqlite3 *db, Table *pTab, const char *zName){
int nName; /* Length of zName */
Module *pMod; /* Module for the virtual table */
if( !IsVirtual(pTab) ) return 0;
nName = sqlite3Strlen30(pTab->zName);
if( sqlite3_strnicmp(zName, pTab->zName, nName)!=0 ) return 0;
if( zName[nName]!='_' ) return 0;
pMod = (Module*)sqlite3HashFind(&db->aModule, pTab->azModuleArg[0]);
if( pMod==0 ) return 0;
if( pMod->pModule->iVersion<3 ) return 0;
if( pMod->pModule->xShadowName==0 ) return 0;
return pMod->pModule->xShadowName(zName+nName+1);
}
#endif /* ifndef SQLITE_OMIT_VIRTUALTABLE */
#ifndef SQLITE_OMIT_VIRTUALTABLE
/*
** Return true if zName is a shadow table name in the current database
@@ -2140,8 +2181,6 @@ static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){
int sqlite3ShadowTableName(sqlite3 *db, const char *zName){
char *zTail; /* Pointer to the last "_" in zName */
Table *pTab; /* Table that zName is a shadow of */
Module *pMod; /* Module for the virtual table */
zTail = strrchr(zName, '_');
if( zTail==0 ) return 0;
*zTail = 0;
@@ -2149,14 +2188,11 @@ int sqlite3ShadowTableName(sqlite3 *db, const char *zName){
*zTail = '_';
if( pTab==0 ) return 0;
if( !IsVirtual(pTab) ) return 0;
pMod = (Module*)sqlite3HashFind(&db->aModule, pTab->azModuleArg[0]);
if( pMod==0 ) return 0;
if( pMod->pModule->iVersion<3 ) return 0;
if( pMod->pModule->xShadowName==0 ) return 0;
return pMod->pModule->xShadowName(zTail+1);
return sqlite3IsShadowTableOf(db, pTab, zName);
}
#endif /* ifndef SQLITE_OMIT_VIRTUALTABLE */
#ifdef SQLITE_DEBUG
/*
** Mark all nodes of an expression as EP_Immutable, indicating that
@@ -4628,7 +4664,7 @@ int sqlite3OpenTempDatabase(Parse *pParse){
}
db->aDb[1].pBt = pBt;
assert( db->aDb[1].pSchema );
if( SQLITE_NOMEM==sqlite3BtreeSetPageSize(pBt, db->nextPagesize, -1, 0) ){
if( SQLITE_NOMEM==sqlite3BtreeSetPageSize(pBt, db->nextPagesize, 0, 0) ){
sqlite3OomFault(db);
return 1;
}
@@ -4739,7 +4775,7 @@ void sqlite3HaltConstraint(
u8 p5Errmsg /* P5_ErrMsg type */
){
Vdbe *v = sqlite3GetVdbe(pParse);
assert( (errCode&0xff)==SQLITE_CONSTRAINT );
assert( (errCode&0xff)==SQLITE_CONSTRAINT || pParse->nested );
if( onError==OE_Abort ){
sqlite3MayAbort(pParse);
}
+3 -3
View File
@@ -193,6 +193,9 @@ static const char * const sqlite3azCompileOpt[] = {
#if SQLITE_ENABLE_BATCH_ATOMIC_WRITE
"ENABLE_BATCH_ATOMIC_WRITE",
#endif
#if SQLITE_ENABLE_BYTECODE_VTAB
"ENABLE_BYTECODE_VTAB",
#endif
#if SQLITE_ENABLE_CEROD
"ENABLE_CEROD=" CTIMEOPT_VAL(SQLITE_ENABLE_CEROD),
#endif
@@ -511,9 +514,6 @@ static const char * const sqlite3azCompileOpt[] = {
#if SQLITE_OMIT_BLOB_LITERAL
"OMIT_BLOB_LITERAL",
#endif
#if SQLITE_OMIT_BTREECOUNT
"OMIT_BTREECOUNT",
#endif
#if SQLITE_OMIT_CAST
"OMIT_CAST",
#endif
+6 -6
View File
@@ -621,12 +621,12 @@ static const struct {
double rLimit; /* Maximum NNN value for this transform */
double rXform; /* Constant used for this transform */
} aXformType[] = {
{ 0, 6, "second", 464269060800.0, 86400000.0/(24.0*60.0*60.0) },
{ 0, 6, "minute", 7737817680.0, 86400000.0/(24.0*60.0) },
{ 0, 4, "hour", 128963628.0, 86400000.0/24.0 },
{ 0, 3, "day", 5373485.0, 86400000.0 },
{ 1, 5, "month", 176546.0, 30.0*86400000.0 },
{ 2, 4, "year", 14713.0, 365.0*86400000.0 },
{ 0, 6, "second", 464269060800.0, 1000.0 },
{ 0, 6, "minute", 7737817680.0, 60000.0 },
{ 0, 4, "hour", 128963628.0, 3600000.0 },
{ 0, 3, "day", 5373485.0, 86400000.0 },
{ 1, 5, "month", 176546.0, 2592000000.0 },
{ 2, 4, "year", 14713.0, 31536000000.0 },
};
/*
+4 -1
View File
@@ -238,6 +238,7 @@ static int statBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
i = 0;
if( iSchema>=0 ){
pIdxInfo->aConstraintUsage[iSchema].argvIndex = ++i;
pIdxInfo->aConstraintUsage[iSchema].omit = 1;
pIdxInfo->idxNum |= 0x01;
}
if( iName>=0 ){
@@ -452,7 +453,9 @@ static int statDecodePage(Btree *pBt, StatPage *p){
if( nPayload>(u32)nLocal ){
int j;
int nOvfl = ((nPayload - nLocal) + nUsable-4 - 1) / (nUsable - 4);
if( iOff+nLocal>nUsable ) goto statPageIsCorrupt;
if( iOff+nLocal>nUsable || nPayload>0x7fffffff ){
goto statPageIsCorrupt;
}
pCell->nLastOvfl = (nPayload-nLocal) - (nOvfl-1) * (nUsable-4);
pCell->nOvfl = nOvfl;
pCell->aOvfl = sqlite3_malloc64(sizeof(u32)*nOvfl);
+1
View File
@@ -858,6 +858,7 @@ void sqlite3GenerateRowIndexDelete(
&iPartIdxLabel, pPrior, r1);
sqlite3VdbeAddOp3(v, OP_IdxDelete, iIdxCur+i, r1,
pIdx->uniqNotNull ? pIdx->nKeyCol : pIdx->nColumn);
sqlite3VdbeChangeP5(v, 1); /* Cause IdxDelete to error if no entry found */
sqlite3ResolvePartIdxLabel(pParse, iPartIdxLabel);
pPrior = pIdx;
}
+44 -36
View File
@@ -45,7 +45,7 @@ char sqlite3TableColumnAffinity(Table *pTab, int iCol){
char sqlite3ExprAffinity(const Expr *pExpr){
int op;
while( ExprHasProperty(pExpr, EP_Skip) ){
assert( pExpr->op==TK_COLLATE );
assert( pExpr->op==TK_COLLATE || pExpr->op==TK_IF_NULL_ROW );
pExpr = pExpr->pLeft;
assert( pExpr!=0 );
}
@@ -112,7 +112,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 );
assert( pExpr->op==TK_COLLATE || pExpr->op==TK_IF_NULL_ROW );
pExpr = pExpr->pLeft;
}
return pExpr;
@@ -131,7 +131,7 @@ Expr *sqlite3ExprSkipCollateAndLikely(Expr *pExpr){
assert( pExpr->op==TK_FUNCTION );
pExpr = pExpr->x.pList->a[0].pExpr;
}else{
assert( pExpr->op==TK_COLLATE );
assert( pExpr->op==TK_COLLATE || pExpr->op==TK_IF_NULL_ROW );
pExpr = pExpr->pLeft;
}
}
@@ -1787,6 +1787,7 @@ void sqlite3ExprListSetName(
int dequote /* True to cause the name to be dequoted */
){
assert( pList!=0 || pParse->db->mallocFailed!=0 );
assert( pParse->eParseMode!=PARSE_MODE_UNMAP || dequote==0 );
if( pList ){
struct ExprList_item *pItem;
assert( pList->nExpr>0 );
@@ -1794,9 +1795,14 @@ void sqlite3ExprListSetName(
assert( pItem->zEName==0 );
assert( pItem->eEName==ENAME_NAME );
pItem->zEName = sqlite3DbStrNDup(pParse->db, pName->z, pName->n);
if( dequote ) sqlite3Dequote(pItem->zEName);
if( IN_RENAME_OBJECT ){
sqlite3RenameTokenMap(pParse, (void*)pItem->zEName, pName);
if( dequote ){
/* If dequote==0, then pName->z does not point to part of a DDL
** statement handled by the parser. And so no token need be added
** to the token-map. */
sqlite3Dequote(pItem->zEName);
if( IN_RENAME_OBJECT ){
sqlite3RenameTokenMap(pParse, (void*)pItem->zEName, pName);
}
}
}
}
@@ -2941,6 +2947,8 @@ void sqlite3CodeRhsOfIN(
affinity = sqlite3ExprAffinity(pLeft);
if( affinity<=SQLITE_AFF_NONE ){
affinity = SQLITE_AFF_BLOB;
}else if( affinity==SQLITE_AFF_REAL ){
affinity = SQLITE_AFF_NUMERIC;
}
if( pKeyInfo ){
assert( sqlite3KeyInfoIsWriteable(pKeyInfo) );
@@ -3179,6 +3187,7 @@ static void sqlite3ExprCodeIN(
int destNotNull; /* Jump here if a comparison is not true in step 6 */
int addrTop; /* Top of the step-6 loop */
int iTab = 0; /* Index to use */
u8 okConstFactor = pParse->okConstFactor;
assert( !ExprHasVVAProperty(pExpr,EP_Immutable) );
pLeft = pExpr->pLeft;
@@ -3223,8 +3232,14 @@ static void sqlite3ExprCodeIN(
** so that the fields are in the same order as an existing index. The
** aiMap[] array contains a mapping from the original LHS field order to
** the field order that matches the RHS index.
*/
**
** Avoid factoring the LHS of the IN(...) expression out of the loop,
** even if it is constant, as OP_Affinity may be used on the register
** by code generated below. */
assert( pParse->okConstFactor==okConstFactor );
pParse->okConstFactor = 0;
rLhsOrig = exprCodeVector(pParse, pLeft, &iDummy);
pParse->okConstFactor = okConstFactor;
for(i=0; i<nVector && aiMap[i]==i; i++){} /* Are LHS fields reordered? */
if( i==nVector ){
/* LHS fields are not reordered */
@@ -3250,21 +3265,13 @@ static void sqlite3ExprCodeIN(
int r2, regToFree;
int regCkNull = 0;
int ii;
int bLhsReal; /* True if the LHS of the IN has REAL affinity */
assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
if( destIfNull!=destIfFalse ){
regCkNull = sqlite3GetTempReg(pParse);
sqlite3VdbeAddOp3(v, OP_BitAnd, rLhs, rLhs, regCkNull);
}
bLhsReal = sqlite3ExprAffinity(pExpr->pLeft)==SQLITE_AFF_REAL;
for(ii=0; ii<pList->nExpr; ii++){
if( bLhsReal ){
r2 = regToFree = sqlite3GetTempReg(pParse);
sqlite3ExprCode(pParse, pList->a[ii].pExpr, r2);
sqlite3VdbeAddOp4(v, OP_Affinity, r2, 1, 0, "E", P4_STATIC);
}else{
r2 = sqlite3ExprCodeTemp(pParse, pList->a[ii].pExpr, &regToFree);
}
r2 = sqlite3ExprCodeTemp(pParse, pList->a[ii].pExpr, &regToFree);
if( regCkNull && sqlite3ExprCanBeNull(pList->a[ii].pExpr) ){
sqlite3VdbeAddOp3(v, OP_BitAnd, regCkNull, r2, regCkNull);
}
@@ -3693,6 +3700,13 @@ static int exprCodeInlineFunction(
sqlite3VdbeResolveLabel(v, endCoalesce);
break;
}
case INLINEFUNC_iif: {
Expr caseExpr;
memset(&caseExpr, 0, sizeof(caseExpr));
caseExpr.op = TK_CASE;
caseExpr.x.pList = pFarg;
return sqlite3ExprCodeTarget(pParse, &caseExpr, target);
}
default: {
/* The UNLIKELY() function is a no-op. The result is the value
@@ -3797,7 +3811,10 @@ expr_code_doover:
switch( op ){
case TK_AGG_COLUMN: {
AggInfo *pAggInfo = pExpr->pAggInfo;
struct AggInfo_col *pCol = &pAggInfo->aCol[pExpr->iAgg];
struct AggInfo_col *pCol;
assert( pAggInfo!=0 );
assert( pExpr->iAgg>=0 && pExpr->iAgg<pAggInfo->nColumn );
pCol = &pAggInfo->aCol[pExpr->iAgg];
if( !pAggInfo->directMode ){
assert( pCol->iMem>0 );
return pCol->iMem;
@@ -3838,10 +3855,6 @@ expr_code_doover:
static const char zAff[] = "B\000C\000D\000E";
assert( SQLITE_AFF_BLOB=='A' );
assert( SQLITE_AFF_TEXT=='B' );
if( iReg!=target ){
sqlite3VdbeAddOp2(v, OP_SCopy, iReg, target);
iReg = target;
}
sqlite3VdbeAddOp4(v, OP_Affinity, iReg, 1, 0,
&zAff[(aff-'B')*2], P4_STATIC);
}
@@ -4101,7 +4114,10 @@ expr_code_doover:
}
case TK_AGG_FUNCTION: {
AggInfo *pInfo = pExpr->pAggInfo;
if( pInfo==0 ){
if( pInfo==0
|| NEVER(pExpr->iAgg<0)
|| NEVER(pExpr->iAgg>=pInfo->nFunc)
){
assert( !ExprHasProperty(pExpr, EP_IntValue) );
sqlite3ErrorMsg(pParse, "misuse of aggregate: %s()", pExpr->u.zToken);
}else{
@@ -4479,7 +4495,7 @@ expr_code_doover:
|| pExpr->affExpr==OE_Fail
|| pExpr->affExpr==OE_Ignore
);
if( !pParse->pTriggerTab ){
if( !pParse->pTriggerTab && !pParse->nested ){
sqlite3ErrorMsg(pParse,
"RAISE() may only be used within a trigger-program");
return 0;
@@ -4493,8 +4509,9 @@ expr_code_doover:
v, OP_Halt, SQLITE_OK, OE_Ignore, 0, pExpr->u.zToken,0);
VdbeCoverage(v);
}else{
sqlite3HaltConstraint(pParse, SQLITE_CONSTRAINT_TRIGGER,
pExpr->affExpr, pExpr->u.zToken, 0, 0);
sqlite3HaltConstraint(pParse,
pParse->pTriggerTab ? SQLITE_CONSTRAINT_TRIGGER : SQLITE_ERROR,
pExpr->affExpr, pExpr->u.zToken, 0, 0);
}
break;
@@ -5856,15 +5873,6 @@ static int analyzeAggregate(Walker *pWalker, Expr *pExpr){
}
return WRC_Continue;
}
static int analyzeAggregatesInSelect(Walker *pWalker, Select *pSelect){
UNUSED_PARAMETER(pSelect);
pWalker->walkerDepth++;
return WRC_Continue;
}
static void analyzeAggregatesInSelectEnd(Walker *pWalker, Select *pSelect){
UNUSED_PARAMETER(pSelect);
pWalker->walkerDepth--;
}
/*
** Analyze the pExpr expression looking for aggregate functions and
@@ -5878,8 +5886,8 @@ static void analyzeAggregatesInSelectEnd(Walker *pWalker, Select *pSelect){
void sqlite3ExprAnalyzeAggregates(NameContext *pNC, Expr *pExpr){
Walker w;
w.xExprCallback = analyzeAggregate;
w.xSelectCallback = analyzeAggregatesInSelect;
w.xSelectCallback2 = analyzeAggregatesInSelectEnd;
w.xSelectCallback = sqlite3WalkerDepthIncrease;
w.xSelectCallback2 = sqlite3WalkerDepthDecrease;
w.walkerDepth = 0;
w.u.pNC = pNC;
w.pParse = 0;
+25 -13
View File
@@ -853,6 +853,7 @@ static void likeFunc(
int nPat;
sqlite3 *db = sqlite3_context_db_handle(context);
struct compareInfo *pInfo = sqlite3_user_data(context);
struct compareInfo backupInfo;
#ifdef SQLITE_LIKE_DOESNT_MATCH_BLOBS
if( sqlite3_value_type(argv[0])==SQLITE_BLOB
@@ -888,6 +889,12 @@ static void likeFunc(
return;
}
escape = sqlite3Utf8Read(&zEsc);
if( escape==pInfo->matchAll || escape==pInfo->matchOne ){
memcpy(&backupInfo, pInfo, sizeof(backupInfo));
pInfo = &backupInfo;
if( escape==pInfo->matchAll ) pInfo->matchAll = 0;
if( escape==pInfo->matchOne ) pInfo->matchOne = 0;
}
}else{
escape = pInfo->matchSet;
}
@@ -1276,7 +1283,7 @@ static void replaceFunc(
** whose index is a power of two: 1, 2, 4, 8, 16, 32, ... */
u8 *zOld;
zOld = zOut;
zOut = sqlite3_realloc64(zOut, (int)nOut + (nOut - nStr - 1));
zOut = sqlite3Realloc(zOut, (int)nOut + (nOut - nStr - 1));
if( zOut==0 ){
sqlite3_result_error_nomem(context);
sqlite3_free(zOld);
@@ -1870,16 +1877,6 @@ int sqlite3IsLikeFunction(sqlite3 *db, Expr *pExpr, int *pIsNocase, char *aWc){
if( NEVER(pDef==0) || (pDef->funcFlags & SQLITE_FUNC_LIKE)==0 ){
return 0;
}
if( nExpr<3 ){
aWc[3] = 0;
}else{
Expr *pEscape = pExpr->x.pList->a[2].pExpr;
char *zEscape;
if( pEscape->op!=TK_STRING ) return 0;
zEscape = pEscape->u.zToken;
if( zEscape[0]==0 || zEscape[1]!=0 ) return 0;
aWc[3] = zEscape[0];
}
/* The memcpy() statement assumes that the wildcard characters are
** the first three statements in the compareInfo structure. The
@@ -1889,6 +1886,20 @@ int sqlite3IsLikeFunction(sqlite3 *db, Expr *pExpr, int *pIsNocase, char *aWc){
assert( (char*)&likeInfoAlt == (char*)&likeInfoAlt.matchAll );
assert( &((char*)&likeInfoAlt)[1] == (char*)&likeInfoAlt.matchOne );
assert( &((char*)&likeInfoAlt)[2] == (char*)&likeInfoAlt.matchSet );
if( nExpr<3 ){
aWc[3] = 0;
}else{
Expr *pEscape = pExpr->x.pList->a[2].pExpr;
char *zEscape;
if( pEscape->op!=TK_STRING ) return 0;
zEscape = pEscape->u.zToken;
if( zEscape[0]==0 || zEscape[1]!=0 ) return 0;
if( zEscape[0]==aWc[0] ) return 0;
if( zEscape[0]==aWc[1] ) return 0;
aWc[3] = zEscape[0];
}
*pIsNocase = (pDef->funcFlags & SQLITE_FUNC_CASE)==0;
return 1;
}
@@ -1969,7 +1980,7 @@ void sqlite3RegisterBuiltinFunctions(void){
FUNCTION(upper, 1, 0, 0, upperFunc ),
FUNCTION(lower, 1, 0, 0, lowerFunc ),
FUNCTION(hex, 1, 0, 0, hexFunc ),
INLINE_FUNC(ifnull, 2, INLINEFUNC_coalesce, SQLITE_FUNC_COALESCE),
INLINE_FUNC(ifnull, 2, INLINEFUNC_coalesce, 0 ),
VFUNCTION(random, 0, 0, 0, randomFunc ),
VFUNCTION(randomblob, 1, 0, 0, randomBlob ),
FUNCTION(nullif, 2, 0, 1, nullifFunc ),
@@ -2009,7 +2020,8 @@ void sqlite3RegisterBuiltinFunctions(void){
#endif
FUNCTION(coalesce, 1, 0, 0, 0 ),
FUNCTION(coalesce, 0, 0, 0, 0 ),
INLINE_FUNC(coalesce, -1, INLINEFUNC_coalesce, SQLITE_FUNC_COALESCE),
INLINE_FUNC(coalesce, -1, INLINEFUNC_coalesce, 0 ),
INLINE_FUNC(iif, 3, INLINEFUNC_iif, 0 ),
};
#ifndef SQLITE_OMIT_ALTERTABLE
sqlite3AlterFunctions();
+1 -1
View File
@@ -1944,7 +1944,7 @@ void sqlite3GenerateConstraintChecks(
sqlite3TableAffinity(v, pTab, regNewData+1);
bAffinityDone = 1;
}
VdbeNoopComment((v, "uniqueness check for %s", pIdx->zName));
VdbeNoopComment((v, "prep index %s", pIdx->zName));
iThisCur = iIdxCur+ix;
+10 -1
View File
@@ -477,8 +477,17 @@ static const sqlite3_api_routines sqlite3Apis = {
/* Version 3.32.0 and later */
sqlite3_create_filename,
sqlite3_free_filename,
sqlite3_database_file_object,
};
/* True if x is the directory separator character
*/
#if SQLITE_OS_WIN
# define DirSep(X) ((X)=='/'||(X)=='\\')
#else
# define DirSep(X) ((X)=='/')
#endif
/*
** Attempt to load an SQLite extension library contained in the file
** zFile. The entry point is zProc. zProc may be 0 in which case a
@@ -580,7 +589,7 @@ static int sqlite3LoadExtension(
return SQLITE_NOMEM_BKPT;
}
memcpy(zAltEntry, "sqlite3_", 8);
for(iFile=ncFile-1; iFile>=0 && zFile[iFile]!='/'; iFile--){}
for(iFile=ncFile-1; iFile>=0 && !DirSep(zFile[iFile]); iFile--){}
iFile++;
if( sqlite3_strnicmp(zFile+iFile, "lib", 3)==0 ) iFile += 3;
for(iEntry=8; (c = zFile[iFile])!=0 && c!='.'; iFile++){
+87 -111
View File
@@ -25,15 +25,78 @@
#if defined(SQLITE_ENABLE_ICU) || defined(SQLITE_ENABLE_ICU_COLLATIONS)
# include "sqliteicu.h"
#endif
/*
** This is an extension initializer that is a no-op and always
** succeeds, except that it fails if the fault-simulation is set
** to 500.
*/
static int sqlite3TestExtInit(sqlite3 *db){
(void)db;
return sqlite3FaultSim(500);
}
/*
** Forward declarations of external module initializer functions
** for modules that need them.
*/
#ifdef SQLITE_ENABLE_FTS1
int sqlite3Fts1Init(sqlite3*);
#endif
#ifdef SQLITE_ENABLE_FTS2
int sqlite3Fts2Init(sqlite3*);
#endif
#ifdef SQLITE_ENABLE_FTS5
int sqlite3Fts5Init(sqlite3*);
#endif
#ifdef SQLITE_ENABLE_JSON1
int sqlite3Json1Init(sqlite3*);
#endif
#ifdef SQLITE_ENABLE_STMTVTAB
int sqlite3StmtVtabInit(sqlite3*);
#endif
#ifdef SQLITE_ENABLE_FTS5
int sqlite3Fts5Init(sqlite3*);
/*
** An array of pointers to extension initializer functions for
** built-in extensions.
*/
static int (*const sqlite3BuiltinExtensions[])(sqlite3*) = {
#ifdef SQLITE_ENABLE_FTS1
sqlite3Fts1Init,
#endif
#ifdef SQLITE_ENABLE_FTS2
sqlite3Fts2Init,
#endif
#ifdef SQLITE_ENABLE_FTS3
sqlite3Fts3Init,
#endif
#ifdef SQLITE_ENABLE_FTS5
sqlite3Fts5Init,
#endif
#if defined(SQLITE_ENABLE_ICU) || defined(SQLITE_ENABLE_ICU_COLLATIONS)
sqlite3IcuInit,
#endif
#ifdef SQLITE_ENABLE_RTREE
sqlite3RtreeInit,
#endif
#ifdef SQLITE_ENABLE_DBPAGE_VTAB
sqlite3DbpageRegister,
#endif
#ifdef SQLITE_ENABLE_DBSTAT_VTAB
sqlite3DbstatRegister,
#endif
sqlite3TestExtInit,
#ifdef SQLITE_ENABLE_JSON1
sqlite3Json1Init,
#endif
#ifdef SQLITE_ENABLE_STMTVTAB
sqlite3StmtVtabInit,
#endif
#ifdef SQLITE_ENABLE_BYTECODE_VTAB
sqlite3VdbeBytecodeVtabInit,
#endif
};
#ifndef SQLITE_AMALGAMATION
/* IMPLEMENTATION-OF: R-46656-45156 The sqlite3_version[] string constant
@@ -250,6 +313,7 @@ int sqlite3_initialize(void){
if( rc==SQLITE_OK ){
sqlite3PCacheBufferSetup( sqlite3GlobalConfig.pPage,
sqlite3GlobalConfig.szPage, sqlite3GlobalConfig.nPage);
sqlite3MemoryBarrier();
sqlite3GlobalConfig.isInit = 1;
#ifdef SQLITE_EXTRA_INIT
bRunExtraInit = 1;
@@ -1551,8 +1615,7 @@ const char *sqlite3ErrStr(int rc){
*/
static int sqliteDefaultBusyCallback(
void *ptr, /* Database connection */
int count, /* Number of times table has been busy */
sqlite3_file *pFile /* The file on which the lock occurred */
int count /* Number of times table has been busy */
){
#if SQLITE_OS_WIN || HAVE_USLEEP
/* This case is for systems that have support for sleeping for fractions of
@@ -1566,19 +1629,6 @@ static int sqliteDefaultBusyCallback(
int tmout = db->busyTimeout;
int delay, prior;
#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
if( sqlite3OsFileControl(pFile,SQLITE_FCNTL_LOCK_TIMEOUT,&tmout)==SQLITE_OK ){
if( count ){
tmout = 0;
sqlite3OsFileControl(pFile, SQLITE_FCNTL_LOCK_TIMEOUT, &tmout);
return 0;
}else{
return 1;
}
}
#else
UNUSED_PARAMETER(pFile);
#endif
assert( count>=0 );
if( count < NDELAY ){
delay = delays[count];
@@ -1598,7 +1648,6 @@ static int sqliteDefaultBusyCallback(
** must be done in increments of whole seconds */
sqlite3 *db = (sqlite3 *)ptr;
int tmout = ((sqlite3 *)ptr)->busyTimeout;
UNUSED_PARAMETER(pFile);
if( (count+1)*1000 > tmout ){
return 0;
}
@@ -1616,19 +1665,10 @@ static int sqliteDefaultBusyCallback(
** If this routine returns non-zero, the lock is retried. If it
** returns 0, the operation aborts with an SQLITE_BUSY error.
*/
int sqlite3InvokeBusyHandler(BusyHandler *p, sqlite3_file *pFile){
int sqlite3InvokeBusyHandler(BusyHandler *p){
int rc;
if( p->xBusyHandler==0 || p->nBusy<0 ) return 0;
if( p->bExtraFileArg ){
/* Add an extra parameter with the pFile pointer to the end of the
** callback argument list */
int (*xTra)(void*,int,sqlite3_file*);
xTra = (int(*)(void*,int,sqlite3_file*))p->xBusyHandler;
rc = xTra(p->pBusyArg, p->nBusy, pFile);
}else{
/* Legacy style busy handler callback */
rc = p->xBusyHandler(p->pBusyArg, p->nBusy);
}
rc = p->xBusyHandler(p->pBusyArg, p->nBusy);
if( rc==0 ){
p->nBusy = -1;
}else{
@@ -1653,7 +1693,6 @@ int sqlite3_busy_handler(
db->busyHandler.xBusyHandler = xBusy;
db->busyHandler.pBusyArg = pArg;
db->busyHandler.nBusy = 0;
db->busyHandler.bExtraFileArg = 0;
db->busyTimeout = 0;
sqlite3_mutex_leave(db->mutex);
return SQLITE_OK;
@@ -1704,7 +1743,6 @@ int sqlite3_busy_timeout(sqlite3 *db, int ms){
sqlite3_busy_handler(db, (int(*)(void*,int))sqliteDefaultBusyCallback,
(void*)db);
db->busyTimeout = ms;
db->busyHandler.bExtraFileArg = 1;
}else{
sqlite3_busy_handler(db, 0, 0);
}
@@ -1721,7 +1759,7 @@ void sqlite3_interrupt(sqlite3 *db){
return;
}
#endif
db->u1.isInterrupted = 1;
AtomicStore(&db->u1.isInterrupted, 1);
}
@@ -2343,7 +2381,7 @@ int sqlite3_wal_checkpoint_v2(
/* If there are no active statements, clear the interrupt flag at this
** point. */
if( db->nVdbeActive==0 ){
db->u1.isInterrupted = 0;
AtomicStore(&db->u1.isInterrupted, 0);
}
sqlite3_mutex_leave(db->mutex);
@@ -3030,6 +3068,7 @@ static int openDatabase(
int isThreadsafe; /* True for threadsafe connections */
char *zOpen = 0; /* Filename argument to pass to BtreeOpen() */
char *zErrMsg = 0; /* Error message from sqlite3ParseUri() */
int i; /* Loop counter */
#ifdef SQLITE_ENABLE_API_ARMOR
if( ppDb==0 ) return SQLITE_MISUSE_BKPT;
@@ -3177,6 +3216,9 @@ static int openDatabase(
#endif
#if defined(SQLITE_DEFAULT_DEFENSIVE)
| SQLITE_Defensive
#endif
#if defined(SQLITE_DEFAULT_LEGACY_ALTER_TABLE)
| SQLITE_LegacyAlter
#endif
;
sqlite3HashInit(&db->aCollSeq);
@@ -3220,7 +3262,7 @@ static int openDatabase(
testcase( (1<<(flags&7))==0x04 ); /* READWRITE */
testcase( (1<<(flags&7))==0x40 ); /* READWRITE | CREATE */
if( ((1<<(flags&7)) & 0x46)==0 ){
rc = SQLITE_MISUSE_BKPT; /* IMP: R-65497-44594 */
rc = SQLITE_MISUSE_BKPT; /* IMP: R-18321-05872 */
}else{
rc = sqlite3ParseUri(zVfs, zFilename, &flags, &db->pVfs, &zOpen, &zErrMsg);
}
@@ -3270,14 +3312,11 @@ static int openDatabase(
sqlite3RegisterPerConnectionBuiltinFunctions(db);
rc = sqlite3_errcode(db);
#ifdef SQLITE_ENABLE_FTS5
/* Register any built-in FTS5 module before loading the automatic
** extensions. This allows automatic extensions to register FTS5
** tokenizers and auxiliary functions. */
if( !db->mallocFailed && rc==SQLITE_OK ){
rc = sqlite3Fts5Init(db);
/* Load compiled-in extensions */
for(i=0; rc==SQLITE_OK && i<ArraySize(sqlite3BuiltinExtensions); i++){
rc = sqlite3BuiltinExtensions[i](db);
}
#endif
/* Load automatic extensions - extensions that have been registered
** using the sqlite3_automatic_extension() API.
@@ -3290,62 +3329,6 @@ static int openDatabase(
}
}
#ifdef SQLITE_ENABLE_FTS1
if( !db->mallocFailed ){
extern int sqlite3Fts1Init(sqlite3*);
rc = sqlite3Fts1Init(db);
}
#endif
#ifdef SQLITE_ENABLE_FTS2
if( !db->mallocFailed && rc==SQLITE_OK ){
extern int sqlite3Fts2Init(sqlite3*);
rc = sqlite3Fts2Init(db);
}
#endif
#ifdef SQLITE_ENABLE_FTS3 /* automatically defined by SQLITE_ENABLE_FTS4 */
if( !db->mallocFailed && rc==SQLITE_OK ){
rc = sqlite3Fts3Init(db);
}
#endif
#if defined(SQLITE_ENABLE_ICU) || defined(SQLITE_ENABLE_ICU_COLLATIONS)
if( !db->mallocFailed && rc==SQLITE_OK ){
rc = sqlite3IcuInit(db);
}
#endif
#ifdef SQLITE_ENABLE_RTREE
if( !db->mallocFailed && rc==SQLITE_OK){
rc = sqlite3RtreeInit(db);
}
#endif
#ifdef SQLITE_ENABLE_DBPAGE_VTAB
if( !db->mallocFailed && rc==SQLITE_OK){
rc = sqlite3DbpageRegister(db);
}
#endif
#ifdef SQLITE_ENABLE_DBSTAT_VTAB
if( !db->mallocFailed && rc==SQLITE_OK){
rc = sqlite3DbstatRegister(db);
}
#endif
#ifdef SQLITE_ENABLE_JSON1
if( !db->mallocFailed && rc==SQLITE_OK){
rc = sqlite3Json1Init(db);
}
#endif
#ifdef SQLITE_ENABLE_STMTVTAB
if( !db->mallocFailed && rc==SQLITE_OK){
rc = sqlite3StmtVtabInit(db);
}
#endif
#ifdef SQLITE_ENABLE_INTERNAL_FUNCTIONS
/* Testing use only!!! The -DSQLITE_ENABLE_INTERNAL_FUNCTIONS=1 compile-time
** option gives access to internal functions by default.
@@ -3831,6 +3814,13 @@ int sqlite3_file_control(sqlite3 *db, const char *zDbName, int op, void *pArg){
}else if( op==SQLITE_FCNTL_DATA_VERSION ){
*(unsigned int*)pArg = sqlite3PagerDataVersion(pPager);
rc = SQLITE_OK;
}else if( op==SQLITE_FCNTL_RESERVE_BYTES ){
int iNew = *(int*)pArg;
*(int*)pArg = sqlite3BtreeGetRequestedReserve(pBtree);
if( iNew>=0 && iNew<=255 ){
sqlite3BtreeSetPageSize(pBtree, 0, iNew, 0);
}
rc = SQLITE_OK;
}else{
rc = sqlite3OsFileControl(fd, op, pArg);
}
@@ -4047,20 +4037,6 @@ int sqlite3_test_control(int op, ...){
break;
}
/* sqlite3_test_control(SQLITE_TESTCTRL_RESERVE, sqlite3 *db, int N)
**
** Set the nReserve size to N for the main database on the database
** connection db.
*/
case SQLITE_TESTCTRL_RESERVE: {
sqlite3 *db = va_arg(ap, sqlite3*);
int x = va_arg(ap,int);
sqlite3_mutex_enter(db->mutex);
sqlite3BtreeSetPageSize(db->aDb[0].pBt, 0, x, 0);
sqlite3_mutex_leave(db->mutex);
break;
}
/* sqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS, sqlite3 *db, int N)
**
** Enable or disable various optimizations for testing purposes. The
+9 -7
View File
@@ -111,7 +111,7 @@ sqlite3_int64 sqlite3_soft_heap_limit64(sqlite3_int64 n){
}
mem0.alarmThreshold = n;
nUsed = sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED);
mem0.nearlyFull = (n>0 && n<=nUsed);
AtomicStore(&mem0.nearlyFull, n>0 && n<=nUsed);
sqlite3_mutex_leave(mem0.mutex);
excess = sqlite3_memory_used() - n;
if( excess>0 ) sqlite3_release_memory((int)(excess & 0x7fffffff));
@@ -179,7 +179,7 @@ int sqlite3MallocInit(void){
** sqlite3_soft_heap_limit().
*/
int sqlite3HeapNearlyFull(void){
return mem0.nearlyFull;
return AtomicLoad(&mem0.nearlyFull);
}
/*
@@ -243,7 +243,7 @@ static void mallocWithAlarm(int n, void **pp){
if( mem0.alarmThreshold>0 ){
sqlite3_int64 nUsed = sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED);
if( nUsed >= mem0.alarmThreshold - nFull ){
mem0.nearlyFull = 1;
AtomicStore(&mem0.nearlyFull, 1);
sqlite3MallocAlarm(nFull);
if( mem0.hardLimit ){
nUsed = sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED);
@@ -253,7 +253,7 @@ static void mallocWithAlarm(int n, void **pp){
}
}
}else{
mem0.nearlyFull = 0;
AtomicStore(&mem0.nearlyFull, 0);
}
}
p = sqlite3GlobalConfig.m.xMalloc(nFull);
@@ -482,10 +482,12 @@ void *sqlite3Realloc(void *pOld, u64 nBytes){
sqlite3MallocAlarm(nDiff);
}
pNew = sqlite3GlobalConfig.m.xRealloc(pOld, nNew);
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
if( pNew==0 && mem0.alarmThreshold>0 ){
sqlite3MallocAlarm((int)nBytes);
pNew = sqlite3GlobalConfig.m.xRealloc(pOld, nNew);
}
#endif
if( pNew ){
nNew = sqlite3MallocSize(pNew);
sqlite3StatusUp(SQLITE_STATUS_MEMORY_USED, nNew-nOld);
@@ -670,7 +672,7 @@ static SQLITE_NOINLINE void *dbReallocFinish(sqlite3 *db, void *p, u64 n){
assert( sqlite3MemdebugHasType(p, (MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) );
assert( sqlite3MemdebugNoType(p, (u8)~(MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) );
sqlite3MemdebugSetType(p, MEMTYPE_HEAP);
pNew = sqlite3_realloc64(p, n);
pNew = sqlite3Realloc(p, n);
if( !pNew ){
sqlite3OomFault(db);
}
@@ -760,7 +762,7 @@ void sqlite3OomFault(sqlite3 *db){
if( db->mallocFailed==0 && db->bBenignMalloc==0 ){
db->mallocFailed = 1;
if( db->nVdbeExec>0 ){
db->u1.isInterrupted = 1;
AtomicStore(&db->u1.isInterrupted, 1);
}
DisableLookaside;
if( db->pParse ){
@@ -779,7 +781,7 @@ void sqlite3OomFault(sqlite3 *db){
void sqlite3OomClear(sqlite3 *db){
if( db->mallocFailed && db->nVdbeExec==0 ){
db->mallocFailed = 0;
db->u1.isInterrupted = 0;
AtomicStore(&db->u1.isInterrupted, 0);
assert( db->lookaside.bDisable>0 );
EnableLookaside;
}
+6 -5
View File
@@ -166,7 +166,7 @@ static int memdbEnlarge(MemFile *p, sqlite3_int64 newSz){
}
newSz *= 2;
if( newSz>p->szMax ) newSz = p->szMax;
pNew = sqlite3_realloc64(p->aData, newSz);
pNew = sqlite3Realloc(p->aData, newSz);
if( pNew==0 ) return SQLITE_NOMEM;
p->aData = pNew;
p->szAlloc = newSz;
@@ -613,10 +613,11 @@ int sqlite3MemdbInit(void){
sqlite3_vfs *pLower = sqlite3_vfs_find(0);
int sz = pLower->szOsFile;
memdb_vfs.pAppData = pLower;
/* In all known configurations of SQLite, the size of a default
** sqlite3_file is greater than the size of a memdb sqlite3_file.
** Should that ever change, remove the following NEVER() */
if( NEVER(sz<sizeof(MemFile)) ) sz = sizeof(MemFile);
/* The following conditional can only be true when compiled for
** Windows x86 and SQLITE_MAX_MMAP_SIZE=0. We always leave
** it in, to be safe, but it is marked as NO_TEST since there
** is no way to reach it under most builds. */
if( sz<sizeof(MemFile) ) sz = sizeof(MemFile); /*NO_TEST*/
memdb_vfs.szOsFile = sz;
return sqlite3_vfs_register(&memdb_vfs, 0);
}
+34 -5
View File
@@ -1565,8 +1565,9 @@ static int osSetPosixAdvisoryLock(
struct flock *pLock, /* The description of the lock */
unixFile *pFile /* Structure holding timeout value */
){
int tm = pFile->iBusyTimeout;
int rc = osFcntl(h,F_SETLK,pLock);
while( rc<0 && pFile->iBusyTimeout>0 ){
while( rc<0 && tm>0 ){
/* On systems that support some kind of blocking file lock with a timeout,
** make appropriate changes here to invoke that blocking file lock. On
** generic posix, however, there is no such API. So we simply try the
@@ -1574,7 +1575,7 @@ static int osSetPosixAdvisoryLock(
** the lock is obtained. */
usleep(1000);
rc = osFcntl(h,F_SETLK,pLock);
pFile->iBusyTimeout--;
tm--;
}
return rc;
}
@@ -3685,7 +3686,7 @@ static int openDirectory(const char *zFilename, int *pFd){
if( zDirname[0]!='/' ) zDirname[0] = '.';
zDirname[1] = 0;
}
fd = robust_open(zDirname, O_RDONLY|O_BINARY|O_NOFOLLOW, 0);
fd = robust_open(zDirname, O_RDONLY|O_BINARY, 0);
if( fd>=0 ){
OSTRACE(("OPENDIR %-3d %s\n", fd, zDirname));
}
@@ -3995,7 +3996,9 @@ static int unixFileControl(sqlite3_file *id, int op, void *pArg){
}
#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
case SQLITE_FCNTL_LOCK_TIMEOUT: {
int iOld = pFile->iBusyTimeout;
pFile->iBusyTimeout = *(int*)pArg;
*(int*)pArg = iOld;
return SQLITE_OK;
}
#endif
@@ -4314,13 +4317,20 @@ static int unixShmSystemLock(
assert( n>=1 && n<=SQLITE_SHM_NLOCK );
if( pShmNode->hShm>=0 ){
int res;
/* Initialize the locking parameters */
f.l_type = lockType;
f.l_whence = SEEK_SET;
f.l_start = ofst;
f.l_len = n;
rc = osSetPosixAdvisoryLock(pShmNode->hShm, &f, pFile);
rc = (rc!=(-1)) ? SQLITE_OK : SQLITE_BUSY;
res = osSetPosixAdvisoryLock(pShmNode->hShm, &f, pFile);
if( res==-1 ){
#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
rc = (pFile->iBusyTimeout ? SQLITE_BUSY_TIMEOUT : SQLITE_BUSY);
#else
rc = SQLITE_BUSY;
#endif
}
}
/* Update the global lock state and do debug tracing */
@@ -4817,6 +4827,25 @@ static int unixShmLock(
assert( pShmNode->hShm>=0 || pDbFd->pInode->bProcessLock==1 );
assert( pShmNode->hShm<0 || pDbFd->pInode->bProcessLock==0 );
/* Check that, if this to be a blocking lock, no locks that occur later
** in the following list than the lock being obtained are already held:
**
** 1. Checkpointer lock (ofst==1).
** 2. Write lock (ofst==0).
** 3. Read locks (ofst>=3 && ofst<SQLITE_SHM_NLOCK).
**
** In other words, if this is a blocking lock, none of the locks that
** occur later in the above list than the lock being obtained may be
** held. */
#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
assert( (flags & SQLITE_SHM_UNLOCK) || pDbFd->iBusyTimeout==0 || (
(ofst!=2) /* not RECOVER */
&& (ofst!=1 || (p->exclMask|p->sharedMask)==0)
&& (ofst!=0 || (p->exclMask|p->sharedMask)<3)
&& (ofst<3 || (p->exclMask|p->sharedMask)<(1<<ofst))
));
#endif
mask = (1<<(ofst+n)) - (1<<ofst);
assert( n>1 || mask==(1<<ofst) );
sqlite3_mutex_enter(pShmNode->pShmMutex);
+19 -4
View File
@@ -3502,6 +3502,7 @@ static void winModeBit(winFile *pFile, unsigned char mask, int *pArg){
/* Forward references to VFS helper methods used for temporary files */
static int winGetTempname(sqlite3_vfs *, char **);
static int winIsDir(const void *);
static BOOL winIsLongPathPrefix(const char *);
static BOOL winIsDriveLetterAndColon(const char *);
/*
@@ -5271,7 +5272,9 @@ static int winOpen(
if( isReadonly ){
pFile->ctrlFlags |= WINFILE_RDONLY;
}
if( sqlite3_uri_boolean(zName, "psow", SQLITE_POWERSAFE_OVERWRITE) ){
if( (flags & SQLITE_OPEN_MAIN_DB)
&& sqlite3_uri_boolean(zName, "psow", SQLITE_POWERSAFE_OVERWRITE)
){
pFile->ctrlFlags |= WINFILE_PSOW;
}
pFile->lastErrno = NO_ERROR;
@@ -5481,6 +5484,17 @@ static int winAccess(
return SQLITE_OK;
}
/*
** Returns non-zero if the specified path name starts with the "long path"
** prefix.
*/
static BOOL winIsLongPathPrefix(
const char *zPathname
){
return ( zPathname[0]=='\\' && zPathname[1]=='\\'
&& zPathname[2]=='?' && zPathname[3]=='\\' );
}
/*
** Returns non-zero if the specified path name starts with a drive letter
** followed by a colon character.
@@ -5545,10 +5559,11 @@ static int winFullPathname(
char *zOut;
#endif
/* If this path name begins with "/X:", where "X" is any alphabetic
** character, discard the initial "/" from the pathname.
/* If this path name begins with "/X:" or "\\?\", where "X" is any
** alphabetic character, discard the initial "/" from the pathname.
*/
if( zRelative[0]=='/' && winIsDriveLetterAndColon(zRelative+1) ){
if( zRelative[0]=='/' && (winIsDriveLetterAndColon(zRelative+1)
|| winIsLongPathPrefix(zRelative+1)) ){
zRelative++;
}
+48 -14
View File
@@ -2536,9 +2536,12 @@ static int pager_delmaster(Pager *pPager, const char *zMaster){
/* One of the journals pointed to by the master journal exists.
** Open it and check if it points at the master journal. If
** so, return without deleting the master journal file.
** NB: zJournal is really a MAIN_JOURNAL. But call it a
** MASTER_JOURNAL here so that the VFS will not send the zJournal
** name into sqlite3_database_file_object().
*/
int c;
int flags = (SQLITE_OPEN_READONLY|SQLITE_OPEN_MAIN_JOURNAL);
int flags = (SQLITE_OPEN_READONLY|SQLITE_OPEN_MASTER_JOURNAL);
rc = sqlite3OsOpen(pVfs, zJournal, pJournal, flags, 0);
if( rc!=SQLITE_OK ){
goto delmaster_out;
@@ -4742,6 +4745,7 @@ int sqlite3PagerOpen(
** Database file handle (pVfs->szOsFile bytes)
** Sub-journal file handle (journalFileSize bytes)
** Main journal file handle (journalFileSize bytes)
** Ptr back to the Pager (sizeof(Pager*) bytes)
** \0\0\0\0 database prefix (4 bytes)
** Database file name (nPathname+1 bytes)
** URI query parameters (nUriByte bytes)
@@ -4781,6 +4785,7 @@ int sqlite3PagerOpen(
ROUND8(pcacheSize) + /* PCache object */
ROUND8(pVfs->szOsFile) + /* The main db file */
journalFileSize * 2 + /* The two journal files */
sizeof(pPager) + /* Space to hold a pointer */
4 + /* Database prefix */
nPathname + 1 + /* database filename */
nUriByte + /* query parameters */
@@ -4801,6 +4806,7 @@ int sqlite3PagerOpen(
pPager->sjfd = (sqlite3_file*)pPtr; pPtr += journalFileSize;
pPager->jfd = (sqlite3_file*)pPtr; pPtr += journalFileSize;
assert( EIGHT_BYTE_ALIGNMENT(pPager->jfd) );
memcpy(pPtr, &pPager, sizeof(pPager)); pPtr += sizeof(pPager);
/* Fill in the Pager.zFilename and pPager.zQueryParam fields */
pPtr += 4; /* Skip zero prefix */
@@ -5001,6 +5007,19 @@ act_like_temp_file:
return SQLITE_OK;
}
/*
** Return the sqlite3_file for the main database given the name
** of the corresonding WAL or Journal name as passed into
** xOpen.
*/
sqlite3_file *sqlite3_database_file_object(const char *zName){
Pager *pPager;
while( zName[-1]!=0 || zName[-2]!=0 || zName[-3]!=0 || zName[-4]!=0 ){
zName--;
}
pPager = *(Pager**)(zName - 4 - sizeof(Pager*));
return pPager->fd;
}
/*
@@ -5686,7 +5705,6 @@ void sqlite3PagerUnrefPageOne(DbPage *pPg){
assert( pPg->pgno==1 );
assert( (pPg->flags & PGHDR_MMAP)==0 ); /* Page1 is never memory mapped */
pPager = pPg->pPager;
sqlite3PagerResetLockTimeout(pPager);
sqlite3PcacheRelease(pPg);
pagerUnlockIfUnused(pPager);
}
@@ -6979,16 +6997,6 @@ sqlite3_file *sqlite3PagerFile(Pager *pPager){
return pPager->fd;
}
#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
/*
** Reset the lock timeout for pager.
*/
void sqlite3PagerResetLockTimeout(Pager *pPager){
int x = 0;
sqlite3OsFileControl(pPager->fd, SQLITE_FCNTL_LOCK_TIMEOUT, &x);
}
#endif
/*
** Return the file handle for the journal file (if it exists).
** This will be either the rollback journal or the WAL file.
@@ -7402,7 +7410,6 @@ int sqlite3PagerCheckpoint(
pPager->walSyncFlags, pPager->pageSize, (u8 *)pPager->pTmpSpace,
pnLog, pnCkpt
);
sqlite3PagerResetLockTimeout(pPager);
}
return rc;
}
@@ -7567,7 +7574,31 @@ int sqlite3PagerCloseWal(Pager *pPager, sqlite3 *db){
return rc;
}
#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
/*
** If pager pPager is a wal-mode database not in exclusive locking mode,
** invoke the sqlite3WalWriteLock() function on the associated Wal object
** with the same db and bLock parameters as were passed to this function.
** Return an SQLite error code if an error occurs, or SQLITE_OK otherwise.
*/
int sqlite3PagerWalWriteLock(Pager *pPager, int bLock){
int rc = SQLITE_OK;
if( pagerUseWal(pPager) && pPager->exclusiveMode==0 ){
rc = sqlite3WalWriteLock(pPager->pWal, bLock);
}
return rc;
}
/*
** Set the database handle used by the wal layer to determine if
** blocking locks are required.
*/
void sqlite3PagerWalDb(Pager *pPager, sqlite3 *db){
if( pagerUseWal(pPager) ){
sqlite3WalDb(pPager->pWal, db);
}
}
#endif
#ifdef SQLITE_ENABLE_SNAPSHOT
/*
@@ -7587,7 +7618,10 @@ int sqlite3PagerSnapshotGet(Pager *pPager, sqlite3_snapshot **ppSnapshot){
** read transaction is opened, attempt to read from the snapshot it
** identifies. If this is not a WAL database, return an error.
*/
int sqlite3PagerSnapshotOpen(Pager *pPager, sqlite3_snapshot *pSnapshot){
int sqlite3PagerSnapshotOpen(
Pager *pPager,
sqlite3_snapshot *pSnapshot
){
int rc = SQLITE_OK;
if( pPager->pWal ){
sqlite3WalSnapshotOpen(pPager->pWal, pSnapshot);
+10 -7
View File
@@ -177,14 +177,22 @@ int sqlite3PagerSharedLock(Pager *pPager);
int sqlite3PagerOpenWal(Pager *pPager, int *pisOpen);
int sqlite3PagerCloseWal(Pager *pPager, sqlite3*);
# ifdef SQLITE_ENABLE_SNAPSHOT
int sqlite3PagerSnapshotGet(Pager *pPager, sqlite3_snapshot **ppSnapshot);
int sqlite3PagerSnapshotOpen(Pager *pPager, sqlite3_snapshot *pSnapshot);
int sqlite3PagerSnapshotGet(Pager*, sqlite3_snapshot **ppSnapshot);
int sqlite3PagerSnapshotOpen(Pager*, sqlite3_snapshot *pSnapshot);
int sqlite3PagerSnapshotRecover(Pager *pPager);
int sqlite3PagerSnapshotCheck(Pager *pPager, sqlite3_snapshot *pSnapshot);
void sqlite3PagerSnapshotUnlock(Pager *pPager);
# endif
#endif
#if !defined(SQLITE_OMIT_WAL) && defined(SQLITE_ENABLE_SETLK_TIMEOUT)
int sqlite3PagerWalWriteLock(Pager*, int);
void sqlite3PagerWalDb(Pager*, sqlite3*);
#else
# define sqlite3PagerWalWriteLock(y,z) SQLITE_OK
# define sqlite3PagerWalDb(x,y)
#endif
#ifdef SQLITE_DIRECT_OVERFLOW_READ
int sqlite3PagerDirectReadOk(Pager *pPager, Pgno pgno);
#endif
@@ -210,11 +218,6 @@ int sqlite3PagerIsMemdb(Pager*);
void sqlite3PagerCacheStat(Pager *, int, int, int *);
void sqlite3PagerClearCache(Pager*);
int sqlite3SectorSize(sqlite3_file *);
#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
void sqlite3PagerResetLockTimeout(Pager *pPager);
#else
# define sqlite3PagerResetLockTimeout(X)
#endif
/* Functions used to truncate the database file. */
void sqlite3PagerTruncateImage(Pager*,Pgno);
+2 -1
View File
@@ -1194,10 +1194,11 @@ expr(A) ::= expr(A) between_op(N) expr(X) AND expr(Y). [BETWEEN] {
*/
sqlite3ExprUnmapAndDelete(pParse, A);
A = sqlite3Expr(pParse->db, TK_INTEGER, N ? "1" : "0");
}else if( 0 && Y->nExpr==1 && sqlite3ExprIsConstant(Y->a[0].pExpr) ){
}else if( Y->nExpr==1 && sqlite3ExprIsConstant(Y->a[0].pExpr) ){
Expr *pRHS = Y->a[0].pExpr;
Y->a[0].pExpr = 0;
sqlite3ExprListDelete(pParse->db, Y);
pRHS = sqlite3PExpr(pParse, TK_UPLUS, pRHS, 0);
A = sqlite3PExpr(pParse, TK_EQ, A, pRHS);
if( N ) A = sqlite3PExpr(pParse, TK_NOT, A, 0);
}else{
+20 -3
View File
@@ -555,7 +555,7 @@ void sqlite3Pragma(
** buffer that the pager module resizes using sqlite3_realloc().
*/
db->nextPagesize = sqlite3Atoi(zRight);
if( SQLITE_NOMEM==sqlite3BtreeSetPageSize(pBt, db->nextPagesize,-1,0) ){
if( SQLITE_NOMEM==sqlite3BtreeSetPageSize(pBt, db->nextPagesize,0,0) ){
sqlite3OomFault(db);
}
}
@@ -1729,7 +1729,6 @@ void sqlite3Pragma(
}
sqlite3VdbeAddOp2(v, OP_Next, iDataCur, loopTop); VdbeCoverage(v);
sqlite3VdbeJumpHere(v, loopTop-1);
#ifndef SQLITE_OMIT_BTREECOUNT
if( !isQuick ){
sqlite3VdbeLoadString(v, 2, "wrong # of entries in index ");
for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
@@ -1743,7 +1742,6 @@ void sqlite3Pragma(
sqlite3VdbeJumpHere(v, addr);
}
}
#endif /* SQLITE_OMIT_BTREECOUNT */
}
}
{
@@ -2178,6 +2176,25 @@ void sqlite3Pragma(
break;
}
/*
** PRAGMA analysis_limit
** PRAGMA analysis_limit = N
**
** Configure the maximum number of rows that ANALYZE will examine
** in each index that it looks at. Return the new limit.
*/
case PragTyp_ANALYSIS_LIMIT: {
sqlite3_int64 N;
if( zRight
&& sqlite3DecOrHexToI64(zRight, &N)==SQLITE_OK
&& N>=0
){
db->nAnalysisLimit = (int)(N&0x7fffffff);
}
returnSingleInt(v, db->nAnalysisLimit);
break;
}
#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
/*
** Report the current state of file logs for all databases
+50 -44
View File
@@ -6,49 +6,50 @@
/* The various pragma types */
#define PragTyp_ACTIVATE_EXTENSIONS 0
#define PragTyp_HEADER_VALUE 1
#define PragTyp_AUTO_VACUUM 2
#define PragTyp_FLAG 3
#define PragTyp_BUSY_TIMEOUT 4
#define PragTyp_CACHE_SIZE 5
#define PragTyp_CACHE_SPILL 6
#define PragTyp_CASE_SENSITIVE_LIKE 7
#define PragTyp_COLLATION_LIST 8
#define PragTyp_COMPILE_OPTIONS 9
#define PragTyp_DATA_STORE_DIRECTORY 10
#define PragTyp_DATABASE_LIST 11
#define PragTyp_DEFAULT_CACHE_SIZE 12
#define PragTyp_ENCODING 13
#define PragTyp_FOREIGN_KEY_CHECK 14
#define PragTyp_FOREIGN_KEY_LIST 15
#define PragTyp_FUNCTION_LIST 16
#define PragTyp_HARD_HEAP_LIMIT 17
#define PragTyp_INCREMENTAL_VACUUM 18
#define PragTyp_INDEX_INFO 19
#define PragTyp_INDEX_LIST 20
#define PragTyp_INTEGRITY_CHECK 21
#define PragTyp_JOURNAL_MODE 22
#define PragTyp_JOURNAL_SIZE_LIMIT 23
#define PragTyp_LOCK_PROXY_FILE 24
#define PragTyp_LOCKING_MODE 25
#define PragTyp_PAGE_COUNT 26
#define PragTyp_MMAP_SIZE 27
#define PragTyp_MODULE_LIST 28
#define PragTyp_OPTIMIZE 29
#define PragTyp_PAGE_SIZE 30
#define PragTyp_PRAGMA_LIST 31
#define PragTyp_SECURE_DELETE 32
#define PragTyp_SHRINK_MEMORY 33
#define PragTyp_SOFT_HEAP_LIMIT 34
#define PragTyp_SYNCHRONOUS 35
#define PragTyp_TABLE_INFO 36
#define PragTyp_TEMP_STORE 37
#define PragTyp_TEMP_STORE_DIRECTORY 38
#define PragTyp_THREADS 39
#define PragTyp_WAL_AUTOCHECKPOINT 40
#define PragTyp_WAL_CHECKPOINT 41
#define PragTyp_LOCK_STATUS 42
#define PragTyp_STATS 43
#define PragTyp_ANALYSIS_LIMIT 1
#define PragTyp_HEADER_VALUE 2
#define PragTyp_AUTO_VACUUM 3
#define PragTyp_FLAG 4
#define PragTyp_BUSY_TIMEOUT 5
#define PragTyp_CACHE_SIZE 6
#define PragTyp_CACHE_SPILL 7
#define PragTyp_CASE_SENSITIVE_LIKE 8
#define PragTyp_COLLATION_LIST 9
#define PragTyp_COMPILE_OPTIONS 10
#define PragTyp_DATA_STORE_DIRECTORY 11
#define PragTyp_DATABASE_LIST 12
#define PragTyp_DEFAULT_CACHE_SIZE 13
#define PragTyp_ENCODING 14
#define PragTyp_FOREIGN_KEY_CHECK 15
#define PragTyp_FOREIGN_KEY_LIST 16
#define PragTyp_FUNCTION_LIST 17
#define PragTyp_HARD_HEAP_LIMIT 18
#define PragTyp_INCREMENTAL_VACUUM 19
#define PragTyp_INDEX_INFO 20
#define PragTyp_INDEX_LIST 21
#define PragTyp_INTEGRITY_CHECK 22
#define PragTyp_JOURNAL_MODE 23
#define PragTyp_JOURNAL_SIZE_LIMIT 24
#define PragTyp_LOCK_PROXY_FILE 25
#define PragTyp_LOCKING_MODE 26
#define PragTyp_PAGE_COUNT 27
#define PragTyp_MMAP_SIZE 28
#define PragTyp_MODULE_LIST 29
#define PragTyp_OPTIMIZE 30
#define PragTyp_PAGE_SIZE 31
#define PragTyp_PRAGMA_LIST 32
#define PragTyp_SECURE_DELETE 33
#define PragTyp_SHRINK_MEMORY 34
#define PragTyp_SOFT_HEAP_LIMIT 35
#define PragTyp_SYNCHRONOUS 36
#define PragTyp_TABLE_INFO 37
#define PragTyp_TEMP_STORE 38
#define PragTyp_TEMP_STORE_DIRECTORY 39
#define PragTyp_THREADS 40
#define PragTyp_WAL_AUTOCHECKPOINT 41
#define PragTyp_WAL_CHECKPOINT 42
#define PragTyp_LOCK_STATUS 43
#define PragTyp_STATS 44
/* Property flags associated with various pragma. */
#define PragFlg_NeedSchema 0x01 /* Force schema load before running */
@@ -139,6 +140,11 @@ static const PragmaName aPragmaName[] = {
/* ColNames: */ 0, 0,
/* iArg: */ 0 },
#endif
{/* zName: */ "analysis_limit",
/* ePragTyp: */ PragTyp_ANALYSIS_LIMIT,
/* ePragFlg: */ PragFlg_Result0,
/* ColNames: */ 0, 0,
/* iArg: */ 0 },
#if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS)
{/* zName: */ "application_id",
/* ePragTyp: */ PragTyp_HEADER_VALUE,
@@ -639,4 +645,4 @@ static const PragmaName aPragmaName[] = {
/* iArg: */ SQLITE_WriteSchema|SQLITE_NoSchemaError },
#endif
};
/* Number of pragmas: 66 on by default, 76 total. */
/* Number of pragmas: 67 on by default, 77 total. */
+17 -3
View File
@@ -194,6 +194,13 @@ static char *printfTempBuf(sqlite3_str *pAccum, sqlite3_int64 n){
#endif
#define etBUFSIZE SQLITE_PRINT_BUF_SIZE /* Size of the output buffer */
/*
** Hard limit on the precision of floating-point conversions.
*/
#ifndef SQLITE_PRINTF_PRECISION_LIMIT
# define SQLITE_FP_PRECISION_LIMIT 100000000
#endif
/*
** Render a string given by "fmt" into the StrAccum object.
*/
@@ -394,6 +401,8 @@ void sqlite3_str_vappendf(
** xtype The class of the conversion.
** infop Pointer to the appropriate info struct.
*/
assert( width>=0 );
assert( precision>=(-1) );
switch( xtype ){
case etPOINTER:
flag_long = sizeof(char*)==sizeof(i64) ? 2 :
@@ -515,6 +524,11 @@ void sqlite3_str_vappendf(
length = 0;
#else
if( precision<0 ) precision = 6; /* Set default precision */
#ifdef SQLITE_FP_PRECISION_LIMIT
if( precision>SQLITE_FP_PRECISION_LIMIT ){
precision = SQLITE_FP_PRECISION_LIMIT;
}
#endif
if( realvalue<0.0 ){
realvalue = -realvalue;
prefix = '-';
@@ -797,7 +811,7 @@ void sqlite3_str_vappendf(
}
isnull = escarg==0;
if( isnull ) escarg = (xtype==etSQLESCAPE2 ? "NULL" : "(NULL)");
/* For %q, %Q, and %w, the precision is the number of byte (or
/* For %q, %Q, and %w, the precision is the number of bytes (or
** characters if the ! flags is present) to use from the input.
** Because of the extra quoting characters inserted, the number
** of output characters may be larger than the precision.
@@ -924,7 +938,7 @@ static int sqlite3StrAccumEnlarge(StrAccum *p, int N){
if( p->db ){
zNew = sqlite3DbRealloc(p->db, zOld, p->nAlloc);
}else{
zNew = sqlite3_realloc64(zOld, p->nAlloc);
zNew = sqlite3Realloc(zOld, p->nAlloc);
}
if( zNew ){
assert( p->zText!=0 || p->nChar==0 );
@@ -1266,7 +1280,7 @@ void sqlite3_log(int iErrCode, const char *zFormat, ...){
void sqlite3DebugPrintf(const char *zFormat, ...){
va_list ap;
StrAccum acc;
char zBuf[500];
char zBuf[SQLITE_PRINT_BUF_SIZE*10];
sqlite3StrAccumInit(&acc, 0, zBuf, sizeof(zBuf), 0);
va_start(ap,zFormat);
sqlite3_str_vappendf(&acc, zFormat, ap);
+74 -23
View File
@@ -24,6 +24,8 @@
**
** incrAggFunctionDepth(pExpr,n) is the main routine. incrAggDepth(..)
** is a helper function - a callback for the tree walker.
**
** See also the sqlite3WindowExtraAggFuncDepth() routine in window.c
*/
static int incrAggDepth(Walker *pWalker, Expr *pExpr){
if( pExpr->op==TK_AGG_FUNCTION ) pExpr->op2 += pWalker->u.n;
@@ -140,7 +142,7 @@ int sqlite3MatchEName(
){
int n;
const char *zSpan;
if( NEVER(pItem->eEName!=ENAME_TAB) ) return 0;
if( pItem->eEName!=ENAME_TAB ) return 0;
zSpan = pItem->zEName;
for(n=0; ALWAYS(zSpan[n]) && zSpan[n]!='.'; n++){}
if( zDb && (sqlite3StrNICmp(zSpan, zDb, n)!=0 || zDb[n]!=0) ){
@@ -175,6 +177,31 @@ static int areDoubleQuotedStringsEnabled(sqlite3 *db, NameContext *pTopNC){
}
}
/*
** The argument is guaranteed to be a non-NULL Expr node of type TK_COLUMN.
** return the appropriate colUsed mask.
*/
Bitmask sqlite3ExprColUsed(Expr *pExpr){
int n;
Table *pExTab;
n = pExpr->iColumn;
pExTab = pExpr->y.pTab;
assert( pExTab!=0 );
if( (pExTab->tabFlags & TF_HasGenerated)!=0
&& (pExTab->aCol[n].colFlags & COLFLAG_GENERATED)!=0
){
testcase( pExTab->nCol==BMS-1 );
testcase( pExTab->nCol==BMS );
return pExTab->nCol>=BMS ? ALLBITS : MASKBIT(pExTab->nCol)-1;
}else{
testcase( n==BMS-1 );
testcase( n==BMS );
if( n>=BMS ) n = BMS-1;
return ((Bitmask)1)<<n;
}
}
/*
** Given the name of a column of the form X.Y.Z or Y.Z or just Z, look up
** that name in the set of source tables in pSrcList and make the pExpr
@@ -252,6 +279,12 @@ static int lookupName(
break;
}
}
if( i==db->nDb && sqlite3StrICmp("main", zDb)==0 ){
/* This branch is taken when the main database has been renamed
** using SQLITE_DBCONFIG_MAINDBNAME. */
pSchema = db->aDb[0].pSchema;
zDb = db->aDb[0].zDbSName;
}
}
}
@@ -263,6 +296,7 @@ static int lookupName(
if( pSrcList ){
for(i=0, pItem=pSrcList->a; i<pSrcList->nSrc; i++, pItem++){
u8 hCol;
pTab = pItem->pTab;
assert( pTab!=0 && pTab->zName!=0 );
assert( pTab->nCol>0 );
@@ -296,8 +330,9 @@ static int lookupName(
if( 0==(cntTab++) ){
pMatch = pItem;
}
hCol = sqlite3StrIHash(zCol);
for(j=0, pCol=pTab->aCol; j<pTab->nCol; j++, pCol++){
if( sqlite3StrICmp(pCol->zName, zCol)==0 ){
if( pCol->hName==hCol && sqlite3StrICmp(pCol->zName, zCol)==0 ){
/* If there has been exactly one prior match and this match
** is for the right-hand table of a NATURAL JOIN or is in a
** USING clause, then skip this match.
@@ -358,10 +393,11 @@ static int lookupName(
if( pTab ){
int iCol;
u8 hCol = sqlite3StrIHash(zCol);
pSchema = pTab->pSchema;
cntTab++;
for(iCol=0, pCol=pTab->aCol; iCol<pTab->nCol; iCol++, pCol++){
if( sqlite3StrICmp(pCol->zName, zCol)==0 ){
if( pCol->hName==hCol && sqlite3StrICmp(pCol->zName, zCol)==0 ){
if( iCol==pTab->iPKey ){
iCol = -1;
}
@@ -571,22 +607,7 @@ static int lookupName(
** of the table.
*/
if( pExpr->iColumn>=0 && pMatch!=0 ){
int n = pExpr->iColumn;
Table *pExTab = pExpr->y.pTab;
assert( pExTab!=0 );
assert( pMatch->iCursor==pExpr->iTable );
if( (pExTab->tabFlags & TF_HasGenerated)!=0
&& (pExTab->aCol[n].colFlags & COLFLAG_GENERATED)!=0
){
testcase( pExTab->nCol==BMS-1 );
testcase( pExTab->nCol==BMS );
pMatch->colUsed = pExTab->nCol>=BMS ? ALLBITS : MASKBIT(pExTab->nCol)-1;
}else{
testcase( n==BMS-1 );
testcase( n==BMS );
if( n>=BMS ) n = BMS-1;
pMatch->colUsed |= ((Bitmask)1)<<n;
}
pMatch->colUsed |= sqlite3ExprColUsed(pExpr);
}
/* Clean up and return
@@ -1177,7 +1198,7 @@ static int resolveOrderByTermToExprList(
nc.nErr = 0;
db = pParse->db;
savedSuppErr = db->suppressErr;
db->suppressErr = 1;
if( IN_RENAME_OBJECT==0 ) db->suppressErr = 1;
rc = sqlite3ResolveExprNames(&nc, pE);
db->suppressErr = savedSuppErr;
if( rc ) return 0;
@@ -1812,11 +1833,41 @@ int sqlite3ResolveExprListNames(
ExprList *pList /* The expression list to be analyzed. */
){
int i;
if( pList ){
for(i=0; i<pList->nExpr; i++){
if( sqlite3ResolveExprNames(pNC, pList->a[i].pExpr) ) return WRC_Abort;
int savedHasAgg = 0;
Walker w;
if( pList==0 ) return WRC_Continue;
w.pParse = pNC->pParse;
w.xExprCallback = resolveExprStep;
w.xSelectCallback = resolveSelectStep;
w.xSelectCallback2 = 0;
w.u.pNC = pNC;
savedHasAgg = pNC->ncFlags & (NC_HasAgg|NC_MinMaxAgg|NC_HasWin);
pNC->ncFlags &= ~(NC_HasAgg|NC_MinMaxAgg|NC_HasWin);
for(i=0; i<pList->nExpr; i++){
Expr *pExpr = pList->a[i].pExpr;
if( pExpr==0 ) continue;
#if SQLITE_MAX_EXPR_DEPTH>0
w.pParse->nHeight += pExpr->nHeight;
if( sqlite3ExprCheckHeight(w.pParse, w.pParse->nHeight) ){
return WRC_Abort;
}
#endif
sqlite3WalkExpr(&w, pExpr);
#if SQLITE_MAX_EXPR_DEPTH>0
w.pParse->nHeight -= pExpr->nHeight;
#endif
assert( EP_Agg==NC_HasAgg );
assert( EP_Win==NC_HasWin );
testcase( pNC->ncFlags & NC_HasAgg );
testcase( pNC->ncFlags & NC_HasWin );
if( pNC->ncFlags & (NC_HasAgg|NC_MinMaxAgg|NC_HasWin) ){
ExprSetProperty(pExpr, pNC->ncFlags & (NC_HasAgg|NC_HasWin) );
savedHasAgg |= pNC->ncFlags & (NC_HasAgg|NC_MinMaxAgg|NC_HasWin);
pNC->ncFlags &= ~(NC_HasAgg|NC_MinMaxAgg|NC_HasWin);
}
if( pNC->nErr>0 || w.pParse->nErr>0 ) return WRC_Abort;
}
pNC->ncFlags |= savedHasAgg;
return WRC_Continue;
}
+56 -37
View File
@@ -103,7 +103,6 @@ static void clearSelect(sqlite3 *db, Select *p, int bFree){
if( OK_IF_ALWAYS_TRUE(p->pWinDefn) ){
sqlite3WindowListDelete(db, p->pWinDefn);
}
assert( p->pWin==0 );
#endif
if( OK_IF_ALWAYS_TRUE(p->pWith) ) sqlite3WithDelete(db, p->pWith);
if( bFree ) sqlite3DbFreeNN(db, p);
@@ -2024,6 +2023,7 @@ int sqlite3ColumnsFromExprList(
if( cnt>3 ) sqlite3_randomness(sizeof(cnt), &cnt);
}
pCol->zName = zName;
pCol->hName = sqlite3StrIHash(zName);
sqlite3ColumnPropertiesFromName(0, pCol);
if( zName && sqlite3HashInsert(&ht, zName, pCol)==pCol ){
sqlite3OomFault(db);
@@ -3477,7 +3477,10 @@ static Expr *substExpr(
){
pExpr->iRightJoinTable = pSubst->iNewTable;
}
if( pExpr->op==TK_COLUMN && pExpr->iTable==pSubst->iTable ){
if( pExpr->op==TK_COLUMN
&& pExpr->iTable==pSubst->iTable
&& !ExprHasProperty(pExpr, EP_FixedCol)
){
if( pExpr->iColumn<0 ){
pExpr->op = TK_NULL;
}else{
@@ -3495,6 +3498,7 @@ static Expr *substExpr(
ifNullRow.op = TK_IF_NULL_ROW;
ifNullRow.pLeft = pCopy;
ifNullRow.iTable = pSubst->iNewTable;
ifNullRow.flags = EP_Skip;
pCopy = &ifNullRow;
}
testcase( ExprHasProperty(pCopy, EP_Subquery) );
@@ -3581,6 +3585,38 @@ static void substSelect(
}
#endif /* !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) */
#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW)
/*
** pSelect is a SELECT statement and pSrcItem is one item in the FROM
** clause of that SELECT.
**
** This routine scans the entire SELECT statement and recomputes the
** pSrcItem->colUsed mask.
*/
static int recomputeColumnsUsedExpr(Walker *pWalker, Expr *pExpr){
struct SrcList_item *pItem;
if( pExpr->op!=TK_COLUMN ) return WRC_Continue;
pItem = pWalker->u.pSrcItem;
if( pItem->iCursor!=pExpr->iTable ) return WRC_Continue;
if( pExpr->iColumn<0 ) return WRC_Continue;
pItem->colUsed |= sqlite3ExprColUsed(pExpr);
return WRC_Continue;
}
static void recomputeColumnsUsed(
Select *pSelect, /* The complete SELECT statement */
struct SrcList_item *pSrcItem /* Which FROM clause item to recompute */
){
Walker w;
if( NEVER(pSrcItem->pTab==0) ) return;
memset(&w, 0, sizeof(w));
w.xExprCallback = recomputeColumnsUsedExpr;
w.xSelectCallback = sqlite3SelectWalkNoop;
w.u.pSrcItem = pSrcItem;
pSrcItem->colUsed = 0;
sqlite3WalkSelect(&w, pSelect);
}
#endif /* !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) */
#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW)
/*
** This routine attempts to flatten subqueries as a performance optimization.
@@ -4119,6 +4155,12 @@ static int flattenSubquery(
pParent->pLimit = pSub->pLimit;
pSub->pLimit = 0;
}
/* Recompute the SrcList_item.colUsed masks for the flattened
** tables. */
for(i=0; i<nSubSrc; i++){
recomputeColumnsUsed(pParent, &pSrc->a[i+iFrom]);
}
}
/* Finially, delete what is left of the subquery and return
@@ -5187,29 +5229,6 @@ static int selectExpander(Walker *pWalker, Select *p){
return WRC_Continue;
}
/*
** No-op routine for the parse-tree walker.
**
** When this routine is the Walker.xExprCallback then expression trees
** are walked without any actions being taken at each node. Presumably,
** when this routine is used for Walker.xExprCallback then
** Walker.xSelectCallback is set to do something useful for every
** subquery in the parser tree.
*/
int sqlite3ExprWalkNoop(Walker *NotUsed, Expr *NotUsed2){
UNUSED_PARAMETER2(NotUsed, NotUsed2);
return WRC_Continue;
}
/*
** No-op routine for the parse-tree walker for SELECT statements.
** subquery in the parser tree.
*/
int sqlite3SelectWalkNoop(Walker *NotUsed, Select *NotUsed2){
UNUSED_PARAMETER2(NotUsed, NotUsed2);
return WRC_Continue;
}
#if SQLITE_DEBUG
/*
** Always assert. This xSelectCallback2 implementation proves that the
@@ -5351,6 +5370,7 @@ static void resetAccumulator(Parse *pParse, AggInfo *pAggInfo){
struct AggInfo_func *pFunc;
int nReg = pAggInfo->nFunc + pAggInfo->nColumn;
if( nReg==0 ) return;
if( pParse->nErr ) return;
#ifdef SQLITE_DEBUG
/* Verify that all AggInfo registers are within the range specified by
** AggInfo.mnReg..AggInfo.mxReg */
@@ -6379,7 +6399,7 @@ int sqlite3Select(
#if SELECTTRACE_ENABLED
if( sqlite3SelectTrace & 0x400 ){
int ii;
SELECTTRACE(0x400,pParse,p,("After aggregate analysis:\n"));
SELECTTRACE(0x400,pParse,p,("After aggregate analysis %p:\n", &sAggInfo));
sqlite3TreeViewSelect(0, p, 0);
for(ii=0; ii<sAggInfo.nColumn; ii++){
sqlite3DebugPrintf("agg-column[%d] iMem=%d\n",
@@ -6620,7 +6640,6 @@ int sqlite3Select(
} /* endif pGroupBy. Begin aggregate queries without GROUP BY: */
else {
#ifndef SQLITE_OMIT_BTREECOUNT
Table *pTab;
if( (pTab = isSimpleCount(p, &sAggInfo))!=0 ){
/* If isSimpleCount() returns a pointer to a Table structure, then
@@ -6656,13 +6675,15 @@ int sqlite3Select(
** passed to keep OP_OpenRead happy.
*/
if( !HasRowid(pTab) ) pBest = sqlite3PrimaryKeyIndex(pTab);
for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
if( pIdx->bUnordered==0
&& pIdx->szIdxRow<pTab->szTabRow
&& pIdx->pPartIdxWhere==0
&& (!pBest || pIdx->szIdxRow<pBest->szIdxRow)
){
pBest = pIdx;
if( !p->pSrc->a[0].fg.notIndexed ){
for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
if( pIdx->bUnordered==0
&& pIdx->szIdxRow<pTab->szTabRow
&& pIdx->pPartIdxWhere==0
&& (!pBest || pIdx->szIdxRow<pBest->szIdxRow)
){
pBest = pIdx;
}
}
}
if( pBest ){
@@ -6678,9 +6699,7 @@ int sqlite3Select(
sqlite3VdbeAddOp2(v, OP_Count, iCsr, sAggInfo.aFunc[0].iMem);
sqlite3VdbeAddOp1(v, OP_Close, iCsr);
explainSimpleCount(pParse, pTab, pBest);
}else
#endif /* SQLITE_OMIT_BTREECOUNT */
{
}else{
int regAcc = 0; /* "populate accumulators" flag */
/* If there are accumulator registers but no min() or max() functions
+182 -100
View File
@@ -17,6 +17,14 @@
#define _CRT_SECURE_NO_WARNINGS
#endif
/*
** Determine if we are dealing with WinRT, which provides only a subset of
** the full Win32 API.
*/
#if !defined(SQLITE_OS_WINRT)
# define SQLITE_OS_WINRT 0
#endif
/*
** Warning pragmas copied from msvc.h in the core.
*/
@@ -129,22 +137,26 @@ typedef unsigned char u8;
#if defined(_WIN32) || defined(WIN32)
# include <io.h>
# include <fcntl.h>
# define isatty(h) _isatty(h)
# ifndef access
# define access(f,m) _access((f),(m))
# if SQLITE_OS_WINRT
# define SQLITE_OMIT_POPEN 1
# else
# include <io.h>
# include <fcntl.h>
# define isatty(h) _isatty(h)
# ifndef access
# define access(f,m) _access((f),(m))
# endif
# ifndef unlink
# define unlink _unlink
# endif
# ifndef strdup
# define strdup _strdup
# endif
# undef popen
# define popen _popen
# undef pclose
# define pclose _pclose
# endif
# ifndef unlink
# define unlink _unlink
# endif
# ifndef strdup
# define strdup _strdup
# endif
# undef popen
# define popen _popen
# undef pclose
# define pclose _pclose
#else
/* Make sure isatty() has a prototype. */
extern int isatty(int);
@@ -173,6 +185,9 @@ typedef unsigned char u8;
#define ToLower(X) (char)tolower((unsigned char)X)
#if defined(_WIN32) || defined(WIN32)
#if SQLITE_OS_WINRT
#include <intrin.h>
#endif
#include <windows.h>
/* string conversion routines only needed on Win32 */
@@ -188,7 +203,7 @@ extern LPWSTR sqlite3_win32_utf8_to_unicode(const char *zText);
** rendering quoted strings that contain \n characters). The following
** routines take care of that.
*/
#if defined(_WIN32) || defined(WIN32)
#if (defined(_WIN32) || defined(WIN32)) && !SQLITE_OS_WINRT
static void setBinaryMode(FILE *file, int isOutput){
if( isOutput ) fflush(file);
_setmode(_fileno(file), _O_BINARY);
@@ -292,6 +307,7 @@ static int hasTimer(void){
if( getProcessTimesAddr ){
return 1;
} else {
#if !SQLITE_OS_WINRT
/* GetProcessTimes() isn't supported in WIN95 and some other Windows
** versions. See if the version we are running on has it, and if it
** does, save off a pointer to it and the current process handle.
@@ -308,6 +324,7 @@ static int hasTimer(void){
FreeLibrary(hinstLib);
}
}
#endif
}
return 0;
}
@@ -993,6 +1010,7 @@ INCLUDE ../ext/misc/fileio.c
INCLUDE ../ext/misc/completion.c
INCLUDE ../ext/misc/appendvfs.c
INCLUDE ../ext/misc/memtrace.c
INCLUDE ../ext/misc/uint.c
#ifdef SQLITE_HAVE_ZLIB
INCLUDE ../ext/misc/zipfile.c
INCLUDE ../ext/misc/sqlar.c
@@ -1089,6 +1107,7 @@ struct ShellState {
unsigned mxProgress; /* Maximum progress callbacks before failing */
unsigned flgProgress; /* Flags for the progress callback */
unsigned shellFlgs; /* Various flags */
unsigned priorShFlgs; /* Saved copy of flags */
sqlite3_int64 szMax; /* --maxsize argument to .open */
char *zDestTable; /* Name of destination table when MODE_Insert */
char *zTempFile; /* Temporary file that might need deleting */
@@ -1389,11 +1408,13 @@ edit_func_end:
*/
static void outputModePush(ShellState *p){
p->modePrior = p->mode;
p->priorShFlgs = p->shellFlgs;
memcpy(p->colSepPrior, p->colSeparator, sizeof(p->colSeparator));
memcpy(p->rowSepPrior, p->rowSeparator, sizeof(p->rowSeparator));
}
static void outputModePop(ShellState *p){
p->mode = p->modePrior;
p->shellFlgs = p->priorShFlgs;
memcpy(p->colSeparator, p->colSepPrior, sizeof(p->colSeparator));
memcpy(p->rowSeparator, p->rowSepPrior, sizeof(p->rowSeparator));
}
@@ -2358,8 +2379,7 @@ static void set_table_name(ShellState *p, const char *zName){
*/
static int run_table_dump_query(
ShellState *p, /* Query context */
const char *zSelect, /* SELECT statement to extract content */
const char *zFirstRow /* Print before first row, if not NULL */
const char *zSelect /* SELECT statement to extract content */
){
sqlite3_stmt *pSelect;
int rc;
@@ -2376,10 +2396,6 @@ static int run_table_dump_query(
rc = sqlite3_step(pSelect);
nResult = sqlite3_column_count(pSelect);
while( rc==SQLITE_ROW ){
if( zFirstRow ){
utf8_printf(p->out, "%s", zFirstRow);
zFirstRow = 0;
}
z = (const char*)sqlite3_column_text(pSelect, 0);
utf8_printf(p->out, "%s", z);
for(i=1; i<nResult; i++){
@@ -2836,9 +2852,9 @@ static void bind_table_init(ShellState *p){
** CREATE TEMP TABLE sqlite_parameters(key TEXT PRIMARY KEY, value)
** WITHOUT ROWID;
**
** No bindings occur if this table does not exist. The special character '$'
** is included in the table name to help prevent collisions with actual tables.
** The table must be in the TEMP schema.
** No bindings occur if this table does not exist. The name of the table
** begins with "sqlite_" so that it will not collide with ordinary application
** tables. The table must be in the TEMP schema.
*/
static void bind_prepared_stmt(ShellState *pArg, sqlite3_stmt *pStmt){
int nVar;
@@ -3142,6 +3158,7 @@ static int shell_exec(
const char *zEQPLine = (const char*)sqlite3_column_text(pExplain,3);
int iEqpId = sqlite3_column_int(pExplain, 0);
int iParentId = sqlite3_column_int(pExplain, 1);
if( zEQPLine==0 ) zEQPLine = "";
if( zEQPLine[0]=='-' ) eqp_render(pArg);
eqp_append(pArg, iEqpId, iParentId, zEQPLine);
}
@@ -3552,11 +3569,12 @@ static const char *(azHelp[]) = {
".databases List names and files of attached databases",
".dbconfig ?op? ?val? List or change sqlite3_db_config() options",
".dbinfo ?DB? Show status information about the database",
".dump ?TABLE? ... Render all database content as SQL",
".dump ?TABLE? Render database content as SQL",
" Options:",
" --preserve-rowids Include ROWID values in the output",
" --newlines Allow unescaped newline characters in 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",
".eqp on|off|full|... Enable or disable automatic EXPLAIN QUERY PLAN",
" Other Modes:",
@@ -3566,11 +3584,13 @@ static const char *(azHelp[]) = {
#endif
" trigger Like \"full\" but also show trigger bytecode",
".excel Display the output of next command in spreadsheet",
" --bom Put a UTF8 byte-order mark on intermediate file",
".exit ?CODE? Exit this program with return-code CODE",
".expert EXPERIMENTAL. Suggest indexes for queries",
".explain ?on|off|auto? Change the EXPLAIN formatting mode. Default: auto",
".filectrl CMD ... Run various sqlite3_file_control() operations",
" Run \".filectrl\" with no arguments for details",
" --schema SCHEMA Use SCHEMA instead of \"main\"",
" --help Show CMD details",
".fullschema ?--indent? Show schema and the content of sqlite_stat tables",
".headers on|off Turn display of headers on or off",
".help ?-all? ?PATTERN? Show help text for PATTERN",
@@ -3617,11 +3637,11 @@ static const char *(azHelp[]) = {
" tabs Tab-separated values",
" tcl TCL list elements",
".nullvalue STRING Use STRING in place of NULL values",
".once (-e|-x|FILE) Output for the next SQL command only to FILE",
".once ?OPTIONS? ?FILE? Output for the next SQL command only to FILE",
" If FILE begins with '|' then open as a pipe",
" Other options:",
" -e Invoke system text editor",
" -x Open in a spreadsheet",
" --bom Put a UTF8 byte-order mark at the beginning",
" -e Send output to the system text editor",
" -x Send output as CSV to a spreadsheet (same as \".excel\")",
#ifdef SQLITE_DEBUG
".oom [--repeat M] [N] Simulate an OOM error on the N-th allocation",
#endif
@@ -3638,7 +3658,11 @@ static const char *(azHelp[]) = {
" --readonly Open FILE readonly",
" --zip FILE is a ZIP archive",
".output ?FILE? Send output to FILE or stdout if FILE is omitted",
" If FILE begins with '|' then open it as a pipe.",
" If FILE begins with '|' then open it as a pipe.",
" Options:",
" --bom Prefix output with a UTF8 byte-order mark",
" -e Send output to the system text editor",
" -x Send output as CSV to a spreadsheet",
".parameter CMD ... Manage SQL parameter bindings",
" clear Erase all bindings",
" init Initialize the TEMP table that holds bindings",
@@ -3758,6 +3782,7 @@ static int showHelp(FILE *out, const char *zPattern){
|| zPattern[0]=='0'
|| strcmp(zPattern,"-a")==0
|| strcmp(zPattern,"-all")==0
|| strcmp(zPattern,"--all")==0
){
/* Show all commands, but only one line per command */
if( zPattern==0 ) zPattern = "";
@@ -4239,6 +4264,7 @@ static void open_db(ShellState *p, int openFlags){
sqlite3_fileio_init(p->db, 0, 0);
sqlite3_shathree_init(p->db, 0, 0);
sqlite3_completion_init(p->db, 0, 0);
sqlite3_uint_init(p->db, 0, 0);
#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB)
sqlite3_dbdata_init(p->db, 0, 0);
#endif
@@ -4958,11 +4984,15 @@ static void output_reset(ShellState *p){
zCmd = sqlite3_mprintf("%s %s", zXdgOpenCmd, p->zTempFile);
if( system(zCmd) ){
utf8_printf(stderr, "Failed: [%s]\n", zCmd);
}else{
/* Give the start/open/xdg-open command some time to get
** going before we continue, and potential delete the
** p->zTempFile data file out from under it */
sqlite3_sleep(2000);
}
sqlite3_free(zCmd);
outputModePop(p);
p->doXdgOpen = 0;
sqlite3_sleep(100);
}
#endif /* !defined(SQLITE_NOHAVE_SYSTEM) */
}
@@ -5038,12 +5068,7 @@ static int shell_dbinfo_command(ShellState *p, int nArg, char **azArg){
"SELECT data FROM sqlite_dbpage(?1) WHERE pgno=1",
-1, &pStmt, 0);
if( rc ){
if( !sqlite3_compileoption_used("ENABLE_DBPAGE_VTAB") ){
utf8_printf(stderr, "the \".dbinfo\" command requires the "
"-DSQLITE_ENABLE_DBPAGE_VTAB compile-time options\n");
}else{
utf8_printf(stderr, "error: %s\n", sqlite3_errmsg(p->db));
}
utf8_printf(stderr, "error: %s\n", sqlite3_errmsg(p->db));
sqlite3_finalize(pStmt);
return 1;
}
@@ -5252,9 +5277,21 @@ static void newTempFile(ShellState *p, const char *zSuffix){
sqlite3_file_control(p->db, 0, SQLITE_FCNTL_TEMPFILENAME, &p->zTempFile);
}
if( p->zTempFile==0 ){
/* If p->db is an in-memory database then the TEMPFILENAME file-control
** will not work and we will need to fallback to guessing */
char *zTemp;
sqlite3_uint64 r;
sqlite3_randomness(sizeof(r), &r);
p->zTempFile = sqlite3_mprintf("temp%llx.%s", r, zSuffix);
zTemp = getenv("TEMP");
if( zTemp==0 ) zTemp = getenv("TMP");
if( zTemp==0 ){
#ifdef _WIN32
zTemp = "\\tmp";
#else
zTemp = "/tmp";
#endif
}
p->zTempFile = sqlite3_mprintf("%s/temp%llx.%s", zTemp, r, zSuffix);
}else{
p->zTempFile = sqlite3_mprintf("%z.%s", p->zTempFile, zSuffix);
}
@@ -7278,7 +7315,8 @@ static int do_meta_command(char *zLine, ShellState *p){
#endif /* !(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB) */
if( c=='d' && strncmp(azArg[0], "dump", n)==0 ){
const char *zLike = 0;
char *zLike = 0;
char *zSql;
int i;
int savedShowHeader = p->showHeader;
int savedShellFlags = p->shellFlgs;
@@ -7306,12 +7344,10 @@ static int do_meta_command(char *zLine, ShellState *p){
goto meta_command_exit;
}
}else if( zLike ){
raw_printf(stderr, "Usage: .dump ?--preserve-rowids? "
"?--newlines? ?LIKE-PATTERN?\n");
rc = 1;
goto meta_command_exit;
zLike = sqlite3_mprintf("%z OR name LIKE %Q ESCAPE '\\'",
zLike, azArg[i]);
}else{
zLike = azArg[i];
zLike = sqlite3_mprintf("name LIKE %Q ESCAPE '\\'", azArg[i]);
}
}
@@ -7329,35 +7365,25 @@ static int do_meta_command(char *zLine, ShellState *p){
** corrupt. */
sqlite3_exec(p->db, "SAVEPOINT dump; PRAGMA writable_schema=ON", 0, 0, 0);
p->nErr = 0;
if( zLike==0 ){
run_schema_dump_query(p,
"SELECT name, type, sql FROM sqlite_master "
"WHERE sql NOT NULL AND type=='table' AND name!='sqlite_sequence'"
);
run_schema_dump_query(p,
"SELECT name, type, sql FROM sqlite_master "
"WHERE name=='sqlite_sequence'"
);
run_table_dump_query(p,
"SELECT sql FROM sqlite_master "
"WHERE sql NOT NULL AND type IN ('index','trigger','view')", 0
);
}else{
char *zSql;
zSql = sqlite3_mprintf(
"SELECT name, type, sql FROM sqlite_master "
"WHERE tbl_name LIKE %Q AND type=='table'"
" AND sql NOT NULL", zLike);
run_schema_dump_query(p,zSql);
sqlite3_free(zSql);
zSql = sqlite3_mprintf(
"SELECT sql FROM sqlite_master "
"WHERE sql NOT NULL"
" AND type IN ('index','trigger','view')"
" AND tbl_name LIKE %Q", zLike);
run_table_dump_query(p, zSql, 0);
sqlite3_free(zSql);
}
if( zLike==0 ) zLike = sqlite3_mprintf("true");
zSql = sqlite3_mprintf(
"SELECT name, type, sql FROM sqlite_master "
"WHERE (%s) AND type=='table'"
" AND sql NOT NULL"
" ORDER BY tbl_name='sqlite_sequence', rowid",
zLike
);
run_schema_dump_query(p,zSql);
sqlite3_free(zSql);
zSql = sqlite3_mprintf(
"SELECT sql FROM sqlite_master "
"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");
p->writableSchema = 0;
@@ -7460,6 +7486,7 @@ static int do_meta_command(char *zLine, ShellState *p){
{ "tempfilename", SQLITE_FCNTL_TEMPFILENAME, "" },
{ "has_moved", SQLITE_FCNTL_HAS_MOVED, "" },
{ "lock_timeout", SQLITE_FCNTL_LOCK_TIMEOUT, "MILLISEC" },
{ "reserve_bytes", SQLITE_FCNTL_RESERVE_BYTES, "[N]" },
};
int filectrl = -1;
int iCtrl = -1;
@@ -7467,10 +7494,21 @@ static int do_meta_command(char *zLine, ShellState *p){
int isOk = 0; /* 0: usage 1: %lld 2: no-result */
int n2, i;
const char *zCmd = 0;
const char *zSchema = 0;
open_db(p, 0);
zCmd = nArg>=2 ? azArg[1] : "help";
if( zCmd[0]=='-'
&& (strcmp(zCmd,"--schema")==0 || strcmp(zCmd,"-schema")==0)
&& nArg>=4
){
zSchema = azArg[2];
for(i=3; i<nArg; i++) azArg[i-2] = azArg[i];
nArg -= 2;
zCmd = azArg[1];
}
/* The argument can optionally begin with "-" or "--" */
if( zCmd[0]=='-' && zCmd[1] ){
zCmd++;
@@ -7512,7 +7550,7 @@ static int do_meta_command(char *zLine, ShellState *p){
case SQLITE_FCNTL_SIZE_LIMIT: {
if( nArg!=2 && nArg!=3 ) break;
iRes = nArg==3 ? integerValue(azArg[2]) : -1;
sqlite3_file_control(p->db, 0, SQLITE_FCNTL_SIZE_LIMIT, &iRes);
sqlite3_file_control(p->db, zSchema, SQLITE_FCNTL_SIZE_LIMIT, &iRes);
isOk = 1;
break;
}
@@ -7521,7 +7559,7 @@ static int do_meta_command(char *zLine, ShellState *p){
int x;
if( nArg!=3 ) break;
x = (int)integerValue(azArg[2]);
sqlite3_file_control(p->db, 0, filectrl, &x);
sqlite3_file_control(p->db, zSchema, filectrl, &x);
isOk = 2;
break;
}
@@ -7530,7 +7568,7 @@ static int do_meta_command(char *zLine, ShellState *p){
int x;
if( nArg!=2 && nArg!=3 ) break;
x = nArg==3 ? booleanValue(azArg[2]) : -1;
sqlite3_file_control(p->db, 0, filectrl, &x);
sqlite3_file_control(p->db, zSchema, filectrl, &x);
iRes = x;
isOk = 1;
break;
@@ -7538,7 +7576,7 @@ static int do_meta_command(char *zLine, ShellState *p){
case SQLITE_FCNTL_HAS_MOVED: {
int x;
if( nArg!=2 ) break;
sqlite3_file_control(p->db, 0, filectrl, &x);
sqlite3_file_control(p->db, zSchema, filectrl, &x);
iRes = x;
isOk = 1;
break;
@@ -7546,7 +7584,7 @@ static int do_meta_command(char *zLine, ShellState *p){
case SQLITE_FCNTL_TEMPFILENAME: {
char *z = 0;
if( nArg!=2 ) break;
sqlite3_file_control(p->db, 0, filectrl, &z);
sqlite3_file_control(p->db, zSchema, filectrl, &z);
if( z ){
utf8_printf(p->out, "%s\n", z);
sqlite3_free(z);
@@ -7554,6 +7592,18 @@ static int do_meta_command(char *zLine, ShellState *p){
isOk = 2;
break;
}
case SQLITE_FCNTL_RESERVE_BYTES: {
int x;
if( nArg>=3 ){
x = atoi(azArg[2]);
sqlite3_file_control(p->db, zSchema, filectrl, &x);
}
x = -1;
sqlite3_file_control(p->db, zSchema, filectrl, &x);
utf8_printf(p->out,"%d\n", x);
isOk = 2;
break;
}
}
}
if( isOk==0 && iCtrl>=0 ){
@@ -8287,42 +8337,66 @@ static int do_meta_command(char *zLine, ShellState *p){
&& (strncmp(azArg[0], "output", n)==0||strncmp(azArg[0], "once", n)==0))
|| (c=='e' && n==5 && strcmp(azArg[0],"excel")==0)
){
const char *zFile = nArg>=2 ? azArg[1] : "stdout";
const char *zFile = 0;
int bTxtMode = 0;
if( azArg[0][0]=='e' ){
/* Transform the ".excel" command into ".once -x" */
nArg = 2;
azArg[0] = "once";
zFile = azArg[1] = "-x";
n = 4;
int i;
int eMode = 0;
int bBOM = 0;
int bOnce = 0; /* 0: .output, 1: .once, 2: .excel */
if( c=='e' ){
eMode = 'x';
bOnce = 2;
}else if( strncmp(azArg[0],"once",n)==0 ){
bOnce = 1;
}
if( nArg>2 ){
utf8_printf(stderr, "Usage: .%s [-e|-x|FILE]\n", azArg[0]);
rc = 1;
goto meta_command_exit;
}
if( n>1 && strncmp(azArg[0], "once", n)==0 ){
if( nArg<2 ){
raw_printf(stderr, "Usage: .once (-e|-x|FILE)\n");
for(i=1; i<nArg; i++){
char *z = azArg[i];
if( z[0]=='-' ){
if( z[1]=='-' ) z++;
if( strcmp(z,"-bom")==0 ){
bBOM = 1;
}else if( c!='e' && strcmp(z,"-x")==0 ){
eMode = 'x'; /* spreadsheet */
}else if( c!='e' && strcmp(z,"-e")==0 ){
eMode = 'e'; /* text editor */
}else{
utf8_printf(p->out, "ERROR: unknown option: \"%s\". Usage:\n",
azArg[i]);
showHelp(p->out, azArg[0]);
rc = 1;
goto meta_command_exit;
}
}else if( zFile==0 ){
zFile = z;
}else{
utf8_printf(p->out,"ERROR: extra parameter: \"%s\". Usage:\n",
azArg[i]);
showHelp(p->out, azArg[0]);
rc = 1;
goto meta_command_exit;
}
}
if( zFile==0 ) zFile = "stdout";
if( bOnce ){
p->outCount = 2;
}else{
p->outCount = 0;
}
output_reset(p);
if( zFile[0]=='-' && zFile[1]=='-' ) zFile++;
#ifndef SQLITE_NOHAVE_SYSTEM
if( strcmp(zFile, "-e")==0 || strcmp(zFile, "-x")==0 ){
if( eMode=='e' || eMode=='x' ){
p->doXdgOpen = 1;
outputModePush(p);
if( zFile[1]=='x' ){
if( eMode=='x' ){
/* spreadsheet mode. Output as CSV. */
newTempFile(p, "csv");
ShellClearFlag(p, SHFLG_Echo);
p->mode = MODE_Csv;
sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Comma);
sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_CrLf);
}else{
/* text editor mode */
newTempFile(p, "txt");
bTxtMode = 1;
}
@@ -8341,6 +8415,7 @@ static int do_meta_command(char *zLine, ShellState *p){
p->out = stdout;
rc = 1;
}else{
if( bBOM ) fprintf(p->out,"\357\273\277");
sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile);
}
#endif
@@ -8353,6 +8428,7 @@ static int do_meta_command(char *zLine, ShellState *p){
p->out = stdout;
rc = 1;
} else {
if( bBOM ) fprintf(p->out,"\357\273\277");
sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile);
}
}
@@ -9416,7 +9492,6 @@ 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?" },
{ "reserve", SQLITE_TESTCTRL_RESERVE, "BYTES-OF-RESERVE"},
};
int testctrl = -1;
int iCtrl = -1;
@@ -9469,7 +9544,6 @@ static int do_meta_command(char *zLine, ShellState *p){
/* sqlite3_test_control(int, db, int) */
case SQLITE_TESTCTRL_OPTIMIZATIONS:
case SQLITE_TESTCTRL_RESERVE:
if( nArg==3 ){
int opt = (int)strtol(azArg[2], 0, 0);
rc2 = sqlite3_test_control(testctrl, p->db, opt);
@@ -10241,14 +10315,18 @@ static void main_init(ShellState *data) {
*/
#ifdef _WIN32
static void printBold(const char *zText){
#if !SQLITE_OS_WINRT
HANDLE out = GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_SCREEN_BUFFER_INFO defaultScreenInfo;
GetConsoleScreenBufferInfo(out, &defaultScreenInfo);
SetConsoleTextAttribute(out,
FOREGROUND_RED|FOREGROUND_INTENSITY
);
#endif
printf("%s", zText);
#if !SQLITE_OS_WINRT
SetConsoleTextAttribute(out, defaultScreenInfo.wAttributes);
#endif
}
#else
static void printBold(const char *zText){
@@ -10316,7 +10394,11 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
fgetc(stdin);
}else{
#if defined(_WIN32) || defined(WIN32)
#if SQLITE_OS_WINRT
__debugbreak();
#else
DebugBreak();
#endif
#elif defined(SIGTRAP)
raise(SIGTRAP);
#endif
+107 -31
View File
@@ -299,26 +299,22 @@ typedef sqlite_uint64 sqlite3_uint64;
** the [sqlite3] object is successfully destroyed and all associated
** resources are deallocated.
**
** ^If the database connection is associated with unfinalized prepared
** statements or unfinished sqlite3_backup objects then sqlite3_close()
** will leave the database connection open and return [SQLITE_BUSY].
** ^If sqlite3_close_v2() is called with unfinalized prepared statements
** and/or unfinished sqlite3_backups, then the database connection becomes
** an unusable "zombie" which will automatically be deallocated when the
** last prepared statement is finalized or the last sqlite3_backup is
** finished. The sqlite3_close_v2() interface is intended for use with
** host languages that are garbage collected, and where the order in which
** destructors are called is arbitrary.
**
** Applications should [sqlite3_finalize | finalize] all [prepared statements],
** [sqlite3_blob_close | close] all [BLOB handles], and
** Ideally, applications should [sqlite3_finalize | finalize] all
** [prepared statements], [sqlite3_blob_close | close] all [BLOB handles], and
** [sqlite3_backup_finish | finish] all [sqlite3_backup] objects associated
** with the [sqlite3] object prior to attempting to close the object. ^If
** sqlite3_close_v2() is called on a [database connection] that still has
** outstanding [prepared statements], [BLOB handles], and/or
** [sqlite3_backup] objects then it returns [SQLITE_OK] and the deallocation
** of resources is deferred until all [prepared statements], [BLOB handles],
** and [sqlite3_backup] objects are also destroyed.
** with the [sqlite3] object prior to attempting to close the object.
** ^If the database connection is associated with unfinalized prepared
** statements, BLOB handlers, and/or unfinished sqlite3_backup objects then
** sqlite3_close() will leave the database connection open and return
** [SQLITE_BUSY]. ^If sqlite3_close_v2() is called with unfinalized prepared
** statements, unclosed BLOB handlers, and/or unfinished sqlite3_backups,
** it returns [SQLITE_OK] regardless, but instead of deallocating the database
** connection immediately, it marks the database connection as an unusable
** "zombie" and makes arrangements to automatically deallocate the database
** connection after all prepared statements are finalized, all BLOB handles
** are closed, and all backups have finished. The sqlite3_close_v2() interface
** is intended for use with host languages that are garbage collected, and
** where the order in which destructors are called is arbitrary.
**
** ^If an [sqlite3] object is destroyed while a transaction is open,
** the transaction is automatically rolled back.
@@ -507,10 +503,12 @@ int sqlite3_exec(
#define SQLITE_IOERR_BEGIN_ATOMIC (SQLITE_IOERR | (29<<8))
#define SQLITE_IOERR_COMMIT_ATOMIC (SQLITE_IOERR | (30<<8))
#define SQLITE_IOERR_ROLLBACK_ATOMIC (SQLITE_IOERR | (31<<8))
#define SQLITE_IOERR_DATA (SQLITE_IOERR | (32<<8))
#define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1<<8))
#define SQLITE_LOCKED_VTAB (SQLITE_LOCKED | (2<<8))
#define SQLITE_BUSY_RECOVERY (SQLITE_BUSY | (1<<8))
#define SQLITE_BUSY_SNAPSHOT (SQLITE_BUSY | (2<<8))
#define SQLITE_BUSY_TIMEOUT (SQLITE_BUSY | (3<<8))
#define SQLITE_CANTOPEN_NOTEMPDIR (SQLITE_CANTOPEN | (1<<8))
#define SQLITE_CANTOPEN_ISDIR (SQLITE_CANTOPEN | (2<<8))
#define SQLITE_CANTOPEN_FULLPATH (SQLITE_CANTOPEN | (3<<8))
@@ -519,6 +517,7 @@ int sqlite3_exec(
#define SQLITE_CANTOPEN_SYMLINK (SQLITE_CANTOPEN | (6<<8))
#define SQLITE_CORRUPT_VTAB (SQLITE_CORRUPT | (1<<8))
#define SQLITE_CORRUPT_SEQUENCE (SQLITE_CORRUPT | (2<<8))
#define SQLITE_CORRUPT_INDEX (SQLITE_CORRUPT | (3<<8))
#define SQLITE_READONLY_RECOVERY (SQLITE_READONLY | (1<<8))
#define SQLITE_READONLY_CANTLOCK (SQLITE_READONLY | (2<<8))
#define SQLITE_READONLY_ROLLBACK (SQLITE_READONLY | (3<<8))
@@ -1087,10 +1086,12 @@ struct sqlite3_io_methods {
** a prior successful call to [SQLITE_FCNTL_BEGIN_ATOMIC_WRITE].
**
** <li>[[SQLITE_FCNTL_LOCK_TIMEOUT]]
** The [SQLITE_FCNTL_LOCK_TIMEOUT] opcode causes attempts to obtain
** a file lock using the xLock or xShmLock methods of the VFS to wait
** for up to M milliseconds before failing, where M is the single
** unsigned integer parameter.
** The [SQLITE_FCNTL_LOCK_TIMEOUT] opcode is used to configure a VFS
** to block for up to M milliseconds before failing when attempting to
** obtain a file lock using the xLock or xShmLock methods of the VFS.
** The parameter is a pointer to a 32-bit signed integer that contains
** the value that M is to be set to. Before returning, the 32-bit signed
** integer is overwritten with the previous value of M.
**
** <li>[[SQLITE_FCNTL_DATA_VERSION]]
** The [SQLITE_FCNTL_DATA_VERSION] opcode is used to detect changes to
@@ -1112,6 +1113,11 @@ struct sqlite3_io_methods {
** happen either internally or externally and that are associated with
** a particular attached database.
**
** <li>[[SQLITE_FCNTL_CKPT_START]]
** The [SQLITE_FCNTL_CKPT_START] opcode is invoked from within a checkpoint
** in wal mode before the client starts to copy pages from the wal
** file to the database file.
**
** <li>[[SQLITE_FCNTL_CKPT_DONE]]
** The [SQLITE_FCNTL_CKPT_DONE] opcode is invoked from within a checkpoint
** in wal mode after the client has finished copying pages from the wal
@@ -1155,6 +1161,8 @@ struct sqlite3_io_methods {
#define SQLITE_FCNTL_DATA_VERSION 35
#define SQLITE_FCNTL_SIZE_LIMIT 36
#define SQLITE_FCNTL_CKPT_DONE 37
#define SQLITE_FCNTL_RESERVE_BYTES 38
#define SQLITE_FCNTL_CKPT_START 39
/* deprecated names */
#define SQLITE_GET_LOCKPROXYFILE SQLITE_FCNTL_GET_LOCKPROXYFILE
@@ -3533,8 +3541,19 @@ int sqlite3_open_v2(
** that check if a database file was a URI that contained a specific query
** parameter, and if so obtains the value of that query parameter.
**
** If F is the database filename pointer passed into the xOpen() method of
** a VFS implementation or it is the return value of [sqlite3_db_filename()]
** The first parameter to these interfaces (hereafter referred to
** as F) must be one of:
** <ul>
** <li> A database filename pointer created by the SQLite core and
** passed into the xOpen() method of a VFS implemention, or
** <li> A filename obtained from [sqlite3_db_filename()], or
** <li> A new filename constructed using [sqlite3_create_filename()].
** </ul>
** If the F parameter is not one of the above, then the behavior is
** undefined and probably undesirable. Older versions of SQLite were
** more tolerant of invalid F parameters than newer versions.
**
** If F is a suitable filename (as described in the previous paragraph)
** and if P is the name of the query parameter, then
** sqlite3_uri_parameter(F,P) returns the value of the P
** parameter if it exists or a NULL pointer if P does not appear as a
@@ -3617,6 +3636,25 @@ const char *sqlite3_filename_database(const char*);
const char *sqlite3_filename_journal(const char*);
const char *sqlite3_filename_wal(const char*);
/*
** CAPI3REF: Database File Corresponding To A Journal
**
** ^If X is the name of a rollback or WAL-mode journal file that is
** passed into the xOpen method of [sqlite3_vfs], then
** sqlite3_database_file_object(X) returns a pointer to the [sqlite3_file]
** object that represents the main database file.
**
** This routine is intended for use in custom [VFS] implementations
** only. It is not a general-purpose interface.
** The argument sqlite3_file_object(X) must be a filename pointer that
** has been passed into [sqlite3_vfs].xOpen method where the
** flags parameter to xOpen contains one of the bits
** [SQLITE_OPEN_MAIN_JOURNAL] or [SQLITE_OPEN_WAL]. Any other use
** of this routine results in undefined and probably undesirable
** behavior.
*/
sqlite3_file *sqlite3_database_file_object(const char*);
/*
** CAPI3REF: Create and Destroy VFS Filenames
**
@@ -3651,7 +3689,7 @@ const char *sqlite3_filename_wal(const char*);
**
** The sqlite3_free_filename(Y) routine releases a memory allocation
** previously obtained from sqlite3_create_filename(). Invoking
** sqlite3_free_filename(Y) is a NULL pointer is a harmless no-op.
** sqlite3_free_filename(Y) where Y is a NULL pointer is a harmless no-op.
**
** If the Y parameter to sqlite3_free_filename(Y) is anything other
** than a NULL pointer or a pointer previously acquired from
@@ -4258,6 +4296,24 @@ typedef struct sqlite3_context sqlite3_context;
** ^If the third parameter to sqlite3_bind_text() or sqlite3_bind_text16()
** or sqlite3_bind_blob() is a NULL pointer then the fourth parameter
** is ignored and the end result is the same as sqlite3_bind_null().
** ^If the third parameter to sqlite3_bind_text() is not NULL, then
** it should be a pointer to well-formed UTF8 text.
** ^If the third parameter to sqlite3_bind_text16() is not NULL, then
** it should be a pointer to well-formed UTF16 text.
** ^If the third parameter to sqlite3_bind_text64() is not NULL, then
** it should be a pointer to a well-formed unicode string that is
** either UTF8 if the sixth parameter is SQLITE_UTF8, or UTF16
** otherwise.
**
** [[byte-order determination rules]] ^The byte-order of
** UTF16 input text is determined by the byte-order mark (BOM, U+FEFF)
** found in first character, which is removed, or in the absence of a BOM
** the byte order is the native byte order of the host
** machine for sqlite3_bind_text16() or the byte order specified in
** the 6th parameter for sqlite3_bind_text64().)^
** ^If UTF16 input text contains invalid unicode
** characters, then SQLite might change those invalid characters
** into the unicode replacement character: U+FFFD.
**
** ^(In those routines that have a fourth argument, its value is the
** number of bytes in the parameter. To be clear: the value is the
@@ -4271,7 +4327,7 @@ typedef struct sqlite3_context sqlite3_context;
** or sqlite3_bind_text16() or sqlite3_bind_text64() then
** that parameter must be the byte offset
** where the NUL terminator would occur assuming the string were NUL
** terminated. If any NUL characters occur at byte offsets less than
** terminated. If any NUL characters occurs at byte offsets less than
** the value of the fourth parameter then the resulting string value will
** contain embedded NULs. The result of expressions involving strings
** with embedded NULs is undefined.
@@ -5439,7 +5495,7 @@ void sqlite3_value_free(sqlite3_value*);
**
** ^(The amount of space allocated by sqlite3_aggregate_context(C,N) is
** determined by the N parameter on first successful call. Changing the
** value of N in any subsequents call to sqlite3_aggregate_context() within
** value of N in any subsequent call to sqlite3_aggregate_context() within
** the same aggregate function instance will not resize the memory
** allocation.)^ Within the xFinal callback, it is customary to set
** N=0 in calls to sqlite3_aggregate_context(C,N) so that no
@@ -5596,8 +5652,9 @@ typedef void (*sqlite3_destructor_type)(void*);
** 2nd parameter of sqlite3_result_error() or sqlite3_result_error16()
** as the text of an error message. ^SQLite interprets the error
** message string from sqlite3_result_error() as UTF-8. ^SQLite
** interprets the string from sqlite3_result_error16() as UTF-16 in native
** byte order. ^If the third parameter to sqlite3_result_error()
** interprets the string from sqlite3_result_error16() as UTF-16 using
** the same [byte-order determination rules] as [sqlite3_bind_text16()].
** ^If the third parameter to sqlite3_result_error()
** or sqlite3_result_error16() is negative then SQLite takes as the error
** message all text up through the first zero character.
** ^If the third parameter to sqlite3_result_error() or
@@ -5665,6 +5722,25 @@ typedef void (*sqlite3_destructor_type)(void*);
** then SQLite makes a copy of the result into space obtained
** from [sqlite3_malloc()] before it returns.
**
** ^For the sqlite3_result_text16(), sqlite3_result_text16le(), and
** sqlite3_result_text16be() routines, and for sqlite3_result_text64()
** when the encoding is not UTF8, if the input UTF16 begins with a
** byte-order mark (BOM, U+FEFF) then the BOM is removed from the
** string and the rest of the string is interpreted according to the
** byte-order specified by the BOM. ^The byte-order specified by
** the BOM at the beginning of the text overrides the byte-order
** specified by the interface procedure. ^So, for example, if
** sqlite3_result_text16le() is invoked with text that begins
** with bytes 0xfe, 0xff (a big-endian byte-order mark) then the
** first two bytes of input are skipped and the remaining input
** is interpreted as UTF16BE text.
**
** ^For UTF16 input text to the sqlite3_result_text16(),
** sqlite3_result_text16be(), sqlite3_result_text16le(), and
** sqlite3_result_text64() routines, if the text contains invalid
** UTF16 characters, the invalid characters might be converted
** into the unicode replacement character, U+FFFD.
**
** ^The sqlite3_result_value() interface sets the result of
** the application-defined function to be a copy of the
** [unprotected sqlite3_value] object specified by the 2nd parameter. ^The
@@ -7612,7 +7688,7 @@ int sqlite3_test_control(int op, ...);
#define SQLITE_TESTCTRL_PENDING_BYTE 11
#define SQLITE_TESTCTRL_ASSERT 12
#define SQLITE_TESTCTRL_ALWAYS 13
#define SQLITE_TESTCTRL_RESERVE 14
#define SQLITE_TESTCTRL_RESERVE 14 /* NOT USED */
#define SQLITE_TESTCTRL_OPTIMIZATIONS 15
#define SQLITE_TESTCTRL_ISKEYWORD 16 /* NOT USED */
#define SQLITE_TESTCTRL_SCRATCHMALLOC 17 /* NOT USED */
+2
View File
@@ -334,6 +334,7 @@ struct sqlite3_api_routines {
char *(*create_filename)(const char*,const char*,const char*,
int,const char**);
void (*free_filename)(char*);
sqlite3_file *(*database_file_object)(const char*);
};
/*
@@ -637,6 +638,7 @@ typedef int (*sqlite3_loadext_entry)(
/* Version 3.32.0 and later */
#define sqlite3_create_filename sqlite3_api->create_filename
#define sqlite3_free_filename sqlite3_api->free_filename
#define sqlite3_database_file_object sqlite3_api->database_file_object
#endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */
#if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
+30 -4
View File
@@ -186,6 +186,21 @@
#pragma warn -spa /* Suspicious pointer arithmetic */
#endif
/*
** WAL mode depends on atomic aligned 32-bit loads and stores in a few
** places. The following macros try to make this explicit.
*/
#ifndef __has_feature
# define __has_feature(x) 0 /* compatibility with non-clang compilers */
#endif
#if GCC_VERSION>=4007000 || __has_feature(c_atomic)
# define AtomicLoad(PTR) __atomic_load_n((PTR),__ATOMIC_RELAXED)
# define AtomicStore(PTR,VAL) __atomic_store_n((PTR),(VAL),__ATOMIC_RELAXED)
#else
# define AtomicLoad(PTR) (*(PTR))
# define AtomicStore(PTR,VAL) (*(PTR) = (VAL))
#endif
/*
** Include standard header files as necessary
*/
@@ -979,7 +994,6 @@ struct BusyHandler {
int (*xBusyHandler)(void *,int); /* The busy callback */
void *pBusyArg; /* First arg to busy callback */
int nBusy; /* Incremented with each busy call */
u8 bExtraFileArg; /* Include sqlite3_file as callback arg */
};
/*
@@ -1524,6 +1538,7 @@ struct sqlite3 {
BusyHandler busyHandler; /* Busy callback */
Db aDbStatic[2]; /* Static space for the 2 default backends */
Savepoint *pSavepoint; /* List of active savepoints */
int nAnalysisLimit; /* Number of index rows to ANALYZE */
int busyTimeout; /* Busy handler timeout, in msec */
int nSavepoint; /* Number of non-transaction savepoints */
int nStatement; /* Number of nested statement-transactions */
@@ -1749,7 +1764,7 @@ struct FuncDestructor {
#define SQLITE_FUNC_LENGTH 0x0040 /* Built-in length() function */
#define SQLITE_FUNC_TYPEOF 0x0080 /* Built-in typeof() function */
#define SQLITE_FUNC_COUNT 0x0100 /* Built-in count(*) aggregate */
#define SQLITE_FUNC_COALESCE 0x0200 /* Built-in coalesce() or ifnull() */
/* 0x0200 -- available for reuse */
#define SQLITE_FUNC_UNLIKELY 0x0400 /* Built-in unlikely() function */
#define SQLITE_FUNC_CONSTANT 0x0800 /* Constant inputs give a constant output */
#define SQLITE_FUNC_MINMAX 0x1000 /* True for min() and max() aggregates */
@@ -1770,6 +1785,7 @@ struct FuncDestructor {
#define INLINEFUNC_expr_implies_expr 2
#define INLINEFUNC_expr_compare 3
#define INLINEFUNC_affinity 4
#define INLINEFUNC_iif 5
#define INLINEFUNC_unlikely 99 /* Default case */
/*
@@ -1934,6 +1950,7 @@ struct Column {
u8 notNull; /* An OE_ code for handling a NOT NULL constraint */
char affinity; /* One of the SQLITE_AFF_... values */
u8 szEst; /* Estimated size of value in this column. sizeof(INT)==1 */
u8 hName; /* Column name hash for faster lookup */
u16 colFlags; /* Boolean properties. See COLFLAG_ defines below */
};
@@ -2469,7 +2486,7 @@ struct Token {
** code for a SELECT that contains aggregate functions.
**
** If Expr.op==TK_AGG_COLUMN or TK_AGG_FUNCTION then Expr.pAggInfo is a
** pointer to this structure. The Expr.iColumn field is the index in
** pointer to this structure. The Expr.iAgg field is the index in
** AggInfo.aCol[] or AggInfo.aFunc[] of information needed to generate
** code for that node.
**
@@ -3695,6 +3712,7 @@ struct Walker {
struct WhereConst *pConst; /* WHERE clause constants */
struct RenameCtx *pRename; /* RENAME COLUMN context */
struct Table *pTab; /* Table of generated column */
struct SrcList_item *pSrcItem; /* A single FROM clause item */
} u;
};
@@ -3707,6 +3725,9 @@ int sqlite3WalkSelectFrom(Walker*, Select*);
int sqlite3ExprWalkNoop(Walker*, Expr*);
int sqlite3SelectWalkNoop(Walker*, Select*);
int sqlite3SelectWalkFail(Walker*, Select*);
int sqlite3WalkerDepthIncrease(Walker*,Select*);
void sqlite3WalkerDepthDecrease(Walker*,Select*);
#ifdef SQLITE_DEBUG
void sqlite3SelectWalkAssert2(Walker*, Select*);
#endif
@@ -4394,6 +4415,7 @@ void sqlite3DeferForeignKey(Parse*, int);
# define sqlite3AuthContextPush(a,b,c)
# define sqlite3AuthContextPop(a) ((void)(a))
#endif
int sqlite3DbIsNamed(sqlite3 *db, int iDb, const char *zName);
void sqlite3Attach(Parse*, Expr*, Expr*, Expr*);
void sqlite3Detach(Parse*, Expr*);
void sqlite3FixInit(DbFixer*, Parse*, int, const char*, const Token*);
@@ -4549,6 +4571,8 @@ int sqlite3MatchEName(
const char*,
const char*
);
Bitmask sqlite3ExprColUsed(Expr*);
u8 sqlite3StrIHash(const char*);
int sqlite3ResolveExprNames(NameContext*, Expr*);
int sqlite3ResolveExprListNames(NameContext*, ExprList*);
void sqlite3ResolveSelectNames(Parse*, Select*, NameContext*);
@@ -4564,7 +4588,7 @@ void sqlite3RenameExprlistUnmap(Parse*, ExprList*);
CollSeq *sqlite3GetCollSeq(Parse*, u8, CollSeq *, const char*);
char sqlite3AffinityType(const char*, Column*);
void sqlite3Analyze(Parse*, Token*, Token*);
int sqlite3InvokeBusyHandler(BusyHandler*, sqlite3_file*);
int sqlite3InvokeBusyHandler(BusyHandler*);
int sqlite3FindDb(sqlite3*, Token*);
int sqlite3FindDbName(sqlite3 *, const char *);
int sqlite3AnalysisLoad(sqlite3*,int iDB);
@@ -4689,8 +4713,10 @@ void sqlite3AutoLoadExtensions(sqlite3*);
int sqlite3ReadOnlyShadowTables(sqlite3 *db);
#ifndef SQLITE_OMIT_VIRTUALTABLE
int sqlite3ShadowTableName(sqlite3 *db, const char *zName);
int sqlite3IsShadowTableOf(sqlite3*,Table*,const char*);
#else
# define sqlite3ShadowTableName(A,B) 0
# define sqlite3IsShadowTableOf(A,B,C) 0
#endif
int sqlite3VtabEponymousTableInit(Parse*,Module*);
void sqlite3VtabEponymousTableClear(sqlite3*,Module*);
+2 -2
View File
@@ -56,7 +56,7 @@ static int sqlite3_get_table_cb(void *pArg, int nCol, char **argv, char **colv){
if( p->nData + need > p->nAlloc ){
char **azNew;
p->nAlloc = p->nAlloc*2 + need;
azNew = sqlite3_realloc64( p->azResult, sizeof(char*)*p->nAlloc );
azNew = sqlite3Realloc( p->azResult, sizeof(char*)*p->nAlloc );
if( azNew==0 ) goto malloc_failed;
p->azResult = azNew;
}
@@ -165,7 +165,7 @@ int sqlite3_get_table(
}
if( res.nAlloc>res.nData ){
char **azNew;
azNew = sqlite3_realloc64( res.azResult, sizeof(char*)*res.nData );
azNew = sqlite3Realloc( res.azResult, sizeof(char*)*res.nData );
if( azNew==0 ){
sqlite3_free_table(&res.azResult[1]);
db->errCode = SQLITE_NOMEM;
+11 -2
View File
@@ -3699,6 +3699,7 @@ static int SQLITE_TCLAPI DbMain(
const char *zFile = 0;
const char *zVfs = 0;
int flags;
int bTranslateFileName = 1;
Tcl_DString translatedFilename;
int rc;
@@ -3796,6 +3797,10 @@ static int SQLITE_TCLAPI DbMain(
}else{
flags &= ~SQLITE_OPEN_URI;
}
}else if( strcmp(zArg, "-translatefilename")==0 ){
if( Tcl_GetBooleanFromObj(interp, objv[i], &bTranslateFileName) ){
return TCL_ERROR;
}
}else{
Tcl_AppendResult(interp, "unknown option: ", zArg, (char*)0);
return TCL_ERROR;
@@ -3805,9 +3810,13 @@ static int SQLITE_TCLAPI DbMain(
p = (SqliteDb*)Tcl_Alloc( sizeof(*p) );
memset(p, 0, sizeof(*p));
if( zFile==0 ) zFile = "";
zFile = Tcl_TranslateFileName(interp, zFile, &translatedFilename);
if( bTranslateFileName ){
zFile = Tcl_TranslateFileName(interp, zFile, &translatedFilename);
}
rc = sqlite3_open_v2(zFile, &p->db, flags, zVfs);
Tcl_DStringFree(&translatedFilename);
if( bTranslateFileName ){
Tcl_DStringFree(&translatedFilename);
}
if( p->db ){
if( SQLITE_OK!=sqlite3_errcode(p->db) ){
zErrMsg = sqlite3_mprintf("%s", sqlite3_errmsg(p->db));
+2 -2
View File
@@ -568,7 +568,7 @@ int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzErrMsg){
assert( zSql!=0 );
mxSqlLen = db->aLimit[SQLITE_LIMIT_SQL_LENGTH];
if( db->nVdbeActive==0 ){
db->u1.isInterrupted = 0;
AtomicStore(&db->u1.isInterrupted, 0);
}
pParse->rc = SQLITE_OK;
pParse->zTail = zSql;
@@ -613,7 +613,7 @@ int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzErrMsg){
if( tokenType>=TK_SPACE ){
assert( tokenType==TK_SPACE || tokenType==TK_ILLEGAL );
#endif /* SQLITE_OMIT_WINDOWFUNC */
if( db->u1.isInterrupted ){
if( AtomicLoad(&db->u1.isInterrupted) ){
pParse->rc = SQLITE_INTERRUPT;
break;
}
+5 -4
View File
@@ -138,8 +138,8 @@ void sqlite3TreeViewSrcList(TreeView *pView, const SrcList *pSrc){
sqlite3_str_appendf(&x, " %s", pItem->zName);
}
if( pItem->pTab ){
sqlite3_str_appendf(&x, " tab=%Q nCol=%d ptr=%p",
pItem->pTab->zName, pItem->pTab->nCol, pItem->pTab);
sqlite3_str_appendf(&x, " tab=%Q nCol=%d ptr=%p used=%llx",
pItem->pTab->zName, pItem->pTab->nCol, pItem->pTab, pItem->colUsed);
}
if( pItem->zAlias ){
sqlite3_str_appendf(&x, " (AS %s)", pItem->zAlias);
@@ -582,8 +582,9 @@ void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 moreToFollow){
#endif
}
if( pExpr->op==TK_AGG_FUNCTION ){
sqlite3TreeViewLine(pView, "AGG_FUNCTION%d %Q%s",
pExpr->op2, pExpr->u.zToken, zFlgs);
sqlite3TreeViewLine(pView, "AGG_FUNCTION%d %Q%s iAgg=%d agg=%p",
pExpr->op2, pExpr->u.zToken, zFlgs,
pExpr->iAgg, pExpr->pAggInfo);
}else if( pExpr->op2!=0 ){
const char *zOp2;
char zBuf[8];
+1 -1
View File
@@ -580,7 +580,7 @@ void sqlite3DropTrigger(Parse *pParse, SrcList *pName, int noErr){
assert( zDb!=0 || sqlite3BtreeHoldsAllMutexes(db) );
for(i=OMIT_TEMPDB; i<db->nDb; i++){
int j = (i<2) ? i^1 : i; /* Search TEMP before MAIN */
if( zDb && sqlite3StrICmp(db->aDb[j].zDbSName, zDb) ) continue;
if( zDb && sqlite3DbIsNamed(db, j, zDb)==0 ) continue;
assert( sqlite3SchemaMutexHeld(db, j, 0) );
pTrigger = sqlite3HashFind(&(db->aDb[j].pSchema->trigHash), zName);
if( pTrigger ) break;
+5 -5
View File
@@ -53,10 +53,10 @@ static void updateVirtualTable(
** function is capable of transforming these types of expressions into
** sqlite3_value objects.
**
** If parameter iReg is not negative, code an OP_RealAffinity instruction
** on register iReg. This is used when an equivalent integer value is
** stored in place of an 8-byte floating point value in order to save
** space.
** If column as REAL affinity and the table is an ordinary b-tree table
** (not a virtual table) then the value might have been stored as an
** integer. In that case, add an OP_RealAffinity opcode to make sure
** it has been converted into REAL.
*/
void sqlite3ColumnDefault(Vdbe *v, Table *pTab, int i, int iReg){
assert( pTab!=0 );
@@ -73,7 +73,7 @@ void sqlite3ColumnDefault(Vdbe *v, Table *pTab, int i, int iReg){
}
}
#ifndef SQLITE_OMIT_FLOATING_POINT
if( pTab->aCol[i].affinity==SQLITE_AFF_REAL ){
if( pTab->aCol[i].affinity==SQLITE_AFF_REAL && !IsVirtual(pTab) ){
sqlite3VdbeAddOp1(v, OP_RealAffinity, iReg);
}
#endif
+16
View File
@@ -284,6 +284,7 @@ SQLITE_NOINLINE int sqlite3VdbeMemTranslate(Mem *pMem, u8 desiredEnc){
c = *(zIn++);
c += (*(zIn++))<<8;
if( c>=0xd800 && c<0xe000 ){
#ifdef SQLITE_REPLACE_INVALID_UTF
if( c>=0xdc00 || zIn>=zTerm ){
c = 0xfffd;
}else{
@@ -296,6 +297,13 @@ SQLITE_NOINLINE int sqlite3VdbeMemTranslate(Mem *pMem, u8 desiredEnc){
c = ((c&0x3ff)<<10) + (c2&0x3ff) + 0x10000;
}
}
#else
if( zIn<zTerm ){
int c2 = (*zIn++);
c2 += ((*zIn++)<<8);
c = (c2&0x03FF) + ((c&0x003F)<<10) + (((c&0x03C0)+0x0040)<<10);
}
#endif
}
WRITE_UTF8(z, c);
}
@@ -305,6 +313,7 @@ SQLITE_NOINLINE int sqlite3VdbeMemTranslate(Mem *pMem, u8 desiredEnc){
c = (*(zIn++))<<8;
c += *(zIn++);
if( c>=0xd800 && c<0xe000 ){
#ifdef SQLITE_REPLACE_INVALID_UTF
if( c>=0xdc00 || zIn>=zTerm ){
c = 0xfffd;
}else{
@@ -317,6 +326,13 @@ SQLITE_NOINLINE int sqlite3VdbeMemTranslate(Mem *pMem, u8 desiredEnc){
c = ((c&0x3ff)<<10) + (c2&0x3ff) + 0x10000;
}
}
#else
if( zIn<zTerm ){
int c2 = ((*zIn++)<<8);
c2 += (*zIn++);
c = (c2&0x03FF) + ((c&0x003F)<<10) + (((c&0x03C0)+0x0040)<<10);
}
#endif
}
WRITE_UTF8(z, c);
}
+13
View File
@@ -317,6 +317,19 @@ int sqlite3_strnicmp(const char *zLeft, const char *zRight, int N){
return N<0 ? 0 : UpperToLower[*a] - UpperToLower[*b];
}
/*
** Compute an 8-bit hash on a string that is insensitive to case differences
*/
u8 sqlite3StrIHash(const char *z){
u8 h = 0;
if( z==0 ) return 0;
while( z[0] ){
h += UpperToLower[(unsigned char)z[0]];
z++;
}
return h;
}
/*
** Compute 10 to the E-th power. Examples: E==1 results in 10.
** E==2 results in 100. E==50 results in 1.0e50.
+2 -2
View File
@@ -233,7 +233,7 @@ SQLITE_NOINLINE int sqlite3RunVacuum(
}
db->mDbFlags |= DBFLAG_VacuumInto;
}
nRes = sqlite3BtreeGetOptimalReserve(pMain);
nRes = sqlite3BtreeGetRequestedReserve(pMain);
sqlite3BtreeSetCacheSize(pTemp, db->aDb[iDb].pSchema->cache_size);
sqlite3BtreeSetSpillSize(pTemp, sqlite3BtreeSetSpillSize(pMain,0));
@@ -377,7 +377,7 @@ end_of_vacuum:
db->nChange = saved_nChange;
db->nTotalChange = saved_nTotalChange;
db->mTrace = saved_mTrace;
sqlite3BtreeSetPageSize(pMain, -1, -1, 1);
sqlite3BtreeSetPageSize(pMain, -1, 0, 1);
/* Currently there is an SQL level transaction open on the vacuum
** database. No locks are held on any other files (since the main file
+51 -31
View File
@@ -707,7 +707,7 @@ int sqlite3VdbeExec(
assert( p->explain==0 );
p->pResultSet = 0;
db->busyHandler.nBusy = 0;
if( db->u1.isInterrupted ) goto abort_due_to_interrupt;
if( AtomicLoad(&db->u1.isInterrupted) ) goto abort_due_to_interrupt;
sqlite3VdbeIOTraceSql(p);
#ifdef SQLITE_DEBUG
sqlite3BeginBenignMalloc();
@@ -891,7 +891,7 @@ jump_to_p2_and_check_for_interrupt:
** checks on every opcode. This helps sqlite3_step() to run about 1.5%
** faster according to "valgrind --tool=cachegrind" */
check_for_interrupt:
if( db->u1.isInterrupted ) goto abort_due_to_interrupt;
if( AtomicLoad(&db->u1.isInterrupted) ) goto abort_due_to_interrupt;
#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
/* Call the progress callback if it is configured and the required number
** of VDBE ops have been executed (either since this invocation of
@@ -3187,13 +3187,16 @@ case OP_MakeRecord: {
break;
}
/* Opcode: Count P1 P2 * * *
/* Opcode: Count P1 P2 p3 * *
** Synopsis: r[P2]=count()
**
** Store the number of entries (an integer value) in the table or index
** opened by cursor P1 in register P2
** opened by cursor P1 in register P2.
**
** If P3==0, then an exact count is obtained, which involves visiting
** every btree page of the table. But if P3 is non-zero, an estimate
** is returned based on the current cursor position.
*/
#ifndef SQLITE_OMIT_BTREECOUNT
case OP_Count: { /* out2 */
i64 nEntry;
BtCursor *pCrsr;
@@ -3201,14 +3204,17 @@ case OP_Count: { /* out2 */
assert( p->apCsr[pOp->p1]->eCurType==CURTYPE_BTREE );
pCrsr = p->apCsr[pOp->p1]->uc.pCursor;
assert( pCrsr );
nEntry = 0; /* Not needed. Only used to silence a warning. */
rc = sqlite3BtreeCount(db, pCrsr, &nEntry);
if( rc ) goto abort_due_to_error;
if( pOp->p3 ){
nEntry = sqlite3BtreeRowCountEst(pCrsr);
}else{
nEntry = 0; /* Not needed. Only used to silence a warning. */
rc = sqlite3BtreeCount(db, pCrsr, &nEntry);
if( rc ) goto abort_due_to_error;
}
pOut = out2Prerelease(p, pOp);
pOut->u.i = nEntry;
goto check_for_interrupt;
}
#endif
/* Opcode: Savepoint P1 * * P4 *
**
@@ -3664,7 +3670,7 @@ case OP_SetCookie: {
** <ul>
** <li> <b>0x02 OPFLAG_SEEKEQ</b>: This cursor will only be used for
** equality lookups (implemented as a pair of opcodes OP_SeekGE/OP_IdxGT
** of OP_SeekLE/OP_IdxGT)
** of OP_SeekLE/OP_IdxLT)
** </ul>
**
** The P4 value may be either an integer (P4_INT32) or a pointer to
@@ -3694,7 +3700,7 @@ case OP_SetCookie: {
** <ul>
** <li> <b>0x02 OPFLAG_SEEKEQ</b>: This cursor will only be used for
** equality lookups (implemented as a pair of opcodes OP_SeekGE/OP_IdxGT
** of OP_SeekLE/OP_IdxGT)
** of OP_SeekLE/OP_IdxLT)
** </ul>
**
** See also: OP_OpenRead, OP_OpenWrite
@@ -3718,7 +3724,7 @@ case OP_SetCookie: {
** <ul>
** <li> <b>0x02 OPFLAG_SEEKEQ</b>: This cursor will only be used for
** equality lookups (implemented as a pair of opcodes OP_SeekGE/OP_IdxGT
** of OP_SeekLE/OP_IdxGT)
** of OP_SeekLE/OP_IdxLT)
** <li> <b>0x08 OPFLAG_FORDELETE</b>: This cursor is used only to seek
** and subsequently delete entries in an index btree. This is a
** hint to the storage engine that the storage engine is allowed to
@@ -3830,9 +3836,7 @@ open_cursor_set_hints:
assert( OPFLAG_BULKCSR==BTREE_BULKLOAD );
assert( OPFLAG_SEEKEQ==BTREE_SEEK_EQ );
testcase( pOp->p5 & OPFLAG_BULKCSR );
#ifdef SQLITE_ENABLE_CURSOR_HINTS
testcase( pOp->p2 & OPFLAG_SEEKEQ );
#endif
sqlite3BtreeCursorHintFlags(pCur->uc.pCursor,
(pOp->p5 & (OPFLAG_BULKCSR|OPFLAG_SEEKEQ)));
if( rc ) goto abort_due_to_error;
@@ -4088,11 +4092,13 @@ case OP_ColumnsUsed: {
** greater than or equal to the key and P2 is not zero, then jump to P2.
**
** If the cursor P1 was opened using the OPFLAG_SEEKEQ flag, then this
** opcode will always land on a record that equally equals the key, or
** else jump immediately to P2. When the cursor is OPFLAG_SEEKEQ, this
** opcode must be followed by an IdxLE opcode with the same arguments.
** The IdxLE opcode will be skipped if this opcode succeeds, but the
** IdxLE opcode will be used on subsequent loop iterations.
** opcode will either land on a record that exactly matches the key, or
** else it will cause a jump to P2. When the cursor is OPFLAG_SEEKEQ,
** this opcode must be followed by an IdxLE opcode with the same arguments.
** The IdxGT opcode will be skipped if this opcode succeeds, but the
** IdxGT opcode will be used on subsequent loop iterations. The
** OPFLAG_SEEKEQ flags is a hint to the btree layer to say that this
** is an equality search.
**
** This opcode leaves the cursor configured to move in forward order,
** from the beginning toward the end. In other words, the cursor is
@@ -4108,7 +4114,7 @@ case OP_ColumnsUsed: {
** to an SQL index, then P3 is the first in an array of P4 registers
** that are used as an unpacked index key.
**
** Reposition cursor P1 so that it points to the smallest entry that
** Reposition cursor P1 so that it points to the smallest entry that
** is greater than the key value. If there are no records greater than
** the key and P2 is not zero, then jump to P2.
**
@@ -4153,11 +4159,13 @@ case OP_ColumnsUsed: {
** configured to use Prev, not Next.
**
** If the cursor P1 was opened using the OPFLAG_SEEKEQ flag, then this
** opcode will always land on a record that equally equals the key, or
** else jump immediately to P2. When the cursor is OPFLAG_SEEKEQ, this
** opcode must be followed by an IdxGE opcode with the same arguments.
** opcode will either land on a record that exactly matches the key, or
** else it will cause a jump to P2. When the cursor is OPFLAG_SEEKEQ,
** this opcode must be followed by an IdxLE opcode with the same arguments.
** The IdxGE opcode will be skipped if this opcode succeeds, but the
** IdxGE opcode will be used on subsequent loop iterations.
** IdxGE opcode will be used on subsequent loop iterations. The
** OPFLAG_SEEKEQ flags is a hint to the btree layer to say that this
** is an equality search.
**
** See also: Found, NotFound, SeekGt, SeekGe, SeekLt
*/
@@ -4194,7 +4202,7 @@ case OP_SeekGT: { /* jump, in3, group */
pC->cacheStatus = CACHE_STALE;
if( pC->isTable ){
u16 flags3, newType;
/* The BTREE_SEEK_EQ flag is only set on index cursors */
/* The OPFLAG_SEEKEQ/BTREE_SEEK_EQ flag is only set on index cursors */
assert( sqlite3BtreeCursorHasHint(pC->uc.pCursor, BTREE_SEEK_EQ)==0
|| CORRUPT_DB );
@@ -4253,14 +4261,17 @@ case OP_SeekGT: { /* jump, in3, group */
goto abort_due_to_error;
}
}else{
/* For a cursor with the BTREE_SEEK_EQ hint, only the OP_SeekGE and
** OP_SeekLE opcodes are allowed, and these must be immediately followed
** by an OP_IdxGT or OP_IdxLT opcode, respectively, with the same key.
/* For a cursor with the OPFLAG_SEEKEQ/BTREE_SEEK_EQ hint, only the
** OP_SeekGE and OP_SeekLE opcodes are allowed, and these must be
** immediately followed by an OP_IdxGT or OP_IdxLT opcode, respectively,
** with the same key.
*/
if( sqlite3BtreeCursorHasHint(pC->uc.pCursor, BTREE_SEEK_EQ) ){
eqOnly = 1;
assert( pOp->opcode==OP_SeekGE || pOp->opcode==OP_SeekLE );
assert( pOp[1].opcode==OP_IdxLT || pOp[1].opcode==OP_IdxGT );
assert( pOp->opcode==OP_SeekGE || pOp[1].opcode==OP_IdxLT );
assert( pOp->opcode==OP_SeekLE || pOp[1].opcode==OP_IdxGT );
assert( pOp[1].p1==pOp[0].p1 );
assert( pOp[1].p2==pOp[0].p2 );
assert( pOp[1].p3==pOp[0].p3 );
@@ -5641,12 +5652,19 @@ case OP_SorterInsert: { /* in2 */
break;
}
/* Opcode: IdxDelete P1 P2 P3 * *
/* Opcode: IdxDelete P1 P2 P3 * P5
** Synopsis: key=r[P2@P3]
**
** The content of P3 registers starting at register P2 form
** an unpacked index key. This opcode removes that entry from the
** index opened by cursor P1.
**
** If P5 is not zero, then raise an SQLITE_CORRUPT_INDEX error
** if no matching index entry is found. This happens when running
** an UPDATE or DELETE statement and the index entry to be updated
** or deleted is not found. For some uses of IdxDelete
** (example: the EXCEPT operator) it does not matter that no matching
** entry is found. For those cases, P5 is zero.
*/
case OP_IdxDelete: {
VdbeCursor *pC;
@@ -5663,7 +5681,6 @@ case OP_IdxDelete: {
sqlite3VdbeIncrWriteCounter(p, pC);
pCrsr = pC->uc.pCursor;
assert( pCrsr!=0 );
assert( pOp->p5==0 );
r.pKeyInfo = pC->pKeyInfo;
r.nField = (u16)pOp->p3;
r.default_rc = 0;
@@ -5673,6 +5690,9 @@ case OP_IdxDelete: {
if( res==0 ){
rc = sqlite3BtreeDelete(pCrsr, BTREE_AUXDELETE);
if( rc ) goto abort_due_to_error;
}else if( pOp->p5 ){
rc = SQLITE_CORRUPT_INDEX;
goto abort_due_to_error;
}
assert( pC->deferredMoveto==0 );
pC->cacheStatus = CACHE_STALE;
@@ -7994,7 +8014,7 @@ no_mem:
** flag.
*/
abort_due_to_interrupt:
assert( db->u1.isInterrupted );
assert( AtomicLoad(&db->u1.isInterrupted) );
rc = db->mallocFailed ? SQLITE_NOMEM_BKPT : SQLITE_INTERRUPT;
p->rc = rc;
sqlite3VdbeError(p, "%s", sqlite3ErrStr(rc));
+3
View File
@@ -290,6 +290,9 @@ void sqlite3VdbeLinkSubProgram(Vdbe *, SubProgram *);
int sqlite3VdbeHasSubProgram(Vdbe*);
int sqlite3NotPureFunc(sqlite3_context*);
#ifdef SQLITE_ENABLE_BYTECODE_VTAB
int sqlite3VdbeBytecodeVtabInit(sqlite3*);
#endif
/* Use SQLITE_ENABLE_COMMENTS to enable generation of extra comments on
** each VDBE opcode.
+12 -4
View File
@@ -31,7 +31,8 @@
** "explain" P4 display logic is enabled.
*/
#if !defined(SQLITE_OMIT_EXPLAIN) || !defined(NDEBUG) \
|| defined(VDBE_PROFILE) || defined(SQLITE_DEBUG)
|| defined(VDBE_PROFILE) || defined(SQLITE_DEBUG) \
|| defined(SQLITE_ENABLE_BYTECODE_VTAB)
# define VDBE_DISPLAY_P4 1
#else
# define VDBE_DISPLAY_P4 0
@@ -418,9 +419,9 @@ struct Vdbe {
u8 errorAction; /* Recovery action to do in case of an error */
u8 minWriteFileFormat; /* Minimum file format for writable database files */
u8 prepFlags; /* SQLITE_PREPARE_* flags */
u8 doingRerun; /* True if rerunning after an auto-reprepare */
bft expired:2; /* 1: recompile VM immediately 2: when convenient */
bft explain:2; /* True if EXPLAIN present on SQL command */
bft doingRerun:1; /* True if rerunning after an auto-reprepare */
bft changeCntOn:1; /* True to update the change-counter */
bft runOnlyOnce:1; /* Automatically expire on reset */
bft usesStmtJournal:1; /* True if uses a statement journal */
@@ -496,7 +497,14 @@ int sqlite2BtreeKeyCompare(BtCursor *, const void *, int, int, int *);
int sqlite3VdbeIdxKeyCompare(sqlite3*,VdbeCursor*,UnpackedRecord*,int*);
int sqlite3VdbeIdxRowid(sqlite3*, BtCursor*, i64*);
int sqlite3VdbeExec(Vdbe*);
#ifndef SQLITE_OMIT_EXPLAIN
#if !defined(SQLITE_OMIT_EXPLAIN) || defined(SQLITE_ENABLE_BYTECODE_VTAB)
int sqlite3VdbeNextOpcode(Vdbe*,Mem*,int,int*,int*,Op**);
char *sqlite3VdbeDisplayP4(sqlite3*,Op*);
#endif
#if defined(SQLITE_ENABLE_EXPLAIN_COMMENTS)
char *sqlite3VdbeDisplayComment(sqlite3*,const Op*,const char*);
#endif
#if !defined(SQLITE_OMIT_EXPLAIN)
int sqlite3VdbeList(Vdbe*);
#endif
int sqlite3VdbeHalt(Vdbe*);
@@ -538,7 +546,7 @@ int sqlite3VdbeMemFinalize(Mem*, FuncDef*);
#ifndef SQLITE_OMIT_WINDOWFUNC
int sqlite3VdbeMemAggValue(Mem*, Mem*, FuncDef*);
#endif
#ifndef SQLITE_OMIT_EXPLAIN
#if !defined(SQLITE_OMIT_EXPLAIN) || defined(SQLITE_ENABLE_BYTECODE_VTAB)
const char *sqlite3OpcodeName(int);
#endif
int sqlite3VdbeMemGrow(Mem *pMem, int n, int preserve);
+2 -2
View File
@@ -663,7 +663,7 @@ static int sqlite3Step(Vdbe *p){
** from interrupting a statement that has not yet started.
*/
if( db->nVdbeActive==0 ){
db->u1.isInterrupted = 0;
AtomicStore(&db->u1.isInterrupted, 0);
}
assert( db->nVdbeWrite>0 || db->autoCommit==0
@@ -1355,7 +1355,7 @@ static int vdbeUnbind(Vdbe *p, int i){
/* If the bit corresponding to this variable in Vdbe.expmask is set, then
** binding a new value to this variable invalidates the current query plan.
**
** IMPLEMENTATION-OF: R-48440-37595 If the specific value bound to host
** IMPLEMENTATION-OF: R-57496-20354 If the specific value bound to a host
** parameter in the WHERE clause might influence the choice of query plan
** for a statement, then the statement will be automatically recompiled,
** as if there had been a schema change, on the first sqlite3_step() call
+195 -178
View File
@@ -424,7 +424,7 @@ void sqlite3ExplainBreakpoint(const char *z1, const char *z2){
#endif
/*
** Add a new OP_ opcode.
** Add a new OP_Explain opcode.
**
** If the bPush flag is true, then make this opcode the parent for
** subsequent Explains until sqlite3VdbeExplainPop() is called.
@@ -1464,11 +1464,10 @@ static int translateP(char c, const Op *pOp){
** "PX@PY+1" -> "r[X..X+Y]" or "r[x]" if y is 0
** "PY..PY" -> "r[X..Y]" or "r[x]" if y<=x
*/
static int displayComment(
char *sqlite3VdbeDisplayComment(
sqlite3 *db, /* Optional - Oom error reporting only */
const Op *pOp, /* The opcode to be commented */
const char *zP4, /* Previously obtained value for P4 */
char *zTemp, /* Write result here */
int nTemp /* Space available in zTemp[] */
const char *zP4 /* Previously obtained value for P4 */
){
const char *zOpName;
const char *zSynopsis;
@@ -1476,8 +1475,8 @@ static int displayComment(
int ii;
char zAlt[50];
StrAccum x;
sqlite3StrAccumInit(&x, 0, zTemp, nTemp, 0);
sqlite3StrAccumInit(&x, 0, 0, 0, SQLITE_MAX_LENGTH);
zOpName = sqlite3OpcodeName(pOp->opcode);
nOpName = sqlite3Strlen30(zOpName);
if( zOpName[nOpName+1] ){
@@ -1544,10 +1543,12 @@ static int displayComment(
}else if( pOp->zComment ){
sqlite3_str_appendall(&x, pOp->zComment);
}
sqlite3StrAccumFinish(&x);
return x.nChar;
if( (x.accError & SQLITE_NOMEM)!=0 && db!=0 ){
sqlite3OomFault(db);
}
return sqlite3StrAccumFinish(&x);
}
#endif /* SQLITE_DEBUG */
#endif /* SQLITE_ENABLE_EXPLAIN_COMMENTS */
#if VDBE_DISPLAY_P4 && defined(SQLITE_ENABLE_CURSOR_HINTS)
/*
@@ -1628,11 +1629,11 @@ static void displayP4Expr(StrAccum *p, Expr *pExpr){
** Compute a string that describes the P4 parameter for an opcode.
** Use zTemp for any required temporary buffer space.
*/
static char *displayP4(Op *pOp, char *zTemp, int nTemp){
char *zP4 = zTemp;
char *sqlite3VdbeDisplayP4(sqlite3 *db, Op *pOp){
char *zP4 = 0;
StrAccum x;
assert( nTemp>=20 );
sqlite3StrAccumInit(&x, 0, zTemp, nTemp, 0);
sqlite3StrAccumInit(&x, 0, 0, 0, SQLITE_MAX_LENGTH);
switch( pOp->p4type ){
case P4_KEYINFO: {
int j;
@@ -1716,36 +1717,32 @@ static char *displayP4(Op *pOp, char *zTemp, int nTemp){
int n = ai[0]; /* The first element of an INTARRAY is always the
** count of the number of elements to follow */
for(i=1; i<=n; i++){
sqlite3_str_appendf(&x, ",%d", ai[i]);
sqlite3_str_appendf(&x, "%c%d", (i==1 ? '[' : ','), ai[i]);
}
zTemp[0] = '[';
sqlite3_str_append(&x, "]", 1);
break;
}
case P4_SUBPROGRAM: {
sqlite3_str_appendf(&x, "program");
zP4 = "program";
break;
}
case P4_DYNBLOB:
case P4_ADVANCE: {
zTemp[0] = 0;
break;
}
case P4_TABLE: {
sqlite3_str_appendf(&x, "%s", pOp->p4.pTab->zName);
zP4 = pOp->p4.pTab->zName;
break;
}
default: {
zP4 = pOp->p4.z;
if( zP4==0 ){
zP4 = zTemp;
zTemp[0] = 0;
}
}
}
sqlite3StrAccumFinish(&x);
assert( zP4!=0 );
return zP4;
if( zP4 ) sqlite3_str_appendall(&x, zP4);
if( (x.accError & SQLITE_NOMEM)!=0 ){
sqlite3OomFault(db);
}
return sqlite3StrAccumFinish(&x);
}
#endif /* VDBE_DISPLAY_P4 */
@@ -1835,24 +1832,30 @@ void sqlite3VdbeLeave(Vdbe *p){
*/
void sqlite3VdbePrintOp(FILE *pOut, int pc, VdbeOp *pOp){
char *zP4;
char zPtr[50];
char zCom[100];
char *zCom;
sqlite3 dummyDb;
static const char *zFormat1 = "%4d %-13s %4d %4d %4d %-13s %.2X %s\n";
if( pOut==0 ) pOut = stdout;
zP4 = displayP4(pOp, zPtr, sizeof(zPtr));
sqlite3BeginBenignMalloc();
dummyDb.mallocFailed = 1;
zP4 = sqlite3VdbeDisplayP4(&dummyDb, pOp);
#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
displayComment(pOp, zP4, zCom, sizeof(zCom));
zCom = sqlite3VdbeDisplayComment(0, pOp, zP4);
#else
zCom[0] = 0;
zCom = 0;
#endif
/* NB: The sqlite3OpcodeName() function is implemented by code created
** by the mkopcodeh.awk and mkopcodec.awk scripts which extract the
** information from the vdbe.c source text */
fprintf(pOut, zFormat1, pc,
sqlite3OpcodeName(pOp->opcode), pOp->p1, pOp->p2, pOp->p3, zP4, pOp->p5,
zCom
sqlite3OpcodeName(pOp->opcode), pOp->p1, pOp->p2, pOp->p3,
zP4 ? zP4 : "", pOp->p5,
zCom ? zCom : ""
);
fflush(pOut);
sqlite3_free(zP4);
sqlite3_free(zCom);
sqlite3EndBenignMalloc();
}
#endif
@@ -1943,6 +1946,121 @@ void sqlite3VdbeFrameMemDel(void *pArg){
pFrame->v->pDelFrame = pFrame;
}
#if defined(SQLITE_ENABLE_BYTECODE_VTAB) || !defined(SQLITE_OMIT_EXPLAIN)
/*
** Locate the next opcode to be displayed in EXPLAIN or EXPLAIN
** QUERY PLAN output.
**
** Return SQLITE_ROW on success. Return SQLITE_DONE if there are no
** more opcodes to be displayed.
*/
int sqlite3VdbeNextOpcode(
Vdbe *p, /* The statement being explained */
Mem *pSub, /* Storage for keeping track of subprogram nesting */
int eMode, /* 0: normal. 1: EQP. 2: TablesUsed */
int *piPc, /* IN/OUT: Current rowid. Overwritten with next rowid */
int *piAddr, /* OUT: Write index into (*paOp)[] here */
Op **paOp /* OUT: Write the opcode array here */
){
int nRow; /* Stop when row count reaches this */
int nSub = 0; /* Number of sub-vdbes seen so far */
SubProgram **apSub = 0; /* Array of sub-vdbes */
int i; /* Next instruction address */
int rc = SQLITE_OK; /* Result code */
Op *aOp = 0; /* Opcode array */
int iPc; /* Rowid. Copy of value in *piPc */
/* When the number of output rows reaches nRow, that means the
** listing has finished and sqlite3_step() should return SQLITE_DONE.
** nRow is the sum of the number of rows in the main program, plus
** the sum of the number of rows in all trigger subprograms encountered
** so far. The nRow value will increase as new trigger subprograms are
** encountered, but p->pc will eventually catch up to nRow.
*/
nRow = p->nOp;
if( pSub!=0 ){
if( pSub->flags&MEM_Blob ){
/* pSub is initiallly NULL. It is initialized to a BLOB by
** the P4_SUBPROGRAM processing logic below */
nSub = pSub->n/sizeof(Vdbe*);
apSub = (SubProgram **)pSub->z;
}
for(i=0; i<nSub; i++){
nRow += apSub[i]->nOp;
}
}
iPc = *piPc;
while(1){ /* Loop exits via break */
i = iPc++;
if( i>=nRow ){
p->rc = SQLITE_OK;
rc = SQLITE_DONE;
break;
}
if( i<p->nOp ){
/* The rowid is small enough that we are still in the
** main program. */
aOp = p->aOp;
}else{
/* We are currently listing subprograms. Figure out which one and
** pick up the appropriate opcode. */
int j;
i -= p->nOp;
assert( apSub!=0 );
assert( nSub>0 );
for(j=0; i>=apSub[j]->nOp; j++){
i -= apSub[j]->nOp;
assert( i<apSub[j]->nOp || j+1<nSub );
}
aOp = apSub[j]->aOp;
}
/* When an OP_Program opcode is encounter (the only opcode that has
** a P4_SUBPROGRAM argument), expand the size of the array of subprograms
** kept in p->aMem[9].z to hold the new program - assuming this subprogram
** has not already been seen.
*/
if( pSub!=0 && aOp[i].p4type==P4_SUBPROGRAM ){
int nByte = (nSub+1)*sizeof(SubProgram*);
int j;
for(j=0; j<nSub; j++){
if( apSub[j]==aOp[i].p4.pProgram ) break;
}
if( j==nSub ){
p->rc = sqlite3VdbeMemGrow(pSub, nByte, nSub!=0);
if( p->rc!=SQLITE_OK ){
rc = SQLITE_ERROR;
break;
}
apSub = (SubProgram **)pSub->z;
apSub[nSub++] = aOp[i].p4.pProgram;
MemSetTypeFlag(pSub, MEM_Blob);
pSub->n = nSub*sizeof(SubProgram*);
nRow += aOp[i].p4.pProgram->nOp;
}
}
if( eMode==0 ) break;
#ifdef SQLITE_ENABLE_BYTECODE_VTAB
if( eMode==2 ){
Op *pOp = aOp + i;
if( pOp->opcode==OP_OpenRead ) break;
if( pOp->opcode==OP_OpenWrite && (pOp->p5 & OPFLAG_P2ISREG)==0 ) break;
if( pOp->opcode==OP_ReopenIdx ) break;
}else
#endif
{
assert( eMode==1 );
if( aOp[i].opcode==OP_Explain ) break;
if( aOp[i].opcode==OP_Init && iPc>1 ) break;
}
}
*piPc = iPc;
*piAddr = i;
*paOp = aOp;
return rc;
}
#endif /* SQLITE_ENABLE_BYTECODE_VTAB || !SQLITE_OMIT_EXPLAIN */
/*
** Delete a VdbeFrame object and its contents. VdbeFrame objects are
@@ -1983,16 +2101,14 @@ void sqlite3VdbeFrameDelete(VdbeFrame *p){
int sqlite3VdbeList(
Vdbe *p /* The VDBE */
){
int nRow; /* Stop when row count reaches this */
int nSub = 0; /* Number of sub-vdbes seen so far */
SubProgram **apSub = 0; /* Array of sub-vdbes */
Mem *pSub = 0; /* Memory cell hold array of subprogs */
sqlite3 *db = p->db; /* The database connection */
int i; /* Loop counter */
int rc = SQLITE_OK; /* Return code */
Mem *pMem = &p->aMem[1]; /* First Mem of result set */
int bListSubprogs = (p->explain==1 || (db->flags & SQLITE_TriggerEQP)!=0);
Op *pOp = 0;
Op *aOp; /* Array of opcodes */
Op *pOp; /* Current opcode */
assert( p->explain );
assert( p->magic==VDBE_MAGIC_RUN );
@@ -2012,14 +2128,6 @@ int sqlite3VdbeList(
return SQLITE_ERROR;
}
/* When the number of output rows reaches nRow, that means the
** listing has finished and sqlite3_step() should return SQLITE_DONE.
** nRow is the sum of the number of rows in the main program, plus
** the sum of the number of rows in all trigger subprograms encountered
** so far. The nRow value will increase as new trigger subprograms are
** encountered, but p->pc will eventually catch up to nRow.
*/
nRow = p->nOp;
if( bListSubprogs ){
/* The first 8 memory cells are used for the result set. So we will
** commandeer the 9th cell to use as storage for an array of pointers
@@ -2027,147 +2135,55 @@ int sqlite3VdbeList(
** cells. */
assert( p->nMem>9 );
pSub = &p->aMem[9];
if( pSub->flags&MEM_Blob ){
/* On the first call to sqlite3_step(), pSub will hold a NULL. It is
** initialized to a BLOB by the P4_SUBPROGRAM processing logic below */
nSub = pSub->n/sizeof(Vdbe*);
apSub = (SubProgram **)pSub->z;
}
for(i=0; i<nSub; i++){
nRow += apSub[i]->nOp;
}
}else{
pSub = 0;
}
while(1){ /* Loop exits via break */
i = p->pc++;
if( i>=nRow ){
p->rc = SQLITE_OK;
rc = SQLITE_DONE;
break;
}
if( i<p->nOp ){
/* The output line number is small enough that we are still in the
** main program. */
pOp = &p->aOp[i];
}else{
/* We are currently listing subprograms. Figure out which one and
** pick up the appropriate opcode. */
int j;
i -= p->nOp;
assert( apSub!=0 );
assert( nSub>0 );
for(j=0; i>=apSub[j]->nOp; j++){
i -= apSub[j]->nOp;
assert( i<apSub[j]->nOp || j+1<nSub );
}
pOp = &apSub[j]->aOp[i];
}
/* When an OP_Program opcode is encounter (the only opcode that has
** a P4_SUBPROGRAM argument), expand the size of the array of subprograms
** kept in p->aMem[9].z to hold the new program - assuming this subprogram
** has not already been seen.
*/
if( bListSubprogs && pOp->p4type==P4_SUBPROGRAM ){
int nByte = (nSub+1)*sizeof(SubProgram*);
int j;
for(j=0; j<nSub; j++){
if( apSub[j]==pOp->p4.pProgram ) break;
}
if( j==nSub ){
p->rc = sqlite3VdbeMemGrow(pSub, nByte, nSub!=0);
if( p->rc!=SQLITE_OK ){
rc = SQLITE_ERROR;
break;
}
apSub = (SubProgram **)pSub->z;
apSub[nSub++] = pOp->p4.pProgram;
pSub->flags |= MEM_Blob;
pSub->n = nSub*sizeof(SubProgram*);
nRow += pOp->p4.pProgram->nOp;
}
}
if( p->explain<2 ) break;
if( pOp->opcode==OP_Explain ) break;
if( pOp->opcode==OP_Init && p->pc>1 ) break;
}
/* Figure out which opcode is next to display */
rc = sqlite3VdbeNextOpcode(p, pSub, p->explain==2, &p->pc, &i, &aOp);
if( rc==SQLITE_OK ){
if( db->u1.isInterrupted ){
pOp = aOp + i;
if( AtomicLoad(&db->u1.isInterrupted) ){
p->rc = SQLITE_INTERRUPT;
rc = SQLITE_ERROR;
sqlite3VdbeError(p, sqlite3ErrStr(p->rc));
}else{
char *zP4;
if( p->explain==1 ){
pMem->flags = MEM_Int;
pMem->u.i = i; /* Program counter */
pMem++;
pMem->flags = MEM_Static|MEM_Str|MEM_Term;
pMem->z = (char*)sqlite3OpcodeName(pOp->opcode); /* Opcode */
assert( pMem->z!=0 );
pMem->n = sqlite3Strlen30(pMem->z);
pMem->enc = SQLITE_UTF8;
pMem++;
}
pMem->flags = MEM_Int;
pMem->u.i = pOp->p1; /* P1 */
pMem++;
pMem->flags = MEM_Int;
pMem->u.i = pOp->p2; /* P2 */
pMem++;
pMem->flags = MEM_Int;
pMem->u.i = pOp->p3; /* P3 */
pMem++;
if( sqlite3VdbeMemClearAndResize(pMem, 100) ){ /* P4 */
assert( p->db->mallocFailed );
return SQLITE_ERROR;
}
pMem->flags = MEM_Str|MEM_Term;
zP4 = displayP4(pOp, pMem->z, pMem->szMalloc);
if( zP4!=pMem->z ){
pMem->n = 0;
sqlite3VdbeMemSetStr(pMem, zP4, -1, SQLITE_UTF8, 0);
char *zP4 = sqlite3VdbeDisplayP4(db, pOp);
if( p->explain==2 ){
sqlite3VdbeMemSetInt64(pMem, pOp->p1);
sqlite3VdbeMemSetInt64(pMem+1, pOp->p2);
sqlite3VdbeMemSetInt64(pMem+2, pOp->p3);
sqlite3VdbeMemSetStr(pMem+3, zP4, -1, SQLITE_UTF8, sqlite3_free);
p->nResColumn = 4;
}else{
assert( pMem->z!=0 );
pMem->n = sqlite3Strlen30(pMem->z);
pMem->enc = SQLITE_UTF8;
}
pMem++;
if( p->explain==1 ){
if( sqlite3VdbeMemClearAndResize(pMem, 4) ){
assert( p->db->mallocFailed );
return SQLITE_ERROR;
}
pMem->flags = MEM_Str|MEM_Term;
pMem->n = 2;
sqlite3_snprintf(3, pMem->z, "%.2x", pOp->p5); /* P5 */
pMem->enc = SQLITE_UTF8;
pMem++;
sqlite3VdbeMemSetInt64(pMem+0, i);
sqlite3VdbeMemSetStr(pMem+1, (char*)sqlite3OpcodeName(pOp->opcode),
-1, SQLITE_UTF8, SQLITE_STATIC);
sqlite3VdbeMemSetInt64(pMem+2, pOp->p1);
sqlite3VdbeMemSetInt64(pMem+3, pOp->p2);
sqlite3VdbeMemSetInt64(pMem+4, pOp->p3);
/* pMem+5 for p4 is done last */
sqlite3VdbeMemSetInt64(pMem+6, pOp->p5);
#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
if( sqlite3VdbeMemClearAndResize(pMem, 500) ){
assert( p->db->mallocFailed );
return SQLITE_ERROR;
{
char *zCom = sqlite3VdbeDisplayComment(db, pOp, zP4);
sqlite3VdbeMemSetStr(pMem+7, zCom, -1, SQLITE_UTF8, sqlite3_free);
}
pMem->flags = MEM_Str|MEM_Term;
pMem->n = displayComment(pOp, zP4, pMem->z, 500);
pMem->enc = SQLITE_UTF8;
#else
pMem->flags = MEM_Null; /* Comment */
sqlite3VdbeMemSetNull(pMem+7);
#endif
sqlite3VdbeMemSetStr(pMem+5, zP4, -1, SQLITE_UTF8, sqlite3_free);
p->nResColumn = 8;
}
p->pResultSet = pMem;
if( db->mallocFailed ){
p->rc = SQLITE_NOMEM;
rc = SQLITE_ERROR;
}else{
p->rc = SQLITE_OK;
rc = SQLITE_ROW;
}
p->nResColumn = 8 - 4*(p->explain-1);
p->pResultSet = &p->aMem[1];
p->rc = SQLITE_OK;
rc = SQLITE_ROW;
}
}
return rc;
@@ -2375,6 +2391,7 @@ void sqlite3VdbeMakeReady(
};
int iFirst, mx, i;
if( nMem<10 ) nMem = 10;
p->explain = pParse->explain;
if( pParse->explain==2 ){
sqlite3VdbeSetNumCols(p, 4);
iFirst = 8;
@@ -2425,7 +2442,6 @@ void sqlite3VdbeMakeReady(
p->pVList = pParse->pVList;
pParse->pVList = 0;
p->explain = pParse->explain;
if( db->mallocFailed ){
p->nVar = 0;
p->nCursor = 0;
@@ -2737,8 +2753,9 @@ static int vdbeCommit(sqlite3 *db, Vdbe *p){
/* Select a master journal file name */
nMainFile = sqlite3Strlen30(zMainFile);
zMaster = sqlite3MPrintf(db, "%s-mjXXXXXX9XXz%c%c", zMainFile, 0, 0);
zMaster = sqlite3MPrintf(db, "%.4c%s%.16c", 0,zMainFile,0);
if( zMaster==0 ) return SQLITE_NOMEM_BKPT;
zMaster += 4;
do {
u32 iRandom;
if( retryCount ){
@@ -2768,7 +2785,7 @@ static int vdbeCommit(sqlite3 *db, Vdbe *p){
);
}
if( rc!=SQLITE_OK ){
sqlite3DbFree(db, zMaster);
sqlite3DbFree(db, zMaster-4);
return rc;
}
@@ -2791,7 +2808,7 @@ static int vdbeCommit(sqlite3 *db, Vdbe *p){
if( rc!=SQLITE_OK ){
sqlite3OsCloseFree(pMaster);
sqlite3OsDelete(pVfs, zMaster, 0);
sqlite3DbFree(db, zMaster);
sqlite3DbFree(db, zMaster-4);
return rc;
}
}
@@ -2805,7 +2822,7 @@ static int vdbeCommit(sqlite3 *db, Vdbe *p){
){
sqlite3OsCloseFree(pMaster);
sqlite3OsDelete(pVfs, zMaster, 0);
sqlite3DbFree(db, zMaster);
sqlite3DbFree(db, zMaster-4);
return rc;
}
@@ -2828,7 +2845,7 @@ static int vdbeCommit(sqlite3 *db, Vdbe *p){
sqlite3OsCloseFree(pMaster);
assert( rc!=SQLITE_BUSY );
if( rc!=SQLITE_OK ){
sqlite3DbFree(db, zMaster);
sqlite3DbFree(db, zMaster-4);
return rc;
}
@@ -2837,7 +2854,7 @@ static int vdbeCommit(sqlite3 *db, Vdbe *p){
** transaction files are deleted.
*/
rc = sqlite3OsDelete(pVfs, zMaster, 1);
sqlite3DbFree(db, zMaster);
sqlite3DbFree(db, zMaster-4);
zMaster = 0;
if( rc ){
return rc;
+424
View File
@@ -0,0 +1,424 @@
/*
** 2020-03-23
**
** The author disclaims copyright to this source code. In place of
** a legal notice, here is a blessing:
**
** May you do good and not evil.
** May you find forgiveness for yourself and forgive others.
** May you share freely, never taking more than you give.
**
*************************************************************************
**
** This file implements virtual-tables for examining the bytecode content
** of a prepared statement.
*/
#include "sqliteInt.h"
#if defined(SQLITE_ENABLE_BYTECODE_VTAB) && !defined(SQLITE_OMIT_VIRTUALTABLE)
#include "vdbeInt.h"
/* An instance of the bytecode() table-valued function.
*/
typedef struct bytecodevtab bytecodevtab;
struct bytecodevtab {
sqlite3_vtab base; /* Base class - must be first */
sqlite3 *db; /* Database connection */
int bTablesUsed; /* 2 for tables_used(). 0 for bytecode(). */
};
/* A cursor for scanning through the bytecode
*/
typedef struct bytecodevtab_cursor bytecodevtab_cursor;
struct bytecodevtab_cursor {
sqlite3_vtab_cursor base; /* Base class - must be first */
sqlite3_stmt *pStmt; /* The statement whose bytecode is displayed */
int iRowid; /* The rowid of the output table */
int iAddr; /* Address */
int needFinalize; /* Cursors owns pStmt and must finalize it */
int showSubprograms; /* Provide a listing of subprograms */
Op *aOp; /* Operand array */
char *zP4; /* Rendered P4 value */
const char *zType; /* tables_used.type */
const char *zSchema; /* tables_used.schema */
const char *zName; /* tables_used.name */
Mem sub; /* Subprograms */
};
/*
** Create a new bytecode() table-valued function.
*/
static int bytecodevtabConnect(
sqlite3 *db,
void *pAux,
int argc, const char *const*argv,
sqlite3_vtab **ppVtab,
char **pzErr
){
bytecodevtab *pNew;
int rc;
int isTabUsed = pAux!=0;
const char *azSchema[2] = {
/* bytecode() schema */
"CREATE TABLE x("
"addr INT,"
"opcode TEXT,"
"p1 INT,"
"p2 INT,"
"p3 INT,"
"p4 TEXT,"
"p5 INT,"
"comment TEXT,"
"subprog TEXT,"
"stmt HIDDEN"
");",
/* Tables_used() schema */
"CREATE TABLE x("
"type TEXT,"
"schema TEXT,"
"name TEXT,"
"wr INT,"
"subprog TEXT,"
"stmt HIDDEN"
");"
};
rc = sqlite3_declare_vtab(db, azSchema[isTabUsed]);
if( rc==SQLITE_OK ){
pNew = sqlite3_malloc( sizeof(*pNew) );
*ppVtab = (sqlite3_vtab*)pNew;
if( pNew==0 ) return SQLITE_NOMEM;
memset(pNew, 0, sizeof(*pNew));
pNew->db = db;
pNew->bTablesUsed = isTabUsed*2;
}
return rc;
}
/*
** This method is the destructor for bytecodevtab objects.
*/
static int bytecodevtabDisconnect(sqlite3_vtab *pVtab){
bytecodevtab *p = (bytecodevtab*)pVtab;
sqlite3_free(p);
return SQLITE_OK;
}
/*
** Constructor for a new bytecodevtab_cursor object.
*/
static int bytecodevtabOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
bytecodevtab *pVTab = (bytecodevtab*)p;
bytecodevtab_cursor *pCur;
pCur = sqlite3_malloc( sizeof(*pCur) );
if( pCur==0 ) return SQLITE_NOMEM;
memset(pCur, 0, sizeof(*pCur));
sqlite3VdbeMemInit(&pCur->sub, pVTab->db, 1);
*ppCursor = &pCur->base;
return SQLITE_OK;
}
/*
** Clear all internal content from a bytecodevtab cursor.
*/
static void bytecodevtabCursorClear(bytecodevtab_cursor *pCur){
sqlite3_free(pCur->zP4);
pCur->zP4 = 0;
sqlite3VdbeMemRelease(&pCur->sub);
sqlite3VdbeMemSetNull(&pCur->sub);
if( pCur->needFinalize ){
sqlite3_finalize(pCur->pStmt);
}
pCur->pStmt = 0;
pCur->needFinalize = 0;
pCur->zType = 0;
pCur->zSchema = 0;
pCur->zName = 0;
}
/*
** Destructor for a bytecodevtab_cursor.
*/
static int bytecodevtabClose(sqlite3_vtab_cursor *cur){
bytecodevtab_cursor *pCur = (bytecodevtab_cursor*)cur;
bytecodevtabCursorClear(pCur);
sqlite3_free(pCur);
return SQLITE_OK;
}
/*
** Advance a bytecodevtab_cursor to its next row of output.
*/
static int bytecodevtabNext(sqlite3_vtab_cursor *cur){
bytecodevtab_cursor *pCur = (bytecodevtab_cursor*)cur;
bytecodevtab *pTab = (bytecodevtab*)cur->pVtab;
int rc;
if( pCur->zP4 ){
sqlite3_free(pCur->zP4);
pCur->zP4 = 0;
}
if( pCur->zName ){
pCur->zName = 0;
pCur->zType = 0;
pCur->zSchema = 0;
}
rc = sqlite3VdbeNextOpcode(
(Vdbe*)pCur->pStmt,
pCur->showSubprograms ? &pCur->sub : 0,
pTab->bTablesUsed,
&pCur->iRowid,
&pCur->iAddr,
&pCur->aOp);
if( rc!=SQLITE_OK ){
sqlite3VdbeMemSetNull(&pCur->sub);
pCur->aOp = 0;
}
return SQLITE_OK;
}
/*
** Return TRUE if the cursor has been moved off of the last
** row of output.
*/
static int bytecodevtabEof(sqlite3_vtab_cursor *cur){
bytecodevtab_cursor *pCur = (bytecodevtab_cursor*)cur;
return pCur->aOp==0;
}
/*
** Return values of columns for the row at which the bytecodevtab_cursor
** is currently pointing.
*/
static int bytecodevtabColumn(
sqlite3_vtab_cursor *cur, /* The cursor */
sqlite3_context *ctx, /* First argument to sqlite3_result_...() */
int i /* Which column to return */
){
bytecodevtab_cursor *pCur = (bytecodevtab_cursor*)cur;
bytecodevtab *pVTab = (bytecodevtab*)cur->pVtab;
Op *pOp = pCur->aOp + pCur->iAddr;
if( pVTab->bTablesUsed ){
if( i==4 ){
i = 8;
}else{
if( i<=2 && pCur->zType==0 ){
Schema *pSchema;
HashElem *k;
int iDb = pOp->p3;
int iRoot = pOp->p2;
sqlite3 *db = pVTab->db;
pSchema = db->aDb[iDb].pSchema;
pCur->zSchema = db->aDb[iDb].zDbSName;
for(k=sqliteHashFirst(&pSchema->tblHash); k; k=sqliteHashNext(k)){
Table *pTab = (Table*)sqliteHashData(k);
if( !IsVirtual(pTab) && pTab->tnum==iRoot ){
pCur->zName = pTab->zName;
pCur->zType = "table";
break;
}
}
if( pCur->zName==0 ){
for(k=sqliteHashFirst(&pSchema->idxHash); k; k=sqliteHashNext(k)){
Index *pIdx = (Index*)sqliteHashData(k);
if( pIdx->tnum==iRoot ){
pCur->zName = pIdx->zName;
pCur->zType = "index";
}
}
}
}
i += 10;
}
}
switch( i ){
case 0: /* addr */
sqlite3_result_int(ctx, pCur->iAddr);
break;
case 1: /* opcode */
sqlite3_result_text(ctx, (char*)sqlite3OpcodeName(pOp->opcode),
-1, SQLITE_STATIC);
break;
case 2: /* p1 */
sqlite3_result_int(ctx, pOp->p1);
break;
case 3: /* p2 */
sqlite3_result_int(ctx, pOp->p2);
break;
case 4: /* p3 */
sqlite3_result_int(ctx, pOp->p3);
break;
case 5: /* p4 */
case 7: /* comment */
if( pCur->zP4==0 ){
pCur->zP4 = sqlite3VdbeDisplayP4(pVTab->db, pOp);
}
if( i==5 ){
sqlite3_result_text(ctx, pCur->zP4, -1, SQLITE_STATIC);
}else{
#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
char *zCom = sqlite3VdbeDisplayComment(pVTab->db, pOp, pCur->zP4);
sqlite3_result_text(ctx, zCom, -1, sqlite3_free);
#endif
}
break;
case 6: /* p5 */
sqlite3_result_int(ctx, pOp->p5);
break;
case 8: { /* subprog */
Op *aOp = pCur->aOp;
assert( aOp[0].opcode==OP_Init );
assert( aOp[0].p4.z==0 || strncmp(aOp[0].p4.z,"-" "- ",3)==0 );
if( pCur->iRowid==pCur->iAddr+1 ){
break; /* Result is NULL for the main program */
}else if( aOp[0].p4.z!=0 ){
sqlite3_result_text(ctx, aOp[0].p4.z+3, -1, SQLITE_STATIC);
}else{
sqlite3_result_text(ctx, "(FK)", 4, SQLITE_STATIC);
}
break;
}
case 10: /* tables_used.type */
sqlite3_result_text(ctx, pCur->zType, -1, SQLITE_STATIC);
break;
case 11: /* tables_used.schema */
sqlite3_result_text(ctx, pCur->zSchema, -1, SQLITE_STATIC);
break;
case 12: /* tables_used.name */
sqlite3_result_text(ctx, pCur->zName, -1, SQLITE_STATIC);
break;
case 13: /* tables_used.wr */
sqlite3_result_int(ctx, pOp->opcode==OP_OpenWrite);
break;
}
return SQLITE_OK;
}
/*
** Return the rowid for the current row. In this implementation, the
** rowid is the same as the output value.
*/
static int bytecodevtabRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
bytecodevtab_cursor *pCur = (bytecodevtab_cursor*)cur;
*pRowid = pCur->iRowid;
return SQLITE_OK;
}
/*
** Initialize a cursor.
**
** idxNum==0 means show all subprograms
** idxNum==1 means show only the main bytecode and omit subprograms.
*/
static int bytecodevtabFilter(
sqlite3_vtab_cursor *pVtabCursor,
int idxNum, const char *idxStr,
int argc, sqlite3_value **argv
){
bytecodevtab_cursor *pCur = (bytecodevtab_cursor *)pVtabCursor;
bytecodevtab *pVTab = (bytecodevtab *)pVtabCursor->pVtab;
int rc = SQLITE_OK;
bytecodevtabCursorClear(pCur);
pCur->iRowid = 0;
pCur->iAddr = 0;
pCur->showSubprograms = idxNum==0;
assert( argc==1 );
if( sqlite3_value_type(argv[0])==SQLITE_TEXT ){
const char *zSql = (const char*)sqlite3_value_text(argv[0]);
if( zSql==0 ){
rc = SQLITE_NOMEM;
}else{
rc = sqlite3_prepare_v2(pVTab->db, zSql, -1, &pCur->pStmt, 0);
pCur->needFinalize = 1;
}
}else{
pCur->pStmt = (sqlite3_stmt*)sqlite3_value_pointer(argv[0],"stmt-pointer");
}
if( pCur->pStmt==0 ){
pVTab->base.zErrMsg = sqlite3_mprintf(
"argument to %s() is not a valid SQL statement",
pVTab->bTablesUsed ? "tables_used" : "bytecode"
);
rc = SQLITE_ERROR;
}else{
bytecodevtabNext(pVtabCursor);
}
return rc;
}
/*
** We must have a single stmt=? constraint that will be passed through
** into the xFilter method. If there is no valid stmt=? constraint,
** then return an SQLITE_CONSTRAINT error.
*/
static int bytecodevtabBestIndex(
sqlite3_vtab *tab,
sqlite3_index_info *pIdxInfo
){
int i;
int rc = SQLITE_CONSTRAINT;
struct sqlite3_index_constraint *p;
bytecodevtab *pVTab = (bytecodevtab*)tab;
int iBaseCol = pVTab->bTablesUsed ? 4 : 8;
pIdxInfo->estimatedCost = (double)100;
pIdxInfo->estimatedRows = 100;
pIdxInfo->idxNum = 0;
for(i=0, p=pIdxInfo->aConstraint; i<pIdxInfo->nConstraint; i++, p++){
if( p->usable==0 ) continue;
if( p->op==SQLITE_INDEX_CONSTRAINT_EQ && p->iColumn==iBaseCol+1 ){
rc = SQLITE_OK;
pIdxInfo->aConstraintUsage[i].omit = 1;
pIdxInfo->aConstraintUsage[i].argvIndex = 1;
}
if( p->op==SQLITE_INDEX_CONSTRAINT_ISNULL && p->iColumn==iBaseCol ){
pIdxInfo->aConstraintUsage[i].omit = 1;
pIdxInfo->idxNum = 1;
}
}
return rc;
}
/*
** This following structure defines all the methods for the
** virtual table.
*/
static sqlite3_module bytecodevtabModule = {
/* iVersion */ 0,
/* xCreate */ 0,
/* xConnect */ bytecodevtabConnect,
/* xBestIndex */ bytecodevtabBestIndex,
/* xDisconnect */ bytecodevtabDisconnect,
/* xDestroy */ 0,
/* xOpen */ bytecodevtabOpen,
/* xClose */ bytecodevtabClose,
/* xFilter */ bytecodevtabFilter,
/* xNext */ bytecodevtabNext,
/* xEof */ bytecodevtabEof,
/* xColumn */ bytecodevtabColumn,
/* xRowid */ bytecodevtabRowid,
/* xUpdate */ 0,
/* xBegin */ 0,
/* xSync */ 0,
/* xCommit */ 0,
/* xRollback */ 0,
/* xFindMethod */ 0,
/* xRename */ 0,
/* xSavepoint */ 0,
/* xRelease */ 0,
/* xRollbackTo */ 0,
/* xShadowName */ 0
};
int sqlite3VdbeBytecodeVtabInit(sqlite3 *db){
int rc;
rc = sqlite3_create_module(db, "bytecode", &bytecodevtabModule, 0);
if( rc==SQLITE_OK ){
rc = sqlite3_create_module(db, "tables_used", &bytecodevtabModule, &db);
}
return rc;
}
#elif defined(SQLITE_ENABLE_BYTECODE_VTAB)
int sqlite3VdbeBytecodeVtabInit(sqlite3 *db){ return SQLITE_OK; }
#endif /* SQLITE_ENABLE_BYTECODE_VTAB */
+1 -1
View File
@@ -1177,7 +1177,7 @@ void sqlite3VtabMakeWritable(Parse *pParse, Table *pTab){
if( pTab==pToplevel->apVtabLock[i] ) return;
}
n = (pToplevel->nVtabLock+1)*sizeof(pToplevel->apVtabLock[0]);
apVtabLock = sqlite3_realloc64(pToplevel->apVtabLock, n);
apVtabLock = sqlite3Realloc(pToplevel->apVtabLock, n);
if( apVtabLock ){
pToplevel->apVtabLock = apVtabLock;
pToplevel->apVtabLock[pToplevel->nVtabLock++] = pTab;
+274 -139
View File
@@ -258,18 +258,6 @@ int sqlite3WalTrace = 0;
# define WALTRACE(X)
#endif
/*
** WAL mode depends on atomic aligned 32-bit loads and stores in a few
** places. The following macros try to make this explicit.
*/
#if GCC_VESRION>=5004000
# define AtomicLoad(PTR) __atomic_load_n((PTR),__ATOMIC_RELAXED)
# define AtomicStore(PTR,VAL) __atomic_store_n((PTR),(VAL),__ATOMIC_RELAXED)
#else
# define AtomicLoad(PTR) (*(PTR))
# define AtomicStore(PTR,VAL) (*(PTR) = (VAL))
#endif
/*
** The maximum (and only) versions of the wal and wal-index formats
** that may be interpreted by this version of SQLite.
@@ -479,6 +467,9 @@ struct Wal {
#ifdef SQLITE_ENABLE_SNAPSHOT
WalIndexHdr *pSnapshot; /* Start transaction here if not NULL */
#endif
#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
sqlite3 *db;
#endif
};
/*
@@ -577,7 +568,7 @@ static SQLITE_NOINLINE int walIndexPageRealloc(
if( pWal->nWiData<=iPage ){
sqlite3_int64 nByte = sizeof(u32*)*(iPage+1);
volatile u32 **apNew;
apNew = (volatile u32 **)sqlite3_realloc64((void *)pWal->apWiData, nByte);
apNew = (volatile u32 **)sqlite3Realloc((void *)pWal->apWiData, nByte);
if( !apNew ){
*ppPage = 0;
return SQLITE_NOMEM_BKPT;
@@ -698,18 +689,35 @@ static void walChecksumBytes(
aOut[1] = s2;
}
/*
** If there is the possibility of concurrent access to the SHM file
** from multiple threads and/or processes, then do a memory barrier.
*/
static void walShmBarrier(Wal *pWal){
if( pWal->exclusiveMode!=WAL_HEAPMEMORY_MODE ){
sqlite3OsShmBarrier(pWal->pDbFd);
}
}
/*
** Add the SQLITE_NO_TSAN as part of the return-type of a function
** definition as a hint that the function contains constructs that
** might give false-positive TSAN warnings.
**
** See tag-20200519-1.
*/
#if defined(__clang__) && !defined(SQLITE_NO_TSAN)
# define SQLITE_NO_TSAN __attribute__((no_sanitize_thread))
#else
# define SQLITE_NO_TSAN
#endif
/*
** Write the header information in pWal->hdr into the wal-index.
**
** The checksum on pWal->hdr is updated before it is written.
*/
static void walIndexWriteHdr(Wal *pWal){
static SQLITE_NO_TSAN void walIndexWriteHdr(Wal *pWal){
volatile WalIndexHdr *aHdr = walIndexHdr(pWal);
const int nCksum = offsetof(WalIndexHdr, aCksum);
@@ -717,6 +725,7 @@ static void walIndexWriteHdr(Wal *pWal){
pWal->hdr.isInit = 1;
pWal->hdr.iVersion = WALINDEX_MAX_VERSION;
walChecksumBytes(1, (u8*)&pWal->hdr, nCksum, 0, pWal->hdr.aCksum);
/* Possible TSAN false-positive. See tag-20200519-1 */
memcpy((void*)&aHdr[1], (const void*)&pWal->hdr, sizeof(WalIndexHdr));
walShmBarrier(pWal);
memcpy((void*)&aHdr[0], (const void*)&pWal->hdr, sizeof(WalIndexHdr));
@@ -852,7 +861,7 @@ static int walLockShared(Wal *pWal, int lockIdx){
SQLITE_SHM_LOCK | SQLITE_SHM_SHARED);
WALTRACE(("WAL%p: acquire SHARED-%s %s\n", pWal,
walLockName(lockIdx), rc ? "failed" : "ok"));
VVA_ONLY( pWal->lockError = (u8)(rc!=SQLITE_OK && rc!=SQLITE_BUSY); )
VVA_ONLY( pWal->lockError = (u8)(rc!=SQLITE_OK && (rc&0xFF)!=SQLITE_BUSY); )
return rc;
}
static void walUnlockShared(Wal *pWal, int lockIdx){
@@ -868,7 +877,7 @@ static int walLockExclusive(Wal *pWal, int lockIdx, int n){
SQLITE_SHM_LOCK | SQLITE_SHM_EXCLUSIVE);
WALTRACE(("WAL%p: acquire EXCLUSIVE-%s cnt=%d %s\n", pWal,
walLockName(lockIdx), n, rc ? "failed" : "ok"));
VVA_ONLY( pWal->lockError = (u8)(rc!=SQLITE_OK && rc!=SQLITE_BUSY); )
VVA_ONLY( pWal->lockError = (u8)(rc!=SQLITE_OK && (rc&0xFF)!=SQLITE_BUSY); )
return rc;
}
static void walUnlockExclusive(Wal *pWal, int lockIdx, int n){
@@ -1688,6 +1697,89 @@ static int walIteratorInit(Wal *pWal, u32 nBackfill, WalIterator **pp){
return rc;
}
#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
/*
** Attempt to enable blocking locks. Blocking locks are enabled only if (a)
** they are supported by the VFS, and (b) the database handle is configured
** with a busy-timeout. Return 1 if blocking locks are successfully enabled,
** or 0 otherwise.
*/
static int walEnableBlocking(Wal *pWal){
int res = 0;
if( pWal->db ){
int tmout = pWal->db->busyTimeout;
if( tmout ){
int rc;
rc = sqlite3OsFileControl(
pWal->pDbFd, SQLITE_FCNTL_LOCK_TIMEOUT, (void*)&tmout
);
res = (rc==SQLITE_OK);
}
}
return res;
}
/*
** Disable blocking locks.
*/
static void walDisableBlocking(Wal *pWal){
int tmout = 0;
sqlite3OsFileControl(pWal->pDbFd, SQLITE_FCNTL_LOCK_TIMEOUT, (void*)&tmout);
}
/*
** If parameter bLock is true, attempt to enable blocking locks, take
** the WRITER lock, and then disable blocking locks. If blocking locks
** cannot be enabled, no attempt to obtain the WRITER lock is made. Return
** an SQLite error code if an error occurs, or SQLITE_OK otherwise. It is not
** an error if blocking locks can not be enabled.
**
** If the bLock parameter is false and the WRITER lock is held, release it.
*/
int sqlite3WalWriteLock(Wal *pWal, int bLock){
int rc = SQLITE_OK;
assert( pWal->readLock<0 || bLock==0 );
if( bLock ){
assert( pWal->db );
if( walEnableBlocking(pWal) ){
rc = walLockExclusive(pWal, WAL_WRITE_LOCK, 1);
if( rc==SQLITE_OK ){
pWal->writeLock = 1;
}
walDisableBlocking(pWal);
}
}else if( pWal->writeLock ){
walUnlockExclusive(pWal, WAL_WRITE_LOCK, 1);
pWal->writeLock = 0;
}
return rc;
}
/*
** Set the database handle used to determine if blocking locks are required.
*/
void sqlite3WalDb(Wal *pWal, sqlite3 *db){
pWal->db = db;
}
/*
** Take an exclusive WRITE lock. Blocking if so configured.
*/
static int walLockWriter(Wal *pWal){
int rc;
walEnableBlocking(pWal);
rc = walLockExclusive(pWal, WAL_WRITE_LOCK, 1);
walDisableBlocking(pWal);
return rc;
}
#else
# define walEnableBlocking(x) 0
# define walDisableBlocking(x)
# define walLockWriter(pWal) walLockExclusive((pWal), WAL_WRITE_LOCK, 1)
# define sqlite3WalDb(pWal, db)
#endif /* ifdef SQLITE_ENABLE_SETLK_TIMEOUT */
/*
** Attempt to obtain the exclusive WAL lock defined by parameters lockIdx and
** n. If the attempt fails and parameter xBusy is not NULL, then it is a
@@ -1705,6 +1797,12 @@ static int walBusyLock(
do {
rc = walLockExclusive(pWal, lockIdx, n);
}while( xBusy && rc==SQLITE_BUSY && xBusy(pBusyArg) );
#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
if( rc==SQLITE_BUSY_TIMEOUT ){
walDisableBlocking(pWal);
rc = SQLITE_BUSY;
}
#endif
return rc;
}
@@ -1742,7 +1840,7 @@ static void walRestartHdr(Wal *pWal, u32 salt1){
sqlite3Put4byte((u8*)&aSalt[0], 1 + sqlite3Get4byte((u8*)&aSalt[0]));
memcpy(&pWal->hdr.aSalt[1], &salt1, 4);
walIndexWriteHdr(pWal);
pInfo->nBackfill = 0;
AtomicStore(&pInfo->nBackfill, 0);
pInfo->nBackfillAttempted = 0;
pInfo->aReadMark[1] = 0;
for(i=2; i<WAL_NREADER; i++) pInfo->aReadMark[i] = READMARK_NOT_USED;
@@ -1817,32 +1915,13 @@ static int walCheckpoint(
mxSafeFrame = pWal->hdr.mxFrame;
mxPage = pWal->hdr.nPage;
for(i=1; i<WAL_NREADER; i++){
/* Thread-sanitizer reports that the following is an unsafe read,
** as some other thread may be in the process of updating the value
** of the aReadMark[] slot. The assumption here is that if that is
** happening, the other client may only be increasing the value,
** not decreasing it. So assuming either that either the "old" or
** "new" version of the value is read, and not some arbitrary value
** that would never be written by a real client, things are still
** safe.
**
** Astute readers have pointed out that the assumption stated in the
** last sentence of the previous paragraph is not guaranteed to be
** true for all conforming systems. However, the assumption is true
** for all compilers and architectures in common use today (circa
** 2019-11-27) and the alternatives are both slow and complex, and
** so we will continue to go with the current design for now. If this
** bothers you, or if you really are running on a system where aligned
** 32-bit reads and writes are not atomic, then you can simply avoid
** the use of WAL mode, or only use WAL mode together with
** PRAGMA locking_mode=EXCLUSIVE and all will be well.
*/
u32 y = pInfo->aReadMark[i];
u32 y = AtomicLoad(pInfo->aReadMark+i);
if( mxSafeFrame>y ){
assert( y<=pWal->hdr.mxFrame );
rc = walBusyLock(pWal, xBusy, pBusyArg, WAL_READ_LOCK(i), 1);
if( rc==SQLITE_OK ){
pInfo->aReadMark[i] = (i==1 ? mxSafeFrame : READMARK_NOT_USED);
u32 iMark = (i==1 ? mxSafeFrame : READMARK_NOT_USED);
AtomicStore(pInfo->aReadMark+i, iMark);
walUnlockExclusive(pWal, WAL_READ_LOCK(i), 1);
}else if( rc==SQLITE_BUSY ){
mxSafeFrame = y;
@@ -1860,7 +1939,7 @@ static int walCheckpoint(
}
if( pIter
&& (rc = walBusyLock(pWal, xBusy, pBusyArg, WAL_READ_LOCK(0),1))==SQLITE_OK
&& (rc = walBusyLock(pWal,xBusy,pBusyArg,WAL_READ_LOCK(0),1))==SQLITE_OK
){
u32 nBackfill = pInfo->nBackfill;
@@ -1875,6 +1954,7 @@ static int walCheckpoint(
if( rc==SQLITE_OK ){
i64 nReq = ((i64)mxPage * szPage);
i64 nSize; /* Current size of database file */
sqlite3OsFileControl(pWal->pDbFd, SQLITE_FCNTL_CKPT_START, 0);
rc = sqlite3OsFileSize(pWal->pDbFd, &nSize);
if( rc==SQLITE_OK && nSize<nReq ){
sqlite3OsFileControlHint(pWal->pDbFd, SQLITE_FCNTL_SIZE_HINT, &nReq);
@@ -1886,7 +1966,7 @@ static int walCheckpoint(
while( rc==SQLITE_OK && 0==walIteratorNext(pIter, &iDbpage, &iFrame) ){
i64 iOffset;
assert( walFramePgno(pWal, iFrame)==iDbpage );
if( db->u1.isInterrupted ){
if( AtomicLoad(&db->u1.isInterrupted) ){
rc = db->mallocFailed ? SQLITE_NOMEM_BKPT : SQLITE_INTERRUPT;
break;
}
@@ -1902,6 +1982,7 @@ static int walCheckpoint(
rc = sqlite3OsWrite(pWal->pDbFd, zBuf, szPage, iOffset);
if( rc!=SQLITE_OK ) break;
}
sqlite3OsFileControl(pWal->pDbFd, SQLITE_FCNTL_CKPT_DONE, 0);
/* If work was actually accomplished... */
if( rc==SQLITE_OK ){
@@ -1914,11 +1995,7 @@ static int walCheckpoint(
}
}
if( rc==SQLITE_OK ){
rc = sqlite3OsFileControl(pWal->pDbFd, SQLITE_FCNTL_CKPT_DONE, 0);
if( rc==SQLITE_NOTFOUND ) rc = SQLITE_OK;
}
if( rc==SQLITE_OK ){
pInfo->nBackfill = mxSafeFrame;
AtomicStore(&pInfo->nBackfill, mxSafeFrame);
}
}
@@ -2077,7 +2154,7 @@ int sqlite3WalClose(
** If the checksum cannot be verified return non-zero. If the header
** is read successfully and the checksum verified, return zero.
*/
static int walIndexTryHdr(Wal *pWal, int *pChanged){
static SQLITE_NO_TSAN int walIndexTryHdr(Wal *pWal, int *pChanged){
u32 aCksum[2]; /* Checksum on the header content */
WalIndexHdr h1, h2; /* Two copies of the header content */
WalIndexHdr volatile *aHdr; /* Header in shared memory */
@@ -2090,13 +2167,19 @@ static int walIndexTryHdr(Wal *pWal, int *pChanged){
** meaning it is possible that an inconsistent snapshot is read
** from the file. If this happens, return non-zero.
**
** tag-20200519-1:
** There are two copies of the header at the beginning of the wal-index.
** When reading, read [0] first then [1]. Writes are in the reverse order.
** Memory barriers are used to prevent the compiler or the hardware from
** reordering the reads and writes.
** reordering the reads and writes. TSAN and similar tools can sometimes
** give false-positive warnings about these accesses because the tools do not
** account for the double-read and the memory barrier. The use of mutexes
** here would be problematic as the memory being accessed is potentially
** shared among multiple processes and not all mutex implementions work
** reliably in that environment.
*/
aHdr = walIndexHdr(pWal);
memcpy(&h1, (void *)&aHdr[0], sizeof(h1));
memcpy(&h1, (void *)&aHdr[0], sizeof(h1)); /* Possible TSAN false-positive */
walShmBarrier(pWal);
memcpy(&h2, (void *)&aHdr[1], sizeof(h2));
@@ -2186,28 +2269,32 @@ static int walIndexReadHdr(Wal *pWal, int *pChanged){
/* If the first attempt failed, it might have been due to a race
** with a writer. So get a WRITE lock and try again.
*/
assert( badHdr==0 || pWal->writeLock==0 );
if( badHdr ){
if( pWal->bShmUnreliable==0 && (pWal->readOnly & WAL_SHM_RDONLY) ){
if( SQLITE_OK==(rc = walLockShared(pWal, WAL_WRITE_LOCK)) ){
walUnlockShared(pWal, WAL_WRITE_LOCK);
rc = SQLITE_READONLY_RECOVERY;
}
}else if( SQLITE_OK==(rc = walLockExclusive(pWal, WAL_WRITE_LOCK, 1)) ){
pWal->writeLock = 1;
if( SQLITE_OK==(rc = walIndexPage(pWal, 0, &page0)) ){
badHdr = walIndexTryHdr(pWal, pChanged);
if( badHdr ){
/* If the wal-index header is still malformed even while holding
** a WRITE lock, it can only mean that the header is corrupted and
** needs to be reconstructed. So run recovery to do exactly that.
*/
rc = walIndexRecover(pWal);
*pChanged = 1;
}else{
int bWriteLock = pWal->writeLock;
if( bWriteLock || SQLITE_OK==(rc = walLockWriter(pWal)) ){
pWal->writeLock = 1;
if( SQLITE_OK==(rc = walIndexPage(pWal, 0, &page0)) ){
badHdr = walIndexTryHdr(pWal, pChanged);
if( badHdr ){
/* If the wal-index header is still malformed even while holding
** a WRITE lock, it can only mean that the header is corrupted and
** needs to be reconstructed. So run recovery to do exactly that.
*/
rc = walIndexRecover(pWal);
*pChanged = 1;
}
}
if( bWriteLock==0 ){
pWal->writeLock = 0;
walUnlockExclusive(pWal, WAL_WRITE_LOCK, 1);
}
}
pWal->writeLock = 0;
walUnlockExclusive(pWal, WAL_WRITE_LOCK, 1);
}
}
@@ -2537,7 +2624,7 @@ static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int cnt){
assert( pWal->nWiData>0 );
assert( pWal->apWiData[0]!=0 );
pInfo = walCkptInfo(pWal);
if( !useWal && pInfo->nBackfill==pWal->hdr.mxFrame
if( !useWal && AtomicLoad(&pInfo->nBackfill)==pWal->hdr.mxFrame
#ifdef SQLITE_ENABLE_SNAPSHOT
&& (pWal->pSnapshot==0 || pWal->hdr.mxFrame==0)
#endif
@@ -2599,7 +2686,8 @@ static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int cnt){
for(i=1; i<WAL_NREADER; i++){
rc = walLockExclusive(pWal, WAL_READ_LOCK(i), 1);
if( rc==SQLITE_OK ){
mxReadMark = AtomicStore(pInfo->aReadMark+i,mxFrame);
AtomicStore(pInfo->aReadMark+i,mxFrame);
mxReadMark = mxFrame;
mxI = i;
walUnlockExclusive(pWal, WAL_READ_LOCK(i), 1);
break;
@@ -2703,7 +2791,7 @@ int sqlite3WalSnapshotRecover(Wal *pWal){
rc = SQLITE_NOMEM;
}else{
u32 i = pInfo->nBackfillAttempted;
for(i=pInfo->nBackfillAttempted; i>pInfo->nBackfill; i--){
for(i=pInfo->nBackfillAttempted; i>AtomicLoad(&pInfo->nBackfill); i--){
WalHashLoc sLoc; /* Hash table location */
u32 pgno; /* Page number in db file */
i64 iDbOff; /* Offset of db file entry */
@@ -2758,12 +2846,35 @@ int sqlite3WalSnapshotRecover(Wal *pWal){
int sqlite3WalBeginReadTransaction(Wal *pWal, int *pChanged){
int rc; /* Return code */
int cnt = 0; /* Number of TryBeginRead attempts */
#ifdef SQLITE_ENABLE_SNAPSHOT
int bChanged = 0;
WalIndexHdr *pSnapshot = pWal->pSnapshot;
if( pSnapshot && memcmp(pSnapshot, &pWal->hdr, sizeof(WalIndexHdr))!=0 ){
bChanged = 1;
#endif
assert( pWal->ckptLock==0 );
#ifdef SQLITE_ENABLE_SNAPSHOT
if( pSnapshot ){
if( memcmp(pSnapshot, &pWal->hdr, sizeof(WalIndexHdr))!=0 ){
bChanged = 1;
}
/* It is possible that there is a checkpointer thread running
** concurrent with this code. If this is the case, it may be that the
** checkpointer has already determined that it will checkpoint
** snapshot X, where X is later in the wal file than pSnapshot, but
** has not yet set the pInfo->nBackfillAttempted variable to indicate
** its intent. To avoid the race condition this leads to, ensure that
** there is no checkpointer process by taking a shared CKPT lock
** before checking pInfo->nBackfillAttempted. */
(void)walEnableBlocking(pWal);
rc = walLockShared(pWal, WAL_CKPT_LOCK);
walDisableBlocking(pWal);
if( rc!=SQLITE_OK ){
return rc;
}
pWal->ckptLock = 1;
}
#endif
@@ -2796,48 +2907,42 @@ int sqlite3WalBeginReadTransaction(Wal *pWal, int *pChanged){
assert( pWal->readLock>0 || pWal->hdr.mxFrame==0 );
assert( pInfo->aReadMark[pWal->readLock]<=pSnapshot->mxFrame );
/* It is possible that there is a checkpointer thread running
** concurrent with this code. If this is the case, it may be that the
** checkpointer has already determined that it will checkpoint
** snapshot X, where X is later in the wal file than pSnapshot, but
** has not yet set the pInfo->nBackfillAttempted variable to indicate
** its intent. To avoid the race condition this leads to, ensure that
** there is no checkpointer process by taking a shared CKPT lock
** before checking pInfo->nBackfillAttempted.
**
** TODO: Does the aReadMark[] lock prevent a checkpointer from doing
** this already?
*/
rc = walLockShared(pWal, WAL_CKPT_LOCK);
if( rc==SQLITE_OK ){
/* Check that the wal file has not been wrapped. Assuming that it has
** not, also check that no checkpointer has attempted to checkpoint any
** frames beyond pSnapshot->mxFrame. If either of these conditions are
** true, return SQLITE_ERROR_SNAPSHOT. Otherwise, overwrite pWal->hdr
** with *pSnapshot and set *pChanged as appropriate for opening the
** snapshot. */
if( !memcmp(pSnapshot->aSalt, pWal->hdr.aSalt, sizeof(pWal->hdr.aSalt))
&& pSnapshot->mxFrame>=pInfo->nBackfillAttempted
){
assert( pWal->readLock>0 );
memcpy(&pWal->hdr, pSnapshot, sizeof(WalIndexHdr));
*pChanged = bChanged;
}else{
rc = SQLITE_ERROR_SNAPSHOT;
}
/* Release the shared CKPT lock obtained above. */
walUnlockShared(pWal, WAL_CKPT_LOCK);
pWal->minFrame = 1;
/* Check that the wal file has not been wrapped. Assuming that it has
** not, also check that no checkpointer has attempted to checkpoint any
** frames beyond pSnapshot->mxFrame. If either of these conditions are
** true, return SQLITE_ERROR_SNAPSHOT. Otherwise, overwrite pWal->hdr
** with *pSnapshot and set *pChanged as appropriate for opening the
** snapshot. */
if( !memcmp(pSnapshot->aSalt, pWal->hdr.aSalt, sizeof(pWal->hdr.aSalt))
&& pSnapshot->mxFrame>=pInfo->nBackfillAttempted
){
assert( pWal->readLock>0 );
memcpy(&pWal->hdr, pSnapshot, sizeof(WalIndexHdr));
*pChanged = bChanged;
}else{
rc = SQLITE_ERROR_SNAPSHOT;
}
/* A client using a non-current snapshot may not ignore any frames
** from the start of the wal file. This is because, for a system
** where (minFrame < iSnapshot < maxFrame), a checkpointer may
** have omitted to checkpoint a frame earlier than minFrame in
** the file because there exists a frame after iSnapshot that
** is the same database page. */
pWal->minFrame = 1;
if( rc!=SQLITE_OK ){
sqlite3WalEndReadTransaction(pWal);
}
}
}
/* Release the shared CKPT lock obtained above. */
if( pWal->ckptLock ){
assert( pSnapshot );
walUnlockShared(pWal, WAL_CKPT_LOCK);
pWal->ckptLock = 0;
}
#endif
return rc;
}
@@ -2917,14 +3022,15 @@ int sqlite3WalFindFrame(
int iKey; /* Hash slot index */
int nCollide; /* Number of hash collisions remaining */
int rc; /* Error code */
u32 iH;
rc = walHashGet(pWal, iHash, &sLoc);
if( rc!=SQLITE_OK ){
return rc;
}
nCollide = HASHTABLE_NSLOT;
for(iKey=walHash(pgno); sLoc.aHash[iKey]; iKey=walNextHash(iKey)){
u32 iH = sLoc.aHash[iKey];
iKey = walHash(pgno);
while( (iH = AtomicLoad(&sLoc.aHash[iKey]))!=0 ){
u32 iFrame = iH + sLoc.iZero;
if( iFrame<=iLast && iFrame>=pWal->minFrame && sLoc.aPgno[iH]==pgno ){
assert( iFrame>iRead || CORRUPT_DB );
@@ -2933,6 +3039,7 @@ int sqlite3WalFindFrame(
if( (nCollide--)==0 ){
return SQLITE_CORRUPT_BKPT;
}
iKey = walNextHash(iKey);
}
if( iRead ) break;
}
@@ -3008,6 +3115,16 @@ Pgno sqlite3WalDbsize(Wal *pWal){
int sqlite3WalBeginWriteTransaction(Wal *pWal){
int rc;
#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
/* If the write-lock is already held, then it was obtained before the
** read-transaction was even opened, making this call a no-op.
** Return early. */
if( pWal->writeLock ){
assert( !memcmp(&pWal->hdr,(void *)walIndexHdr(pWal),sizeof(WalIndexHdr)) );
return SQLITE_OK;
}
#endif
/* Cannot start a write transaction without first holding a read
** transaction. */
assert( pWal->readLock>=0 );
@@ -3584,45 +3701,52 @@ int sqlite3WalCheckpoint(
if( pWal->readOnly ) return SQLITE_READONLY;
WALTRACE(("WAL%p: checkpoint begins\n", pWal));
/* IMPLEMENTATION-OF: R-62028-47212 All calls obtain an exclusive
** "checkpoint" lock on the database file. */
rc = walLockExclusive(pWal, WAL_CKPT_LOCK, 1);
if( rc ){
/* EVIDENCE-OF: R-10421-19736 If any other process is running a
** checkpoint operation at the same time, the lock cannot be obtained and
** SQLITE_BUSY is returned.
** EVIDENCE-OF: R-53820-33897 Even if there is a busy-handler configured,
** it will not be invoked in this case.
*/
testcase( rc==SQLITE_BUSY );
testcase( xBusy!=0 );
return rc;
}
pWal->ckptLock = 1;
/* Enable blocking locks, if possible. If blocking locks are successfully
** enabled, set xBusy2=0 so that the busy-handler is never invoked. */
sqlite3WalDb(pWal, db);
(void)walEnableBlocking(pWal);
/* IMPLEMENTATION-OF: R-59782-36818 The SQLITE_CHECKPOINT_FULL, RESTART and
** TRUNCATE modes also obtain the exclusive "writer" lock on the database
** file.
**
** EVIDENCE-OF: R-60642-04082 If the writer lock cannot be obtained
** immediately, and a busy-handler is configured, it is invoked and the
** writer lock retried until either the busy-handler returns 0 or the
** lock is successfully obtained.
/* IMPLEMENTATION-OF: R-62028-47212 All calls obtain an exclusive
** "checkpoint" lock on the database file.
** EVIDENCE-OF: R-10421-19736 If any other process is running a
** checkpoint operation at the same time, the lock cannot be obtained and
** SQLITE_BUSY is returned.
** EVIDENCE-OF: R-53820-33897 Even if there is a busy-handler configured,
** it will not be invoked in this case.
*/
if( eMode!=SQLITE_CHECKPOINT_PASSIVE ){
rc = walBusyLock(pWal, xBusy, pBusyArg, WAL_WRITE_LOCK, 1);
if( rc==SQLITE_OK ){
pWal->writeLock = 1;
}else if( rc==SQLITE_BUSY ){
eMode2 = SQLITE_CHECKPOINT_PASSIVE;
xBusy2 = 0;
rc = SQLITE_OK;
rc = walLockExclusive(pWal, WAL_CKPT_LOCK, 1);
testcase( rc==SQLITE_BUSY );
testcase( rc!=SQLITE_OK && xBusy2!=0 );
if( rc==SQLITE_OK ){
pWal->ckptLock = 1;
/* IMPLEMENTATION-OF: R-59782-36818 The SQLITE_CHECKPOINT_FULL, RESTART and
** TRUNCATE modes also obtain the exclusive "writer" lock on the database
** file.
**
** EVIDENCE-OF: R-60642-04082 If the writer lock cannot be obtained
** immediately, and a busy-handler is configured, it is invoked and the
** writer lock retried until either the busy-handler returns 0 or the
** lock is successfully obtained.
*/
if( eMode!=SQLITE_CHECKPOINT_PASSIVE ){
rc = walBusyLock(pWal, xBusy2, pBusyArg, WAL_WRITE_LOCK, 1);
if( rc==SQLITE_OK ){
pWal->writeLock = 1;
}else if( rc==SQLITE_BUSY ){
eMode2 = SQLITE_CHECKPOINT_PASSIVE;
xBusy2 = 0;
rc = SQLITE_OK;
}
}
}
/* Read the wal-index header. */
if( rc==SQLITE_OK ){
walDisableBlocking(pWal);
rc = walIndexReadHdr(pWal, &isChanged);
(void)walEnableBlocking(pWal);
if( isChanged && pWal->pDbFd->pMethods->iVersion>=3 ){
sqlite3OsUnfetch(pWal->pDbFd, 0, 0);
}
@@ -3654,11 +3778,19 @@ int sqlite3WalCheckpoint(
memset(&pWal->hdr, 0, sizeof(WalIndexHdr));
}
walDisableBlocking(pWal);
sqlite3WalDb(pWal, 0);
/* Release the locks. */
sqlite3WalEndWriteTransaction(pWal);
walUnlockExclusive(pWal, WAL_CKPT_LOCK, 1);
pWal->ckptLock = 0;
if( pWal->ckptLock ){
walUnlockExclusive(pWal, WAL_CKPT_LOCK, 1);
pWal->ckptLock = 0;
}
WALTRACE(("WAL%p: checkpoint %s\n", pWal, rc ? "failed" : "ok"));
#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
if( rc==SQLITE_BUSY_TIMEOUT ) rc = SQLITE_BUSY;
#endif
return (rc==SQLITE_OK && eMode!=eMode2 ? SQLITE_BUSY : rc);
}
@@ -3775,7 +3907,10 @@ int sqlite3WalSnapshotGet(Wal *pWal, sqlite3_snapshot **ppSnapshot){
/* Try to open on pSnapshot when the next read-transaction starts
*/
void sqlite3WalSnapshotOpen(Wal *pWal, sqlite3_snapshot *pSnapshot){
void sqlite3WalSnapshotOpen(
Wal *pWal,
sqlite3_snapshot *pSnapshot
){
pWal->pSnapshot = (WalIndexHdr*)pSnapshot;
}
+5
View File
@@ -146,5 +146,10 @@ int sqlite3WalFramesize(Wal *pWal);
/* Return the sqlite3_file object for the WAL file */
sqlite3_file *sqlite3WalFile(Wal *pWal);
#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
int sqlite3WalWriteLock(Wal *pWal, int bLock);
void sqlite3WalDb(Wal *pWal, sqlite3 *db);
#endif
#endif /* ifndef SQLITE_OMIT_WAL */
#endif /* SQLITE_WAL_H */
+47 -9
View File
@@ -156,15 +156,16 @@ int sqlite3WalkSelectFrom(Walker *pWalker, Select *p){
struct SrcList_item *pItem;
pSrc = p->pSrc;
assert( pSrc!=0 );
for(i=pSrc->nSrc, pItem=pSrc->a; i>0; i--, pItem++){
if( pItem->pSelect && sqlite3WalkSelect(pWalker, pItem->pSelect) ){
return WRC_Abort;
}
if( pItem->fg.isTabFunc
&& sqlite3WalkExprList(pWalker, pItem->u1.pFuncArg)
){
return WRC_Abort;
if( pSrc ){
for(i=pSrc->nSrc, pItem=pSrc->a; i>0; i--, pItem++){
if( pItem->pSelect && sqlite3WalkSelect(pWalker, pItem->pSelect) ){
return WRC_Abort;
}
if( pItem->fg.isTabFunc
&& sqlite3WalkExprList(pWalker, pItem->u1.pFuncArg)
){
return WRC_Abort;
}
}
}
return WRC_Continue;
@@ -206,3 +207,40 @@ int sqlite3WalkSelect(Walker *pWalker, Select *p){
}while( p!=0 );
return WRC_Continue;
}
/* Increase the walkerDepth when entering a subquery, and
** descrease when leaving the subquery.
*/
int sqlite3WalkerDepthIncrease(Walker *pWalker, Select *pSelect){
UNUSED_PARAMETER(pSelect);
pWalker->walkerDepth++;
return WRC_Continue;
}
void sqlite3WalkerDepthDecrease(Walker *pWalker, Select *pSelect){
UNUSED_PARAMETER(pSelect);
pWalker->walkerDepth--;
}
/*
** No-op routine for the parse-tree walker.
**
** When this routine is the Walker.xExprCallback then expression trees
** are walked without any actions being taken at each node. Presumably,
** when this routine is used for Walker.xExprCallback then
** Walker.xSelectCallback is set to do something useful for every
** subquery in the parser tree.
*/
int sqlite3ExprWalkNoop(Walker *NotUsed, Expr *NotUsed2){
UNUSED_PARAMETER2(NotUsed, NotUsed2);
return WRC_Continue;
}
/*
** No-op routine for the parse-tree walker for SELECT statements.
** subquery in the parser tree.
*/
int sqlite3SelectWalkNoop(Walker *NotUsed, Select *NotUsed2){
UNUSED_PARAMETER2(NotUsed, NotUsed2);
return WRC_Continue;
}
+9 -8
View File
@@ -5178,7 +5178,7 @@ WhereInfo *sqlite3WhereBegin(
&& (pWInfo->wctrlFlags&WHERE_ORDERBY_MIN)==0
&& pWInfo->eDistinct!=WHERE_DISTINCT_ORDERED
){
sqlite3VdbeChangeP5(v, OPFLAG_SEEKEQ); /* Hint to COMDB2 */
sqlite3VdbeChangeP5(v, OPFLAG_SEEKEQ);
}
VdbeComment((v, "%s", pIx->zName));
#ifdef SQLITE_ENABLE_COLUMN_USED_MASK
@@ -5336,12 +5336,6 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){
if( pIn->eEndLoopOp!=OP_Noop ){
if( pIn->nPrefix ){
assert( pLoop->wsFlags & WHERE_IN_EARLYOUT );
if( (pLoop->wsFlags & WHERE_VIRTUALTABLE)==0 ){
sqlite3VdbeAddOp4Int(v, OP_IfNoHope, pLevel->iIdxCur,
sqlite3VdbeCurrentAddr(v)+2+(pLevel->iLeftJoin!=0),
pIn->iBase, pIn->nPrefix);
VdbeCoverage(v);
}
if( pLevel->iLeftJoin ){
/* For LEFT JOIN queries, cursor pIn->iCur may not have been
** opened yet. This occurs for WHERE clauses such as
@@ -5352,10 +5346,17 @@ 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
sqlite3VdbeCurrentAddr(v) + 2 +
((pLoop->wsFlags & WHERE_VIRTUALTABLE)==0)
);
VdbeCoverage(v);
}
if( (pLoop->wsFlags & WHERE_VIRTUALTABLE)==0 ){
sqlite3VdbeAddOp4Int(v, OP_IfNoHope, pLevel->iIdxCur,
sqlite3VdbeCurrentAddr(v)+2,
pIn->iBase, pIn->nPrefix);
VdbeCoverage(v);
}
}
sqlite3VdbeAddOp2(v, pIn->eEndLoopOp, pIn->iCur, pIn->addrInTop);
VdbeCoverage(v);
+36 -5
View File
@@ -895,13 +895,19 @@ static ExprList *exprListAppendList(
int i;
int nInit = pList ? pList->nExpr : 0;
for(i=0; i<pAppend->nExpr; i++){
int iDummy;
Expr *pDup = sqlite3ExprDup(pParse->db, pAppend->a[i].pExpr, 0);
assert( pDup==0 || !ExprHasProperty(pDup, EP_MemToken) );
if( bIntToNull && pDup && sqlite3ExprIsInteger(pDup, &iDummy) ){
pDup->op = TK_NULL;
pDup->flags &= ~(EP_IntValue|EP_IsTrue|EP_IsFalse);
pDup->u.zToken = 0;
if( bIntToNull && pDup ){
int iDummy;
Expr *pSub;
for(pSub=pDup; ExprHasProperty(pSub, EP_Skip); pSub=pSub->pLeft){
assert( pSub );
}
if( sqlite3ExprIsInteger(pSub, &iDummy) ){
pSub->op = TK_NULL;
pSub->flags &= ~(EP_IntValue|EP_IsTrue|EP_IsFalse);
pSub->u.zToken = 0;
}
}
pList = sqlite3ExprListAppend(pParse, pList, pDup);
if( pList ) pList->a[nInit+i].sortFlags = pAppend->a[i].sortFlags;
@@ -910,6 +916,23 @@ static ExprList *exprListAppendList(
return pList;
}
/*
** When rewriting a query, if the new subquery in the FROM clause
** contains TK_AGG_FUNCTION nodes that refer to an outer query,
** then we have to increase the Expr->op2 values of those nodes
** due to the extra subquery layer that was added.
**
** See also the incrAggDepth() routine in resolve.c
*/
static int sqlite3WindowExtraAggFuncDepth(Walker *pWalker, Expr *pExpr){
if( pExpr->op==TK_AGG_FUNCTION
&& pExpr->op2>=pWalker->walkerDepth
){
pExpr->op2++;
}
return WRC_Continue;
}
/*
** If the SELECT statement passed as the second argument does not invoke
** any SQL window functions, this function is a no-op. Otherwise, it
@@ -933,6 +956,7 @@ int sqlite3WindowRewrite(Parse *pParse, Select *p){
Window *pMWin = p->pWin; /* Master window object */
Window *pWin; /* Window object iterator */
Table *pTab;
u32 selFlags = p->selFlags;
pTab = sqlite3DbMallocZero(db, sizeof(Table));
if( pTab==0 ){
@@ -1018,10 +1042,12 @@ int sqlite3WindowRewrite(Parse *pParse, Select *p){
p->pSrc = sqlite3SrcListAppend(pParse, 0, 0, 0);
if( p->pSrc ){
Table *pTab2;
Walker w;
p->pSrc->a[0].pSelect = pSub;
sqlite3SrcListAssignCursors(pParse, p->pSrc);
pSub->selFlags |= SF_Expanded;
pTab2 = sqlite3ResultSetOfSelect(pParse, pSub, SQLITE_AFF_NONE);
pSub->selFlags |= (selFlags & SF_Aggregate);
if( pTab2==0 ){
/* Might actually be some other kind of error, but in that case
** pParse->nErr will be set, so if SQLITE_NOMEM is set, we will get
@@ -1032,6 +1058,11 @@ int sqlite3WindowRewrite(Parse *pParse, Select *p){
pTab->tabFlags |= TF_Ephemeral;
p->pSrc->a[0].pTab = pTab;
pTab = pTab2;
memset(&w, 0, sizeof(w));
w.xExprCallback = sqlite3WindowExtraAggFuncDepth;
w.xSelectCallback = sqlite3WalkerDepthIncrease;
w.xSelectCallback2 = sqlite3WalkerDepthDecrease;
sqlite3WalkSelect(&w, pSub);
}
}else{
sqlite3SelectDelete(db, pSub);
+1
View File
@@ -840,6 +840,7 @@ do_test alter-13.3 {
do_test alter-14.1 {
catchsql {
CREATE TABLE t3651(a UNIQUE);
INSERT INTO t3651 VALUES(5);
ALTER TABLE t3651 ADD COLUMN b UNIQUE;
}
} {1 {Cannot add a UNIQUE column}}
+1
View File
@@ -116,6 +116,7 @@ do_test alter3-1.99 {
do_test alter3-2.1 {
execsql {
CREATE TABLE t1(a, b);
INSERT INTO t1 VALUES(1,2);
}
catchsql {
ALTER TABLE t1 ADD c PRIMARY KEY;
+2
View File
@@ -123,6 +123,7 @@ do_test alter4-1.99 {
do_test alter4-2.1 {
execsql {
CREATE TABLE temp.t1(a, b);
INSERT INTO t1 VALUES(1,2);
}
catchsql {
ALTER TABLE t1 ADD c PRIMARY KEY;
@@ -397,6 +398,7 @@ do_test alter4-10.1 {
reset_db
do_execsql_test alter4-11.0 {
CREATE TABLE t1(c INTEGER PRIMARY KEY, d);
INSERT INTO t1(c,d) VALUES(1,2);
PRAGMA foreign_keys = on;
ALTER TABLE t1 ADD COLUMN e;
}
+30 -1
View File
@@ -594,7 +594,6 @@ reset_db
do_execsql_test 18.1.0 {
CREATE TABLE t0 (c0 INTEGER, PRIMARY KEY(c0)) WITHOUT ROWID;
}
breakpoint
do_execsql_test 18.1.1 {
ALTER TABLE t0 RENAME COLUMN c0 TO c1;
}
@@ -630,4 +629,34 @@ do_execsql_test 19.120 {
SELECT * FROM t2;
} {1 1 1 1 1 1 1 1}
# Ticket 4722bdab08cb14
reset_db
do_execsql_test 20.0 {
CREATE TABLE a(a);
CREATE VIEW b AS SELECT(SELECT *FROM c JOIN a USING(d, a, a, a) JOIN a) IN();
}
do_execsql_test 20.1 {
ALTER TABLE a RENAME a TO e;
} {}
reset_db
do_execsql_test 21.0 {
CREATE TABLE a(b);
CREATE VIEW c AS
SELECT NULL INTERSECT
SELECT NULL ORDER BY
likelihood(NULL, (d, (SELECT c)));
} {}
do_catchsql_test 21.1 {
SELECT likelihood(NULL, (d, (SELECT c)));
} {1 {second argument to likelihood() must be a constant between 0.0 and 1.0}}
do_catchsql_test 21.2 {
SELECT * FROM c;
} {1 {1st ORDER BY term does not match any column in the result set}}
do_catchsql_test 21.3 {
ALTER TABLE a RENAME TO e;
} {1 {error in view c: 1st ORDER BY term does not match any column in the result set}}
finish_test
+5 -8
View File
@@ -148,10 +148,8 @@ do_test attach-1.14 {
ATTACH 'test.db' as db9;
}
} {1 {database db9 is already in use}}
do_test attach-1.15 {
catchsql {
ATTACH 'test.db' as main;
}
do_catchsql_test attach-1.15 {
ATTACH 'test.db' as main;
} {1 {database main is already in use}}
ifcapable tempdb {
do_test attach-1.16 {
@@ -160,10 +158,8 @@ ifcapable tempdb {
}
} {1 {database temp is already in use}}
}
do_test attach-1.17 {
catchsql {
ATTACH 'test.db' as MAIN;
}
do_catchsql_test attach-1.17 {
ATTACH 'test.db' as MAIN;
} {1 {database MAIN is already in use}}
do_test attach-1.18 {
catchsql {
@@ -231,6 +227,7 @@ do_test attach-1.26 {
}
} {1 {cannot detach database main}}
ifcapable tempdb {
do_test attach-1.27 {
catchsql {
+38
View File
@@ -196,4 +196,42 @@ do_catchsql_test count-6.1 {
SELECT count(DISTINCT) FROM t6 GROUP BY x;
} {1 {DISTINCT aggregates must have exactly one argument}}
# 2020-05-08.
# The count() optimization should honor the NOT INDEXED clause
#
reset_db
do_execsql_test count-7.1 {
CREATE TABLE t1(a INTEGER PRIMARY KEY, b INT, c VARCHAR(1000));
CREATE INDEX t1b ON t1(b);
INSERT INTO t1(a,b,c) values(1,2,'count.test cases for NOT INDEXED');
ANALYZE;
UPDATE sqlite_stat1 SET stat='1000000 10' WHERE idx='t1b';
ANALYZE sqlite_master;
}
do_eqp_test count-7.2 {
SELECT count(1) FROM t1;
} {
QUERY PLAN
`--SCAN TABLE t1 USING COVERING INDEX t1b
}
do_eqp_test count-7.3 {
SELECT count(1) FROM t1 NOT INDEXED
} {
QUERY PLAN
`--SCAN TABLE t1
}
do_eqp_test count-7.3 {
SELECT count(*) FROM t1;
} {
QUERY PLAN
`--SCAN TABLE t1 USING COVERING INDEX t1b
}
do_eqp_test count-7.4 {
SELECT count(*) FROM t1 NOT INDEXED
} {
QUERY PLAN
`--SCAN TABLE t1
}
finish_test
+40
View File
@@ -18,6 +18,7 @@
set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix cse
do_test cse-1.1 {
execsql {
@@ -157,4 +158,43 @@ for {set i 1} {$i<100} {incr i} {
} $answer
}
#-------------------------------------------------------------------------
# Ticket fd1bda016d1a
#
reset_db
do_execsql_test 3.0 {
CREATE TABLE t1(a TEXT, b);
INSERT INTO t1 VALUES('hello', 0);
INSERT INTO t1 VALUES('world', 0);
CREATE TABLE t2(x TEXT);
INSERT INTO t2 VALUES('hello');
INSERT INTO t2 VALUES('world');
CREATE TABLE t3(y);
INSERT INTO t3 VALUES(1000);
} {}
do_execsql_test 3.1 {
SELECT 1000 = y FROM t3
} {1}
do_execsql_test 3.2 {
SELECT 1000 IN (SELECT x FROM t2), 1000 = y FROM t3
} {0 1}
do_execsql_test 3.3 {
SELECT 0 IN (SELECT a), (SELECT a LIMIT 0) FROM t1
} {0 {} 0 {}}
do_execsql_test 3.4 {
SELECT 0 IN (SELECT a) FROM t1 WHERE a = 'hello' OR (SELECT a LIMIT 0);
} {0}
do_execsql_test 3.5 {
CREATE TABLE v0(v1 VARCHAR0);
INSERT INTO v0 VALUES(2), (3);
SELECT 0 IN(SELECT v1) FROM v0 WHERE v1 = 2 OR(SELECT v1 LIMIT 0);
} {0}
finish_test
+4 -4
View File
@@ -69,7 +69,7 @@ do_test 1.2 {
p5_of_opcode db OpenRead {
SELECT * FROM t1 CROSS JOIN t2 WHERE a=x
}
} {00 00}
} {0 0}
# Do the same test the other way around.
#
@@ -82,7 +82,7 @@ do_test 2.2 {
p5_of_opcode db OpenRead {
SELECT * FROM t2 CROSS JOIN t1 WHERE a=x
}
} {00 00}
} {0 0}
# Various expressions captured by CursorHint
#
@@ -117,7 +117,7 @@ do_test 4.2 {
p5_of_opcode db OpenRead {
SELECT * FROM t1 WHERE b>11;
}
} {02 00}
} {2 0}
do_test 4.3asc {
p4_of_opcode db CursorHint {
SELECT c FROM t1 WHERE b<11 ORDER BY b ASC;
@@ -132,7 +132,7 @@ do_test 4.4 {
p5_of_opcode db OpenRead {
SELECT c FROM t1 WHERE b<11;
}
} {00}
} {0}
do_test 4.5asc {
p4_of_opcode db CursorHint {
+2 -2
View File
@@ -51,8 +51,8 @@ proc do_temptables_test {tn sql temptables} {
set ret ""
db eval "EXPLAIN [set sql]" {
if {$opcode == "OpenEphemeral" || $opcode == "SorterOpen"} {
if {$p5 != "08" && $p5!="00"} { error "p5 = $p5" }
if {$p5 == "08"} {
if {$p5!=8 && $p5!=0} { error "p5 = $p5" }
if {$p5==8} {
lappend ret hash
} else {
lappend ret btree
+44 -36
View File
@@ -395,17 +395,19 @@ do_createtable_tests 1.2.2 {
4 {CREATE TABLE auxb.xyz(z)} {}
}
drop_all_tables
do_createtable_tests 1.3 -tclquery {
unset -nocomplain X
array set X [table_list]
list $X(main) $X(temp) $X(auxa) $X(auxb)
} {
1 "CREATE TABLE main.abc(a, b, c)" {abc {} {} {}}
2 "CREATE TABLE main.t1(a, b, c)" {{abc t1} {} {} {}}
3 "CREATE TABLE temp.tmp(a, b, c)" {{abc t1} tmp {} {}}
4 "CREATE TABLE auxb.tbl(x, y)" {{abc t1} tmp {} tbl}
5 "CREATE TABLE auxb.t1(k, v)" {{abc t1} tmp {} {t1 tbl}}
6 "CREATE TABLE auxa.next(c, d)" {{abc t1} tmp next {t1 tbl}}
if {[permutation]!="maindbname"} {
do_createtable_tests 1.3 -tclquery {
unset -nocomplain X
array set X [table_list]
list $X(main) $X(temp) $X(auxa) $X(auxb)
} {
1 "CREATE TABLE main.abc(a, b, c)" {abc {} {} {}}
2 "CREATE TABLE main.t1(a, b, c)" {{abc t1} {} {} {}}
3 "CREATE TABLE temp.tmp(a, b, c)" {{abc t1} tmp {} {}}
4 "CREATE TABLE auxb.tbl(x, y)" {{abc t1} tmp {} tbl}
5 "CREATE TABLE auxb.t1(k, v)" {{abc t1} tmp {} {t1 tbl}}
6 "CREATE TABLE auxa.next(c, d)" {{abc t1} tmp next {t1 tbl}}
}
}
# EVIDENCE-OF: R-18895-27365 If the "TEMP" or "TEMPORARY" keyword occurs
@@ -413,13 +415,15 @@ do_createtable_tests 1.3 -tclquery {
# temp database.
#
drop_all_tables
do_createtable_tests 1.4 -tclquery {
unset -nocomplain X
array set X [table_list]
list $X(main) $X(temp) $X(auxa) $X(auxb)
} {
1 "CREATE TEMP TABLE t1(a, b)" {{} t1 {} {}}
2 "CREATE TEMPORARY TABLE t2(a, b)" {{} {t1 t2} {} {}}
if {[permutation]!="maindbname"} {
do_createtable_tests 1.4 -tclquery {
unset -nocomplain X
array set X [table_list]
list $X(main) $X(temp) $X(auxa) $X(auxb)
} {
1 "CREATE TEMP TABLE t1(a, b)" {{} t1 {} {}}
2 "CREATE TEMPORARY TABLE t2(a, b)" {{} {t1 t2} {} {}}
}
}
# EVIDENCE-OF: R-23976-43329 It is an error to specify both a
@@ -436,30 +440,34 @@ do_createtable_tests 1.5.1 -error {
4 "CREATE TEMPORARY TABLE main.xxx(x)" {}
}
drop_all_tables
do_createtable_tests 1.5.2 -tclquery {
unset -nocomplain X
array set X [table_list]
list $X(main) $X(temp) $X(auxa) $X(auxb)
} {
1 "CREATE TEMP TABLE temp.t1(a, b)" {{} t1 {} {}}
2 "CREATE TEMPORARY TABLE temp.t2(a, b)" {{} {t1 t2} {} {}}
3 "CREATE TEMP TABLE TEMP.t3(a, b)" {{} {t1 t2 t3} {} {}}
4 "CREATE TEMPORARY TABLE TEMP.xxx(x)" {{} {t1 t2 t3 xxx} {} {}}
if {[permutation]!="maindbname"} {
do_createtable_tests 1.5.2 -tclquery {
unset -nocomplain X
array set X [table_list]
list $X(main) $X(temp) $X(auxa) $X(auxb)
} {
1 "CREATE TEMP TABLE temp.t1(a, b)" {{} t1 {} {}}
2 "CREATE TEMPORARY TABLE temp.t2(a, b)" {{} {t1 t2} {} {}}
3 "CREATE TEMP TABLE TEMP.t3(a, b)" {{} {t1 t2 t3} {} {}}
4 "CREATE TEMPORARY TABLE TEMP.xxx(x)" {{} {t1 t2 t3 xxx} {} {}}
}
}
# EVIDENCE-OF: R-31997-24564 If no schema name is specified and the TEMP
# keyword is not present then the table is created in the main database.
#
drop_all_tables
do_createtable_tests 1.6 -tclquery {
unset -nocomplain X
array set X [table_list]
list $X(main) $X(temp) $X(auxa) $X(auxb)
} {
1 "CREATE TABLE t1(a, b)" {t1 {} {} {}}
2 "CREATE TABLE t2(a, b)" {{t1 t2} {} {} {}}
3 "CREATE TABLE t3(a, b)" {{t1 t2 t3} {} {} {}}
4 "CREATE TABLE xxx(x)" {{t1 t2 t3 xxx} {} {} {}}
if {[permutation]!="maindbname"} {
do_createtable_tests 1.6 -tclquery {
unset -nocomplain X
array set X [table_list]
list $X(main) $X(temp) $X(auxa) $X(auxb)
} {
1 "CREATE TABLE t1(a, b)" {t1 {} {} {}}
2 "CREATE TABLE t2(a, b)" {{t1 t2} {} {} {}}
3 "CREATE TABLE t3(a, b)" {{t1 t2 t3} {} {} {}}
4 "CREATE TABLE xxx(x)" {{t1 t2 t3 xxx} {} {} {}}
}
}
drop_all_tables
+18 -18
View File
@@ -126,37 +126,37 @@ do_execsql_test 3.1.0 { SELECT * FROM temp.v1 } {{a temp} {b temp}}
do_execsql_test 3.1.1 { DROP VIEW temp.v1 } {}
do_catchsql_test 3.1.2 { SELECT * FROM temp.v1 } {1 {no such table: temp.v1}}
do_test 3.1.3 { list_all_views } {main.v1 main.v2 aux.v1 aux.v2 aux.v3}
do_test 3.1.4 { list_all_data } $databasedata
do_test 3.1.4 { string compare [list_all_data] $databasedata } 0
do_execsql_test 3.2.0 { SELECT * FROM v1 } {{a main} {b main}}
do_execsql_test 3.2.1 { DROP VIEW v1 } {}
do_catchsql_test 3.2.2 { SELECT * FROM main.v1 } {1 {no such table: main.v1}}
do_test 3.2.3 { list_all_views } {main.v2 aux.v1 aux.v2 aux.v3}
do_test 3.2.4 { list_all_data } $databasedata
do_test 3.2.4 { string compare [list_all_data] $databasedata } 0
do_execsql_test 3.3.0 { SELECT * FROM v2 } {{a main} {b main}}
do_execsql_test 3.3.1 { DROP VIEW v2 } {}
do_catchsql_test 3.3.2 { SELECT * FROM main.v2 } {1 {no such table: main.v2}}
do_test 3.3.3 { list_all_views } {aux.v1 aux.v2 aux.v3}
do_test 3.3.4 { list_all_data } $databasedata
do_test 3.3.4 { string compare [list_all_data] $databasedata } 0
do_execsql_test 3.4.0 { SELECT * FROM v1 } {{a aux} {b aux}}
do_execsql_test 3.4.1 { DROP VIEW v1 } {}
do_catchsql_test 3.4.2 { SELECT * FROM v1 } {1 {no such table: v1}}
do_test 3.4.3 { list_all_views } {aux.v2 aux.v3}
do_test 3.4.4 { list_all_data } $databasedata
do_test 3.4.4 { string compare [list_all_data] $databasedata } 0
do_execsql_test 3.4.0 { SELECT * FROM aux.v2 } {{a aux} {b aux}}
do_execsql_test 3.4.1 { DROP VIEW aux.v2 } {}
do_catchsql_test 3.4.2 { SELECT * FROM aux.v2 } {1 {no such table: aux.v2}}
do_test 3.4.3 { list_all_views } {aux.v3}
do_test 3.4.4 { list_all_data } $databasedata
do_execsql_test 3.5.0 { SELECT * FROM aux.v2 } {{a aux} {b aux}}
do_execsql_test 3.5.1 { DROP VIEW aux.v2 } {}
do_catchsql_test 3.5.2 { SELECT * FROM aux.v2 } {1 {no such table: aux.v2}}
do_test 3.5.3 { list_all_views } {aux.v3}
do_test 3.5.4 { string compare [list_all_data] $databasedata } 0
do_execsql_test 3.5.0 { SELECT * FROM v3 } {{a aux} {b aux}}
do_execsql_test 3.5.1 { DROP VIEW v3 } {}
do_catchsql_test 3.5.2 { SELECT * FROM v3 } {1 {no such table: v3}}
do_test 3.5.3 { list_all_views } {}
do_test 3.5.4 { list_all_data } $databasedata
do_execsql_test 3.6.0 { SELECT * FROM v3 } {{a aux} {b aux}}
do_execsql_test 3.6.1 { DROP VIEW v3 } {}
do_catchsql_test 3.6.2 { SELECT * FROM v3 } {1 {no such table: v3}}
do_test 3.6.3 { list_all_views } {}
do_test 3.6.4 { string compare [list_all_data] $databasedata } 0
# EVIDENCE-OF: R-25558-37487 If the specified view cannot be found and
# the IF EXISTS clause is not present, it is an error.
@@ -179,11 +179,11 @@ do_dropview_tests 5 -repair {
dropview_reopen_db
} -tclquery {
list_all_views
expr {[list_all_views] == "main.v1 main.v2 temp.v1 aux.v1 aux.v2 aux.v3"}
#expr {[list_all_views] == "main.v1 main.v2 temp.v1 aux.v1 aux.v2 aux.v3"}
} {
1 "DROP VIEW IF EXISTS xx" 1
2 "DROP VIEW IF EXISTS main.xx" 1
3 "DROP VIEW IF EXISTS temp.v2" 1
1 "DROP VIEW IF EXISTS xx" "main.v1 main.v2 temp.v1 aux.v1 aux.v2 aux.v3"
2 "DROP VIEW IF EXISTS main.xx" "main.v1 main.v2 temp.v1 aux.v1 aux.v2 aux.v3"
3 "DROP VIEW IF EXISTS temp.v2" "main.v1 main.v2 temp.v1 aux.v1 aux.v2 aux.v3"
}
+25 -25
View File
@@ -1139,7 +1139,7 @@ sqlite3 db test.db
#-------------------------------------------------------------------------
# Test cases for the testable statements related to the CASE expression.
#
# EVIDENCE-OF: R-15199-61389 There are two basic forms of the CASE
# EVIDENCE-OF: R-57495-24088 There are two fundamental forms of the CASE
# expression: those with a base expression and those without.
#
do_execsql_test e_expr-20.1 {
@@ -1235,11 +1235,11 @@ db nullvalue {}
# evaluating WHEN terms.
#
do_execsql_test e_expr-21.4.1 {
SELECT CASE WHEN NULL THEN 'A' WHEN 1 THEN 'B' END
} {B}
SELECT CASE WHEN NULL THEN 'A' WHEN 1 THEN 'B' END, iif(NULL,8,99);
} {B 99}
do_execsql_test e_expr-21.4.2 {
SELECT CASE WHEN 0 THEN 'A' WHEN NULL THEN 'B' ELSE 'C' END
} {C}
SELECT CASE WHEN 0 THEN 'A' WHEN NULL THEN 'B' ELSE 'C' END, iif(0,8,99);
} {C 99}
# EVIDENCE-OF: R-38620-19499 In a CASE with a base expression, the base
# expression is evaluated just once and the result is compared against
@@ -1952,39 +1952,39 @@ foreach {tn expr} {
# 'english' and '0' are all considered to be false.
#
do_execsql_test e_expr-37.1 {
SELECT CASE WHEN NULL THEN 'true' ELSE 'false' END;
} {false}
SELECT CASE WHEN NULL THEN 'true' ELSE 'false' END, iif(NULL,'true','false');
} {false false}
do_execsql_test e_expr-37.2 {
SELECT CASE WHEN 0.0 THEN 'true' ELSE 'false' END;
} {false}
SELECT CASE WHEN 0.0 THEN 'true' ELSE 'false' END, iif(0.0,'true','false');
} {false false}
do_execsql_test e_expr-37.3 {
SELECT CASE WHEN 0 THEN 'true' ELSE 'false' END;
} {false}
SELECT CASE WHEN 0 THEN 'true' ELSE 'false' END, iif(0,'true','false');
} {false false}
do_execsql_test e_expr-37.4 {
SELECT CASE WHEN 'engligh' THEN 'true' ELSE 'false' END;
} {false}
SELECT CASE WHEN 'engligh' THEN 'true' ELSE 'false' END, iif('engligh','true','false');
} {false false}
do_execsql_test e_expr-37.5 {
SELECT CASE WHEN '0' THEN 'true' ELSE 'false' END;
} {false}
SELECT CASE WHEN '0' THEN 'true' ELSE 'false' END, iif('0','true','false');
} {false false}
# EVIDENCE-OF: R-55532-10108 Values 1, 1.0, 0.1, -0.1 and '1english' are
# considered to be true.
#
do_execsql_test e_expr-37.6 {
SELECT CASE WHEN 1 THEN 'true' ELSE 'false' END;
} {true}
SELECT CASE WHEN 1 THEN 'true' ELSE 'false' END, iif(1,'true','false');
} {true true}
do_execsql_test e_expr-37.7 {
SELECT CASE WHEN 1.0 THEN 'true' ELSE 'false' END;
} {true}
SELECT CASE WHEN 1.0 THEN 'true' ELSE 'false' END, iif(1.0,'true','false');
} {true true}
do_execsql_test e_expr-37.8 {
SELECT CASE WHEN 0.1 THEN 'true' ELSE 'false' END;
} {true}
SELECT CASE WHEN 0.1 THEN 'true' ELSE 'false' END, iif(0.1,'true','false');
} {true true}
do_execsql_test e_expr-37.9 {
SELECT CASE WHEN -0.1 THEN 'true' ELSE 'false' END;
} {true}
SELECT CASE WHEN -0.1 THEN 'true' ELSE 'false' END, iif(-0.1,'true','false');
} {true true}
do_execsql_test e_expr-37.10 {
SELECT CASE WHEN '1english' THEN 'true' ELSE 'false' END;
} {true}
SELECT CASE WHEN '1english' THEN 'true' ELSE 'false' END, iif('1engl','true','false');
} {true true}
finish_test
+2 -2
View File
@@ -2507,7 +2507,7 @@ proc test_efkey_6 {tn zAlter isError} {
drop_all_tables
do_test e_fkey-56.$tn.1 "
execsql { CREATE TABLE tbl(a, b) }
execsql { CREATE TABLE tbl(a, b); INSERT INTO tbl VALUES(1, 2); }
[list catchsql $zAlter]
" [lindex {{0 {}} {1 {Cannot add a REFERENCES column with non-NULL default value}}} $isError]
@@ -2771,7 +2771,7 @@ do_test e_fkey-60.6 {
#
do_test e_fkey-61.1.1 {
drop_all_tables
execsql { CREATE TABLE t1(a, b) }
execsql { CREATE TABLE t1(a, b) ; INSERT INTO t1 VALUES(1, 2) }
catchsql { ALTER TABLE t1 ADD COLUMN c DEFAULT 'xxx' REFERENCES t2 }
} {1 {Cannot add a REFERENCES column with non-NULL default value}}
do_test e_fkey-61.1.2 {
+3
View File
@@ -955,6 +955,7 @@ ifcapable altertable {
execsql {
CREATE TABLE t1(a PRIMARY KEY);
CREATE TABLE t2(a, b);
INSERT INTO t2 VALUES(1,2);
}
catchsql { ALTER TABLE t2 ADD COLUMN c REFERENCES t1 }
} {0 {}}
@@ -1046,6 +1047,7 @@ ifcapable altertable {
execsql {
CREATE TEMP TABLE t1(a PRIMARY KEY);
CREATE TEMP TABLE t2(a, b);
INSERT INTO temp.t2 VALUES(1,2);
}
catchsql { ALTER TABLE t2 ADD COLUMN c REFERENCES t1 }
} {0 {}}
@@ -1130,6 +1132,7 @@ ifcapable altertable {
ATTACH ':memory:' AS aux;
CREATE TABLE aux.t1(a PRIMARY KEY);
CREATE TABLE aux.t2(a, b);
INSERT INTO aux.t2(a,b) VALUES(1,2);
}
catchsql { ALTER TABLE t2 ADD COLUMN c REFERENCES t1 }
} {0 {}}
+1 -1
View File
@@ -48,7 +48,7 @@ proc analyze_delete_program {sql} {
set obj $T($root)
set O($obj) ""
if {"0x$R(p5)" & 0x08} {
if {$R(p5) & 0x08} {
set O($obj) *
} else {
set O($obj) ""
+232
View File
@@ -5834,4 +5834,236 @@ do_catchsql_test 36.1 {
INSERT INTO f(f) VALUES ('merge=59,59');
} {1 {database disk image is malformed}}
#-------------------------------------------------------------------------
#
reset_db
do_execsql_test 37.0 {
CREATE VIRTUAL TABLE f USING fts3(a,b);
INSERT INTO f_segdir VALUES (28,0,0,0,'0 0',x'00');
INSERT INTO f_segdir VALUES (0,241,0,0,'0 0',x'0001000030310000f1');
}
do_catchsql_test 37.1 {
INSERT INTO f VALUES (0,x'00');
} {1 {database disk image is malformed}}
#-------------------------------------------------------------------------
#
reset_db
reset_db
do_test 38.0 {
sqlite3 db {}
db deserialize [decode_hexdb {
.open --hexdb
| size 24576 pagesize 4096 filename crash-1cc4f8a70485ce.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 0e b1 00 06 0d a4 00 0f 8d 0f 21 ...............!
| 112: 0e b9 0d c8 0e 7e 0d a4 00 00 00 00 00 00 00 00 .....~..........
| 3488: 00 00 00 00 22 07 06 17 11 11 01 31 74 61 62 6c ...........1tabl
| 3504: 65 74 32 74 32 07 43 52 45 41 54 45 20 54 41 42 et2t2.CREATE TAB
| 3520: 4c 45 20 74 32 28 78 29 81 33 05 07 17 1f 1f 01 LE t2(x).3......
| 3536: 82 35 74 61 62 6c 65 74 31 5f 73 65 67 64 69 72 .5tablet1_segdir
| 3552: 74 31 5f 73 65 67 64 69 72 05 43 52 45 41 54 45 t1_segdir.CREATE
| 3568: 20 54 41 42 4c 45 20 27 74 31 5f 73 65 67 64 69 TABLE 't1_segdi
| 3584: 72 27 28 6c 65 76 65 6c 20 49 4e 54 45 47 45 52 r'(level INTEGER
| 3600: 2c 69 64 78 20 49 4e 54 45 47 45 52 2c 73 74 61 ,idx INTEGER,sta
| 3616: 72 74 5f 62 6c 6f 63 6b 20 49 4e 54 45 47 45 52 rt_block INTEGER
| 3632: 2c 6c 65 61 76 65 73 5f 65 6e 64 5f 62 6c 6f 63 ,leaves_end_bloc
| 3648: 6b 20 49 4e 54 45 47 45 52 2c 65 6e 64 5f 62 6c k INTEGER,end_bl
| 3664: 6f 63 6b 20 49 4e 54 45 47 45 62 2c 72 6f 6f 74 ock INTEGEb,root
| 3680: 20 42 4c 4f 42 2c 50 52 49 4d 41 52 59 20 4b 45 BLOB,PRIMARY KE
| 3696: 59 28 6c 65 76 65 6c 2c 20 69 64 78 29 29 31 06 Y(level, idx))1.
| 3712: 06 17 45 1f 01 00 69 6e 64 65 78 73 71 6c 69 74 ..E...indexsqlit
| 3728: 65 5f 61 75 74 6f 69 6e 64 65 78 5f 74 31 5f 73 e_autoindex_t1_s
| 3744: 65 67 64 69 72 5f 31 74 31 5f 73 65 67 64 69 72 egdir_1t1_segdir
| 3760: 06 0f c7 00 08 00 00 00 00 66 04 07 17 23 23 01 .........f...##.
| 3776: 81 13 74 61 62 6c 65 74 31 5f 73 65 67 6d 65 6e ..tablet1_segmen
| 3792: 74 73 74 31 5f 73 65 67 6d 65 6e 74 73 04 43 52 tst1_segments.CR
| 3808: 45 41 54 45 20 54 41 42 4c 45 20 27 74 31 5f 73 EATE TABLE 't1_s
| 3824: 65 67 6d 65 6e 74 73 27 28 62 6c 6f 63 6b 69 64 egments'(blockid
| 3840: 20 49 4e 54 45 47 45 52 20 50 52 49 4d 41 52 59 INTEGER PRIMARY
| 3856: 20 4b 45 59 2c 20 62 6c 6f 63 6b 20 42 4c 4f 42 KEY, block BLOB
| 3872: 29 6a 03 07 17 21 21 01 81 1f 74 61 62 6c 65 74 )j...!!...tablet
| 3888: 31 5f 63 6f 6e 74 65 6e 74 74 31 5f 63 6f 6e 74 1_contentt1_cont
| 3904: 65 6e 74 03 43 52 45 41 54 45 20 54 41 42 4c 45 ent.CREATE TABLE
| 3920: 20 27 74 31 5f 63 6f 6e 74 65 6e 74 27 28 64 6f 't1_content'(do
| 3936: 63 69 64 20 49 4e 54 45 47 45 52 20 50 52 49 4d cid INTEGER PRIM
| 3952: 41 52 59 20 4b 45 59 2c 20 27 63 30 61 27 2c 20 ARY KEY, 'c0a',
| 3968: 27 63 31 62 27 2c 20 27 63 32 63 27 29 38 02 06 'c1b', 'c2c')8..
| 3984: 17 11 11 08 5f 74 61 62 6c 65 74 31 74 31 43 52 ...._tablet1t1CR
| 4000: 45 41 54 45 20 56 49 52 54 55 41 4c 20 54 41 42 EATE VIRTUAL TAB
| 4016: 4c 45 20 74 31 20 55 53 49 4e 47 20 66 74 73 33 LE t1 USING fts3
| 4032: 28 61 2c 62 2c 63 29 00 00 00 00 00 00 00 00 00 (a,b,c).........
| page 3 offset 8192
| 0: 0d 00 00 00 25 0b 48 00 0f d8 0f af 0f 86 0f 74 ....%.H........t
| 16: 0f 61 0f 4e 0f 2f 0f 0f 0e ef 0e d7 0e be 0e a5 .a.N./..........
| 32: 0e 8d 0e 74 0e 5b 0e 40 0e 24 0e 08 0d ef 00 00 ...t.[.@.$......
| 2880: 00 00 00 00 00 00 00 00 81 3f 25 06 00 82 7e f0 .........?%...~.
| 2896: 00 43 4f 4d 50 49 4c 45 52 3d 67 63 63 2d 35 2e .COMPILER=gcc-5.
| 2912: 34 23 00 20 42 30 31 36 2f 36 30 39 20 44 45 42 4#. B016/609 DEB
| 2928: 55 47 20 45 4e 41 42 4c 45 20 44 42 53 54 41 54 UG ENABLE DBSTAT
| 2944: 20 56 54 41 42 20 45 4e 42 92 4c 45 20 46 54 53 VTAB ENB.LE FTS
| 2960: 34 20 45 4e 41 42 4c 45 20 46 54 53 35 20 45 4e 4 ENABLE FTS5 EN
| 2976: 41 42 4c 45 20 47 45 4f 50 4f 4c 59 20 45 4e 41 ABLE GEOPOLY ENA
| 2992: 42 5c 45 1f 4a 53 4f 4e 31 20 45 4e 41 42 4c 45 B.E.JSON1 ENABLE
| 3008: 20 4d 45 4d 53 59 53 35 20 45 4e 41 42 4c 45 20 MEMSYS5 ENABLE
| 3024: 52 54 52 45 45 20 4d 41 58 20 4d 45 4d 4f 52 59 RTREE MAX MEMORY
| 3040: 3d 35 30 30 30 30 30 30 30 20 4f 4d 49 54 20 4c =50000000 OMIT L
| 3056: 4f 41 44 20 45 58 54 45 4e 53 49 4f 4e 20 54 48 OAD EXTENSION TH
| 3072: 52 45 41 44 53 41 46 45 3d 30 18 24 05 00 25 0f READSAFE=0.$..%.
| 3088: 19 54 48 52 45 41 44 53 41 46 45 3d 30 58 42 49 .THREADSAFE=0XBI
| 3104: 4e 41 52 59 18 23 05 00 25 0f 19 54 48 52 45 41 NARY.#..%..THREA
| 3120: 44 53 41 46 45 3d 30 88 4e 4f 43 41 53 45 17 22 DSAFE=0.NOCASE..
| 3136: 05 00 25 0f 17 54 48 52 45 41 44 53 41 46 45 3d ..%..THREADSAFE=
| 3152: 30 58 52 54 52 49 4d 1f 21 05 00 33 0f 19 4f 4d 0XRTRIM.!..3..OM
| 3168: 49 54 20 4c 4f 41 44 20 45 58 54 45 4e 53 49 4f IT LOAD EXTENSIO
| 3184: 4e 58 42 49 4e 41 52 59 1f 20 05 00 33 0f 19 4f NXBINARY. ..3..O
| 3200: 4d 49 54 20 4c 4f 41 44 20 45 58 54 45 4e 53 49 MIT LOAD EXTENSI
| 3216: 4f 4e 58 4e 4f 43 41 53 45 1e 1f 05 00 33 0f 17 ONXNOCASE....3..
| 3232: 4f 4d 49 54 20 4c 4f 41 54 20 45 58 54 45 4e 53 OMIT LOAT EXTENS
| 3248: 49 4f 4e 58 52 54 52 49 4d 1f 1e 04 00 33 0f 19 IONXRTRIM....3..
| 3264: 82 41 58 20 4d 45 4d 4f 52 59 3d 35 30 30 30 30 .AX MEMORY=50000
| 3280: 30 30 30 58 42 49 4e 41 52 59 1f 1d 05 00 33 0f 000XBINARY....3.
| 3296: 19 4d 41 58 20 4d 45 4d 4f 52 59 3d 35 30 30 30 .MAX MEMORY=5000
| 3312: 30 30 30 30 58 4e 4f 43 41 53 45 1e 1c 05 00 33 0000XNOCASE....3
| 3328: 0f 17 4d 41 58 20 4d 45 4d fa 52 59 3d 35 30 20 ..MAX MEM.RY=50
| 3344: 30 30 30 30 30 58 52 54 52 49 4d 18 1b 05 00 25 00000XRTRIM....%
| 3360: 0f 19 45 4e 41 42 4c 45 20 52 54 52 45 45 58 42 ..ENABLE RTREEXB
| 3376: 49 4e 41 52 59 18 1a 05 00 25 0f 19 45 4e 41 42 INARY....%..ENAB
| 3392: 4c 45 20 52 54 52 45 45 58 4e 4f 43 41 53 45 17 LE RTREEXNOCASE.
| 3408: 19 05 00 25 0f 17 45 4e 42 42 4c 45 20 52 54 52 ...%..ENBBLE RTR
| 3424: 45 45 58 52 54 52 49 4d 1a 18 05 00 29 0f 19 45 EEXRTRIM....)..E
| 3440: 4e 41 42 4c 45 20 4d 45 4d 53 59 53 35 58 42 49 NABLE MEMSYS5XBI
| 3456: 4e 41 52 59 1a 17 05 00 29 0f 19 45 4e 41 42 3c NARY....)..ENAB<
| 3472: 45 20 4d 45 4d 53 59 53 35 58 4e 4f 43 41 53 45 E MEMSYS5XNOCASE
| 3488: 19 16 05 00 29 0f 17 45 4e 41 42 4c 45 20 4d 45 ....)..ENABLE ME
| 3504: 4d 53 59 53 35 58 52 54 52 49 4d 18 15 05 00 25 MSYS5XRTRIM....%
| 3520: 0f 19 45 4e 41 42 4c 45 20 4a 53 4f 4e 31 58 42 ..ENABLE JSON1XB
| 3536: 49 4e 41 52 59 18 14 05 00 25 0f 19 45 4e 41 42 INARY....%..ENAB
| 3552: 4c 45 20 4a 53 4f 4e 31 58 4e 4f 43 41 53 45 17 LE JSON1XNOCASE.
| 3568: 13 05 00 25 0f 17 45 4e 41 42 4c 45 20 4a 53 4f ...%..ENABLE JSO
| 3584: 4e 31 58 52 54 52 49 4d 95 12 05 00 29 0f 19 45 N1XRTRIM....)..E
| 3600: 4e 31 42 4c 45 20 47 45 4e 50 4f 4c 59 58 42 49 N1BLE GENPOLYXBI
| 3616: 4e 41 52 59 1a 11 05 00 29 0f 19 45 3e f2 1e 4c NARY....)..E>..L
| 3632: 45 20 47 45 4f 50 4f 4c 59 58 4e 4f 43 41 53 45 E GEOPOLYXNOCASE
| 3648: 19 10 05 00 29 0f 17 45 4e 41 42 4c 45 20 47 45 ....)..ENABLE GE
| 3664: 4f 50 4f 4c 59 58 52 54 52 49 4d 17 0f 05 00 23 OPOLYXRTRIM....#
| 3680: 0f 19 45 4e 41 42 4c 45 20 46 54 53 35 58 42 49 ..ENABLE FTS5XBI
| 3696: 4e 41 52 59 17 0e 05 00 23 0f 19 45 4e 41 42 3c NARY....#..ENAB<
| 3712: 45 20 46 54 53 35 58 4e 4f 43 41 53 45 16 0d 05 E FTS5XNOCASE...
| 3728: 00 23 0f 17 45 4e 41 42 4c 45 20 46 54 53 35 58 .#..ENABLE FTS5X
| 3744: 5d 24 52 49 4d 17 0c 05 00 23 0f 19 45 4e 41 42 ]$RIM....#..ENAB
| 3760: 4c 45 20 46 54 53 34 58 42 49 4e 41 52 59 17 0b LE FTS4XBINARY..
| 3776: 05 00 23 0f 19 45 4e 41 42 4c 45 20 46 54 53 35 ..#..ENABLE FTS5
| 3792: 58 4e 4f 43 40 53 45 16 0a 05 00 23 0f 17 45 4e XNOC@SE....#..EN
| 3808: 41 42 4c 45 20 46 54 53 34 58 52 54 52 49 4d 1e ABLE FTS4XRTRIM.
| 3824: 09 05 00 31 0f 19 45 4e 41 42 4c 45 20 44 42 53 ...1..ENABLE DBS
| 3840: 54 41 54 20 56 54 41 42 58 42 49 4e 41 52 59 1e TAT VTABXBINARY.
| 3856: 08 05 00 31 0f 19 45 4e 41 42 4c 45 20 44 42 53 ...1..ENABLE DBS
| 3872: 54 41 54 20 56 54 41 42 58 4e 4f 43 41 53 45 1d TAT VTABXNOCASE.
| 3888: 07 05 00 31 0f 17 45 4e 41 42 4b 45 20 44 42 53 ...1..ENABKE DBS
| 3904: 54 41 54 20 56 53 41 42 58 52 54 62 49 4d 11 06 TAT VSABXRTbIM..
| 3920: 05 00 17 0f 19 44 45 42 54 47 58 42 49 4e 41 52 .....DEBTGXBINAR
| 3936: 59 11 05 05 00 17 0f 19 44 45 42 55 47 58 4e 4f Y.......DEBUGXNO
| 3952: 43 41 53 45 10 04 05 00 17 0f 17 44 45 42 55 47 CASE.......DEBUG
| 3968: 68 52 54 52 49 4d 27 03 05 00 43 0f 19 43 4f 4d hRTRIM'...C..COM
| 3984: 50 49 4c 45 52 3d 67 63 63 2d 35 2e 34 2e 30 20 PILER=gcc-5.4.0
| 4000: 32 30 31 36 30 36 30 39 58 42 49 4e 41 52 59 27 20160609XBINARY'
| 4016: 02 05 00 43 0f 19 43 4f 4d 50 49 4c 45 52 3d 67 ...C..COMPILER=g
| 4032: 63 63 2d 35 2e 34 2e 30 20 32 30 31 36 30 36 30 cc-5.4.0 2016060
| 4048: 39 58 4f 4f 43 41 53 45 26 01 05 00 43 0f 17 43 9XOOCASE&...C..C
| 4064: 4f 4d 50 49 4c 45 52 3d 67 63 63 2d 35 2e 34 2e OMPILER=gcc-5.4.
| 4080: 30 20 32 30 31 36 30 36 30 39 58 52 54 52 49 4d 0 20160609XRTRIM
| page 4 offset 12288
| 0: 0d 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
| page 5 offset 16384
| 0: 0d 00 00 00 02 0b a0 00 0c ad 0b a0 00 00 00 00 ................
| 2976: 82 0a 02 08 08 09 08 08 17 84 06 30 20 32 35 33 ...........0 253
| 2992: 00 01 30 04 25 06 1b 00 00 08 32 30 31 36 8c 36 ..0.%.....2016.6
| 3008: 30 39 03 25 07 00 00 01 34 03 25 05 00 00 01 35 09.%....4.%....5
| 3024: 03 25 04 00 01 07 30 30 30 30 30 30 30 03 25 1a .%....0000000.%.
| 3040: 00 00 08 63 6f 5d 70 69 6c 65 72 03 25 02 00 00 ...co]piler.%...
| 3056: 06 64 62 73 74 61 74 03 25 0a 00 01 04 65 62 75 .dbstat.%....ebu
| 3072: 67 03 25 08 00 00 06 65 6e 61 62 6c 65 09 25 09 g.%....enable.%.
| 3088: 05 04 04 04 04 04 00 01 08 78 74 65 7e 73 69 6f .........xte~sio
| 3104: 6e 03 25 1d 00 00 04 66 74 73 34 03 25 0d 00 03 n.%....fts4.%...
| 3120: 01 35 03 25 0f 00 00 03 67 63 63 03 25 03 00 01 .5.%....gcc.%...
| 3136: 06 65 6f 70 7f 6c 79 03 25 11 00 00 05 6a 73 6f .eop.ly.%....jso
| 3152: 6e 31 03 25 14 00 e8 04 6c 6f 61 64 03 25 1c 00 n1.%....load.%..
| 3168: 00 03 6d 61 78 03 25 18 00 01 05 65 6d 6f 72 79 ..max.%....emory
| 3184: 03 25 19 00 03 04 73 79 73 35 03 25 15 00 00 04 .%....sys5.%....
| 3200: 6f 6d 69 74 03 25 1b 00 00 05 72 74 72 65 65 03 omit.%....rtree.
| 3216: 25 17 00 00 0a 74 68 72 65 61 64 73 61 66 65 03 %....threadsafe.
| 3232: 25 1e 00 00 04 76 74 61 62 03 25 0b 00 86 50 01 %....vtab.%...P.
| 3248: 08 08 08 08 08 17 8d 12 30 20 38 33 35 00 01 30 ........0 835..0
| 3264: 12 01 06 00 01 06 00 01 06 00 1f 03 00 01 03 00 ................
| 3280: 01 03 00 00 08 32 30 31 36 30 36 30 39 09 01 07 .....20160609...
| 3296: 00 01 07 00 01 07 00 00 01 34 09 01 05 00 01 05 .........4......
| 3312: 00 01 05 00 00 01 35 09 01 04 00 01 04 00 01 04 ......5.........
| 3328: 00 01 07 30 30 30 30 30 30 30 09 1c 04 00 01 04 ...0000000......
| 3344: 00 01 04 00 00 06 62 69 6e 61 72 79 3c 03 01 02 ......binary<...
| 3360: 02 00 03 01 02 02 00 03 01 02 02 00 03 01 02 02 ................
| 3376: 00 03 01 02 c2 00 03 01 02 02 00 03 01 04 82 00 ................
| 3392: 03 01 02 02 00 03 01 02 02 00 03 01 02 02 00 03 ................
| 3408: 01 02 02 00 03 01 02 02 00 00 08 63 6f 6d 70 69 ...........compi
| 3424: 6c 65 72 09 01 02 00 01 02 00 01 02 00 00 06 64 ler............d
| 3440: 62 73 74 61 74 09 07 03 00 01 03 00 01 03 00 01 bstat...........
| 3456: 04 65 62 75 67 09 04 02 00 01 02 00 01 02 00 00 .ebug...........
| 3472: 06 65 6e 60 62 6c 65 3f 07 02 00 01 02 92 e1 a4 .en`ble?........
| 3488: ff fc a2 8c 95 b2 3f 01 01 f0 f1 02 00 57 02 00 ......?......W..
| 3504: 01 02 00 01 02 00 01 02 00 01 02 00 01 02 10 01 ................
| 3520: 02 00 01 02 00 01 02 00 01 02 01 01 02 00 01 02 ................
| 3536: 00 01 02 00 00 f2 00 01 08 78 74 65 6e 73 69 6f .........xtensio
| 3552: 6e 09 1f 04 00 01 04 00 01 04 00 00 04 66 74 73 n............fts
| 3568: 34 09 0a 03 00 01 03 00 01 03 00 03 01 35 09 0d 4............5..
| 3584: 03 00 01 03 00 01 03 00 00 03 67 63 63 09 01 03 ..........gcc...
| 3600: 00 01 03 00 01 03 00 01 06 65 5f 70 6f 6c 79 09 .........e_poly.
| 3616: 10 03 00 01 03 00 01 03 00 00 b3 6a 73 6f 6e 31 ...........json1
| 3632: 09 13 03 00 01 03 00 01 03 00 00 04 6c 6f 61 64 ............load
| 3648: 09 1f 03 00 01 03 00 01 03 00 00 03 6d 61 78 09 ............max.
| 3664: 1c 02 00 01 02 00 01 02 00 01 05 65 6d 6f 72 79 ...........emory
| 3680: 09 1c 03 00 01 03 00 01 03 00 03 04 73 79 73 35 ............sys5
| 3696: 09 16 03 00 01 03 00 01 03 cc 00 06 6e 6f 63 61 ............noca
| 3712: 73 65 3c 02 01 02 02 00 03 01 02 02 00 03 01 02 se<.............
| 3728: 02 00 03 01 02 02 00 03 01 02 02 00 03 01 02 02 ................
| 3744: 00 03 01 02 02 00 03 01 02 02 00 03 01 02 02 00 ................
| 3760: 03 01 02 02 00 03 01 02 02 00 03 01 02 02 00 00 ................
| 3776: 04 6f 6d 69 74 09 1f 02 00 01 02 00 01 02 00 00 .omit...........
| 3792: 05 72 74 62 65 65 09 19 03 00 01 03 00 01 03 00 .rtbee..........
| 3808: 03 02 69 6d 3c 01 01 02 02 00 03 01 02 02 00 03 ..im<...........
| 3824: 01 02 02 00 03 01 02 02 00 03 01 02 02 00 03 01 ................
| 3840: 02 02 00 03 01 02 02 00 03 01 02 02 00 03 01 02 ................
| 3856: 02 00 03 01 02 02 00 03 01 02 01 00 03 01 02 02 ................
| 3872: 00 00 0a 74 68 72 65 61 64 73 61 66 65 09 22 02 ...threadsafe...
| 3888: 00 01 02 00 02 02 00 00 04 76 74 61 62 09 07 04 .........vtab...
| 3904: 00 01 03 00 01 04 00 00 01 78 b4 01 01 01 01 02 .........x......
| 3920: 00 01 01 01 02 00 01 01 01 02 00 01 01 01 02 00 ................
| 3936: 01 01 01 02 00 01 01 01 02 00 01 01 01 02 00 01 ................
| 3952: 01 01 02 00 01 01 01 02 00 01 01 01 02 00 01 01 ................
| 3968: 01 02 00 01 01 01 02 00 01 01 01 02 00 01 01 01 ................
| 3984: 02 01 01 01 01 02 00 01 01 01 02 00 01 01 01 02 ................
| 4000: 00 01 01 01 02 00 01 01 01 02 00 01 01 01 02 00 ................
| 4016: 01 01 01 02 00 01 01 01 02 00 01 01 01 02 00 01 ................
| 4032: 01 01 02 00 01 01 01 da 00 00 f1 01 02 00 01 01 ................
| 4048: 01 02 00 01 01 01 01 ff ff 01 01 02 00 01 01 01 ................
| 4064: 02 00 01 01 01 02 00 01 01 01 02 00 01 01 01 02 ................
| 4080: 00 01 01 01 02 00 01 01 01 02 00 01 01 01 02 00 ................
| page 6 offset 20480
| 0: 0a 00 00 00 02 0f f5 00 0f fb 0f f5 01 00 00 00 ................
| 4080: 00 00 00 00 00 05 04 08 09 01 02 04 04 08 08 09 ................
| end crash-1cc4f8a70485ce.db
}]} {}
do_execsql_test 38.1 {
UPDATE t1 SET b=a;
}
do_catchsql_test 38.1 {
SELECT b FROM t1 WHERE a MATCH 'e*e*e*e*e*e*e*e*e*e*e*e*e*e*e*e*'
} {1 {database disk image is malformed}}
finish_test
+35
View File
@@ -0,0 +1,35 @@
# 2020-05-14
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
# May you find forgiveness for yourself and forgive others.
# May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for the FTS3 module. The focus
# of this file is tables created with the "matchinfo=fts3" option.
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
# If SQLITE_ENABLE_FTS3 is not defined, omit this file.
ifcapable !fts3 { finish_test ; return }
set sqlite_fts3_enable_parentheses 1
# Crash case found by cyg0810 at gmail.com 2020-05-14. Reported to
# chromium (which is not vulnerable) who kindly referred it to us.
#
do_execsql_test 1.0 {
CREATE TABLE t_content(col0 INTEGER);
CREATE VIRTUAL TABLE t0 USING fts3(col0 INTEGER PRIMARY KEY,col1 VARCHAR(8),col2 BINARY,col3 BINARY);
INSERT INTO t0 VALUES (1, '1234','aaaa','bbbb');
SELECT hex(matchinfo(t0,'yxy')) FROM t0 WHERE t0 MATCH x'2b0a312b0a312a312a2a0b5d0a0b0b0a312a0a0b0b0a312a0b310a392a0b0a27312a2a0b5d0a312a0b310a31315d0b310a312a316d2a0b313b15bceaa50a312a0b0a27312a2a0b5d0a312a0b310a312b0b2a310a312a0b2a0b2a0b2e5d0a0bff313336e34a2a312a0b0a3c310b0a0b4b4b0b4b2a4bec40322b2a0b310a0a312a0a0a0a0a0a0a0a0a0b310a312a2a2a0b5d0a0b0b0a312a0b310a312a0b0a4e4541530b310a5df5ced70a0a0a0a0a4f520a0a0a0a0a0a0a312a0b0a4e4541520b310a5d616161610a0a0a0a4f520a0a0a0a0a0a312b0a312a312a0a0a0a0a0a0a004a0b0a310b220a0b0a310a4a22310a0b0a7e6fe0e0e030e0e0e0e0e01176e02000e0e0e0e0e01131320226310a0b0a310a4a22310a0b0a310a766f8b8b4ee0e0300ae0090909090909090909090909090909090909090909090909090909090909090947aaaa540b09090909090909090909090909090909090909090909090909090909090909fae0e0f2f22164e0e0f273e07fefefef7d6dfafafafa6d6d6d6d';
} {/000000.*0000000/}
set sqlite_fts3_enable_parentheses 0
finish_test
+20
View File
@@ -303,4 +303,24 @@ do_execsql_test 9.2 {
-4764623217061966105 8324454597464624651
}
#-------------------------------------------------------------------------
reset_db
do_execsql_test 10.0 {
CREATE VIRTUAL TABLE f USING fts3(a,b);
CREATE TABLE 'f_stat'(id INTEGER PRIMARY KEY, value BLOB);
INSERT INTO f_stat VALUES (1,x'3b3b3b3b3b3b3b28ffffffffffffffffff1807f9073481f1d43bc93b3b3b3b3b3b3b3b3b3b18073b3b3b3b3b3b3b9b003b');
} {}
do_catchsql_test 10.1 {
INSERT INTO f(f) VALUES ('merge=69,59');
} {1 {database disk image is malformed}}
#-------------------------------------------------------------------------
do_execsql_test 11.0 {
CREATE VIRTUAL TABLE xyz USING fts3();
}
do_execsql_test 11.1 {
SELECT * FROM xyz WHERE xyz MATCH 'a NEAR/4294836224 a';
}
finish_test
-13
View File
@@ -588,18 +588,5 @@ do_execsql_test 5.1 {
{[a70] [a71] [a72]}
}
#-------------------------------------------------------------------------
# Request a snippet from a query with more than 64 phrases.
#
reset_db
do_execsql_test 6.0 {
CREATE VIRTUAL TABLE f USING fts3(b);
INSERT INTO f VALUES ( x'746e6e6d64612e082a011065616e656d655a616c702a2f65732e0f42014001380230018218');
}
do_execsql_test 6.1 {
SELECT length(snippet(f))>0 FROM f WHERE b MATCH x'1065616e656d655a616c702a2f65732e0f42014001380230018218021001081e0a3d746e6e6d64612e082a010f42014001380230018218021001081e0a3d746e6e6d64612e082a011065616e656d655a616c702a2f65732e0f42014001380230018218021001081e0a3d746e6e6d64612e082a011065616e656d655a616c702a2f65732e0f42014001380230018218021001081e0a3d746e6e6d64612e082a011065616e656d655a616c702a2f0a3d746e6e6d64612e082a011065616e656d655a616c702a2f65732e0f42014001018218021001081e0a3d746e6e6d64612e082a011065616e656d655a616c702a018218021001081e0a3d746e6e6d64612e082a011065616e656d655a616c2a2f65732e0f42014001380230018218021001081e0a3d746e6e6d64612e082a011065616e656d655a616c702a2f65732e0f42014001380230018218021001081e0a3d746e6e6d64612e082a011065616e656d655a616c702a2f65732e0f42014001380230018218021001081e0a3d746e6e6d64612e082a011065616e656d655a616c702a2f65732e0f42014001380230018218021001081e0a3d746e6e6d64612e0f42';
} {1}
set sqlite_fts3_enable_parentheses 0
finish_test
+60
View File
@@ -0,0 +1,60 @@
# 2020-05-14
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
# May you find forgiveness for yourself and forgive others.
# May you share freely, never taking more than you give.
#
#*************************************************************************
#
# The tests in this file test the FTS3 auxillary functions offsets(),
# snippet() and matchinfo() work. At time of writing, running this file
# provides full coverage of fts3_snippet.c.
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix fts3snippet
# If SQLITE_ENABLE_FTS3 is not defined, omit this file.
ifcapable !fts3 { finish_test ; return }
source $testdir/fts3_common.tcl
set sqlite_fts3_enable_parentheses 1
#-------------------------------------------------------------------------
# Request a snippet from a query with more than 64 phrases.
#
reset_db
do_execsql_test 1.0 {
CREATE VIRTUAL TABLE f USING fts3(b);
INSERT INTO f VALUES ( x'746e6e6d64612e082a011065616e656d655a616c702a2f65732e0f42014001380230018218');
}
do_execsql_test 1.1 {
SELECT length(snippet(f))>0 FROM f WHERE b MATCH x'1065616e656d655a616c702a2f65732e0f42014001380230018218021001081e0a3d746e6e6d64612e082a010f42014001380230018218021001081e0a3d746e6e6d64612e082a011065616e656d655a616c702a2f65732e0f42014001380230018218021001081e0a3d746e6e6d64612e082a011065616e656d655a616c702a2f65732e0f42014001380230018218021001081e0a3d746e6e6d64612e082a011065616e656d655a616c702a2f0a3d746e6e6d64612e082a011065616e656d655a616c702a2f65732e0f42014001018218021001081e0a3d746e6e6d64612e082a011065616e656d655a616c702a018218021001081e0a3d746e6e6d64612e082a011065616e656d655a616c2a2f65732e0f42014001380230018218021001081e0a3d746e6e6d64612e082a011065616e656d655a616c702a2f65732e0f42014001380230018218021001081e0a3d746e6e6d64612e082a011065616e656d655a616c702a2f65732e0f42014001380230018218021001081e0a3d746e6e6d64612e082a011065616e656d655a616c702a2f65732e0f42014001380230018218021001081e0a3d746e6e6d64612e0f42';
} {1}
reset_db
do_execsql_test 2.0 {
CREATE VIRTUAL TABLE t0 USING fts3(col0 INTEGER PRIMARY KEY,col1 VARCHAR(8),col2 BINARY,col3 BINARY);
INSERT INTO t0 VALUES (1, '1234','aaaa','bbbb');
SELECT snippet(t0) FROM t0 WHERE t0 MATCH x'0a4d4d4d4d320a4f52d70a310a310a4e4541520a0a31f6ce0a4f520a0a310a310a310a4f520a75fc2a242424' ;
} {<b>1</b>}
reset_db
do_execsql_test 2.1 {
CREATE VIRTUAL TABLE t0 USING fts3(
col0 INTEGER PRIMARY KEY,col1 VARCHAR(8),col2 BINARY,col3 BINARY
);
INSERT INTO t0 VALUES ('one', '1234','aaaa','bbbb');
}
do_execsql_test 2.2 {
SELECT snippet(t0) FROM t0 WHERE t0 MATCH
'(def AND (one NEAR abc)) OR one'
} {<b>one</b>}
set sqlite_fts3_enable_parentheses 0
finish_test
+2 -2
View File
@@ -234,13 +234,13 @@ if {$tcl_platform(byteOrder)=="littleEndian"} {
} else {
set res {X'0000000200000000000000000000000E0000000E00000001000000010000000100000001'}
}
do_execsql_test fts4aa-6.10 {
do_catchsql_test fts4aa-6.10 {
CREATE VIRTUAL TABLE f USING fts4();
INSERT INTO f_segdir VALUES (77,91,0,0,'255 77',x'0001308000004d5c4ddddddd4d4d7b4d4d4d614d8019ff4d05000001204d4d2e4d6e4d4d4d4b4d6c4d004d4d4d4d4d4d3d000000004d5d4d4d645d4d004d4d4d4d4d4d4d4d4d454d6910004d05ffff054d646c4d004d5d4d4d4d4d3d000000004d4d4d4d4d4d4d4d4d4d4d69624d4d4d04004d4d4d4d4d604d4ce1404d554d45');
INSERT INTO f_segdir VALUES (77,108,0,0,'255 77',x'0001310000fa64004d4d4d3c5d4d654d4d4d614d8000ff4d05000001204d4d2e4d6e4d4d4dff4d4d4d4d4d4d00104d4d4d4d000000004d4d4d0400311d4d4d4d4d4d4d4d4d4d684d6910004d05ffff054d4d6c4d004d4d4d4d4d4d3d000000004d4d4d4d644d4d4d4d4d4d69624d4d4d03ed4d4d4d4d4d604d4ce1404d550080');
INSERT INTO f_stat VALUES (0,x'80808080100000000064004d4d4d3c4d4d654d4d4d614d8000ff4df6ff1a00204d4d2e4d6e4d4d4d104d4d4d4d4d4d00104d4d4d4d4d4d69574d4d4d000031044d4d4d3e4d4d4c4d05004d6910');
SELECT quote(matchinfo(f,'pnax')) from f where f match '0 1';
} $res
} {1 {database disk image is malformed}}
# 2019-11-18 Detect infinite loop in fts3SelectLeaf()
db close
+25 -9
View File
@@ -94,11 +94,9 @@
# include <unistd.h>
#endif
#ifdef SQLITE_OSS_FUZZ
# include <stddef.h>
# if !defined(_MSC_VER)
# include <stdint.h>
# endif
#include <stddef.h>
#if !defined(_MSC_VER)
# include <stdint.h>
#endif
#if defined(_MSC_VER)
@@ -896,6 +894,7 @@ int runCombinedDbSqlInput(const uint8_t *aData, size_t nByte){
if( depthLimit>0 ){
sqlite3_limit(cx.db, SQLITE_LIMIT_EXPR_DEPTH, depthLimit);
}
sqlite3_limit(cx.db, SQLITE_LIMIT_LIKE_PATTERN_LENGTH, 100);
sqlite3_hard_heap_limit64(heapLimit);
if( nDb>=20 && aDb[18]==2 && aDb[19]==2 ){
@@ -1425,6 +1424,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"
" --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"
" -v|--verbose Increased output. Repeat for more output.\n"
@@ -1451,6 +1451,7 @@ int main(int argc, char **argv){
int rebuildFlag = 0; /* --rebuild */
int vdbeLimitFlag = 0; /* --limit-vdbe */
int infoFlag = 0; /* --info */
int bSpinner = 0; /* True for --spinner */
int timeoutTest = 0; /* undocumented --timeout-test flag */
int runFlags = 0; /* Flags sent to runSql() */
char *zMsg = 0; /* Add this message */
@@ -1577,6 +1578,9 @@ int main(int argc, char **argv){
if( strcmp(z,"result-trace")==0 ){
runFlags |= SQL_OUTPUT;
}else
if( strcmp(z,"spinner")==0 ){
bSpinner = 1;
}else
if( strcmp(z,"sqlid")==0 ){
if( i>=argc-1 ) fatalError("missing arguments on %s", argv[i]);
onlySqlid = integerValue(argv[++i]);
@@ -1872,11 +1876,16 @@ int main(int argc, char **argv){
/* Run a test using each SQL script against each database.
*/
if( !verboseFlag && !quietFlag ) printf("%s:", zDbName);
if( !verboseFlag && !quietFlag && !bSpinner ) printf("%s:", zDbName);
for(pSql=g.pFirstSql; pSql; pSql=pSql->pNext){
if( isDbSql(pSql->a, pSql->sz) ){
sqlite3_snprintf(sizeof(g.zTestName), g.zTestName, "sqlid=%d",pSql->id);
if( verboseFlag ){
if( bSpinner ){
int nTotal =g.nSql;
int idx = pSql->seq;
printf("\r%s: %d/%d ", zDbName, idx, nTotal);
fflush(stdout);
}else if( verboseFlag ){
printf("%s\n", g.zTestName);
fflush(stdout);
}else if( !quietFlag ){
@@ -1900,7 +1909,12 @@ int main(int argc, char **argv){
const char *zVfs = "inmem";
sqlite3_snprintf(sizeof(g.zTestName), g.zTestName, "sqlid=%d,dbid=%d",
pSql->id, pDb->id);
if( verboseFlag ){
if( bSpinner ){
int nTotal = g.nDb*g.nSql;
int idx = pSql->seq*g.nDb + pDb->id - 1;
printf("\r%s: %d/%d ", zDbName, idx, nTotal);
fflush(stdout);
}else if( verboseFlag ){
printf("%s\n", g.zTestName);
fflush(stdout);
}else if( !quietFlag ){
@@ -1979,7 +1993,9 @@ int main(int argc, char **argv){
}
}
}
if( !quietFlag && !verboseFlag ){
if( bSpinner ){
printf("\n");
}else if( !quietFlag && !verboseFlag ){
printf(" 100%% - %d tests\n", g.nDb*g.nSql);
}

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