Compare commits

...

72 Commits

Author SHA1 Message Date
dan d49a37a8ef Fix an RBU problem with restarting an update after the *-oal file is already larger than 4GiB.
FossilOrigin-Name: 56869f54f31186231a4467f10208bcc08d9edae23c6e21831d6d3dff47da51de
2021-08-11 18:56:49 +00:00
dan 86732babe3 If the special "sqlite_rbu_replace_hack" table is present in an RBU database, use REPLACE instead of INSERT when writing index entries to imposter tables.
FossilOrigin-Name: 4b73e151cdb4b89bdd2f1bab5c0378500234ce6c479cc1d8cd4e006be79d1162
2021-08-11 18:44:50 +00:00
drh 228a52d973 Version 3.30.0
FossilOrigin-Name: c20a35336432025445f9f7e289d0cc3e4003fb17f45a4ce74c6269c407c6e09f
2019-10-04 15:03:17 +00:00
dan 6117a17323 Avoid running a couple of tests in affinity2.test as part of the valgrind permutations, as the way floating point computations are simulated by valgrind causes them to fail.
FossilOrigin-Name: 7f9a4b6015ac332a04d3e394a6b3210fc95253d8786a261178a5639cb8d9d987
2019-10-03 16:02:22 +00:00
drh d1c472dab6 Increase the precision of floating point value display in VDBE debugging
output.  No changes to normally deployed code.

FossilOrigin-Name: a561a656ff50efc0103da3988626cea3ef05757403b83960f2aa6c0a48c2765e
2019-10-03 14:51:59 +00:00
dan b008e4d744 Fix some test script issues that come up with SQLITE_OMIT_VIRTUALTABLE builds.
FossilOrigin-Name: 3934d2d08ee14d644dc01f967c10f219b76b172c963c90a7a8141f2b08a7d5bf
2019-10-03 14:36:36 +00:00
dan 367b8d7aa7 Fix issues with command line invocation of wapptest.tcl.
FossilOrigin-Name: 9e0d5d2640a92070967bc9fdf5c5b1653e41b9c04e04dcb70f18ead10f053aef
2019-10-03 13:44:08 +00:00
drh 9a50f4c72a Update error detection logic in releasetest.tcl to account for new
output formats in USAN.

FossilOrigin-Name: 3f36b988360204628d5ad1df2db34818b9a2d6ba989018d4c17757229f4b0f65
2019-10-02 19:44:42 +00:00
dan f0578823dd Update corruptM.test to account for the fact that the database schema may be loaded from within the "sqlite3" command for some test permutations.
FossilOrigin-Name: cb9470fc064aad72a4e42c6a021410401b3b1a32446ae8b9cd9c759f0a2a01ef
2019-10-02 19:43:38 +00:00
dan 23d3f5d661 Fix a long-standing problem in fts4 incrmental merge.
FossilOrigin-Name: 67da31e24ebb49c4cac81c9e7cfca37ca422555fd0fdb01d8f180890783c84ff
2019-10-02 19:33:34 +00:00
drh e2b7a7693e Disable sqlite3_drop_module() tests when virtual tables are omitted from
the build.

FossilOrigin-Name: 9f4035f91a9f914797c67afbf19139b2cd25aea48595f7254fe5d18cd693d972
2019-10-02 00:25:08 +00:00
drh cfee884e73 Remove references to test scripts analyzeA.test and analyzeB.test from
permutations.test, since those test modules no longer exist.

FossilOrigin-Name: 2394879698107479270c9d899c704de3756ceae177a338b3c37844e2a31aa6dd
2019-10-01 21:31:57 +00:00
drh 5e81e9fdae The nodeReaderInit() function in FTS3 may not assume that the node is
non-empty.

FossilOrigin-Name: 361eb2f682a303bba72b39d322d9de630494ca044fe0508dcb23b6130d312d85
2019-09-30 19:13:31 +00:00
drh 905d4729d3 Add missing comment to constant definitions.
FossilOrigin-Name: 661a3789eb329a2487855e49c31067a9dde4c91c1a3a65b65375d079f906b1da
2019-09-28 18:28:19 +00:00
drh 018dbb17a8 Improvements to a comment. No code changes.
FossilOrigin-Name: 1a3671c7003bfff817a8239424c2f945d9dfced97daadb5a5acab203b9bda69b
2019-09-28 16:14:55 +00:00
drh 5c0666d9e3 In FTS3/4, the poslist end marker must be larger than any other possible
poslist value, even on a corrupt poslist.

FossilOrigin-Name: 752679aea5a6bbde24cbf39e2fa018f7dd1c226d463ca4bd74125303b2255170
2019-09-28 11:19:56 +00:00
drh 5f419b3bba Update requirement marks due to changes in documentation wording.
FossilOrigin-Name: 326cdc16f4db23c1d17596e4ef8d9d7abc672d48665950029ba53fd40c1b2d99
2019-09-27 17:36:37 +00:00
drh e4079e1fc5 Allow compile-time options -DHAVE_GETHOSTUUID=0 and -DHAVE_GETHOSTUUID=1.
FossilOrigin-Name: 3bcb9cc104e0265a600b03415ad955187fc6445ea8e46dc656412cba5bc1d621
2019-09-27 16:33:27 +00:00
drh ebc6408484 Alternative implementation of the previous check-in which is testable.
FossilOrigin-Name: 102ef64462cf0d78395ccc7ebb8e3bf6b7647c06b7657a037e051697bc08d6b7
2019-09-27 15:15:38 +00:00
drh 818a3b5486 Fix sqlite3ExprCompare() so that it ignores differences in the Expr.iTable
field for IN operators, as otherwise it can lead to false negatives, which
is usually harmless, but can cause problems for an assert() in the window
function logic.

FossilOrigin-Name: 6a204b192a6c6f21988cab217366f21b14c672b81ceadc43675761a6d8c4484f
2019-09-27 15:01:02 +00:00
dan 7971b7fe92 More minor test file fixes.
FossilOrigin-Name: 352878fe1cbcf7b6803624544bba5a95565d1638d4dd09e91764ddad17889301
2019-09-26 20:57:53 +00:00
drh 91f34eab2d Allow DROP TABLE to work on tables name "sqlite_parameters" just as it
does with tables named "sqlite_stat%".  Fix for the ".parameter clear"
command in the shell.

FossilOrigin-Name: e768179baacb2423205a774cc8149fe58ed86a9320102aff4844b1d8933aa1db
2019-09-26 20:05:16 +00:00
dan 9d30c8ff8f Minor fix for test file indexexpr1.test.
FossilOrigin-Name: 0ceab26f15c4c7039647cbccf8939dd5c36a60b70ffeefcd3b415c8d4d8351cd
2019-09-26 19:53:26 +00:00
drh ec39707fe6 New dbsqlfuzz cases added to test/fuzzdata8.db.
FossilOrigin-Name: 49073b7003330027303c4c776e9f85112f8b99b89f848fec3f953eba501d7505
2019-09-26 16:57:42 +00:00
drh d79cd92b23 Test for an OOM condition in resolveAlias().
FossilOrigin-Name: 322eca7f6ad2234059669015aabb773a790e8bc3da95431c9c851ff5342c969b
2019-09-26 16:08:35 +00:00
dan a51ddb1ed7 Fix a window-functions problem that could occur if an ORDER BY clause contains an alias for a window-function that is not a top-level expression.
FossilOrigin-Name: 1cc6cf6407c6e25aeafeca379a93d0ad2614839c07fb3644e46926fce5f1cfab
2019-09-26 15:53:37 +00:00
drh b19131a8c6 Add a missing VdbeCoverage() macro.
FossilOrigin-Name: 36d35dbd5a80dc4a149ed7409cc4b43712622fc4c6a8915b4fbb62fd1d6b7763
2019-09-25 18:44:49 +00:00
drh 2829df082c Remove an unused variable.
FossilOrigin-Name: a19884455b9bafcdc769362d61cfd02df1b5643263e004cb533698bbcfca752b
2019-09-25 17:47:41 +00:00
dan e7579a53fb Further simplifications to window-function code.
FossilOrigin-Name: 5fe15c1d8383989257e11d1806e6b035acacd1b504ae385ba58d20db10f26eee
2019-09-25 16:41:44 +00:00
drh edf8a7bf57 In the previous check-in, the variable should be openMode, not openFlags.
FossilOrigin-Name: 77b0db22d6c7a031f332bfcf1c8fcd94e464de9f2396f0327ee761a30ebc8b60
2019-09-25 11:49:36 +00:00
drh 1116b1785c In the unix VFS layer, do not attempt to chown() the journal to be the same
as the database if running in 8+3 filename mode.  Also, update the comments
on the chown() attempt to be more precise.

FossilOrigin-Name: ab853724a7e01ca32167d294c3c80d6632e805bdf39b6d56db82226a00ad72dc
2019-09-25 10:36:31 +00:00
drh c5b35ae567 Simplifications to the window-function code.
FossilOrigin-Name: 489a1eb3aa2f1225b97b50a5f8688cf1a4ab0371973da1badc29616d70386c03
2019-09-25 02:07:50 +00:00
dan 37d296a717 Bug fixes for window frames of the form (... RANGE BETWEEN b PRECEDING AND a PRECEDING) or (... RANGE a FOLLOWING AND b FOLLOWING) where (a > b).
FossilOrigin-Name: 040e196a8be3ca41b9365310ab88c2a3cc84b918a6511c77a6d95d4b4e0da3ed
2019-09-24 20:20:05 +00:00
drh 5776ee5cf5 Omit the sqlite3IntTokens array constant for a code simplification.
FossilOrigin-Name: f907395ef5a2dc1d084b6a286af00de4c742cf12d4f347c21e1b757786508f57
2019-09-23 12:38:10 +00:00
drh 7ca1347f59 When a scalar subquery has a pre-existing "LIMIT X" then change it to
"LIMIT X<>0" rather than just "LIMIT 1" so that if X is 0 the limit
will still be zero.  Ticket [99cd4807dc03f178]

FossilOrigin-Name: 82e5dcf5c1d500ed82f398b38fdae0f30033804e897fbab3c10f1e15e2abedef
2019-09-23 11:55:22 +00:00
drh b7fc7c8556 Fix a harmless unused variable warning in the test logic.
FossilOrigin-Name: d7673a445f4cde8f71153ce81efdc34fbed8b8625714d54afae1a83d548671ff
2019-09-21 18:49:12 +00:00
drh e39f388eb1 Fix harmless compiler warnings.
FossilOrigin-Name: 8ea1dc727d391b15d0c4fa858ff68d5b8a63dde46408f24027dac8d28f044cbd
2019-09-21 17:31:03 +00:00
dan 8c9bcb2328 Allow SQLite to omit redundant ORDER BY sorts in the case where a SELECT statement has GROUP BY and ORDER BY clauses that use the same expressions, even when the ORDER BY expressions are marked "DESC".
FossilOrigin-Name: 20f7951bb238ddc0b8932a55145df426b6fdf7b8631e069345902c853c90f191
2019-09-21 15:44:12 +00:00
drh e47d5ca737 Add --multithread, --serialized, and --singlethread options to the
speed-check.sh test script.

FossilOrigin-Name: c17078af6046ba3cb0d7819c915a800c851d7368e13d149140db2a124df32bab
2019-09-21 13:34:59 +00:00
dan af9b58b335 Simplify the fix in the previous commit.
FossilOrigin-Name: 5ef64b0f55d952c7b0016055eaf6bbc1b5b7afc09a62ee8e5e694ffa9863ac7c
2019-09-20 21:12:40 +00:00
dan ed09dddece Fix a problem with queries containing a min() or max() function for which the FILTER clause excludes all rows.
FossilOrigin-Name: b1d7e104e034655fe41bc55c562d91e8074a2973d538b8b29301458db45afc57
2019-09-20 20:52:16 +00:00
dan 14e3e22773 Fix an assert() in fts3 that could fail when accessing a corrupt database.
FossilOrigin-Name: 601ce9532d34f97a5faa170b6d8a272e5c54f2eabff84660201a1840e0fd9929
2019-09-19 13:51:52 +00:00
drh 6d2566dfc2 Always clear the temporary register cache after coding a subroutine.
FossilOrigin-Name: b6f2a7f9cdb547c925f08306df82519e41a7a0dd2cabd9861a48917bb6eef845
2019-09-18 20:34:54 +00:00
dan 572b0dddee Add extra tests for the handling of corrupt records in fts3.
FossilOrigin-Name: 40e29a47d1266c16a4992e43579a51addcc632503099c4cd128f77dd4e67da3c
2019-09-18 17:22:00 +00:00
drh aa16c603ab Fix another potential "jump depends on uninitialized value" warning.
FossilOrigin-Name: 633b214e9b9d99788ed72ab4823a69a43c7c40ed07fb76c7d56c50453c0e58ab
2019-09-18 12:49:34 +00:00
dan 4b48c72721 Fix a "jump depends on unititialized value" valgrind error in fts5 triggered by corrupt database records.
FossilOrigin-Name: 6b6751cd90601a1e2744a7d233c973291ecb783801b9327c3b99734dd22bcd27
2019-09-18 11:46:34 +00:00
drh 9d70284022 Fix an OOB read in the INSTR() function introduced yesterday by check-in
[3fb40f518086c1e8] and detected by OSSFuzz.  The test case is in TH3.

FossilOrigin-Name: d49047c1b59bbfd05204af9973cdb0fab51b4d2661b550aec10d917fff94dc9b
2019-09-18 11:16:46 +00:00
drh ec722c1088 Do not change the OP_String8 opcode into OP_String until *after* any necessary
encoding conversions are accomplished.  Otherwise, a rerun of the prepared
statement after an OOM can result in errors.  Test case in TH3.

FossilOrigin-Name: 8efd62594eae725decb719aa7777c020f982b7cdc2c92bab3b91bf349a5bc298
2019-09-17 21:28:54 +00:00
drh e691dcb506 Test cases for ticket [587791f92620090e]
FossilOrigin-Name: ca0e3a83a1c015b346a791e6de03904d17a769c52dad0e3d71316c6e2e3f43c7
2019-09-17 13:30:30 +00:00
drh 97b0250599 Fix the instr() SQL function so that it makes a copy of its argument
before changing the datatype, since the datatype affects processing.
Also fix the sqlite3_value_text() routine so that it always works even
for values obtained form sqlite3_value_dup().  Ticket [587791f92620090e]

FossilOrigin-Name: 3fb40f518086c1e8d11eb1f4134e965450dbedfa4277bce39ef1e969fc747d38
2019-09-17 03:16:29 +00:00
drh 70738712de Improved type information display when tracing VDBE execution.
FossilOrigin-Name: ee83d8e30d6f9ca8f1cce653ee094ff151f633f4b6a21dd814ab07e8cfb901eb
2019-09-16 20:16:17 +00:00
drh 91f473b5cc Do not attempt the LIKE optimization for non-text columns and a pattern
prefix of "-".  Ticket [0f0428096f17252a]

FossilOrigin-Name: 6fe0367f9a337b7c62886b7771f3ce0642faa13f4e4f3d9a0c848abbab514cd0
2019-09-16 18:19:41 +00:00
drh 130dbc3d96 Add recent interesting cases from dbsqlfuzz.
FossilOrigin-Name: f06ef3d75d85545dd58c6dda10f7ad04fafbb7ae8706b3821be21f86a94795f1
2019-09-16 15:15:38 +00:00
drh 2ad35d980b Documentation updates for the SQLITE_DIRECTONLY flag.
FossilOrigin-Name: 5beb6dc9bc2d3d0003e33488df9c01aaf28c41c30fd9ca35543cbe3ec5a8d9ce
2019-09-16 14:42:07 +00:00
dan b42eb3571c Fix a problem with processing CTEs that use a WINDOW clause.
FossilOrigin-Name: ca564d4b5b19fe56842a04f31bb61352e6ae9d72a7e7634eb27ebcf5f670545a
2019-09-16 05:34:08 +00:00
dan 8cce6b8310 Add the --no-rowids option to the ".recover" command.
FossilOrigin-Name: 01d71b947a7422081d5c7d6ac2c91b9c936dc41926ab58c92f4a088a64e8c051
2019-09-14 16:44:51 +00:00
drh d44c617ad4 Extra comments on fields of the Window object.
FossilOrigin-Name: 3dbed162518a73213bbfb137c763064518fdc2daeae3952cfab39ce0e6813d3f
2019-09-14 16:21:02 +00:00
drh fab5b07395 Fix the windows inverse function on the JSON aggregates.
FossilOrigin-Name: f464d847af490dd3ec45565dcc4c2e6ff4ed1ebb65036f30ca0b3ce2e73080e6
2019-09-14 00:21:34 +00:00
dan 51a75aaa76 Fix a problem with using json1 window functions with an EXCLUDE clause.
FossilOrigin-Name: 4a1978814da41608a16f6953bd575c97d587a34bd80b7ac0e619d62bfdc903d2
2019-09-13 20:42:46 +00:00
drh e087a7c35b Fix the windowB test module so that it works even if SQLite is built without
JSON support.

FossilOrigin-Name: 807975c76b36347f02aa0ce9661d608adbffe1f7e77c15f8da677e47e1187153
2019-09-13 18:59:04 +00:00
dan cd9cb85a41 Add the SQLITE_SUBTYPE flag, which may be passed to sqlite3_create_window_function() to indicate that the window function uses sqlite3_value_subtype() to check the sub-type of its arguments.
FossilOrigin-Name: ba2ebc3a348decc5cedaf14960e30e7ae26a26824cfa198727f2499162142ef3
2019-09-13 18:27:17 +00:00
drh 477f1f12e2 Fix a typo in the carray extension header comment - the comment that serves
as the documentation to this extension.

FossilOrigin-Name: 658a42d3633b31fda260f2c5a1a2c7dd8eb4eb0114d322369017c56faf5ecd42
2019-09-13 17:30:24 +00:00
dan 01a3b6b1b2 Change the meaning of the SQLITE_SUBTYPE flag so that it indicates that the user-defined function cares about the subtypes of its arguments.
FossilOrigin-Name: af1bc20f502816db460d2b2d353f715da5cf660e59095de5214c829c1cb20981
2019-09-13 17:05:48 +00:00
dan 945a3527d5 Merge latest trunk changes with this branch.
FossilOrigin-Name: 14ef7543465dd14d8fa141fcceb1950b5c2d265a3e862323969d747b39c0cd8c
2019-09-13 16:19:53 +00:00
drh 3f3f2c7357 Ensure that the idxStr for FTS5 is always zero-terminated.
Fix for check-in [e6db945454a0dae2]

FossilOrigin-Name: 090cd07d37904da4610d6a6787a3cc825c9a8bdcc5f051267d4608bba9b49d03
2019-09-13 13:23:13 +00:00
drh fbb9a5b1e3 Fix harmless compiler warnings.
FossilOrigin-Name: a8927d14f88c44828e794787bab080455ab62705c93f65ce7d8db83478aa5a8e
2019-09-13 12:24:58 +00:00
dan 685b2ee0c3 Allow fts5 to filter on multiple MATCH clauses in a single scan.
FossilOrigin-Name: 9d418a7a491761eeb38a70898677a493e2631e5d62e75ee88431f52d3dfd2344
2019-09-12 19:38:40 +00:00
mistachkin acf6e08d20 Fix typo for one instance of line number handling in the Lemon tool.
FossilOrigin-Name: 980be1730dc1239c63a107923bf2e32b4ec7d4bc31b9190e711cc35f18cc2bb4
2019-09-11 15:25:26 +00:00
drh c204d81a6c Enhance treeview to show SOFT-COLLATE for TK_COLLATE operators that omit
the EP_Collate flag.

FossilOrigin-Name: a97804620a27acc30bebd2aaa04e38f2f36de48b0931038ca8bdc9cb0c36b8f4
2019-09-10 17:51:27 +00:00
dan fa50834914 Ensure the columns of views and sub-queries maintain their implicit collation sequences when the "push-down" optimization is applied. Fix for [18458b1a].
FossilOrigin-Name: 36997c4ade2ef3a274cd1ac52b44118fb3a05325adb650b7b338ecb43d060575
2019-09-10 15:33:52 +00:00
dan d5deb6b3c4 Ensure the columns of views and sub-selects in the FROM clause of a select are always assigned implicit collation sequences, just as table columns are. Fix for [a7debbe0].
FossilOrigin-Name: b9ec72203c19c2b95e648ac1dfad74eec98d4ff82581cdc10dc4221ba551728f
2019-09-09 20:17:24 +00:00
dan e2ba6df9f0 Add the SQLITE_SUBTYPE flag, which can be passed to sqlite3_create_function() and similar to indicate to the core that a user function is likely to use sqlite3_result_subtype().
FossilOrigin-Name: 6aa438ce41d460a6782ae63503128b9140c28ff59c2b2eed48b004acf83e0560
2019-09-07 18:20:43 +00:00
70 changed files with 2477 additions and 524 deletions
+22 -18
View File
@@ -308,6 +308,18 @@
SQLITE_EXTENSION_INIT1
#endif
/*
** The following are copied from sqliteInt.h.
**
** Constants for the largest and smallest possible 64-bit signed integers.
** These macros are designed to work correctly on both 32-bit and 64-bit
** compilers.
*/
#ifndef SQLITE_AMALGAMATION
# define LARGEST_INT64 (0xffffffff|(((sqlite3_int64)0x7fffffff)<<32))
# define SMALLEST_INT64 (((sqlite3_int64)-1) - LARGEST_INT64)
#endif
static int fts3EvalNext(Fts3Cursor *pCsr);
static int fts3EvalStart(Fts3Cursor *pCsr);
static int fts3TermSegReaderCursor(
@@ -2086,10 +2098,11 @@ static void fts3ColumnlistCopy(char **pp, char **ppPoslist){
}
/*
** Value used to signify the end of an position-list. This is safe because
** it is not possible to have a document with 2^31 terms.
** Value used to signify the end of an position-list. This must be
** as large or larger than any value that might appear on the
** position-list, even a position list that has been corrupted.
*/
#define POSITION_LIST_END 0x7fffffff
#define POSITION_LIST_END LARGEST_INT64
/*
** This function is used to help parse position-lists. When this function is
@@ -2165,14 +2178,14 @@ static int fts3PoslistMerge(
fts3GetVarint32(&p1[1], &iCol1);
if( iCol1==0 ) return FTS_CORRUPT_VTAB;
}
else if( *p1==POS_END ) iCol1 = POSITION_LIST_END;
else if( *p1==POS_END ) iCol1 = 0x7fffffff;
else iCol1 = 0;
if( *p2==POS_COLUMN ){
fts3GetVarint32(&p2[1], &iCol2);
if( iCol2==0 ) return FTS_CORRUPT_VTAB;
}
else if( *p2==POS_END ) iCol2 = POSITION_LIST_END;
else if( *p2==POS_END ) iCol2 = 0x7fffffff;
else iCol2 = 0;
if( iCol1==iCol2 ){
@@ -2474,7 +2487,8 @@ static void fts3PutDeltaVarint3(
iWrite = *piPrev - iVal;
}
assert( *pbFirst || *piPrev==0 );
assert( *pbFirst==0 || iWrite>0 );
assert_fts3_nc( *pbFirst==0 || iWrite>0 );
assert( *pbFirst==0 || iWrite>=0 );
*pp += sqlite3Fts3PutVarint(*pp, iWrite);
*piPrev = iVal;
*pbFirst = 1;
@@ -2580,6 +2594,8 @@ static int fts3DoclistOrMerge(
fts3PoslistCopy(&p, &p2);
fts3GetDeltaVarint3(&p2, pEnd2, bDescDoclist, &i2);
}
assert( (p-aOut)<=((p1?(p1-a1):n1)+(p2?(p2-a2):n2)+FTS3_VARINT_MAX-1) );
}
if( rc!=SQLITE_OK ){
@@ -3179,18 +3195,6 @@ static int fts3NextMethod(sqlite3_vtab_cursor *pCursor){
return rc;
}
/*
** The following are copied from sqliteInt.h.
**
** Constants for the largest and smallest possible 64-bit signed integers.
** These macros are designed to work correctly on both 32-bit and 64-bit
** compilers.
*/
#ifndef SQLITE_AMALGAMATION
# define LARGEST_INT64 (0xffffffff|(((sqlite3_int64)0x7fffffff)<<32))
# define SMALLEST_INT64 (((sqlite3_int64)-1) - LARGEST_INT64)
#endif
/*
** If the numeric type of argument pVal is "integer", then return it
** converted to a 64-bit signed integer. Otherwise, return a copy of
+4 -4
View File
@@ -3797,14 +3797,14 @@ static int nodeReaderInit(NodeReader *p, const char *aNode, int nNode){
p->nNode = nNode;
/* Figure out if this is a leaf or an internal node. */
if( p->aNode[0] ){
if( aNode && aNode[0] ){
/* An internal node. */
p->iOff = 1 + sqlite3Fts3GetVarint(&p->aNode[1], &p->iChild);
}else{
p->iOff = 1;
}
return nodeReaderNext(p);
return aNode ? nodeReaderNext(p) : SQLITE_OK;
}
/*
@@ -4296,8 +4296,8 @@ static int fts3IncrmergeLoad(
NodeReader reader;
pNode = &pWriter->aNodeWriter[i];
rc = nodeReaderInit(&reader, pNode->block.a, pNode->block.n);
if( reader.aNode ){
if( pNode->block.a){
rc = nodeReaderInit(&reader, pNode->block.a, pNode->block.n);
while( reader.aNode && rc==SQLITE_OK ) rc = nodeReaderNext(&reader);
blobGrowBuffer(&pNode->key, reader.term.n, &rc);
if( rc==SQLITE_OK ){
+1
View File
@@ -695,6 +695,7 @@ int sqlite3Fts5ExprEof(Fts5Expr*);
i64 sqlite3Fts5ExprRowid(Fts5Expr*);
void sqlite3Fts5ExprFree(Fts5Expr*);
int sqlite3Fts5ExprAnd(Fts5Expr **pp1, Fts5Expr *p2);
/* Called during startup to register a UDF with SQLite */
int sqlite3Fts5ExprInit(Fts5Global*, sqlite3*);
+1 -1
View File
@@ -683,7 +683,7 @@ int sqlite3Fts5ConfigDeclareVtab(Fts5Config *pConfig){
rc = sqlite3_declare_vtab(pConfig->db, zSql);
sqlite3_free(zSql);
}
return rc;
}
+36
View File
@@ -309,6 +309,42 @@ void sqlite3Fts5ExprFree(Fts5Expr *p){
}
}
int sqlite3Fts5ExprAnd(Fts5Expr **pp1, Fts5Expr *p2){
Fts5Parse sParse;
memset(&sParse, 0, sizeof(sParse));
if( *pp1 ){
Fts5Expr *p1 = *pp1;
int nPhrase = p1->nPhrase + p2->nPhrase;
p1->pRoot = sqlite3Fts5ParseNode(&sParse, FTS5_AND, p1->pRoot, p2->pRoot,0);
p2->pRoot = 0;
if( sParse.rc==SQLITE_OK ){
Fts5ExprPhrase **ap = (Fts5ExprPhrase**)sqlite3_realloc(
p1->apExprPhrase, nPhrase * sizeof(Fts5ExprPhrase*)
);
if( ap==0 ){
sParse.rc = SQLITE_NOMEM;
}else{
int i;
memmove(&ap[p2->nPhrase], ap, p1->nPhrase*sizeof(Fts5ExprPhrase*));
for(i=0; i<p2->nPhrase; i++){
ap[i] = p2->apExprPhrase[i];
}
p1->nPhrase = nPhrase;
p1->apExprPhrase = ap;
}
}
sqlite3_free(p2->apExprPhrase);
sqlite3_free(p2);
}else{
*pp1 = p2;
}
return sParse.rc;
}
/*
** Argument pTerm must be a synonym iterator. Return the current rowid
** that it points to.
+1 -1
View File
@@ -713,7 +713,7 @@ static void fts5DataRelease(Fts5Data *pData){
static Fts5Data *fts5LeafRead(Fts5Index *p, i64 iRowid){
Fts5Data *pRet = fts5DataRead(p, iRowid);
if( pRet ){
if( pRet->szLeaf>pRet->nn ){
if( pRet->nn<4 || pRet->szLeaf>pRet->nn ){
p->rc = FTS5_CORRUPT;
fts5DataRelease(pRet);
pRet = 0;
+162 -104
View File
@@ -465,17 +465,39 @@ static void fts5SetUniqueFlag(sqlite3_index_info *pIdxInfo){
** Implementation of the xBestIndex method for FTS5 tables. Within the
** WHERE constraint, it searches for the following:
**
** 1. A MATCH constraint against the special column.
** 1. A MATCH constraint against the table column.
** 2. A MATCH constraint against the "rank" column.
** 3. An == constraint against the rowid column.
** 4. A < or <= constraint against the rowid column.
** 5. A > or >= constraint against the rowid column.
** 3. A MATCH constraint against some other column.
** 4. An == constraint against the rowid column.
** 5. A < or <= constraint against the rowid column.
** 6. A > or >= constraint against the rowid column.
**
** Within the ORDER BY, either:
** Within the ORDER BY, the following are supported:
**
** 5. ORDER BY rank [ASC|DESC]
** 6. ORDER BY rowid [ASC|DESC]
**
** Information for the xFilter call is passed via both the idxNum and
** idxStr variables. Specifically, idxNum is a bitmask of the following
** flags used to encode the ORDER BY clause:
**
** FTS5_BI_ORDER_RANK
** FTS5_BI_ORDER_ROWID
** FTS5_BI_ORDER_DESC
**
** idxStr is used to encode data from the WHERE clause. For each argument
** passed to the xFilter method, the following is appended to idxStr:
**
** Match against table column: "m"
** Match against rank column: "r"
** Match against other column: "<column-number>"
** Equality constraint against the rowid: "="
** A < or <= against the rowid: "<"
** A > or >= against the rowid: ">"
**
** This function ensures that there is at most one "r" or "=". And that if
** there exists an "=" then there is no "<" or ">".
**
** Costs are assigned as follows:
**
** a) If an unusable MATCH operator is present in the WHERE clause, the
@@ -503,32 +525,18 @@ static int fts5BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){
Fts5Config *pConfig = pTab->pConfig;
const int nCol = pConfig->nCol;
int idxFlags = 0; /* Parameter passed through to xFilter() */
int bHasMatch;
int iNext;
int i;
struct Constraint {
int op; /* Mask against sqlite3_index_constraint.op */
int fts5op; /* FTS5 mask for idxFlags */
int iCol; /* 0==rowid, 1==tbl, 2==rank */
int omit; /* True to omit this if found */
int iConsIndex; /* Index in pInfo->aConstraint[] */
} aConstraint[] = {
{SQLITE_INDEX_CONSTRAINT_MATCH|SQLITE_INDEX_CONSTRAINT_EQ,
FTS5_BI_MATCH, 1, 1, -1},
{SQLITE_INDEX_CONSTRAINT_MATCH|SQLITE_INDEX_CONSTRAINT_EQ,
FTS5_BI_RANK, 2, 1, -1},
{SQLITE_INDEX_CONSTRAINT_EQ, FTS5_BI_ROWID_EQ, 0, 0, -1},
{SQLITE_INDEX_CONSTRAINT_LT|SQLITE_INDEX_CONSTRAINT_LE,
FTS5_BI_ROWID_LE, 0, 0, -1},
{SQLITE_INDEX_CONSTRAINT_GT|SQLITE_INDEX_CONSTRAINT_GE,
FTS5_BI_ROWID_GE, 0, 0, -1},
};
char *idxStr;
int iIdxStr = 0;
int iCons = 0;
int bSeenEq = 0;
int bSeenGt = 0;
int bSeenLt = 0;
int bSeenMatch = 0;
int bSeenRank = 0;
int aColMap[3];
aColMap[0] = -1;
aColMap[1] = nCol;
aColMap[2] = nCol+1;
assert( SQLITE_INDEX_CONSTRAINT_EQ<SQLITE_INDEX_CONSTRAINT_MATCH );
assert( SQLITE_INDEX_CONSTRAINT_GT<SQLITE_INDEX_CONSTRAINT_MATCH );
@@ -543,40 +551,78 @@ static int fts5BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){
return SQLITE_ERROR;
}
/* Set idxFlags flags for all WHERE clause terms that will be used. */
idxStr = (char*)sqlite3_malloc(pInfo->nConstraint * 6 + 1);
if( idxStr==0 ) return SQLITE_NOMEM;
pInfo->idxStr = idxStr;
pInfo->needToFreeIdxStr = 1;
for(i=0; i<pInfo->nConstraint; i++){
struct sqlite3_index_constraint *p = &pInfo->aConstraint[i];
int iCol = p->iColumn;
if( (p->op==SQLITE_INDEX_CONSTRAINT_MATCH && iCol>=0 && iCol<=nCol)
|| (p->op==SQLITE_INDEX_CONSTRAINT_EQ && iCol==nCol)
if( p->op==SQLITE_INDEX_CONSTRAINT_MATCH
|| (p->op==SQLITE_INDEX_CONSTRAINT_EQ && iCol>=nCol)
){
/* A MATCH operator or equivalent */
if( p->usable ){
idxFlags = (idxFlags & 0xFFFF) | FTS5_BI_MATCH | (iCol << 16);
aConstraint[0].iConsIndex = i;
}else{
if( p->usable==0 || iCol<0 ){
/* As there exists an unusable MATCH constraint this is an
** unusable plan. Set a prohibitively high cost. */
pInfo->estimatedCost = 1e50;
assert( iIdxStr < pInfo->nConstraint*6 + 1 );
idxStr[iIdxStr] = 0;
return SQLITE_OK;
}else{
if( iCol==nCol+1 ){
if( bSeenRank ) continue;
idxStr[iIdxStr++] = 'r';
bSeenRank = 1;
}else{
bSeenMatch = 1;
idxStr[iIdxStr++] = 'm';
if( iCol<nCol ){
sqlite3_snprintf(6, &idxStr[iIdxStr], "%d", iCol);
idxStr += strlen(&idxStr[iIdxStr]);
assert( idxStr[iIdxStr]=='\0' );
}
}
pInfo->aConstraintUsage[i].argvIndex = ++iCons;
pInfo->aConstraintUsage[i].omit = 1;
}
}else if( p->op<=SQLITE_INDEX_CONSTRAINT_MATCH ){
int j;
for(j=1; j<ArraySize(aConstraint); j++){
struct Constraint *pC = &aConstraint[j];
if( iCol==aColMap[pC->iCol] && (p->op & pC->op) && p->usable ){
pC->iConsIndex = i;
idxFlags |= pC->fts5op;
}
else if( p->usable && bSeenEq==0
&& p->op==SQLITE_INDEX_CONSTRAINT_EQ && iCol<0
){
idxStr[iIdxStr++] = '=';
bSeenEq = 1;
pInfo->aConstraintUsage[i].argvIndex = ++iCons;
}
}
if( bSeenEq==0 ){
for(i=0; i<pInfo->nConstraint; i++){
struct sqlite3_index_constraint *p = &pInfo->aConstraint[i];
if( p->iColumn<0 && p->usable ){
int op = p->op;
if( op==SQLITE_INDEX_CONSTRAINT_LT || op==SQLITE_INDEX_CONSTRAINT_LE ){
if( bSeenLt ) continue;
idxStr[iIdxStr++] = '<';
pInfo->aConstraintUsage[i].argvIndex = ++iCons;
bSeenLt = 1;
}else
if( op==SQLITE_INDEX_CONSTRAINT_GT || op==SQLITE_INDEX_CONSTRAINT_GE ){
if( bSeenGt ) continue;
idxStr[iIdxStr++] = '>';
pInfo->aConstraintUsage[i].argvIndex = ++iCons;
bSeenGt = 1;
}
}
}
}
idxStr[iIdxStr] = '\0';
/* Set idxFlags flags for the ORDER BY clause */
if( pInfo->nOrderBy==1 ){
int iSort = pInfo->aOrderBy[0].iColumn;
if( iSort==(pConfig->nCol+1) && BitFlagTest(idxFlags, FTS5_BI_MATCH) ){
if( iSort==(pConfig->nCol+1) && bSeenMatch ){
idxFlags |= FTS5_BI_ORDER_RANK;
}else if( iSort==-1 ){
idxFlags |= FTS5_BI_ORDER_ROWID;
@@ -590,26 +636,15 @@ static int fts5BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){
}
/* Calculate the estimated cost based on the flags set in idxFlags. */
bHasMatch = BitFlagTest(idxFlags, FTS5_BI_MATCH);
if( BitFlagTest(idxFlags, FTS5_BI_ROWID_EQ) ){
pInfo->estimatedCost = bHasMatch ? 100.0 : 10.0;
if( bHasMatch==0 ) fts5SetUniqueFlag(pInfo);
}else if( BitFlagAllTest(idxFlags, FTS5_BI_ROWID_LE|FTS5_BI_ROWID_GE) ){
pInfo->estimatedCost = bHasMatch ? 500.0 : 250000.0;
}else if( BitFlagTest(idxFlags, FTS5_BI_ROWID_LE|FTS5_BI_ROWID_GE) ){
pInfo->estimatedCost = bHasMatch ? 750.0 : 750000.0;
if( bSeenEq ){
pInfo->estimatedCost = bSeenMatch ? 100.0 : 10.0;
if( bSeenMatch==0 ) fts5SetUniqueFlag(pInfo);
}else if( bSeenLt && bSeenGt ){
pInfo->estimatedCost = bSeenMatch ? 500.0 : 250000.0;
}else if( bSeenLt || bSeenGt ){
pInfo->estimatedCost = bSeenMatch ? 750.0 : 750000.0;
}else{
pInfo->estimatedCost = bHasMatch ? 1000.0 : 1000000.0;
}
/* Assign argvIndex values to each constraint in use. */
iNext = 1;
for(i=0; i<ArraySize(aConstraint); i++){
struct Constraint *pC = &aConstraint[i];
if( pC->iConsIndex>=0 ){
pInfo->aConstraintUsage[pC->iConsIndex].argvIndex = iNext++;
pInfo->aConstraintUsage[pC->iConsIndex].omit = (unsigned char)pC->omit;
}
pInfo->estimatedCost = bSeenMatch ? 1000.0 : 1000000.0;
}
pInfo->idxNum = idxFlags;
@@ -1132,7 +1167,7 @@ static i64 fts5GetRowidLimit(sqlite3_value *pVal, i64 iDefault){
static int fts5FilterMethod(
sqlite3_vtab_cursor *pCursor, /* The cursor used for this query */
int idxNum, /* Strategy index */
const char *zUnused, /* Unused */
const char *idxStr, /* Unused */
int nVal, /* Number of elements in apVal */
sqlite3_value **apVal /* Arguments for the indexing scheme */
){
@@ -1140,19 +1175,17 @@ static int fts5FilterMethod(
Fts5Config *pConfig = pTab->p.pConfig;
Fts5Cursor *pCsr = (Fts5Cursor*)pCursor;
int rc = SQLITE_OK; /* Error code */
int iVal = 0; /* Counter for apVal[] */
int bDesc; /* True if ORDER BY [rank|rowid] DESC */
int bOrderByRank; /* True if ORDER BY rank */
sqlite3_value *pMatch = 0; /* <tbl> MATCH ? expression (or NULL) */
sqlite3_value *pRank = 0; /* rank MATCH ? expression (or NULL) */
sqlite3_value *pRowidEq = 0; /* rowid = ? expression (or NULL) */
sqlite3_value *pRowidLe = 0; /* rowid <= ? expression (or NULL) */
sqlite3_value *pRowidGe = 0; /* rowid >= ? expression (or NULL) */
int iCol; /* Column on LHS of MATCH operator */
char **pzErrmsg = pConfig->pzErrmsg;
UNUSED_PARAM(zUnused);
UNUSED_PARAM(nVal);
int i;
int iIdxStr = 0;
Fts5Expr *pExpr = 0;
if( pCsr->ePlan ){
fts5FreeCursorComponents(pCsr);
@@ -1165,23 +1198,60 @@ static int fts5FilterMethod(
assert( pCsr->pRank==0 );
assert( pCsr->zRank==0 );
assert( pCsr->zRankArgs==0 );
assert( pTab->pSortCsr==0 || nVal==0 );
assert( pzErrmsg==0 || pzErrmsg==&pTab->p.base.zErrMsg );
pConfig->pzErrmsg = &pTab->p.base.zErrMsg;
/* Decode the arguments passed through to this function.
**
** Note: The following set of if(...) statements must be in the same
** order as the corresponding entries in the struct at the top of
** fts5BestIndexMethod(). */
if( BitFlagTest(idxNum, FTS5_BI_MATCH) ) pMatch = apVal[iVal++];
if( BitFlagTest(idxNum, FTS5_BI_RANK) ) pRank = apVal[iVal++];
if( BitFlagTest(idxNum, FTS5_BI_ROWID_EQ) ) pRowidEq = apVal[iVal++];
if( BitFlagTest(idxNum, FTS5_BI_ROWID_LE) ) pRowidLe = apVal[iVal++];
if( BitFlagTest(idxNum, FTS5_BI_ROWID_GE) ) pRowidGe = apVal[iVal++];
iCol = (idxNum>>16);
assert( iCol>=0 && iCol<=pConfig->nCol );
assert( iVal==nVal );
/* Decode the arguments passed through to this function. */
for(i=0; i<nVal; i++){
switch( idxStr[iIdxStr++] ){
case 'r':
pRank = apVal[i];
break;
case 'm': {
const char *zText = (const char*)sqlite3_value_text(apVal[i]);
if( zText==0 ) zText = "";
if( idxStr[iIdxStr]>='0' && idxStr[iIdxStr]<='9' ){
iCol = 0;
do{
iCol = iCol*10 + (idxStr[iIdxStr]-'0');
iIdxStr++;
}while( idxStr[iIdxStr]>='0' && idxStr[iIdxStr]<='9' );
}else{
iCol = pConfig->nCol;
}
if( zText[0]=='*' ){
/* The user has issued a query of the form "MATCH '*...'". This
** indicates that the MATCH expression is not a full text query,
** but a request for an internal parameter. */
rc = fts5SpecialMatch(pTab, pCsr, &zText[1]);
goto filter_out;
}else{
char **pzErr = &pTab->p.base.zErrMsg;
rc = sqlite3Fts5ExprNew(pConfig, iCol, zText, &pExpr, pzErr);
if( rc==SQLITE_OK ){
rc = sqlite3Fts5ExprAnd(&pCsr->pExpr, pExpr);
pExpr = 0;
}
if( rc!=SQLITE_OK ) goto filter_out;
}
break;
}
case '=':
pRowidEq = apVal[i];
break;
case '<':
pRowidLe = apVal[i];
break;
default: assert( idxStr[iIdxStr-1]=='>' );
pRowidGe = apVal[i];
break;
}
}
bOrderByRank = ((idxNum & FTS5_BI_ORDER_RANK) ? 1 : 0);
pCsr->bDesc = bDesc = ((idxNum & FTS5_BI_ORDER_DESC) ? 1 : 0);
@@ -1208,7 +1278,7 @@ static int fts5FilterMethod(
** (pCursor) is used to execute the query issued by function
** fts5CursorFirstSorted() above. */
assert( pRowidEq==0 && pRowidLe==0 && pRowidGe==0 && pRank==0 );
assert( nVal==0 && pMatch==0 && bOrderByRank==0 && bDesc==0 );
assert( nVal==0 && bOrderByRank==0 && bDesc==0 );
assert( pCsr->iLastRowid==LARGEST_INT64 );
assert( pCsr->iFirstRowid==SMALLEST_INT64 );
if( pTab->pSortCsr->bDesc ){
@@ -1221,29 +1291,15 @@ static int fts5FilterMethod(
pCsr->ePlan = FTS5_PLAN_SOURCE;
pCsr->pExpr = pTab->pSortCsr->pExpr;
rc = fts5CursorFirst(pTab, pCsr, bDesc);
}else if( pMatch ){
const char *zExpr = (const char*)sqlite3_value_text(apVal[0]);
if( zExpr==0 ) zExpr = "";
}else if( pCsr->pExpr ){
rc = fts5CursorParseRank(pConfig, pCsr, pRank);
if( rc==SQLITE_OK ){
if( zExpr[0]=='*' ){
/* The user has issued a query of the form "MATCH '*...'". This
** indicates that the MATCH expression is not a full text query,
** but a request for an internal parameter. */
rc = fts5SpecialMatch(pTab, pCsr, &zExpr[1]);
if( bOrderByRank ){
pCsr->ePlan = FTS5_PLAN_SORTED_MATCH;
rc = fts5CursorFirstSorted(pTab, pCsr, bDesc);
}else{
char **pzErr = &pTab->p.base.zErrMsg;
rc = sqlite3Fts5ExprNew(pConfig, iCol, zExpr, &pCsr->pExpr, pzErr);
if( rc==SQLITE_OK ){
if( bOrderByRank ){
pCsr->ePlan = FTS5_PLAN_SORTED_MATCH;
rc = fts5CursorFirstSorted(pTab, pCsr, bDesc);
}else{
pCsr->ePlan = FTS5_PLAN_MATCH;
rc = fts5CursorFirst(pTab, pCsr, bDesc);
}
}
pCsr->ePlan = FTS5_PLAN_MATCH;
rc = fts5CursorFirst(pTab, pCsr, bDesc);
}
}
}else if( pConfig->zContent==0 ){
@@ -1260,7 +1316,7 @@ static int fts5FilterMethod(
);
if( rc==SQLITE_OK ){
if( pCsr->ePlan==FTS5_PLAN_ROWID ){
sqlite3_bind_value(pCsr->pStmt, 1, apVal[0]);
sqlite3_bind_value(pCsr->pStmt, 1, pRowidEq);
}else{
sqlite3_bind_int64(pCsr->pStmt, 1, pCsr->iFirstRowid);
sqlite3_bind_int64(pCsr->pStmt, 2, pCsr->iLastRowid);
@@ -1269,6 +1325,8 @@ static int fts5FilterMethod(
}
}
filter_out:
sqlite3Fts5ExprFree(pExpr);
pConfig->pzErrmsg = pzErrmsg;
return rc;
}
+81
View File
@@ -9693,6 +9693,87 @@ do_catchsql_test 65.1 {
SELECT ( MATCH (t1,591)) FROM t1 WHERE t1 MATCH 'e*eŸ'
} {1 {database disk image is malformed}}
#-------------------------------------------------------------------------
#
reset_db
do_test 66.0 {
sqlite3 db {}
db deserialize [decode_hexdb {
.open --hexdb
| size 28672 pagesize 4096 filename crash-37cecb4e784e9f.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 07 .....@ ........
| 96: 00 00 00 00 0d 00 00 00 07 0d d2 00 0f c4 0f 6d ...............m
| 112: 0f 02 0e ab 0e 4e 0d f6 0d d2 00 00 00 00 00 00 .....N..........
| 3536: 00 00 22 07 06 17 11 11 01 31 74 61 62 6c 65 74 .........1tablet
| 3552: 32 74 32 07 43 52 45 41 54 45 20 54 41 42 4c 45 2t2.CREATE TABLE
| 3568: 20 74 32 28 78 29 56 06 06 17 1f 1f 01 7d 74 61 t2(x)V.......ta
| 3584: 62 6c 65 74 31 5f 63 6f 6e 66 69 67 74 31 5f 63 blet1_configt1_c
| 3600: 6f 6e 66 69 67 06 43 52 45 41 54 45 20 54 41 42 onfig.CREATE TAB
| 3616: 4c 45 20 27 74 31 5f 63 6f 6e 66 69 67 27 28 6b LE 't1_config'(k
| 3632: 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 76 29 PRIMARY KEY, v)
| 3648: 20 57 49 54 48 4f 55 54 20 52 4f 57 49 44 5b 05 WITHOUT ROWID[.
| 3664: 07 17 21 21 01 81 01 74 61 62 6c 65 74 31 5f 64 ..!!...tablet1_d
| 3680: 6f 63 73 69 7a 65 74 31 5f 64 6f 63 73 69 7a 65 ocsizet1_docsize
| 3696: 05 43 52 45 41 54 45 20 54 41 42 4c 45 20 27 74 .CREATE TABLE 't
| 3712: 31 5f 64 6f 63 73 69 7a 65 27 28 69 64 20 49 4e 1_docsize'(id IN
| 3728: 54 45 47 45 52 20 50 52 49 4d 41 52 59 20 4b 45 TEGER PRIMARY KE
| 3744: 59 2c 20 73 7a 20 42 4c 4f 42 29 55 04 06 17 21 Y, sz BLOB)U...!
| 3760: 21 01 77 74 61 62 6c 65 74 31 5f 63 6f 6e 74 65 !.wtablet1_conte
| 3776: 6e 74 74 31 5f 63 6f 6e 74 65 6e 74 04 43 52 45 ntt1_content.CRE
| 3792: 41 54 45 20 54 41 42 4c 45 20 27 74 31 5f 63 6f ATE TABLE 't1_co
| 3808: 6e 74 65 6e 74 27 28 69 64 20 49 4e 54 45 47 45 ntent'(id INTEGE
| 3824: 52 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 63 R PRIMARY KEY, c
| 3840: 30 29 69 03 07 17 19 19 01 81 2d 74 61 62 6c 65 0)i.......-table
| 3856: 74 31 5f 69 64 78 74 31 5f 69 64 78 03 43 52 45 t1_idxt1_idx.CRE
| 3872: 41 54 45 20 54 41 42 4c 45 20 27 74 31 5f 69 64 ATE TABLE 't1_id
| 3888: 78 27 28 73 65 67 69 64 2c 20 74 65 72 6d 2c 20 x'(segid, term,
| 3904: 70 67 6e 6f 2c 20 50 52 49 4d 41 52 59 20 4b 45 pgno, PRIMARY KE
| 3920: 59 28 73 65 67 69 64 2c 20 74 65 72 6d 29 29 20 Y(segid, term))
| 3936: 57 49 54 48 4f 55 54 20 52 4f 57 49 44 55 02 07 WITHOUT ROWIDU..
| 3952: 17 1b 1b 01 81 01 74 61 62 6c 65 74 31 5f 64 61 ......tablet1_da
| 3968: 74 61 74 31 5f 64 61 74 61 02 43 52 45 41 54 45 tat1_data.CREATE
| 3984: 20 54 41 42 4c 45 20 27 74 31 5f 64 61 74 61 27 TABLE 't1_data'
| 4000: 28 69 64 20 49 4e 54 45 47 45 52 20 50 52 49 4d (id INTEGER PRIM
| 4016: 41 52 49 20 4b 45 59 2c 20 62 6c 6f 63 6b 20 42 ARI KEY, block B
| 4032: 4c 4f 42 29 3a 01 06 17 11 11 08 63 74 61 62 6c LOB):......ctabl
| 4048: 65 74 31 74 31 43 52 45 41 54 45 20 56 49 52 54 et1t1CREATE VIRT
| 4064: 55 41 4c 20 54 41 42 4c 45 20 74 31 20 55 53 49 UAL TABLE t1 USI
| 4080: 4e 47 20 66 74 73 35 28 63 6f 6e 74 65 6e 74 29 NG fts5(content)
| page 2 offset 4096
| 0: 0d 00 00 00 03 0f bd 00 0f e8 0f ef 0f bd 00 01 ................
| 4016: 00 00 00 00 00 00 00 00 00 00 00 00 00 24 84 80 .............$..
| 4032: 80 80 80 01 03 00 4e 00 00 00 1e 06 30 61 62 61 ......N.....0aba
| 4048: 63 6b 01 02 02 04 02 66 74 02 02 02 04 04 6e 64 ck.....ft.....nd
| 4064: 6f 6e 03 02 02 04 0a 07 05 01 03 00 10 03 03 0f on..............
| 4080: 0a 03 00 24 00 00 00 00 01 01 01 00 01 00 01 01 ...$............
| page 3 offset 8192
| 0: 0a 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
| 4080: 00 00 00 00 00 00 00 00 00 00 05 04 09 0c 01 02 ................
| page 4 offset 12288
| 0: 0d 00 00 00 03 0f e0 00 0f f6 0f ec 0f e0 00 00 ................
| 4064: 0a 03 03 00 1b 61 62 61 6e 64 6f 6e 08 02 03 00 .....abandon....
| 4080: 17 61 62 61 66 74 08 01 03 00 17 61 62 61 63 6b .abaft.....aback
| page 5 offset 16384
| 0: 0d 00 00 00 03 0f ee 00 0f fa 0f f4 0f ee 00 00 ................
| 4064: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 04 03 ................
| 4080: 03 00 0e 01 04 02 03 00 0e 01 04 01 03 00 0e 01 ................
| page 6 offset 20480
| 0: 0a 00 00 01 01 0f f4 00 0f f4 00 00 00 00 00 00 ................
| 4080: 00 00 00 00 0b 03 1b 01 76 65 72 73 69 6f 6e 04 ........version.
| page 7 offset 24576
| 0: 0d 00 00 00 03 0f d6 00 0f f4 0f e1 0f d6 00 00 ................
| 4048: 00 00 00 00 00 00 09 01 52 1b 72 65 62 75 69 6c ........R.rebuil
| 4064: 64 11 02 02 2b 69 6e 74 65 67 72 69 74 79 2d 63 d...+integrity-c
| 4080: 68 65 63 6b 0a 01 02 1d 6f 70 74 69 6d 69 7a 65 heck....optimize
| end crash-37cecb4e784e9f.db
}]} {}
do_catchsql_test 66.1 {
INSERT INTO t1(t1) VALUES('integrity-check');
} {1 {database disk image is malformed}}
sqlite3_fts5_may_be_corrupt 0
+22
View File
@@ -147,5 +147,27 @@ do_faultsim_test 5.1 -faults oom* -body {
faultsim_test_result {0 {1 4}}
}
#-------------------------------------------------------------------------
# Test OOM injection in a query with two MATCH expressions
#
reset_db
do_execsql_test 6.0 {
CREATE VIRTUAL TABLE t1 USING fts5(a);
INSERT INTO t1 VALUES('a b c d'); -- 1
INSERT INTO t1 VALUES('d a b c'); -- 2
INSERT INTO t1 VALUES('c d a b'); -- 3
INSERT INTO t1 VALUES('b c d a'); -- 4
}
do_faultsim_test 6.1 -faults oom* -body {
execsql { SELECT rowid FROM t1 WHERE t1 MATCH 'a' AND t1 MATCH 'b' }
} -test {
faultsim_test_result {0 {1 2 3 4}}
}
do_faultsim_test 6.2 -faults oom* -body {
execsql { SELECT rowid FROM t1 WHERE t1 MATCH 'a OR b' AND t1 MATCH 'c OR d' }
} -test {
faultsim_test_result {0 {1 2 3 4}}
}
finish_test
+99
View File
@@ -0,0 +1,99 @@
# 2014 September 13
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
# May you find forgiveness for yourself and forgive others.
# May you share freely, never taking more than you give.
#
#*************************************************************************
# This file implements regression tests for SQLite library. The
# focus of this script is testing the FTS5 module.
#
source [file join [file dirname [info script]] fts5_common.tcl]
set testprefix fts5multi
# If SQLITE_ENABLE_FTS5 is not defined, omit this file.
ifcapable !fts5 {
finish_test
return
}
fts5_aux_test_functions db
do_execsql_test 1.0 {
CREATE VIRTUAL TABLE t1 USING fts5(a, b, c);
INSERT INTO t1 VALUES('gg bb bb' ,'gg ff gg' ,'ii ii');
INSERT INTO t1 VALUES('dd dd hh kk','jj' ,'aa');
INSERT INTO t1 VALUES('kk gg ee' ,'hh cc' ,'hh jj aa cc');
INSERT INTO t1 VALUES('hh' ,'bb jj cc' ,'kk ii');
INSERT INTO t1 VALUES('kk dd kk ii','aa ee aa' ,'ee');
INSERT INTO t1 VALUES('ee' ,'ff gg kk aa','ee ff ee');
INSERT INTO t1 VALUES('ff jj' ,'gg ee' ,'kk ee gg kk');
INSERT INTO t1 VALUES('ff ee dd hh','kk ee' ,'gg dd');
INSERT INTO t1 VALUES('bb' ,'aa' ,'bb aa');
INSERT INTO t1 VALUES('hh cc bb' ,'ff bb' ,'cc');
INSERT INTO t1 VALUES('jj' ,'ff dd bb aa','dd dd ff ff');
INSERT INTO t1 VALUES('ff dd gg dd','gg aa bb ff','cc');
INSERT INTO t1 VALUES('ff aa cc jj','kk' ,'ii dd');
INSERT INTO t1 VALUES('jj dd' ,'cc' ,'ii hh ee aa');
INSERT INTO t1 VALUES('ff ii hh' ,'dd' ,'gg');
INSERT INTO t1 VALUES('ff dd gg hh','hh' ,'ff dd');
INSERT INTO t1 VALUES('cc cc' ,'ff dd ff' ,'bb');
INSERT INTO t1 VALUES('ii' ,'bb ii' ,'jj kk');
INSERT INTO t1 VALUES('ff hh' ,'hh bb' ,'bb dd ee');
INSERT INTO t1 VALUES('jj kk' ,'jj' ,'gg ff cc');
INSERT INTO t1 VALUES('dd kk' ,'ii gg' ,'dd');
INSERT INTO t1 VALUES('cc' ,'aa ff' ,'ii');
INSERT INTO t1 VALUES('bb ff bb ii','bb kk bb aa','hh ff ii dd');
INSERT INTO t1 VALUES('aa' ,'ee bb jj jj','dd');
INSERT INTO t1 VALUES('kk dd cc' ,'aa jj' ,'ee aa ff');
INSERT INTO t1 VALUES('aa gg aa' ,'jj' ,'ii kk hh gg');
INSERT INTO t1 VALUES('ff hh aa' ,'jj ii' ,'hh dd bb jj');
INSERT INTO t1 VALUES('hh' ,'aa gg kk' ,'bb ee');
INSERT INTO t1 VALUES('bb' ,'ee' ,'gg');
INSERT INTO t1 VALUES('dd kk' ,'kk bb aa' ,'ee');
}
foreach {tn c1 e1 c2 e2} {
1 t1 aa t1 bb
2 a aa b bb
3 a "aa OR bb OR cc" b "jj OR ii OR hh"
4 t1 "aa AND bb" t1 "cc"
5 c "kk" b "aa OR bb OR cc OR dd OR ee"
} {
if {$c1=="t1"} {
set lhs "( $e1 )"
} else {
set lhs "$c1 : ( $e1 )"
}
if {$c2=="t1"} {
set rhs "( $e2 )"
} else {
set rhs "$c2 : ( $e2 )"
}
set q1 "t1 MATCH '($lhs) AND ($rhs)'"
set q2 "$c1 MATCH '$e1' AND $c2 MATCH '$e2'"
set ret [execsql "SELECT rowid FROM t1 WHERE $q1"]
set N [llength $ret]
do_execsql_test 1.$tn.1.($N) "SELECT rowid FROM t1 WHERE $q2" $ret
set ret [execsql "SELECT fts5_test_poslist(t1) FROM t1 WHERE $q1"]
do_execsql_test 1.$tn.2.($N) "
SELECT fts5_test_poslist(t1) FROM t1 WHERE $q2
" $ret
}
do_catchsql_test 2.1.1 {
SELECT rowid FROM t1 WHERE t1 MATCH '(NOT' AND t1 MATCH 'aa bb';
} {1 {fts5: syntax error near "NOT"}}
do_catchsql_test 2.1.2 {
SELECT rowid FROM t1 WHERE t1 MATCH 'aa bb' AND t1 MATCH '(NOT';
} {1 {fts5: syntax error near "NOT"}}
finish_test
+3 -3
View File
@@ -31,7 +31,7 @@ do_eqp_test 1.1 {
} {
QUERY PLAN
|--SCAN TABLE t1
`--SCAN TABLE f1 VIRTUAL TABLE INDEX 65537:
`--SCAN TABLE f1 VIRTUAL TABLE INDEX 0:m
}
do_eqp_test 1.2 {
@@ -46,7 +46,7 @@ do_eqp_test 1.3 {
SELECT * FROM f1 WHERE f1 MATCH ? ORDER BY ff
} {
QUERY PLAN
|--SCAN TABLE f1 VIRTUAL TABLE INDEX 65537:
|--SCAN TABLE f1 VIRTUAL TABLE INDEX 0:m
`--USE TEMP B-TREE FOR ORDER BY
}
@@ -60,6 +60,6 @@ do_eqp_test 1.4 {
do_eqp_test 1.5 {
SELECT * FROM f1 WHERE rank MATCH ?
} {SCAN TABLE f1 VIRTUAL TABLE INDEX 2:}
} {SCAN TABLE f1 VIRTUAL TABLE INDEX 0:r}
finish_test
+13
View File
@@ -467,4 +467,17 @@ do_execsql_test 21.3 {
SELECT rowid FROM x1($doc);
} {11112}
#-------------------------------------------------------------------------
reset_db
do_execsql_test 22.0 {
CREATE VIRTUAL TABLE x1 USING fts5(x);
INSERT INTO x1(x) VALUES('a b c');
INSERT INTO x1(x) VALUES('x y z');
INSERT INTO x1(x) VALUES('c b a');
INSERT INTO x1(x) VALUES('z y x');
}
do_catchsql_test 22.1 {SELECT * FROM x1('')} {1 {fts5: syntax error near ""}}
do_catchsql_test 22.2 {SELECT * FROM x1(NULL)} {1 {fts5: syntax error near ""}}
finish_test
+1 -1
View File
@@ -24,7 +24,7 @@
**
** static int aX[] = { 53, 9, 17, 2231, 4, 99 };
** int i = sqlite3_bind_parameter_index(pStmt, "$ptr");
** sqlite3_bind_value(pStmt, i, aX, "carray", 0);
** sqlite3_bind_pointer(pStmt, i, aX, "carray", 0);
**
** There is an optional third parameter to determine the datatype of
** the C-language array. Allowed values of the third parameter are
+17 -9
View File
@@ -1820,7 +1820,7 @@ static void jsonArrayStep(
if( pStr->zBuf==0 ){
jsonInit(pStr, ctx);
jsonAppendChar(pStr, '[');
}else{
}else if( pStr->nUsed>1 ){
jsonAppendChar(pStr, ',');
pStr->pCtx = ctx;
}
@@ -1868,9 +1868,11 @@ static void jsonGroupInverse(
int argc,
sqlite3_value **argv
){
int i;
unsigned int i;
int inStr = 0;
int nNest = 0;
char *z;
char c;
JsonString *pStr;
UNUSED_PARAM(argc);
UNUSED_PARAM(argv);
@@ -1881,12 +1883,18 @@ static void jsonGroupInverse(
if( NEVER(!pStr) ) return;
#endif
z = pStr->zBuf;
for(i=1; z[i]!=',' || inStr; i++){
assert( i<pStr->nUsed );
if( z[i]=='"' ){
for(i=1; (c = z[i])!=',' || inStr || nNest; i++){
if( i>=pStr->nUsed ){
pStr->nUsed = 1;
return;
}
if( c=='"' ){
inStr = !inStr;
}else if( z[i]=='\\' ){
}else if( c=='\\' ){
i++;
}else if( !inStr ){
if( c=='{' || c=='[' ) nNest++;
if( c=='}' || c==']' ) nNest--;
}
}
pStr->nUsed -= i;
@@ -1916,7 +1924,7 @@ static void jsonObjectStep(
if( pStr->zBuf==0 ){
jsonInit(pStr, ctx);
jsonAppendChar(pStr, '{');
}else{
}else if( pStr->nUsed>1 ){
jsonAppendChar(pStr, ',');
pStr->pCtx = ctx;
}
@@ -2504,14 +2512,14 @@ int sqlite3Json1Init(sqlite3 *db){
#endif
for(i=0; i<sizeof(aFunc)/sizeof(aFunc[0]) && rc==SQLITE_OK; i++){
rc = sqlite3_create_function(db, aFunc[i].zName, aFunc[i].nArg,
SQLITE_UTF8 | SQLITE_DETERMINISTIC,
SQLITE_UTF8 | SQLITE_DETERMINISTIC,
(void*)&aFunc[i].flag,
aFunc[i].xFunc, 0, 0);
}
#ifndef SQLITE_OMIT_WINDOWFUNC
for(i=0; i<sizeof(aAgg)/sizeof(aAgg[0]) && rc==SQLITE_OK; i++){
rc = sqlite3_create_window_function(db, aAgg[i].zName, aAgg[i].nArg,
SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
SQLITE_SUBTYPE | SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
aAgg[i].xStep, aAgg[i].xFinal,
aAgg[i].xValue, jsonGroupInverse, 0);
}
+165
View File
@@ -0,0 +1,165 @@
# 2014 August 30
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
# May you find forgiveness for yourself and forgive others.
# May you share freely, never taking more than you give.
#
#***********************************************************************
#
source [file join [file dirname [info script]] rbu_common.tcl]
set ::testprefix rbu1
forcedelete test.db2
do_execsql_test 1.0 {
CREATE TABLE t1(a INTEGER, b, c, PRIMARY KEY(a));
CREATE INDEX t1b ON t1(b); -- root=3
CREATE INDEX t1c ON t1(c); -- root=4
ATTACH 'test.db2' AS 'rbu';
CREATE TABLE rbu.data_t1(a, b, c, rbu_control);
INSERT INTO data_t1 VALUES(1, 1, 1, 0);
INSERT INTO data_t1 VALUES(2, 2, 2, 0);
INSERT INTO data_t1 VALUES(3, 3, 3, 0);
}
do_test 1.1 {
sqlite3_test_control SQLITE_TESTCTRL_IMPOSTER db main 1 3
execsql {
CREATE TABLE imp1(b, id, PRIMARY KEY(b, id)) WITHOUT ROWID;
INSERT INTO imp1 VALUES(2, 2);
}
sqlite3_test_control SQLITE_TESTCTRL_IMPOSTER db main 0 3
} {}
db close
sqlite3 db test.db
do_test 1.2 {
sqlite3_test_control SQLITE_TESTCTRL_IMPOSTER db main 1 4
execsql {
CREATE TABLE imp1(b, id, PRIMARY KEY(b, id)) WITHOUT ROWID;
INSERT INTO imp1 VALUES(3, 3);
}
sqlite3_test_control SQLITE_TESTCTRL_IMPOSTER db main 0 4
} {}
db close
db_save
sqlite3 db test.db
do_catchsql_test 1.3 { PRAGMA integrity_check } {0 {{wrong # of entries in index t1c} {wrong # of entries in index t1b}}}
db close
do_test 1.4 {
sqlite3rbu rbu test.db test.db2
while 1 {
set rc [rbu step]
if {$rc!="SQLITE_OK"} break
}
list [catch { rbu close } msg] $msg
} {1 {SQLITE_CONSTRAINT - UNIQUE constraint failed: t1.b, t1.a}}
db_restore
sqlite3 db test.db2
do_execsql_test 1.5 {
PRAGMA writable_schema = 1;
CREATE TABLE sqlite_rbu_replace_hack('v');
}
db close
do_test 1.6 {
sqlite3rbu rbu test.db test.db2
while 1 {
set rc [rbu step]
if {$rc!="SQLITE_OK"} break
}
list [catch { rbu close } msg] $msg
} {0 SQLITE_DONE}
sqlite3 db test.db
do_execsql_test 1.7 {
PRAGMA integrity_check;
SELECT count(*) FROM t1;
} {ok 3}
#-------------------------------------------------------------------------
reset_db
forcedelete test.db2
do_execsql_test 2.0 {
CREATE TABLE t1(a, b, c, PRIMARY KEY(a, b));
CREATE INDEX t1c ON t1(c); -- root=4
ATTACH 'test.db2' AS 'rbu';
CREATE TABLE rbu.data_t1(a, b, c, rbu_control);
INSERT INTO data_t1 VALUES(1, 1, 1, 0);
INSERT INTO data_t1 VALUES(2, 2, 2, 0);
INSERT INTO data_t1 VALUES(3, 3, 3, 0);
}
do_test 2.1 {
sqlite3_test_control SQLITE_TESTCTRL_IMPOSTER db main 1 3
execsql {
CREATE TABLE imp1(a, b, id, PRIMARY KEY(b, id)) WITHOUT ROWID;
INSERT INTO imp1 VALUES(2, 2, 2);
}
sqlite3_test_control SQLITE_TESTCTRL_IMPOSTER db main 0 3
} {}
db close
sqlite3 db test.db
do_test 2.2 {
sqlite3_test_control SQLITE_TESTCTRL_IMPOSTER db main 1 4
execsql {
CREATE TABLE imp1(c, id, PRIMARY KEY(c, id)) WITHOUT ROWID;
INSERT INTO imp1 VALUES(3, 3);
}
sqlite3_test_control SQLITE_TESTCTRL_IMPOSTER db main 0 4
} {}
db close
db_save
sqlite3 db test.db
do_catchsql_test 2.3 { PRAGMA integrity_check } {0 {{wrong # of entries in index t1c} {wrong # of entries in index sqlite_autoindex_t1_1}}}
db close
do_test 2.4 {
sqlite3rbu rbu test.db test.db2
while 1 {
set rc [rbu step]
if {$rc!="SQLITE_OK"} break
}
list [catch { rbu close } msg] $msg
} {1 {SQLITE_CONSTRAINT - UNIQUE constraint failed: t1.a, t1.b}}
db_restore
sqlite3 db test.db2
do_execsql_test 2.5 {
PRAGMA writable_schema = 1;
CREATE TABLE sqlite_rbu_replace_hack('v');
}
db close
do_test 2.6 {
sqlite3rbu rbu test.db test.db2
while 1 {
set rc [rbu step]
if {$rc!="SQLITE_OK"} break
}
list [catch { rbu close } msg] $msg
} {0 SQLITE_DONE}
sqlite3 db test.db
do_execsql_test 2.7 {
PRAGMA integrity_check;
SELECT count(*) FROM t1;
} {ok 3}
finish_test
+28 -3
View File
@@ -103,6 +103,8 @@
# define RBU_ENABLE_DELTA_CKSUM 0
#endif
#define RBU_REPLACE_HACK_TABLE "sqlite_rbu_replace_hack"
/*
** Swap two objects of type TYPE.
*/
@@ -376,6 +378,7 @@ struct sqlite3rbu {
char *zRbu; /* Path to rbu db */
char *zState; /* Path to state db (or NULL if zRbu) */
char zStateDb[5]; /* Db name for state ("stat" or "main") */
int bRbuReplaceHack; /* Do the REPLACE hack */
int rc; /* Value returned by last rbu_step() call */
char *zErrmsg; /* Error message if rc!=SQLITE_OK */
int nStep; /* Rows processed for current object */
@@ -2350,7 +2353,10 @@ static int rbuObjIterPrepareAll(
if( p->rc==SQLITE_OK ){
p->rc = prepareFreeAndCollectError(
p->dbMain, &pIter->pInsert, &p->zErrmsg,
sqlite3_mprintf("INSERT INTO \"rbu_imp_%w\" VALUES(%s)", zTbl, zBind)
sqlite3_mprintf("%s INTO \"rbu_imp_%w\" VALUES(%s)",
p->bRbuReplaceHack ? "REPLACE" : "INSERT",
zTbl, zBind
)
);
}
@@ -2442,7 +2448,8 @@ static int rbuObjIterPrepareAll(
if( p->rc==SQLITE_OK ){
p->rc = prepareFreeAndCollectError(p->dbMain, &pIter->pInsert, pz,
sqlite3_mprintf(
"INSERT INTO \"%s%w\"(%s%s) VALUES(%s)",
"%s INTO \"%s%w\"(%s%s) VALUES(%s)",
p->bRbuReplaceHack ? "REPLACE" : "INSERT",
zWrite, zTbl, zCollist, (bRbuRowid ? ", _rowid_" : ""), zBindings
)
);
@@ -2725,7 +2732,7 @@ static RbuState *rbuLoadState(sqlite3rbu *p){
break;
case RBU_STATE_OALSZ:
pRet->iOalSz = (u32)sqlite3_column_int64(pStmt, 1);
pRet->iOalSz = sqlite3_column_int64(pStmt, 1);
break;
case RBU_STATE_PHASEONESTEP:
@@ -2744,6 +2751,24 @@ static RbuState *rbuLoadState(sqlite3rbu *p){
rc2 = sqlite3_finalize(pStmt);
if( rc==SQLITE_OK ) rc = rc2;
/* If this is not a vacuum operation, search for the special table
** "sqlite_rbu_replace_hack". Set the flag if it is found.
*/
if( rc==SQLITE_OK && !rbuIsVacuum(p) ){
sqlite3_stmt *pQuery = 0;
rc = prepareFreeAndCollectError(p->dbRbu, &pQuery, &p->zErrmsg,
sqlite3_mprintf("SELECT 1 FROM main.sqlite_master WHERE name='%s'",
RBU_REPLACE_HACK_TABLE
)
);
if( rc==SQLITE_OK ){
if( sqlite3_step(pQuery)==SQLITE_ROW ){
p->bRbuReplaceHack = 1;
}
rc = sqlite3_finalize(pQuery);
}
}
p->rc = rc;
return pRet;
}
+74 -69
View File
@@ -1,5 +1,5 @@
C Ensure\sthe\scolumns\sof\sviews\sand\ssub-selects\sin\sthe\sFROM\sclause\sof\sa\sselect\sare\salways\sassigned\simplicit\scollation\ssequences,\sjust\sas\stable\scolumns\sare.\sPossible\sfix\sfor\s[a7debbe0].
D 2019-09-09T19:49:42.715
C Fix\san\sRBU\sproblem\swith\srestarting\san\supdate\safter\sthe\s*-oal\sfile\sis\salready\slarger\sthan\s4GiB.
D 2021-08-11T18:56:49.597
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@@ -81,7 +81,7 @@ 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 33958a8c05a6c22bf559fedb1176ad1f313a7b42ccf5f0c0bcc8a88609e58d60
F ext/fts3/fts3.c a01da95e840a6ddb14d0a14b35c9017a8b034b08511ca97af716f00df102fb3f
F ext/fts3/fts3.h 3a10a0af180d502cecc50df77b1b22df142817fe
F ext/fts3/fts3Int.h 74384e28b778a057f1467529715668b98f3f12f52eeb564fd6ae1e894125c00c
F ext/fts3/fts3_aux.c 96708c8b3a7d9b8ca1b68ea2b7e503e283f20e95f145becadedfad096dbd0f34
@@ -99,7 +99,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 6efc4cd7dc554df06c35bfd3335503838645806a78fc33137a55eb97a8b2f3b2
F ext/fts3/fts3_write.c 13582783abedf905e6946ce95edff7103c07810fb03a9c3b40212d21a3efa09c
F ext/fts3/fts3speed.tcl b54caf6a18d38174f1a6e84219950d85e98bb1e9
F ext/fts3/mkfts3amal.tcl 252ecb7fe6467854f2aa237bf2c390b74e71f100
F ext/fts3/tool/fts3cov.sh c331d006359456cf6f8f953e37f2b9c7d568f3863f00bb5f7eb87fea4ac01b73
@@ -110,14 +110,14 @@ F ext/fts3/unicode/mkunicode.tcl bf7fcaa6d68e6d38223467983785d054f1cff4d9e3905dd
F ext/fts3/unicode/parseunicode.tcl a981bd6466d12dd17967515801c3ff23f74a281be1a03cf1e6f52a6959fc77eb
F ext/fts5/extract_api_docs.tcl a36e54ec777172ddd3f9a88daf593b00848368e0
F ext/fts5/fts5.h 7c9da96f2b9dcfa4dd94081fb2d87ec418d8cdb35b25df56756c334b6b558fd7
F ext/fts5/fts5Int.h d87fb17d12296613cdec2d1f4213ecd8840d3deb34837b6d3889b830d06baac4
F ext/fts5/fts5Int.h 0ec19a906a54c0e53f8a380c0ff70f11a866aa259490bc13aa39f8d2491800fd
F ext/fts5/fts5_aux.c dcc627d8b6e3fc773db528ff67b39955dab7b51628f9dba8e15849e5bedfd7fa
F ext/fts5/fts5_buffer.c 5a5fe0159752c0fb0a5a93c722e9db2662822709490769d482b76a6dc8aaca70
F ext/fts5/fts5_config.c d7523cba5e66da077233c023aecbc3e6a37978ff75a18131c5ab5b1229d5bac7
F ext/fts5/fts5_expr.c 840c88d55e78083a5e61a35968df877712ae28791b347eced1e98e3b337d2d3c
F ext/fts5/fts5_config.c 606a29f2962a8f4508923e6ad833974b32a3ab4093f63fd6de0fb33a87eed54c
F ext/fts5/fts5_expr.c 5661fe64f4f5a499710df9561075de84b743f01e808af46df4130a9ec343a0fd
F ext/fts5/fts5_hash.c 1cc0095646f5f3b46721aa112fb4f9bf29ae175cb5338f89dcec66ed97acfe75
F ext/fts5/fts5_index.c b062bdb836e195656aac8d6684e943585cff4bf7d7c593c80cb67c3b6cfef7ee
F ext/fts5/fts5_main.c 15dc14ea594ff2ea183f5e79c8f6fea14640ac7c4bd5d93ad1d506a4db80c998
F ext/fts5/fts5_index.c 6601d085d8e8cf4750ee49e2e1d18907582cc0aab78233d3b21bc240ba76a199
F ext/fts5/fts5_main.c bf637030722badf06667d28f7159e4c209dbafd7aa76c33f387104b78ad147e1
F ext/fts5/fts5_storage.c 801b4e3cd33786a60a07b6b01f86d0fbdf7e68325054e08d17176293a8081e99
F ext/fts5/fts5_tcl.c 39bcbae507f594aad778172fa914cad0f585bf92fd3b078c686e249282db0d95
F ext/fts5/fts5_test_mi.c 08c11ec968148d4cb4119d96d819f8c1f329812c568bac3684f5464be177d3ee
@@ -157,7 +157,7 @@ F ext/fts5/test/fts5connect.test 08030168fc96fc278fa81f28654fb7e90566f33aff269c0
F ext/fts5/test/fts5content.test 9517cc527a8e8a33949652d5c7b5e251f8c3d5ae3f23f01d4320e30f29a0336b
F ext/fts5/test/fts5corrupt.test 77ae6f41a7eba10620efb921cf7dbe218b0ef232b04519deb43581cb17a57ebe
F ext/fts5/test/fts5corrupt2.test 7453752ba12ce91690c469a6449d412561cc604b1dec994e16ab132952e7805f
F ext/fts5/test/fts5corrupt3.test f326d70e08acffcbd8a551edd72b5723db7d3a902d288d958014c81a111cae21
F ext/fts5/test/fts5corrupt3.test e188a43cecb3ff53b6236f862f82b2ec36962b9e39f20cb620dfa07aed70afa4
F ext/fts5/test/fts5corrupt4.test ea805c4d7c68b5f185b9db5d2060a7ae5875339738dd48203c92162f41e7ca91
F ext/fts5/test/fts5delete.test cbf87e3b8867c4d5cfcaed975c7475fd3f99d072bce2075fcedf43d1f82af775
F ext/fts5/test/fts5detail.test 31b240dbf6d44ac3507e2f8b65f29fdc12465ffd531212378c7ce1066766f54e
@@ -176,7 +176,7 @@ F ext/fts5/test/fts5fault7.test 0acbec416edb24b8881f154e99c31e9ccf73f539cfcd1640
F ext/fts5/test/fts5fault8.test 318238659d35f82ad215ecb57ca4c87486ea85d45dbeedaee42f148ff5105ee2
F ext/fts5/test/fts5fault9.test 098e6b894bbdf9b2192f994a30f4043673fb3f338b6b8ab1624c704422f39119
F ext/fts5/test/fts5faultA.test be4487576bff8c22cee6597d1893b312f306504a8c6ccd3c53ca85af12290c8c
F ext/fts5/test/fts5faultB.test e6d04f9ea7b21be1d89abb8df2cb4baf65b0453b744d5a805fcd3ef45ff86a7e
F ext/fts5/test/fts5faultB.test d606bdb8e81aaeb6f41de3fc9fc7ae315733f0903fbff05cf54f5b045b729ab5
F ext/fts5/test/fts5faultD.test cc5d1225556e356615e719c612e845d41bff7d5a
F ext/fts5/test/fts5first.test 3fcf2365c00a15fc9704233674789a3b95131d12de18a9b996159f6909dc8079
F ext/fts5/test/fts5full.test 49b565da02918c06e58f51f0b953b0302b96f155aa68baba24782b81570685e2
@@ -190,12 +190,13 @@ F ext/fts5/test/fts5matchinfo.test 79129ff6c9a2d86943b287a5a8caa7ee639f6dcf004d8
F ext/fts5/test/fts5merge.test e92a8db28b45931e7a9c7b1bbd36101692759d00274df74d83fd29d25d53b3a6
F ext/fts5/test/fts5merge2.test 3ebad1a59d6ad3fb66eff6523a09e95dc6367cbefb3cd73196801dea0425c8e2
F ext/fts5/test/fts5misc.test 5becd134b66f7370042968a2b127b92ea7748e249f16cb6a996f450812e89eec
F ext/fts5/test/fts5multi.test a15bc91cdb717492e6e1b66fec1c356cb57386b980c7ba5af1915f97fe878581
F ext/fts5/test/fts5multiclient.test 5ff811c028d6108045ffef737f1e9f05028af2458e456c0937c1d1b8dea56d45
F ext/fts5/test/fts5near.test 211477940142d733ac04fad97cb24095513ab2507073a99c2765c3ddd2ef58bd
F ext/fts5/test/fts5onepass.test f9b7d9b2c334900c6542a869760290e2ab5382af8fbd618834bf1fcc3e7b84da
F ext/fts5/test/fts5optimize.test 36a752d24c818792032e4ff502936fc9cc5ef938721696396fdc79214b2717f1
F ext/fts5/test/fts5phrase.test 13e5d8e9083077b3d9c74315b3c92ec723cc6eb37c8155e0bfe1bba00559f07b
F ext/fts5/test/fts5plan.test 00dc4c974938b509db7cb3680407f068ee6e9cc824f492f68cb741a7b679fe41
F ext/fts5/test/fts5plan.test 771b999d161e24fd803ce0290adb7c6e7c9b9cc2c6a0adb344813fb89473aa32
F ext/fts5/test/fts5porter.test 8d08010c28527db66bc3feebd2b8767504aaeb9b101a986342fa7833d49d0d15
F ext/fts5/test/fts5porter2.test 0d251a673f02fa13ca7f011654873b3add20745f7402f108600a23e52d8c7457
F ext/fts5/test/fts5prefix.test a0fa67b06650f2deaa7bf27745899d94e0fb547ad9ecbd08bfad98c04912c056
@@ -204,7 +205,7 @@ F ext/fts5/test/fts5rank.test c9fd4a1e36b4fa92d572ec13d846469b97da249d1c2f7fd3ee
F ext/fts5/test/fts5rebuild.test 55d6f17715cddbf825680dd6551efbc72ed916d8cf1cde40a46fc5d785b451e7
F ext/fts5/test/fts5restart.test 835ecc8f449e3919f72509ab58056d0cedca40d1fe04108ccf8ac4c2ba41f415
F ext/fts5/test/fts5rowid.test b8790ec170a8dc1942a15aef3db926a5f3061b1ff171013003d8297203a20ad6
F ext/fts5/test/fts5simple.test 313ad28ef38ebe25f0a1673dd18f2fac446e25feb15bbb0c223a65ea00594f72
F ext/fts5/test/fts5simple.test a298670508c1458b88ce6030440f26a30673931884eb5f4094ac1773b3ba217b
F ext/fts5/test/fts5simple2.test 258a1b0c590409bfa5271e872c79572b319d2a56554d0585f68f146a0da603f0
F ext/fts5/test/fts5simple3.test d5c74a9d3ca71bd5dd5cacb7c55b86ea12cdddfc8b1910e3de2995206898380f
F ext/fts5/test/fts5synonym.test 1651815b8008de170e8e600dcacc17521d765482ea8f074ae82cfa870d8bb7fb
@@ -281,7 +282,7 @@ F ext/misc/anycollseq.c 5ffdfde9829eeac52219136ad6aa7cd9a4edb3b15f4f2532de52f4a2
F ext/misc/appendvfs.c 3777f22ec1057dc4e5fd89f2fbddcc7a29fbeef1ad038c736c54411bb1967af7
F ext/misc/blobio.c a867c4c4617f6ec223a307ebfe0eabb45e0992f74dd47722b96f3e631c0edb2a
F ext/misc/btreeinfo.c 4f0ebf278f46e68e6306c667917766cebc5550fd35d5de17847988e22892d4d2
F ext/misc/carray.c ed96c218ea940b85c9a274c4d9c59fe9491c299147a38a8bba537687bd6c6005
F ext/misc/carray.c 91e9a7f512fda934894bed30464552fffa7d3073b5be04189ae0bd0c59f26bfd
F ext/misc/closure.c dbfd8543b2a017ae6b1a5843986b22ddf99ff126ec9634a2f4047cd14c85c243
F ext/misc/completion.c cec672d40604075bb341a7f11ac48393efdcd90a979269b8fe7977ea62d0547f
F ext/misc/compress.c dd4f8a6d0baccff3c694757db5b430f3bbd821d8686d1fc24df55cf9f035b189
@@ -294,7 +295,7 @@ F ext/misc/fileio.c 288e7230e0fe464d71b0694e2d8bdd3a353118ac2e31da3964b95f460f09
F ext/misc/fossildelta.c 7708651072eb5620ab21bbfb518d184f27b2c29c0131b09b9a2d8852a8016430
F ext/misc/fuzzer.c c4e27daf41433a64cad5265cd27dbcb891147e9994d0422200ce81ce9a54b625
F ext/misc/ieee754.c f190d0cc5182529acb15babd177781be1ac1718c
F ext/misc/json1.c 71ce4e39793b743fc7e4790bc3bab15598e95cab57ad8da4326fa640ae5e5310
F ext/misc/json1.c 66ccdfa63283adb2c015019b431eeee1f5af40a78d9aad10afd22c2c6db0e3b0
F ext/misc/memstat.c 3017a0832c645c0f8c773435620d663855f04690172316bd127270d1a7523d4d
F ext/misc/memtrace.c 7c0d115d2ef716ad0ba632c91e05bd119cb16c1aedf3bec9f06196ead2d5537b
F ext/misc/memvfs.c ab36f49e02ebcdf85a1e08dc4d8599ea8f343e073ac9e0bca18a98b7e1ec9567
@@ -352,6 +353,7 @@ F ext/rbu/rbufault2.test c81327a3ac2c385b9b954db3644d4e0df93eeebfc3de9f1f29975a1
F ext/rbu/rbufault3.test b2fcc9db5c982b869f67d1d4688d8cb515d5b92f58011fff95665f2e62cec179
F ext/rbu/rbufault4.test 03d2849c3df7d7bd14a622e789ff049e5080edd34a79cd432e01204db2a5930a
F ext/rbu/rbufts.test 0ae8d1da191c75bd776b86e24456db0fb6e97b7c944259fae5407ea55d23c31d
F ext/rbu/rbuhack.test 95e7b35e58d5b2a8d182dde1a404949edf077c07485e6c2bce8a7f582941e729
F ext/rbu/rbumisc.test 329986cf5dd51890c4eb906c2f960ebb773a79a64bed90f506b7c417825b37eb
F ext/rbu/rbumulti.test 5fb139058f37ddc5a113c5b93238de915b769b7792de41b44c983bc7c18cf5b9
F ext/rbu/rbupartial.test f25df014b8dbe3c5345851fba6e66f79ab237f57dc201b2d5f0dbae658ae5a4c
@@ -364,7 +366,7 @@ F ext/rbu/rbuvacuum.test 55e101e90168c2b31df6c9638fe73dc7f7cc666b6142266d1563697
F ext/rbu/rbuvacuum2.test b8e5b51dc8b2c0153373d024c0936be3f66f9234acbd6d0baab0869d56b14e6b
F ext/rbu/rbuvacuum3.test 8addd82e4b83b4c93fa47428eae4fd0dbf410f8512c186f38e348feb49ba03dc
F ext/rbu/rbuvacuum4.test a78898e438a44803eb2bc897ba3323373c9f277418e2d6d76e90f2f1dbccfd10
F ext/rbu/sqlite3rbu.c f3a3e09f575157052813be667d6ab3b54f47fb02e6e1c9f767ad7bb8f1fb90b3
F ext/rbu/sqlite3rbu.c d175cbd98baba39cdea85df1de376277ab207ef1e4af8071aa1c208bb4fccc84
F ext/rbu/sqlite3rbu.h 1dc88ab7bd32d0f15890ea08d23476c4198d3da3056985403991f8c9cd389812
F ext/rbu/test_rbu.c 03f6f177096a5f822d68d8e4069ad8907fe572c62ff2d19b141f59742821828a
F ext/repair/README.md 92f5e8aae749a4dae14f02eea8e1bb42d4db2b6ce5e83dbcdd6b1446997e0c15
@@ -468,7 +470,7 @@ F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6
F src/btree.c fdc4389b271bca30138db27dc2dfb9f52c2a7baaa44845aaf31a3c54663d837f
F src/btree.h c11446f07ec0e9dc85af8041cb0855c52f5359c8b2a43e47e02a685282504d89
F src/btreeInt.h 6111c15868b90669f79081039d19e7ea8674013f907710baa3c814dc3f8bfd3f
F src/build.c da5d5d82eb53cb004e9120277cfe93a9c3dd294871eae3d728ebd0faee84d969
F src/build.c 4814d55abb5553ac82763f6df9e185503d913f912cc0abea00965bb02912cc2d
F src/callback.c 25dda5e1c2334a367b94a64077b1d06b2553369f616261ca6783c48bcb6bda73
F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e
F src/ctime.c 1b0724e66f95f33b160b1af85caaf9cceb325d22abf39bd24df4f54a73982251
@@ -476,19 +478,19 @@ F src/date.c e1d8ac7102f3f283e63e13867acb0efa33861cf34f0faf4cdbaf9fa7a1eb7041
F src/dbpage.c 135eb3b5e74f9ef74bde5cec2571192c90c86984fa534c88bf4a055076fa19b7
F src/dbstat.c c12833de69cb655751487d2c5a59607e36be1c58ba1f4bd536609909ad47b319
F src/delete.c d08c9e01a2664afd12edcfa3a9c6578517e8ff8735f35509582693adbe0edeaf
F src/expr.c 10d90c4676047a75276446779d18fb3f7d3a1f9debc8b322e3772d2bd51f52ff
F src/expr.c 1e9a6da29e3e13c14783891e867e19a54e2731c6a9b58d011cc4f3b4742a59e4
F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007
F src/fkey.c 6b79f4c2447691aa9ac86e2a6a774b65f3b3dd053d4220a4893051a0de20f82e
F src/func.c 4ee36219698d50d672a28eca4adb0fd6b92e607a1883d318315e0d2fd5044467
F src/global.c d7a7a45a78ffe01302d61c271ed50474ef1b9d2d23bf17a46a58c8a1926424ee
F src/func.c ed33e38cd642058182a31a3f518f2e34f4bbe53aa483335705c153c4d3e50b12
F src/global.c a1a8d698762ddd9a1543aac26c1e0029b20fcc3fcb56bfa41ec8cea2368f2798
F src/hash.c 8d7dda241d0ebdafb6ffdeda3149a412d7df75102cecfc1021c98d6219823b19
F src/hash.h 9d56a9079d523b648774c1784b74b89bd93fac7b365210157482e4319a468f38
F src/hwtime.h 747c1bbe9df21a92e9c50f3bbec1de841dc5e5da
F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71
F src/insert.c 40557ebd69f4115e7a273f9304a8ab637a47ce44f3c6923396928f023967b5e8
F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa
F src/loadext.c a045bb3425a9a633cc0f78e93d9beda6866f4c0f15bfdee735aba7c6b39f5cc4
F src/main.c 51c55eb579eac4180bfcc6242741084710911350d2cd0c3fdd0f9fde55442128
F src/loadext.c 4ddc65ae13c0d93db0ceedc8b14a28c8c260513448b0eb8c5a2ac375e3b6a85d
F src/main.c 3851950717170ade4f6d718c18c6c7400ef5994c2a654679af2cff2ffd0fb2b9
F src/malloc.c 0f9da2a66b230a5785af94b9672126845099b57b70a32c987d04ac28c69da990
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
F src/mem1.c c12a42539b1ba105e3707d0e628ad70e611040d8f5e38cf942cee30c867083de
@@ -499,7 +501,7 @@ F src/memdb.c 02a5fcec19b9d40dd449ca802dc1b2e8f93f255fbf2a886277a3c3800d8d35db
F src/memjournal.c 7561c01c90958f3ba9bc6cb2d857123d932bdfa5539ea34427a0957b2e35154d
F src/msvc.h 3a15918220367a8876be3fa4f2abe423a861491e84b864fb2b7426bf022a28f8
F src/mutex.c bae36f8af32c22ad80bbf0ccebec63c252b6a2b86e4d3e42672ff287ebf4a604
F src/mutex.h 779d588e3b7756ec3ecf7d78cde1d84aba414f85
F src/mutex.h a7b2293c48db5f27007c3bdb21d438873637d12658f5a0bf8ad025bb96803c4a
F src/mutex_noop.c 9d4309c075ba9cc7249e19412d3d62f7f94839c4
F src/mutex_unix.c aaf9ebc3f89df28483c52208497a99a02cc3650011422fc9d4c57e4392f7fe58
F src/mutex_w32.c 7670d770c94bbfe8289bec9d7f1394c5a00a57c37f892aab6b6612d085255235
@@ -508,12 +510,12 @@ F src/os.c 20f7b32c1e8839999fa7e79756a6cdc3041b44d7fc635c25a1b9399180d1fbd9
F src/os.h 48388821692e87da174ea198bf96b1b2d9d83be5dfc908f673ee21fafbe0d432
F src/os_common.h b2f4707a603e36811d9b1a13278bffd757857b85
F src/os_setup.h 0dbaea40a7d36bf311613d31342e0b99e2536586
F src/os_unix.c 4ec5b1305ced509ca52c4c0cb3aeabed2ed3972147b4090cf94eb31d48caeb53
F src/os_unix.c a76a75f179cb233d54e505c3e0c84832224cfe5dfb3ee470bdcaf1ed29da57ab
F src/os_win.c 035a813cbd17f355bdcad7ab894af214a9c13a1db8aeac902365350b98cd45a7
F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a
F src/pager.c 422fd8cfa59fb9173eff36a95878904a0eeb0dcc62ba49350acc8b1e51c4dc7b
F src/pager.h 217921e81eb5fe455caa5cda96061959706bcdd29ddb57166198645ef7822ac3
F src/parse.y 6f284f7488ad9db9ae2762161e52bec2e9609462b98a3354fcc6e0ce7aa7be8d
F src/parse.y 50bfcb34be7320dd0cb875021a93ae6451c8f0b083f21b71934a1a3a9108015a
F src/pcache.c 385ff064bca69789d199a98e2169445dc16e4291fa807babd61d4890c3b34177
F src/pcache.h 4f87acd914cef5016fae3030343540d75f5b85a1877eed1a2a19b9f284248586
F src/pcache1.c 62714cbd1b7299a6e6a27a587b66b4fd3a836a84e1181e7f96f5c34a50917848
@@ -522,19 +524,19 @@ F src/pragma.h 40962d65b645bb3f08c1f4c456effd01c6e7f073f68ea25177e0c95e181cff75
F src/prepare.c 132484635a30f873ee7eccd47f93ed1932503863b93b28423b42332d81adffaf
F src/printf.c 9be6945837c839ba57837b4bc3af349eba630920fa5532aa518816defe42a7d4
F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384
F src/resolve.c 9891cf5fd155bb199f8b1ff5d1429b9f70484487f4c455bba94348d4cb6f829f
F src/resolve.c e021be0c1c4a2125fa38aabcd8dbb764bf5b2c889a948c30d3708430ec6ccd00
F src/rowset.c d977b011993aaea002cab3e0bb2ce50cf346000dff94e944d547b989f4b1fe93
F src/select.c 8685adae94dffa6e4542e2194e491d69e27d5b79fe72b219e9255b08e56eaf76
F src/shell.c.in e5fb91505f29ae9458cabf1a63bbd1faf6b4b34eabca33d0f75a06aacecca21b
F src/sqlite.h.in 50fc0914ccd347437db9a0278a47d7541df3a45eb6e641e9680750c6f98dad27
F src/select.c f509982c96bb24ccf57a0155fbe1e6184e0b8fb8866a04397dc41baa400e5240
F src/shell.c.in d70bcf630c4073eaa994fa74be98886c781918e794cb8b562be8df10f018e274
F src/sqlite.h.in 5725a6b20190a1e8d662077a1c1c8ea889ad7be90dd803f914c2de226f5fe6ab
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
F src/sqlite3ext.h cef696ce3293242c67b2339763608427bf72ee66f1f3a05389ac2a7b46001c31
F src/sqliteInt.h b1fca535f01f02ae6927dd44e760c6ab54c7a181e88f813d16b55a1bc95d13c0
F src/sqliteInt.h 246740eab76d3ac87f856f8d979567089e8749104c12932143a6ba570e38e415
F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b
F src/status.c 46e7aec11f79dad50965a5ca5fa9de009f7d6bde08be2156f1538a0a296d4d0e
F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34
F src/tclsqlite.c 50c93be3e1c03b4e6cf6756e5197afcfe7f5cd0497d83a7ac317cde09e19b290
F src/test1.c 8ce455da8dcec886a0e1e608da0fee7de67c8195b14517a8824a2a40c2d11fbf
F src/test1.c 17e1395cbddeb9226b756d723a7566b45b43b99a5f9f55afb4ff70888de6ad6f
F src/test2.c 3efb99ab7f1fc8d154933e02ae1378bac9637da5
F src/test3.c 61798bb0d38b915067a8c8e03f5a534b431181f802659a6616f9b4ff7d872644
F src/test4.c 405834f6a93ec395cc4c9bb8ecebf7c3d8079e7ca16ae65e82d01afd229694bb
@@ -555,7 +557,7 @@ F src/test_demovfs.c 86142ba864d4297d54c5b2e972e74f3141ae4b30f05b3a95824184ed2d3
F src/test_devsym.c 6109b45c3db3ef7b002320947ed448c027356ab8b885156ff535fd8684d4a571
F src/test_fs.c ba1e1dc18fd3159fdba0b9c4256f14032159785320dfbd6776eb9973cb75d480
F src/test_func.c 181f992e5495644434c4f0e3cc72362a78c295eb2cf3ff4d02498b8bde7aa276
F src/test_hexio.c 1d4469ca61ab202a1fcec6543f584d2407205e8d
F src/test_hexio.c d170d0e1a6431afdeac086a250d2595078288c2257615d37949355361399bcaa
F src/test_init.c 4413c211a94b62157ca4c145b3f27c497f03c664
F src/test_intarray.c 39b4181662a0f33a427748d87218e7578d913e683dc27eab7098bb41617cac71
F src/test_intarray.h d57ae92f420cda25e22790dac474d60961bd0c500cbaa3338a05152d4a669ef7
@@ -589,20 +591,20 @@ F src/test_window.c cdae419fdcea5bad6dcd9368c685abdad6deb59e9fc8b84b153de513d394
F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9
F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c
F src/tokenize.c d3615f0cbe4db5949503bf5916f3cd4fa5de855d5b4ef560f3b6dd5629423a1e
F src/treeview.c fc8c6c0a8a26afb3a97e3f844d65403dd27cf1450baf4415034fa4ccf00c4d7e
F src/treeview.c fddeb413159c3eeeaea3f496172f121cf3695606c461dc4e6dcee51417952df5
F src/trigger.c 845ccc08f60716c58aa28fe6470385c18ef8c4e1d88c93dcf449bc13d464eb2e
F src/update.c 7f05fad5e145248a00048aeb0bac78b8fdb4ed17216e14a6eb24c55596e87ee7
F src/upsert.c 710c91bb13e3c3fed5b6fe17cb13e09560bdd003ad8b8c51e6b16c80cfc48b10
F src/utf.c 2f0fac345c7660d5c5bd3df9e9d8d33d4c27f366bcfb09e07443064d751a0507
F src/util.c fffdfa627be74d69ef425f92db124e7148af449bb8a3286e79577c42bca84061
F src/vacuum.c 82dcec9e7b1afa980288718ad11bc499651c722d7b9f32933c4d694d91cb6ebf
F src/vdbe.c 145e417fda9377a809d9c754d4098de9a9620aec1bc3e4d2d4ca8f8d525dace3
F src/vdbe.c 7f43ed8e055a4290535d2e4520d33f0ac6cc00ef76a0c099e4c6bd85be74a6b9
F src/vdbe.h 3f2b571e702e77e6bf031f0236e554aedfae643e991f69000320f481408455cf
F src/vdbeInt.h e95de5129124d77f01439e6635012adfaf23c0017bff47296126143cf18bd0c6
F src/vdbeapi.c 95001d0f84ee3cda344fed98ca0d7961deb4fc836b83495630d0af1f7cc4789e
F src/vdbeaux.c 7ccf418141df1c7f87b0d69510523ae522abbe47c769d1b2c15120e88fac3eb9
F src/vdbeblob.c 253ed82894924c362a7fa3079551d3554cd1cdace39aa833da77d3bc67e7c1b1
F src/vdbemem.c 920285c3b7f5c64369e02da437dab71e9e91862df9c486541c14633739f91d75
F src/vdbemem.c d8e10d1773806105e62094c4ede0a4684f46caaf07667a45e6d461e94306b530
F src/vdbesort.c da75f505aba230060ce6472605a4aa6494f73eeb1071e1cc2643c3d4035e671b
F src/vdbetrace.c fa3bf238002f0bbbdfb66cc8afb0cea284ff9f148d6439bc1f6f2b4c3b7143f0
F src/vtab.c 5a0b7193d586991b3db30e343d6b59959906bfe8658a6a0a85709b20ca50bb49
@@ -610,13 +612,13 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9
F src/wal.c bbd6838bd79c0a32144d482fb0b6a9d2d1a252fb3b16d5005ec30f2f80413b0d
F src/wal.h 606292549f5a7be50b6227bd685fa76e3a4affad71bb8ac5ce4cb5c79f6a176a
F src/walker.c d5a94907dcac990e31976be9dc769d17f6a806782593d6aec9d760ee01ec22cd
F src/where.c 9685d5988b79b93ebbe46941fbdb60d14861bb0fe3f9126117ef1753acc69b64
F src/where.c 9f3f23efc45934e7b7ea6c0c1042420b73053e7c3264feef6faf9ce6fbd5df61
F src/whereInt.h 2c6bae136a7c0be6ff75dc36950d1968c67d005c8e51d7a9d77cb996bb4843d9
F src/wherecode.c 535c8e228478fd971b9a5b6cb6773995b0fbf7020d5989508a5094ce5b8cd95b
F src/whereexpr.c b3bbae199e7acd8d0fa822c9a29cbb822ef2b3d84d68de55a3d60b013f5d5da4
F src/window.c b1e56b1281538b5cdd796b4f6c6281549bef6f977aab63e2493704a2a9f31937
F src/whereexpr.c 05c283d26aa9c3f5d1bf13a5f6a573b43295b9db280eff18e26f97d7d7f119b4
F src/window.c 064f251451c8e2a1c76b6269229d911a651e119c6a5f522b6eaebf8dc8714041
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
F test/affinity2.test da465d3d490ab24ef64f7715b5953343a4967762b9350b29eb1462879ff3fb9e
F test/affinity2.test ce1aafc86e110685b324e9a763eab4f2a73f737842ec3b687bd965867de90627
F test/affinity3.test 6a101af2fc945ce2912f6fe54dd646018551710d
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
F test/aggnested.test 12106f0748e8e9bfc1a8e6840e203e051eae06a26ed13fc9fd5db108a8d6db54
@@ -768,8 +770,8 @@ F test/corruptH.test 79801d97ec5c2f9f3c87739aa1ec2eb786f96454
F test/corruptI.test a17bbf54fdde78d43cf3cc34b0057719fd4a173a3d824285b67dc5257c064c7b
F test/corruptJ.test 4d5ccc4bf959464229a836d60142831ef76a5aa4
F test/corruptK.test 5b4212fe346699831c5ad559a62c54e11c0611bdde1ea8423a091f9c01aa32af
F test/corruptL.test 865cb75ed971b72b5ee9ad9017befee6bd38794011cae69f00676d82c5a5dd69
F test/corruptM.test 04a4061b1979283851953217e411187be79e50f5e5e3ef340c3f8e564173aae1
F test/corruptL.test dfad96373bf9264d73039315ea6013994b90bf6776847adc7ec06b6fad3c04b2
F test/corruptM.test 7d574320e08c1b36caa3e47262061f186367d593a7e305d35f15289cc2c3e067
F test/cost.test 51f4fcaae6e78ad5a57096831259ed6c760e2ac6876836e91c00030fad385b34
F test/count.test cb2e0f934c6eb33670044520748d2ecccd46259c
F test/countofview.test e17d6e6688cf74f22783c9ec6e788c0790ee4fbbaee713affd00b1ac0bb39b86
@@ -858,7 +860,7 @@ F test/extraquick.test cb254400bd42bfb777ff675356aabf3287978f79
F test/fallocate.test 37a62e396a68eeede8f8d2ecf23573a80faceb630788d314d0a073d862616717
F test/filectrl.test 6e871c2d35dead1d9a88e176e8d2ca094fec6bb3
F test/filefmt.test f393e80c4b8d493b7a7f8f3809a8425bbf4292af1f5140f01cb1427798a2bbd4
F test/filter1.test 94a6d26588db0e4e7305e1f0985a99405e98dd034dc393dd6264603eed6645d4
F test/filter1.test c2f34e58ee82a60c3ee9b5b4c4f2004ec2f529dff2f473706eeffa684cbb6719
F test/filter2.tcl 44e525497ce07382915f01bd29ffd0fa49dab3adb87253b5e5103ba8f93393e8
F test/filter2.test 485cf95d1f6d6ceee5632201ca52a71868599836f430cdee42e5f7f14666e30a
F test/filterfault.test c08fb491d698e8df6c122c98f7db1c65ffcfcad2c1ab0e07fa8a5be1b34eaa8b
@@ -936,7 +938,7 @@ F test/fts3conf.test c84bbaec81281c1788aa545ac6e78a6bd6cde2bdbbce2da261690e3659f
F test/fts3corrupt.test 46b9ddda7f6588fd5a5b1f4bb4fc0618dc45010e7dddb8a3a188baf3197177ae
F test/fts3corrupt2.test bf55c3fa0b0dc8ea1c0fe5543623bd27714585da6a129038fd6999fe3b0d25f3
F test/fts3corrupt3.test 0d5b69a0998b4adf868cc301fc78f3d0707745f1d984ce044c205cdb764b491f
F test/fts3corrupt4.test d5389e14950e57333bfc972f262c90b5ba0e864a958df9e437e3aacd3a5570a7
F test/fts3corrupt4.test 545c50e70d1fe922b6efef12019a92829832f52993c5421086489ce72bde2251
F test/fts3corrupt5.test 0549f85ec4bd22e992f645f13c59b99d652f2f5e643dac75568bfd23a6db7ed5
F test/fts3cov.test cb932743da52a1c79a1ab8983e26c8121cf02263d6ff16e1f642e6f9b8348338
F test/fts3d.test 2bd8c97bcb9975f2334147173b4872505b6a41359a4f9068960a36afe07a679f
@@ -984,9 +986,11 @@ F test/fts4merge.test 1096e30b58ad616bd502141bfe5bfe4c3a518df89e958d41a5ed1ce322
F test/fts4merge2.test 5faa558d1b672f82b847d2a337465fa745e46891
F test/fts4merge3.test 8d9ccb4a3d41c4c617a149d6c4b13ad02de797d0
F test/fts4merge4.test d895b1057a7798b67e03455d0fa50e9ea836c47b
F test/fts4merge5.test 69932d85cda8a1c4dcfb742865900ed8fbda51724b8cf9a45bbe226dfd06c596
F test/fts4noti.test 5553d7bb2e20bf4a06b23e849352efc022ce6309
F test/fts4onepass.test d69ddc4ee3415e40b0c5d1d0408488a87614d4f63ba9c44f3e52db541d6b7cc7
F test/fts4opt.test 0fd0cc84000743ff2a883b9b84b4a5be07249f0ba790c8848a757164cdd46b2a
F test/fts4record.test a48508f69a84c9287c8019d3a1ae712f5730d8335ffaf8e2101e691d078950bb
F test/fts4rename.test 15fd9985c2bce6dea20da2245b22029ec89bd4710ed317c4c53abbe3cfd0c880
F test/fts4umlaut.test fcaca4471de7e78c9d1f7e8976e3e8704d7d8ad979d57a739d00f3f757380429
F test/fts4unicode.test ceca76422abc251818cb25dabe33d3c3970da5f7c90e1540f190824e6b3a7c95
@@ -1012,7 +1016,7 @@ F test/fuzzdata4.db b502c7d5498261715812dd8b3c2005bad08b3a26e6489414bd13926cd3e4
F test/fuzzdata5.db e35f64af17ec48926481cfaf3b3855e436bd40d1cfe2d59a9474cb4b748a52a5
F test/fuzzdata6.db 92a80e4afc172c24f662a10a612d188fb272de4a9bd19e017927c95f737de6d7
F test/fuzzdata7.db e7a86fd83dda151d160445d542e32e5c6019c541b3a74c2a525b6ac640639711
F test/fuzzdata8.db dc52be9b732f5bc1cdc0db0ff5b8e69b87bc8989b13a94eb8acaef63897a007c
F test/fuzzdata8.db c75b0fd1d28c262f9c3a9428393ff9c420ea5bdbe0b33c557a971915a94bab71
F test/fuzzer1.test 3d4c4b7e547aba5e5511a2991e3e3d07166cfbb8
F test/fuzzer2.test a85ef814ce071293bce1ad8dffa217cbbaad4c14
F test/fuzzerfault.test 8792cd77fd5bce765b05d0c8e01b9edcf8af8536
@@ -1053,7 +1057,7 @@ F test/index7.test 1d764c0cca45f5a76150b08e127ccc8d52492cfa788b5fafed4be784a351b
F test/index8.test bc2e3db70e8e62459aaa1bd7e4a9b39664f8f9d7
F test/index9.test 0aa3e509dddf81f93380396e40e9bb386904c1054924ba8fa9bcdfe85a8e7721
F test/indexedby.test a52c8c6abfae4fbfb51d99440de4ca1840dbacc606b05e29328a2a8ba7cd914e
F test/indexexpr1.test fb56f0b9a9d147b38979d154176f150b5e45fdd5d0162fab639a7f9478134fa3
F test/indexexpr1.test c26c8b352311c1deb30642cd0379e5cb94e416c7e9e0885e92d9e01554df2db9
F test/indexexpr2.test b580f378423bca443ffab47ada677203cfcf8a60f48a8aa20065f27c8f7739b5
F test/indexfault.test 98d78a8ff1f5335628b62f886a1cb7c7dac1ef6d48fa39c51ec871c87dce9811
F test/init.test 15c823093fdabbf7b531fe22cf037134d09587a7
@@ -1063,7 +1067,7 @@ F test/insert3.test 1b7db95a03ad9c5013fdf7d6722b6cd66ee55e30
F test/insert4.test 7802ada6ba8738661b9f6c0e26858d3375b40cc7180289fd350644cd7a08fec9
F test/insert5.test 394f96728d1258f406fe5f5aeb0aaf29487c39a6
F test/insertfault.test ac63d14ea3b49c573673a572f4014b9117383a03e497c58f308b5c776e4a7f74
F test/instr.test 9a8802f28437d8ade53fedfc47b2ca599b4e48ba
F test/instr.test 107df2b9b74a4b59315916b575590a08f2a714de0754abe541f10a0971d0a2a4
F test/instrfault.test 0f870b218ea17cd477bb19ed330eecdb460dd53a
F test/intarray.test bb976b0b3df0ebb6a2eddfb61768280440e672beba5460ed49679ea984ccf440
F test/interrupt.test 16ea879ec728cb76414c148c5f24afd5d1f91054
@@ -1101,7 +1105,7 @@ F test/laststmtchanges.test ae613f53819206b3222771828d024154d51db200
F test/lemon-test01.y 58b764610fd934e189ffbb0bbfa33d171b9cb06019b55bdc04d090d6767e11d7
F test/like.test 3d702d79bf871fa32985b1ce334294c587e3948d3ab972001e811a58577e8b3c
F test/like2.test 3b2ee13149ba4a8a60b59756f4e5d345573852da
F test/like3.test 62bf82ac674b7d4126e73532e1ad96cdcd8e1752a4ed90b28a6f98305f5a66aa
F test/like3.test 4f940ad275c006319950054a7a65661f476772171b82b6fdf795e4dda36f246f
F test/limit.test 0c99a27a87b14c646a9d583c7c89fd06c352663e
F test/limit2.test 9409b033284642a859fafc95f29a5a6a557bd57c1f0d7c3f554bd64ed69df77e
F test/loadext.test faa4f6eed07a5aac35d57fdd7bc07f8fc82464cfd327567c10cf0ba3c86cde04
@@ -1200,6 +1204,7 @@ F test/orderby6.test 8b38138ab0972588240b3fca0985d2e400432859
F test/orderby7.test 3d1383d52ade5b9eb3a173b3147fdd296f0202da
F test/orderby8.test 23ef1a5d72bd3adcc2f65561c654295d1b8047bd
F test/orderby9.test 87fb9548debcc2cd141c5299002dd94672fa76a3
F test/orderbyA.test df608e59efc2ef50c1eddf1a773b272de3252e9401bfec86d04b52fd973866d5
F test/oserror.test 1fc9746b83d778e70d115049747ba19c7fba154afce7cc165b09feb6ca6abbc5
F test/ossfuzz.c 18af635fa73d12a109b305faca727a734c1fa28a421b161d9d15c5a84a4998a2
F test/ossshell.c f125c5bd16e537a2549aa579b328dd1c59905e7ab1338dfc210e755bb7b69f17
@@ -1217,9 +1222,9 @@ F test/parser1.test 6ccdf5e459a5dc4673d3273dc311a7e9742ca952dd0551a6a6320d27035c
F test/pcache.test c8acbedd3b6fd0f9a7ca887a83b11d24a007972b
F test/pcache2.test af7f3deb1a819f77a6d0d81534e97d1cf62cd442
F test/percentile.test 4243af26b8f3f4555abe166f723715a1f74c77ff
F test/permutations.test 4282fb00e5ac0f8c2cd1be62652f6da4ac03ce3c58b7d785fa17f4684492a0e0
F test/permutations.test 8587800fe1a0eb01456a3f4500b821e54e3347e78acf11dbf05f4990530f6cee
F test/pg_common.tcl 222a1bad1c41c308fa366313cd7b51b3be7e9b21c8736a421b974ac941693b54
F test/pragma.test cf066fe0f7f5d49f4758de4986407b8676c61aaa7871599340d64f42a8edc352
F test/pragma.test 59becdfd720b80d463ab750f69f7118fde10dfd556aa5d554f3bf6b7e5ea7533
F test/pragma2.test e5d5c176360c321344249354c0c16aec46214c9f
F test/pragma3.test 8300aa9c63cff1027006ca34bf413a148abbd6dcd471fa9a1ded322fe18c0df9
F test/pragma4.test 1cb4b32f1a304ed9e291d7c4d49c91c2c8dc1b9450e6d2c1198b2cc895d40d77
@@ -1245,8 +1250,8 @@ F test/recover.test ccb8c2623902a92ebb76770edd075cb4f75a4760bb7afde38026572c6e79
F test/regexp1.test 497ea812f264d12b6198d6e50a76be4a1973a9d8
F test/regexp2.test 40e894223b3d6672655481493f1be12012f2b33c
F test/reindex.test cd9d6021729910ece82267b4f5e1b5ac2911a7566c43b43c176a6a4732e2118d
F test/releasetest.tcl 968fc1e8fd23e113fb8a04379747f3a9f2c12d207b2de85aeff5a825962e1cd7 x
F test/releasetest_data.tcl 4f55292d7e3e7995754373612a16b71f41be22dfded3a0375ccaf65c465d3765
F test/releasetest.tcl fb76d8fcc95ac29d6356cd9e52b726ab9e43a24082897618dfbcb7c2b0049153 x
F test/releasetest_data.tcl 9919fc6ac5bc92f8878fecfd1840db15999f660a6c9f609240b41aa62b885c88
F test/resetdb.test 8062cf10a09d8c048f8de7711e94571c38b38168db0e5877ba7561789e5eeb2b
F test/resolver01.test f4022acafda7f4d40eca94dbf16bc5fc4ac30ceb
F test/rollback.test 06680159bc6746d0f26276e339e3ae2f951c64812468308838e0a3362d911eaa
@@ -1413,6 +1418,7 @@ F test/threadtest3.c 38a612ea62854349ed66372f330a40d73c5cf956
F test/threadtest4.c c1e67136ceb6c7ec8184e56ac61db28f96bd2925
F test/time-wordcount.sh 8e0b0f8109367827ad5d58f5cc849705731e4b90
F test/tkt-02a8e81d44.test 6c80d9c7514e2a42d4918bf87bf6bc54f379110c
F test/tkt-18458b1a.test c543c4b8e8c7c2200579a635e72c15bc374a92d44eddb1d588d4fdeca9cca532
F test/tkt-26ff0c2d1e.test c15bec890c4d226c0da2f35ff30f9e84c169cfef90e73a8cb5cec11d723dfa96
F test/tkt-2a5629202f.test 0521bd25658428baa26665aa53ffed9367d33af2
F test/tkt-2d1a5c67d.test be1326f3061caec85085f4c9ee4490561ca037c0
@@ -1422,7 +1428,7 @@ F test/tkt-313723c356.test 4b306ad45c736cedf2f5221f6155b92143244b6d
F test/tkt-385a5b56b9.test 5204a7cba0e28c99df0acbf95af5e1af4d32965a7a14de6eccebf949607618b1
F test/tkt-38cb5df375.test f3cc8671f1eb604d4ae9cf886ed4366bec656678
F test/tkt-3998683a16.test 6d1d04d551ed1704eb3396ca87bb9ccc8c5c1eb7
F test/tkt-3a77c9714e.test b08bca26de1140bdf004a37716582a43d7bd8be8
F test/tkt-3a77c9714e.test 90e3e8455ee945a4076d4c44062b8845708af24a880355328fe7008f2047c9f0
F test/tkt-3fe897352e.test 27e26eb0f1811aeba4d65aba43a4c52e99da5e70
F test/tkt-4a03edc4c8.test 91c0e135888cdc3d4eea82406a44b05c8c1648d0
F test/tkt-4c86b126f2.test cbcc611becd0396890169ab23102dd70048bbc9a
@@ -1448,12 +1454,12 @@ F test/tkt-9a8b09f8e6.test b2ef151d0984b2ebf237760dbeaa50724e5a0667
F test/tkt-9d68c883.test 16f7cb96781ba579bc2e19bb14b4ad609d9774b6
F test/tkt-9f2eb3abac.test cb6123ac695a08b4454c3792fbe85108f67fabf8
F test/tkt-a7b7803e.test 159ef554234fa1f9fb318c751b284bd1cf858da4
F test/tkt-a7debbe0.test 27b977fea9d42021d9ef67e5811bdc56fd0b9599517e0244c528dddd3264ed4e
F test/tkt-a7debbe0.test 65a647034e3416d068f81e7d86fffc07edfae371c70b8761714edb56ec1c7521
F test/tkt-a8a0d2996a.test 002e1cde8fc30c39611b52cf981c88200b858765748556822da72e0d32fac73e
F test/tkt-b1d3a2e531.test 8f7576e41ca179289ee1a8fee28386fd8e4b0550
F test/tkt-b351d95f9.test d14a503c414c5c58fdde3e80f9a3cfef986498c0
F test/tkt-b72787b1.test a95e8cdad0b98af1853ac7f0afd4ab27b77bf5f3
F test/tkt-b75a9ca6b0.test 1bc0381538fd21f96a10dbabc10ffc51b5b2e5f412d34bae571273ca784003d7
F test/tkt-b75a9ca6b0.test ade89229d853a67a21bbd5e6e1e787a8f9d21f19908d1b7fca6bf3d4d5aa0767
F test/tkt-ba7cbfaedc.test b4c0deccc12aeb55cfdb57935b16b5d67c5a9877
F test/tkt-bd484a090c.test 60460bf946f79a79712b71f202eda501ca99b898
F test/tkt-bdc6bbbb38.test fc38bb09bdd440e3513a1f5f98fc60a075182d7d
@@ -1672,7 +1678,7 @@ F test/walslow.test c05c68d4dc2700a982f89133ce103a1a84cc285f
F test/walthread.test 14b20fcfa6ae152f5d8e12f5dc8a8a724b7ef189f5d8ef1e2ceab79f2af51747
F test/walvfs.test f1accd66c876e3a0f6b4bef5b18d13411062d0ff0a0016e32bb41570474e99fc
F test/wapp.tcl b440cd8cf57953d3a49e7ee81e6a18f18efdaf113b69f7d8482b0710a64566ec
F test/wapptest.tcl 3090239c59379d41e1a0644feb6683082fdb86edfab0c668973f8003f22c0e5d x
F test/wapptest.tcl 3cca775aede0591756a1fc0da55bbb3715d8c363873fd2cfdd4d555b0a4af57d x
F test/where.test 19c709c9f0f6ed12c23f909f6592aa55fba34269d5a2898537aa27a22b9ce650
F test/where2.test 478d2170637b9211f593120648858593bf2445a1
F test/where3.test 2341a294e17193a6b1699ea7f192124a5286ca6acfcc3f4b06d16c931fbcda2c
@@ -1703,8 +1709,8 @@ F test/win32lock.test fbf107c91d8f5512be5a5b87c4c42ab9fdd54972
F test/win32longpath.test 169c75a3b2e43481f4a62122510210c67b08f26d
F test/win32nolock.test ac4f08811a562e45a5755e661f45ca85892bdbbc
F test/window1.test 376a7c9c5b9df9868d92a6d9d455262e1b769f4410b19006f5f8c5507c2a7ed7
F test/window2.tcl a44834af6267be6e14882311ef8790bf5047f1b9bc25685ee1762d48dc24f1e7
F test/window2.test 2f3ae63e171dce7f2ac29a41020f4da413b1d7bdaba48ee124fd336b152e34c5
F test/window2.tcl 66db96fd9fd202bc31ee7f8ce7904cb469564864cff3f74e009bfef8102333f4
F test/window2.test af2a001ded703bb8f2474fb0edfef170d5aba00f5c1f2aa9f65935b5da13df90
F test/window3.tcl acea6e86a4324a210fd608d06741010ca83ded9fde438341cb978c49928faf03
F test/window3.test e9959a993c8a71e96433be8daaa1827d78b8921e4f12debd7bdbeb3c856ef3cb
F test/window4.tcl d732df0e81beedc0ba8a563ade68611d322d27303ad0c0c8e4444107c39e84ec
@@ -1715,8 +1721,9 @@ F test/window7.tcl 6a1210f05d40ec89c22960213a22cd3f98d4e2f2eb20646c83c8c30d4d761
F test/window7.test 1d31276961ae7801edc72173edaf7593e3cbc79c06d1f1f09e20d8418af403cd
F test/window8.tcl f2711aa3571e4e6b0dad98db8d95fd6cb8d9db0c92bbdf535f153b07606a1ce2
F test/window8.test c4331b27a6f66d69fa8f8bab10cc731db1a81d293ae108a68f7c3487fa94e65b
F test/window9.test 20a6b590be718b6bc98a5356d4396d6cdf19329c547da084fa225b92d68e1693
F test/window9.test ae8be07be05a5a4c8ead1818ac5d45f278b8dd456e589d67f24270b0070c35a0
F test/windowA.test 6d63dc1260daa17141a55007600581778523a8b420629f1282d2acfc36af23be
F test/windowB.test 7a983ea1cc1cf72be7f378e4b32f6cb2d73014c5cd8b25aaee825164cd4269e5
F test/windowerr.tcl f5acd6fbc210d7b5546c0e879d157888455cd4a17a1d3f28f07c1c8a387019e0
F test/windowerr.test a8b752402109c15aa1c5efe1b93ccb0ce1ef84fa964ae1cd6684dd0b3cc1819b
F test/windowfault.test a90b397837209f15e54afa62e8be39b2759a0101fae04e05a08bcc50e243a452
@@ -1725,13 +1732,13 @@ F test/with2.test e0030e2f0267a910d6c0e4f46f2dfe941c1cc0d4f659ba69b3597728e7e8f1
F test/with3.test b5f1372097690c6ef84db2f13fc7e64a88c7263c3f88493605f90597e8a68d45
F test/with4.test 257be66c0c67fee1defbbac0f685c3465e2cad037f21ce65f23f86084f198205
F test/withM.test 693b61765f2b387b5e3e24a4536e2e82de15ff64
F test/without_rowid1.test f40c2757272ce171b88e4227f14450db2c4d42800d447baa7656a65562d2f8d9
F test/without_rowid1.test 0abe18762b74714580c1d4d00a8e540e58966d3e46aae41ddb1a1d2c88c9277d
F test/without_rowid2.test af260339f79d13cb220288b67cd287fbcf81ad99
F test/without_rowid3.test ea4b59dd1b0d7f5f5e4b7cca978cdb905752a9d7c57dc4344a591dba765a3691
F test/without_rowid4.test 4e08bcbaee0399f35d58b5581881e7a6243d458a
F test/without_rowid5.test 89b1c587bd92a0590e440da33e7666bf4891572a
F test/without_rowid6.test 3c1bbf0eb81c672115933158b62b009e67cf1a7f8c2c612bbce63a7385efa18e
F test/without_rowid7.test 0e0d7be00f05f54898e20e07bcc947cd97b42d7106021fa0d2897324bc6d330e
F test/without_rowid6.test 8463b20098e9f75a501a9f17dfb42fffc79068eac0b2775fe56ef2281d2df45e
F test/without_rowid7.test d7c59a93d726b55812d620f8f284e01904a5b85f9ee9eea8f2f68571a5e8c40e
F test/wordcount.c d721a4b6fae93e6e33449700bce1686bc23257c27425bc3ef1599dc912adec66
F test/writecrash.test f1da7f7adfe8d7f09ea79b42e5ca6dcc41102f27f8e334ad71539501ddd910cc
F test/zeroblob.test 07a5b11ab591d1f26c626945fb7f228f68b993533b2ada77273edf6ee29db174
@@ -1759,7 +1766,7 @@ F tool/genfkey.test b6afd7b825d797a1e1274f519ab5695373552ecad5cd373530c63533638a
F tool/getlock.c f4c39b651370156cae979501a7b156bdba50e7ce
F tool/index_usage.c 9ec344d29cbeb03fdc0fce668eedfb7495792170de933adf95cf8d6904a166ad
F tool/kvtest-speed.sh 4761a9c4b3530907562314d7757995787f7aef8f
F tool/lemon.c c9848ef9694689d244a5097238ca1f83df85cc52c80ad149a4cf49595a0ee9c2
F tool/lemon.c 61d5f0af1eff8f754b75ddca668c9897fd30759e389bfffb42ce9e4d38fd4746
F tool/lempar.c eb2841e2a7fd484cf44b1f526b06e7ab0f216d2f41818bf9485e8f38e3d1db19
F tool/libvers.c caafc3b689638a1d88d44bc5f526c2278760d9b9
F tool/loadfts.c c3c64e4d5e90e8ba41159232c2189dba4be7b862
@@ -1798,7 +1805,7 @@ F tool/showstat4.c 0682ebea7abf4d3657f53c4a243f2e7eab48eab344ed36a94bb75dcd19a5c
F tool/showwal.c ad9d768f96ca6199ad3a8c9562d679680bd032dd01204ea3e5ea6fb931d81847
F tool/soak1.tcl 8d407956e1a45b485a8e072470a3e629a27037fe
F tool/spaceanal.tcl 4bfd19aad7eb3ce0372ef0255f58035e0bba4ff5e9acfd763a10c6fb365c8dec
F tool/speed-check.sh 27c7fe178d5b2f7c90a04a127907acda0bfe637fa85b13c43e03e5ed39b008b6
F tool/speed-check.sh 2b042d703a9472f08c3b13be27afac658426f8e4fc87cd2d575953fda86f08d1
F tool/speedtest.tcl 06c76698485ccf597b9e7dbb1ac70706eb873355
F tool/speedtest16.c ecb6542862151c3e6509bbc00509b234562ae81e
F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
@@ -1840,10 +1847,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
P cb3e2be674316e1d39968eb6567f1fe1b72f9d89af49640a9e83f944979c4cf0
R 8499ff2bdbcbd0ce456fbfc5655f865d
T *branch * tkt-a7debbe0.
T *sym-tkt-a7debbe0. *
T -sym-trunk *
P 4b73e151cdb4b89bdd2f1bab5c0378500234ce6c479cc1d8cd4e006be79d1162
Q +087b8b41c6ed76b55c11315e7e95679d67590be20ae21108b593d00bb7d1c57a
R f1bc15780a98eb9fb1abdadc164e3b34
U dan
Z b93432e9313cfc8d7991fd66b06bef63
Z 02ec0c40b41079c9dff32d6e22ece993
+1 -1
View File
@@ -1 +1 @@
1863b7bf12521bdd2b51c5b8d3a4634bff3e15d3713e0b5343952df7da02f794
56869f54f31186231a4467f10208bcc08d9edae23c6e21831d6d3dff47da51de
+2 -1
View File
@@ -2816,7 +2816,8 @@ void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView, int noErr){
}
#endif
if( sqlite3StrNICmp(pTab->zName, "sqlite_", 7)==0
&& sqlite3StrNICmp(pTab->zName, "sqlite_stat", 11)!=0 ){
&& sqlite3StrNICmp(pTab->zName+7, "stat", 4)!=0
&& sqlite3StrNICmp(pTab->zName+7, "parameters", 10)!=0 ){
sqlite3ErrorMsg(pParse, "table %s may not be dropped", pTab->zName);
goto exit_drop_table;
}
+22 -4
View File
@@ -905,7 +905,7 @@ Expr *sqlite3ExprAnd(Parse *pParse, Expr *pLeft, Expr *pRight){
}else if( ExprAlwaysFalse(pLeft) || ExprAlwaysFalse(pRight) ){
sqlite3ExprUnmapAndDelete(pParse, pLeft);
sqlite3ExprUnmapAndDelete(pParse, pRight);
return sqlite3ExprAlloc(db, TK_INTEGER, &sqlite3IntTokens[0], 0);
return sqlite3Expr(db, TK_INTEGER, "0");
}else{
return sqlite3PExpr(pParse, TK_AND, pLeft, pRight);
}
@@ -2867,6 +2867,7 @@ void sqlite3CodeRhsOfIN(
/* Subroutine return */
sqlite3VdbeAddOp1(v, OP_Return, pExpr->y.sub.regReturn);
sqlite3VdbeChangeP1(v, pExpr->y.sub.iAddr-1, sqlite3VdbeCurrentAddr(v)-1);
sqlite3ClearTempRegCache(pParse);
}
}
#endif /* SQLITE_OMIT_SUBQUERY */
@@ -2958,11 +2959,21 @@ int sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){
sqlite3VdbeAddOp2(v, OP_Integer, 0, dest.iSDParm);
VdbeComment((v, "Init EXISTS result"));
}
pLimit = sqlite3ExprAlloc(pParse->db, TK_INTEGER,&sqlite3IntTokens[1], 0);
if( pSel->pLimit ){
sqlite3ExprDelete(pParse->db, pSel->pLimit->pLeft);
/* The subquery already has a limit. If the pre-existing limit is X
** then make the new limit X<>0 so that the new limit is either 1 or 0 */
sqlite3 *db = pParse->db;
pLimit = sqlite3Expr(db, TK_INTEGER, "0");
if( pLimit ){
pLimit->affExpr = SQLITE_AFF_NUMERIC;
pLimit = sqlite3PExpr(pParse, TK_NE,
sqlite3ExprDup(db, pSel->pLimit->pLeft, 0), pLimit);
}
sqlite3ExprDelete(db, pSel->pLimit->pLeft);
pSel->pLimit->pLeft = pLimit;
}else{
/* If there is no pre-existing limit add a limit of 1 */
pLimit = sqlite3Expr(pParse->db, TK_INTEGER, "1");
pSel->pLimit = sqlite3PExpr(pParse, TK_LIMIT, pLimit, 0);
}
pSel->iLimit = 0;
@@ -2977,6 +2988,7 @@ int sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){
/* Subroutine return */
sqlite3VdbeAddOp1(v, OP_Return, pExpr->y.sub.regReturn);
sqlite3VdbeChangeP1(v, pExpr->y.sub.iAddr-1, sqlite3VdbeCurrentAddr(v)-1);
sqlite3ClearTempRegCache(pParse);
}
return rReg;
@@ -4944,7 +4956,8 @@ int sqlite3ExprCompare(Parse *pParse, Expr *pA, Expr *pB, int iTab){
){
if( pA->iColumn!=pB->iColumn ) return 2;
if( pA->op2!=pB->op2 ) return 2;
if( pA->iTable!=pB->iTable
if( pA->op!=TK_IN
&& pA->iTable!=pB->iTable
&& (pA->iTable!=iTab || NEVER(pB->iTable>=0)) ) return 2;
}
}
@@ -5608,6 +5621,11 @@ void sqlite3ReleaseTempRange(Parse *pParse, int iReg, int nReg){
/*
** Mark all temporary registers as being unavailable for reuse.
**
** Always invoke this procedure after coding a subroutine or co-routine
** that might be invoked from other parts of the code, to ensure that
** the sub/co-routine does not use registers in common with the code that
** invokes the sub/co-routine.
*/
void sqlite3ClearTempRegCache(Parse *pParse){
pParse->nTempReg = 0;
+21 -2
View File
@@ -203,6 +203,8 @@ static void instrFunc(
int N = 1;
int isText;
unsigned char firstChar;
sqlite3_value *pC1 = 0;
sqlite3_value *pC2 = 0;
UNUSED_PARAMETER(argc);
typeHaystack = sqlite3_value_type(argv[0]);
@@ -215,12 +217,22 @@ static void instrFunc(
zHaystack = sqlite3_value_blob(argv[0]);
zNeedle = sqlite3_value_blob(argv[1]);
isText = 0;
}else{
}else if( typeHaystack!=SQLITE_BLOB && typeNeedle!=SQLITE_BLOB ){
zHaystack = sqlite3_value_text(argv[0]);
zNeedle = sqlite3_value_text(argv[1]);
isText = 1;
}else{
pC1 = sqlite3_value_dup(argv[0]);
zHaystack = sqlite3_value_text(pC1);
if( zHaystack==0 ) goto endInstrOOM;
nHaystack = sqlite3_value_bytes(pC1);
pC2 = sqlite3_value_dup(argv[1]);
zNeedle = sqlite3_value_text(pC2);
if( zNeedle==0 ) goto endInstrOOM;
nNeedle = sqlite3_value_bytes(pC2);
isText = 1;
}
if( zNeedle==0 || (nHaystack && zHaystack==0) ) return;
if( zNeedle==0 || (nHaystack && zHaystack==0) ) goto endInstrOOM;
firstChar = zNeedle[0];
while( nNeedle<=nHaystack
&& (zHaystack[0]!=firstChar || memcmp(zHaystack, zNeedle, nNeedle)!=0)
@@ -234,6 +246,13 @@ static void instrFunc(
if( nNeedle>nHaystack ) N = 0;
}
sqlite3_result_int(context, N);
endInstr:
sqlite3_value_free(pC1);
sqlite3_value_free(pC2);
return;
endInstrOOM:
sqlite3_result_error_nomem(context);
goto endInstr;
}
/*
-8
View File
@@ -271,14 +271,6 @@ SQLITE_WSD struct Sqlite3Config sqlite3Config = {
*/
FuncDefHash sqlite3BuiltinFunctions;
/*
** Constant tokens for values 0 and 1.
*/
const Token sqlite3IntTokens[] = {
{ "0", 1 },
{ "1", 1 }
};
#ifdef VDBE_PROFILE
/*
** The following performance counter can be used in place of
+4
View File
@@ -463,7 +463,11 @@ static const sqlite3_api_routines sqlite3Apis = {
sqlite3_stmt_isexplain,
sqlite3_value_frombind,
/* Version 3.30.0 and later */
#ifndef SQLITE_OMIT_VIRTUALTABLE
sqlite3_drop_modules,
#else
0,
#endif
};
/*
+1 -1
View File
@@ -1719,7 +1719,7 @@ int sqlite3CreateFunc(
assert( SQLITE_FUNC_CONSTANT==SQLITE_DETERMINISTIC );
assert( SQLITE_FUNC_DIRECT==SQLITE_DIRECTONLY );
extraFlags = enc & (SQLITE_DETERMINISTIC|SQLITE_DIRECTONLY);
extraFlags = enc & (SQLITE_DETERMINISTIC|SQLITE_DIRECTONLY|SQLITE_SUBTYPE);
enc &= (SQLITE_FUNC_ENCMASK|SQLITE_ANY);
#ifndef SQLITE_OMIT_UTF16
+1
View File
@@ -67,4 +67,5 @@
#define MUTEX_LOGIC(X)
#else
#define MUTEX_LOGIC(X) X
int sqlite3_mutex_held(sqlite3_mutex*);
#endif /* defined(SQLITE_MUTEX_OMIT) */
+38 -14
View File
@@ -105,13 +105,29 @@
# include <sys/param.h>
#endif /* SQLITE_ENABLE_LOCKING_STYLE */
#if defined(__APPLE__) && ((__MAC_OS_X_VERSION_MIN_REQUIRED > 1050) || \
(__IPHONE_OS_VERSION_MIN_REQUIRED > 2000))
# if (!defined(TARGET_OS_EMBEDDED) || (TARGET_OS_EMBEDDED==0)) \
&& (!defined(TARGET_IPHONE_SIMULATOR) || (TARGET_IPHONE_SIMULATOR==0))
# define HAVE_GETHOSTUUID 1
# else
# warning "gethostuuid() is disabled."
/*
** Try to determine if gethostuuid() is available based on standard
** macros. This might sometimes compute the wrong value for some
** obscure platforms. For those cases, simply compile with one of
** the following:
**
** -DHAVE_GETHOSTUUID=0
** -DHAVE_GETHOSTUUID=1
**
** None if this matters except when building on Apple products with
** -DSQLITE_ENABLE_LOCKING_STYLE.
*/
#ifndef HAVE_GETHOSTUUID
# define HAVE_GETHOSTUUID 0
# if defined(__APPLE__) && ((__MAC_OS_X_VERSION_MIN_REQUIRED > 1050) || \
(__IPHONE_OS_VERSION_MIN_REQUIRED > 2000))
# if (!defined(TARGET_OS_EMBEDDED) || (TARGET_OS_EMBEDDED==0)) \
&& (!defined(TARGET_IPHONE_SIMULATOR) || (TARGET_IPHONE_SIMULATOR==0))
# undef HAVE_GETHOSTUUID
# define HAVE_GETHOSTUUID 1
# else
# warning "gethostuuid() is disabled."
# endif
# endif
#endif
@@ -5824,7 +5840,7 @@ static int getFileMode(
** If the SQLITE_ENABLE_8_3_NAMES option is enabled, then the
** original filename is unavailable. But 8_3_NAMES is only used for
** FAT filesystems and permissions do not matter there, so just use
** the default permissions.
** the default permissions. In 8_3_NAMES mode, leave *pMode set to zero.
*/
static int findCreateFileMode(
const char *zPath, /* Path of file (possibly) being created */
@@ -6059,11 +6075,19 @@ static int unixOpen(
goto open_finished;
}
/* If this process is running as root and if creating a new rollback
** journal or WAL file, set the ownership of the journal or WAL to be
** the same as the original database.
/* The owner of the rollback journal or WAL file should always be the
** same as the owner of the database file. Try to ensure that this is
** the case. The chown() system call will be a no-op if the current
** process lacks root privileges, be we should at least try. Without
** this step, if a root process opens a database file, it can leave
** behinds a journal/WAL that is owned by root and hence make the
** database inaccessible to unprivileged processes.
**
** If openMode==0, then that means uid and gid are not set correctly
** (probably because SQLite is configured to use 8+3 filename mode) and
** in that case we do not want to attempt the chown().
*/
if( flags & (SQLITE_OPEN_WAL|SQLITE_OPEN_MAIN_JOURNAL) ){
if( openMode && (flags & (SQLITE_OPEN_WAL|SQLITE_OPEN_MAIN_JOURNAL))!=0 ){
robustFchown(fd, uid, gid);
}
}
@@ -6921,7 +6945,7 @@ int sqlite3_hostid_num = 0;
#define PROXY_HOSTIDLEN 16 /* conch file host id length */
#ifdef HAVE_GETHOSTUUID
#if HAVE_GETHOSTUUID
/* Not always defined in the headers as it ought to be */
extern int gethostuuid(uuid_t id, const struct timespec *wait);
#endif
@@ -6932,7 +6956,7 @@ extern int gethostuuid(uuid_t id, const struct timespec *wait);
static int proxyGetHostID(unsigned char *pHostID, int *pError){
assert(PROXY_HOSTIDLEN == sizeof(uuid_t));
memset(pHostID, 0, PROXY_HOSTIDLEN);
#ifdef HAVE_GETHOSTUUID
#if HAVE_GETHOSTUUID
{
struct timespec timeout = {1, 0}; /* 1 sec timeout */
if( gethostuuid(pHostID, &timeout) ){
+1 -1
View File
@@ -1181,7 +1181,7 @@ expr(A) ::= expr(A) between_op(N) expr(X) AND expr(Y). [BETWEEN] {
** regardless of the value of expr1.
*/
sqlite3ExprUnmapAndDelete(pParse, A);
A = sqlite3ExprAlloc(pParse->db, TK_INTEGER,&sqlite3IntTokens[N],1);
A = sqlite3Expr(pParse->db, TK_INTEGER, N ? "1" : "0");
}else{
A = sqlite3PExpr(pParse, TK_IN, A, 0);
if( A ){
+7
View File
@@ -96,6 +96,13 @@ static void resolveAlias(
pExpr->u.zToken = sqlite3DbStrDup(db, pExpr->u.zToken);
pExpr->flags |= EP_MemToken;
}
if( ExprHasProperty(pExpr, EP_WinFunc) ){
if( pExpr->y.pWin!=0 ){
pExpr->y.pWin->pOwner = pExpr;
}else{
assert( db->mallocFailed );
}
}
sqlite3DbFree(db, pDup);
}
ExprSetProperty(pExpr, EP_Alias);
+52 -24
View File
@@ -3418,7 +3418,6 @@ typedef struct SubstContext {
int iNewTable; /* New table number */
int isLeftJoin; /* Add TK_IF_NULL_ROW opcodes on each replacement */
ExprList *pEList; /* Replacement expressions */
int bFlattener; /* True for query-flattener, false otherwise */
} SubstContext;
/* Forward Declarations */
@@ -3480,9 +3479,9 @@ static Expr *substExpr(
sqlite3ExprDelete(db, pExpr);
pExpr = pNew;
/* If this call is part of query-flattening, ensure that the
** new expression has an implicit collation sequence. */
if( pSubst->bFlattener && pExpr ){
/* Ensure that the expression now has an implicit collation sequence,
** just as it did when it was a column of a view or sub-query. */
if( pExpr ){
if( pExpr->op!=TK_COLUMN && pExpr->op!=TK_COLLATE ){
CollSeq *pColl = sqlite3ExprCollSeq(pSubst->pParse, pExpr);
pExpr = sqlite3ExprAddCollateString(pSubst->pParse, pExpr,
@@ -4056,7 +4055,6 @@ static int flattenSubquery(
x.iNewTable = iNewParent;
x.isLeftJoin = isLeftJoin;
x.pEList = pSub->pEList;
x.bFlattener = 1;
substSelect(&x, pParent, 0);
}
@@ -4382,7 +4380,6 @@ static int pushDownWhereTerms(
x.iNewTable = iCursor;
x.isLeftJoin = 0;
x.pEList = pSubq->pEList;
x.bFlattener = 0;
pNew = substExpr(&x, pNew);
if( pSubq->selFlags & SF_Aggregate ){
pSubq->pHaving = sqlite3ExprAnd(pParse, pSubq->pHaving, pNew);
@@ -5359,6 +5356,19 @@ static void updateAccumulator(Parse *pParse, int regAcc, AggInfo *pAggInfo){
assert( !IsWindowFunc(pF->pExpr) );
if( ExprHasProperty(pF->pExpr, EP_WinFunc) ){
Expr *pFilter = pF->pExpr->y.pWin->pFilter;
if( pAggInfo->nAccumulator
&& (pF->pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL)
){
if( regHit==0 ) regHit = ++pParse->nMem;
/* If this is the first row of the group (regAcc==0), clear the
** "magnet" register regHit so that the accumulator registers
** are populated if the FILTER clause jumps over the the
** invocation of min() or max() altogether. Or, if this is not
** the first row (regAcc==1), set the magnet register so that the
** accumulators are not populated unless the min()/max() is invoked and
** indicates that they should be. */
sqlite3VdbeAddOp2(v, OP_Copy, regAcc, regHit);
}
addrNext = sqlite3VdbeMakeLabel(pParse);
sqlite3ExprIfFalse(pParse, pFilter, addrNext, SQLITE_JUMPIFNULL);
}
@@ -5409,6 +5419,7 @@ static void updateAccumulator(Parse *pParse, int regAcc, AggInfo *pAggInfo){
for(i=0, pC=pAggInfo->aCol; i<pAggInfo->nAccumulator; i++, pC++){
sqlite3ExprCode(pParse, pC->pExpr, pC->iMem);
}
pAggInfo->directMode = 0;
if( addrHitTest ){
sqlite3VdbeJumpHere(v, addrHitTest);
@@ -5454,7 +5465,7 @@ static int havingToWhereExprCb(Walker *pWalker, Expr *pExpr){
Select *pS = pWalker->u.pSelect;
if( sqlite3ExprIsConstantOrGroupBy(pWalker->pParse, pExpr, pS->pGroupBy) ){
sqlite3 *db = pWalker->pParse->db;
Expr *pNew = sqlite3ExprAlloc(db, TK_INTEGER, &sqlite3IntTokens[1], 0);
Expr *pNew = sqlite3Expr(db, TK_INTEGER, "1");
if( pNew ){
Expr *pWhere = pS->pWhere;
SWAP(Expr, *pNew, *pExpr);
@@ -6212,23 +6223,35 @@ int sqlite3Select(
}
assert( 66==sqlite3LogEst(100) );
if( p->nSelectRow>66 ) p->nSelectRow = 66;
/* If there is both a GROUP BY and an ORDER BY clause and they are
** identical, then it may be possible to disable the ORDER BY clause
** on the grounds that the GROUP BY will cause elements to come out
** in the correct order. It also may not - the GROUP BY might use a
** database index that causes rows to be grouped together as required
** but not actually sorted. Either way, record the fact that the
** ORDER BY and GROUP BY clauses are the same by setting the orderByGrp
** variable. */
if( sSort.pOrderBy && pGroupBy->nExpr==sSort.pOrderBy->nExpr ){
int ii;
/* The GROUP BY processing doesn't care whether rows are delivered in
** ASC or DESC order - only that each group is returned contiguously.
** So set the ASC/DESC flags in the GROUP BY to match those in the
** ORDER BY to maximize the chances of rows being delivered in an
** order that makes the ORDER BY redundant. */
for(ii=0; ii<pGroupBy->nExpr; ii++){
u8 sortFlags = sSort.pOrderBy->a[ii].sortFlags & KEYINFO_ORDER_DESC;
pGroupBy->a[ii].sortFlags = sortFlags;
}
if( sqlite3ExprListCompare(pGroupBy, sSort.pOrderBy, -1)==0 ){
orderByGrp = 1;
}
}
}else{
assert( 0==sqlite3LogEst(1) );
p->nSelectRow = 0;
}
/* If there is both a GROUP BY and an ORDER BY clause and they are
** identical, then it may be possible to disable the ORDER BY clause
** on the grounds that the GROUP BY will cause elements to come out
** in the correct order. It also may not - the GROUP BY might use a
** database index that causes rows to be grouped together as required
** but not actually sorted. Either way, record the fact that the
** ORDER BY and GROUP BY clauses are the same by setting the orderByGrp
** variable. */
if( sqlite3ExprListCompare(pGroupBy, sSort.pOrderBy, -1)==0 ){
orderByGrp = 1;
}
/* Create a label to jump to when we want to abort the query */
addrEnd = sqlite3VdbeMakeLabel(pParse);
@@ -6584,13 +6607,18 @@ int sqlite3Select(
{
int regAcc = 0; /* "populate accumulators" flag */
/* If there are accumulator registers but no min() or max() functions,
** allocate register regAcc. Register regAcc will contain 0 the first
** time the inner loop runs, and 1 thereafter. The code generated
** by updateAccumulator() only updates the accumulator registers if
** regAcc contains 0. */
/* If there are accumulator registers but no min() or max() functions
** without FILTER clauses, allocate register regAcc. Register regAcc
** will contain 0 the first time the inner loop runs, and 1 thereafter.
** The code generated by updateAccumulator() uses this to ensure
** that the accumulator registers are (a) updated only once if
** there are no min() or max functions or (b) always updated for the
** first row visited by the aggregate, so that they are updated at
** least once even if the FILTER clause means the min() or max()
** function visits zero rows. */
if( sAggInfo.nAccumulator ){
for(i=0; i<sAggInfo.nFunc; i++){
if( ExprHasProperty(sAggInfo.aFunc[i].pExpr, EP_WinFunc) ) continue;
if( sAggInfo.aFunc[i].pFunc->funcFlags&SQLITE_FUNC_NEEDCOLL ) break;
}
if( i==sAggInfo.nFunc ){
+18 -8
View File
@@ -3588,6 +3588,8 @@ static const char *(azHelp[]) = {
" --freelist-corrupt Assume the freelist is corrupt",
" --recovery-db NAME Store recovery metadata in database file NAME",
" --lost-and-found TABLE Alternative name for the lost-and-found table",
" --no-rowids Do not attempt to recover rowid values",
" that are not also INTEGER PRIMARY KEYs",
#endif
".restore ?DB? FILE Restore content of DB (default \"main\") from FILE",
".save FILE Write in-memory database into FILE",
@@ -6592,6 +6594,7 @@ static int recoverDatabaseCmd(ShellState *pState, int nArg, char **azArg){
RecoverTable *pOrphan = 0;
int bFreelist = 1; /* 0 if --freelist-corrupt is specified */
int bRowids = 1; /* 0 if --no-rowids */
for(i=1; i<nArg; i++){
char *z = azArg[i];
int n;
@@ -6607,6 +6610,9 @@ static int recoverDatabaseCmd(ShellState *pState, int nArg, char **azArg){
if( n<=15 && memcmp("-lost-and-found", z, n)==0 && i<(nArg-1) ){
i++;
zLostAndFound = azArg[i];
}else
if( n<=10 && memcmp("-no-rowids", z, n)==0 ){
bRowids = 0;
}
else{
utf8_printf(stderr, "unexpected option: %s\n", azArg[i]);
@@ -6772,8 +6778,11 @@ static int recoverDatabaseCmd(ShellState *pState, int nArg, char **azArg){
shellPrepare(pState->db, &rc,
"SELECT pgno FROM recovery.map WHERE root=?", &pPages
);
shellPrepare(pState->db, &rc,
"SELECT max(field), group_concat(shell_escape_crnl(quote(value)), ', ')"
"SELECT max(field), group_concat(shell_escape_crnl(quote"
"(case when (? AND field<0) then NULL else value end)"
"), ', ')"
", min(field) "
"FROM sqlite_dbdata WHERE pgno = ? AND field != ?"
"GROUP BY cell", &pCells
@@ -6808,11 +6817,16 @@ static int recoverDatabaseCmd(ShellState *pState, int nArg, char **azArg){
raw_printf(pState->out, "DELETE FROM sqlite_sequence;\n");
}
sqlite3_bind_int(pPages, 1, iRoot);
sqlite3_bind_int(pCells, 2, pTab->iPk);
if( bRowids==0 && pTab->iPk<0 ){
sqlite3_bind_int(pCells, 1, 1);
}else{
sqlite3_bind_int(pCells, 1, 0);
}
sqlite3_bind_int(pCells, 3, pTab->iPk);
while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pPages) ){
int iPgno = sqlite3_column_int(pPages, 0);
sqlite3_bind_int(pCells, 1, iPgno);
sqlite3_bind_int(pCells, 2, iPgno);
while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pCells) ){
int nField = sqlite3_column_int(pCells, 0);
int iMin = sqlite3_column_int(pCells, 2);
@@ -8134,12 +8148,8 @@ static int do_meta_command(char *zLine, ShellState *p){
** Clear all bind parameters by dropping the TEMP table that holds them.
*/
if( nArg==2 && strcmp(azArg[1],"clear")==0 ){
int wrSchema = 0;
sqlite3_db_config(p->db, SQLITE_DBCONFIG_WRITABLE_SCHEMA, -1, &wrSchema);
sqlite3_db_config(p->db, SQLITE_DBCONFIG_WRITABLE_SCHEMA, 1, 0);
sqlite3_exec(p->db, "DROP TABLE IF EXISTS temp.sqlite_parameters;",
0, 0, 0);
sqlite3_db_config(p->db, SQLITE_DBCONFIG_WRITABLE_SCHEMA, wrSchema, 0);
}else
/* .parameter list
@@ -9409,7 +9419,7 @@ static int do_meta_command(char *zLine, ShellState *p){
}else
#endif /* !defined(SQLITE_OMIT_TRACE) */
#ifdef SQLITE_DEBUG
#if defined(SQLITE_DEBUG) && !defined(SQLITE_OMIT_VIRTUALTABLE)
if( c=='u' && strncmp(azArg[0], "unmodule", n)==0 ){
int ii;
int lenOpt;
+19 -2
View File
@@ -4860,9 +4860,12 @@ int sqlite3_reset(sqlite3_stmt *pStmt);
** function that is not deterministic. The SQLite query planner is able to
** perform additional optimizations on deterministic functions, so use
** of the [SQLITE_DETERMINISTIC] flag is recommended where possible.
**
** ^The fourth parameter may also optionally include the [SQLITE_DIRECTONLY]
** flag, which if present prevents the function from being invoked from
** within VIEWs or TRIGGERs.
** within VIEWs or TRIGGERs. For security reasons, the [SQLITE_DIRECTONLY]
** flag is recommended for any application-defined SQL function that has
** side-effects.
**
** ^(The fifth parameter is an arbitrary pointer. The implementation of the
** function can gain access to this pointer using [sqlite3_user_data()].)^
@@ -4986,10 +4989,24 @@ int sqlite3_create_window_function(
** deterministic, for example, but randomblob() is not.
**
** The SQLITE_DIRECTONLY flag means that the function may only be invoked
** from top-level SQL, and cannot be used in VIEWs or TRIGGERs.
** from top-level SQL, and cannot be used in VIEWs or TRIGGERs. This is
** a security feature which is recommended for all
** [application-defined SQL functions] that have side-effects. This flag
** prevents an attacker from adding triggers and views to a schema then
** tricking a high-privilege application into causing unintended side-effects
** while performing ordinary queries.
**
** The SQLITE_SUBTYPE flag indicates to SQLite that a function may call
** [sqlite3_value_subtype()] to inspect the sub-types of its arguments.
** Specifying this flag makes no difference for scalar or aggregate user
** functions. However, if it is not specified for a user-defined window
** function, then any sub-types belonging to arguments passed to the window
** function may be discarded before the window function is called (i.e.
** sqlite3_value_subtype() will always return 0).
*/
#define SQLITE_DETERMINISTIC 0x000000800
#define SQLITE_DIRECTONLY 0x000080000
#define SQLITE_SUBTYPE 0x000100000
/*
** CAPI3REF: Deprecated Functions
+11 -5
View File
@@ -1686,6 +1686,7 @@ struct FuncDestructor {
#define SQLITE_FUNC_WINDOW 0x00010000 /* Built-in window-only function */
#define SQLITE_FUNC_INTERNAL 0x00040000 /* For use by NestedParse() only */
#define SQLITE_FUNC_DIRECT 0x00080000 /* Not for use in TRIGGERs or VIEWs */
#define SQLITE_FUNC_SUBTYPE 0x00100000 /* Result likely to have sub-type */
/*
** The following three macros, FUNCTION(), LIKEFUNC() and AGGREGATE() are
@@ -2142,8 +2143,11 @@ struct KeyInfo {
CollSeq *aColl[1]; /* Collating sequence for each term of the key */
};
#define KEYINFO_ORDER_DESC 0x01
#define KEYINFO_ORDER_BIGNULL 0x02
/*
** Allowed bit values for entries in the KeyInfo.aSortFlags[] array.
*/
#define KEYINFO_ORDER_DESC 0x01 /* DESC sort order */
#define KEYINFO_ORDER_BIGNULL 0x02 /* NULL is larger than any other value */
/*
** This object holds a record which has been parsed out into individual
@@ -2473,6 +2477,7 @@ struct Expr {
** TK_REGISTER: register number
** TK_TRIGGER: 1 -> new, 0 -> old
** EP_Unlikely: 134217728 times likelihood
** TK_IN: ephemerial table holding RHS
** TK_SELECT_COLUMN: Number of columns on the LHS
** TK_SELECT: 1st register of result vector */
ynVar iColumn; /* TK_COLUMN: column index. -1 for rowid.
@@ -3600,8 +3605,8 @@ struct Window {
Expr *pFilter; /* The FILTER expression */
FuncDef *pFunc; /* The function */
int iEphCsr; /* Partition buffer or Peer buffer */
int regAccum;
int regResult;
int regAccum; /* Accumulator */
int regResult; /* Interim result */
int csrApp; /* Function cursor (used by min/max) */
int regApp; /* Function register (also used by min/max) */
int regPart; /* Array of registers for PARTITION BY values */
@@ -3611,6 +3616,8 @@ struct Window {
int regOne; /* Register containing constant value 1 */
int regStartRowid;
int regEndRowid;
u8 bExprArgs; /* Defer evaluation of window function arguments
** due to the SQLITE_SUBTYPE flag */
};
#ifndef SQLITE_OMIT_WINDOWFUNC
@@ -4315,7 +4322,6 @@ extern const unsigned char sqlite3OpcodeProperty[];
extern const char sqlite3StrBINARY[];
extern const unsigned char sqlite3UpperToLower[];
extern const unsigned char sqlite3CtypeMap[];
extern const Token sqlite3IntTokens[];
extern SQLITE_WSD struct Sqlite3Config sqlite3Config;
extern FuncDefHash sqlite3BuiltinFunctions;
#ifndef SQLITE_OMIT_WSD
+3
View File
@@ -1131,7 +1131,9 @@ static int SQLITE_TCLAPI test_drop_modules(
return TCL_ERROR;
}
if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
#ifndef SQLITE_OMIT_VIRTUALTABLE
sqlite3_drop_modules(db, argc>2 ? (const char**)(argv+2) : 0);
#endif
return TCL_OK;
}
@@ -7200,6 +7202,7 @@ static int SQLITE_TCLAPI optimization_control(
{ "omit-noop-join", SQLITE_OmitNoopJoin },
{ "stat4", SQLITE_Stat4 },
{ "skip-scan", SQLITE_SkipScan },
{ "push-down", SQLITE_PushDown },
};
if( objc!=4 ){
+73
View File
@@ -337,6 +337,17 @@ static int getFts3Varint(const char *p, sqlite_int64 *v){
return (int) (q - (unsigned char *)p);
}
static int putFts3Varint(char *p, sqlite_int64 v){
unsigned char *q = (unsigned char *) p;
sqlite_uint64 vu = v;
do{
*q++ = (unsigned char) ((vu & 0x7f) | 0x80);
vu >>= 7;
}while( vu!=0 );
q[-1] &= 0x7f; /* turn off high bit in final byte */
assert( q - (unsigned char *)p <= 10 );
return (int) (q - (unsigned char *)p);
}
/*
** USAGE: read_fts3varint BLOB VARNAME
@@ -367,6 +378,67 @@ static int SQLITE_TCLAPI read_fts3varint(
return TCL_OK;
}
/*
** USAGE: make_fts3record ARGLIST
*/
static int SQLITE_TCLAPI make_fts3record(
void * clientData,
Tcl_Interp *interp,
int objc,
Tcl_Obj *CONST objv[]
){
Tcl_Obj **aArg = 0;
int nArg = 0;
unsigned char *aOut = 0;
int nOut = 0;
int nAlloc = 0;
int i;
if( objc!=2 ){
Tcl_WrongNumArgs(interp, 1, objv, "LIST");
return TCL_ERROR;
}
if( Tcl_ListObjGetElements(interp, objv[1], &nArg, &aArg) ){
return TCL_ERROR;
}
for(i=0; i<nArg; i++){
sqlite3_int64 iVal;
if( TCL_OK==Tcl_GetWideIntFromObj(0, aArg[i], &iVal) ){
if( nOut+10>nAlloc ){
int nNew = nAlloc?nAlloc*2:128;
unsigned char *aNew = sqlite3_realloc(aOut, nNew);
if( aNew==0 ){
sqlite3_free(aOut);
return TCL_ERROR;
}
aOut = aNew;
nAlloc = nNew;
}
nOut += putFts3Varint((char*)&aOut[nOut], iVal);
}else{
int nVal = 0;
char *zVal = Tcl_GetStringFromObj(aArg[i], &nVal);
while( (nOut + nVal)>nAlloc ){
int nNew = nAlloc?nAlloc*2:128;
unsigned char *aNew = sqlite3_realloc(aOut, nNew);
if( aNew==0 ){
sqlite3_free(aOut);
return TCL_ERROR;
}
aOut = aNew;
nAlloc = nNew;
}
memcpy(&aOut[nOut], zVal, nVal);
nOut += nVal;
}
}
Tcl_SetObjResult(interp, Tcl_NewByteArrayObj(aOut, nOut));
sqlite3_free(aOut);
return TCL_OK;
}
/*
** Register commands with the TCL interpreter.
@@ -383,6 +455,7 @@ int Sqlitetest_hexio_Init(Tcl_Interp *interp){
{ "hexio_render_int32", hexio_render_int32 },
{ "utf8_to_utf8", utf8_to_utf8 },
{ "read_fts3varint", read_fts3varint },
{ "make_fts3record", make_fts3record },
};
int i;
for(i=0; i<sizeof(aObjCmd)/sizeof(aObjCmd[0]); i++){
+8 -1
View File
@@ -536,7 +536,14 @@ void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 moreToFollow){
}
case TK_COLLATE: {
sqlite3TreeViewLine(pView, "COLLATE %Q", pExpr->u.zToken);
/* COLLATE operators without the EP_Collate flag are intended to
** emulate collation associated with a table column. These show
** up in the treeview output as "SOFT-COLLATE". Explicit COLLATE
** operators that appear in the original SQL always have the
** EP_Collate bit set and appear in treeview output as just "COLLATE" */
sqlite3TreeViewLine(pView, "%sCOLLATE %Q%s",
!ExprHasProperty(pExpr, EP_Collate) ? "SOFT-" : "",
pExpr->u.zToken, zFlgs);
sqlite3TreeViewExpr(pView, pExpr->pLeft, 0);
break;
}
+3 -2
View File
@@ -483,6 +483,7 @@ void sqlite3VdbeMemPrettyPrint(Mem *pMem, char *zBuf){
c = 's';
}
*(zCsr++) = c;
*(zCsr++) = 'x';
sqlite3_snprintf(100, zCsr, "%d[", pMem->n);
zCsr += sqlite3Strlen30(zCsr);
for(i=0; i<25 && i<pMem->n; i++){
@@ -553,7 +554,7 @@ static void memTracePrint(Mem *p){
printf(" i:%lld", p->u.i);
#ifndef SQLITE_OMIT_FLOATING_POINT
}else if( p->flags & MEM_Real ){
printf(" r:%g", p->u.r);
printf(" r:%.17g", p->u.r);
#endif
}else if( sqlite3VdbeMemIsRowSet(p) ){
printf(" (rowset)");
@@ -1142,7 +1143,6 @@ case OP_Real: { /* same as TK_FLOAT, out2 */
case OP_String8: { /* same as TK_STRING, out2 */
assert( pOp->p4.z!=0 );
pOut = out2Prerelease(p, pOp);
pOp->opcode = OP_String;
pOp->p1 = sqlite3Strlen30(pOp->p4.z);
#ifndef SQLITE_OMIT_UTF16
@@ -1166,6 +1166,7 @@ case OP_String8: { /* same as TK_STRING, out2 */
if( pOp->p1>db->aLimit[SQLITE_LIMIT_LENGTH] ){
goto too_big;
}
pOp->opcode = OP_String;
assert( rc==SQLITE_OK );
/* Fall through to the next case, OP_String */
}
+7 -1
View File
@@ -232,7 +232,13 @@ SQLITE_NOINLINE int sqlite3VdbeMemGrow(Mem *pMem, int n, int bPreserve){
assert( pMem->szMalloc==0
|| pMem->szMalloc==sqlite3DbMallocSize(pMem->db, pMem->zMalloc) );
if( pMem->szMalloc>0 && bPreserve && pMem->z==pMem->zMalloc ){
pMem->z = pMem->zMalloc = sqlite3DbReallocOrFree(pMem->db, pMem->z, n);
if( pMem->db ){
pMem->z = pMem->zMalloc = sqlite3DbReallocOrFree(pMem->db, pMem->z, n);
}else{
pMem->zMalloc = sqlite3Realloc(pMem->z, n);
if( pMem->zMalloc==0 ) sqlite3_free(pMem->z);
pMem->z = pMem->zMalloc;
}
bPreserve = 0;
}else{
if( pMem->szMalloc>0 ) sqlite3DbFreeNN(pMem->db, pMem->zMalloc);
+2 -1
View File
@@ -2268,7 +2268,7 @@ static void whereLoopOutputAdjust(
){
WhereTerm *pTerm, *pX;
Bitmask notAllowed = ~(pLoop->prereq|pLoop->maskSelf);
int i, j, k;
int i, j;
LogEst iReduce = 0; /* pLoop->nOut should not exceed nRow-iReduce */
assert( (pLoop->wsFlags & WHERE_AUTO_INDEX)==0 );
@@ -2294,6 +2294,7 @@ static void whereLoopOutputAdjust(
pLoop->nOut--;
if( pTerm->eOperator&(WO_EQ|WO_IS) ){
Expr *pRight = pTerm->pExpr->pRight;
int k = 0;
testcase( pTerm->pExpr->op==TK_IS );
if( sqlite3ExprIsInteger(pRight, &k) && k>=(-1) && k<=1 ){
k = 10;
+8 -3
View File
@@ -284,6 +284,7 @@ static int isLikeOrGlob(
** 2019-05-02 https://sqlite.org/src/info/b043a54c3de54b28
** 2019-06-10 https://sqlite.org/src/info/fd76310a5e843e07
** 2019-06-14 https://sqlite.org/src/info/ce8717f0885af975
** 2019-09-03 https://sqlite.org/src/info/0f0428096f17252a
*/
if( pLeft->op!=TK_COLUMN
|| sqlite3ExprAffinity(pLeft)!=SQLITE_AFF_TEXT
@@ -293,9 +294,13 @@ static int isLikeOrGlob(
double rDummy;
isNum = sqlite3AtoF(zNew, &rDummy, iTo, SQLITE_UTF8);
if( isNum<=0 ){
zNew[iTo-1]++;
isNum = sqlite3AtoF(zNew, &rDummy, iTo, SQLITE_UTF8);
zNew[iTo-1]--;
if( iTo==1 && zNew[0]=='-' ){
isNum = +1;
}else{
zNew[iTo-1]++;
isNum = sqlite3AtoF(zNew, &rDummy, iTo, SQLITE_UTF8);
zNew[iTo-1]--;
}
}
if( isNum>0 ){
sqlite3ExprDelete(db, pPrefix);
+171 -120
View File
@@ -965,8 +965,15 @@ int sqlite3WindowRewrite(Parse *pParse, Select *p){
** window function - one for the accumulator, another for interim
** results. */
for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
pWin->iArgCol = (pSublist ? pSublist->nExpr : 0);
pSublist = exprListAppendList(pParse, pSublist, pWin->pOwner->x.pList, 0);
ExprList *pArgs = pWin->pOwner->x.pList;
if( pWin->pFunc->funcFlags & SQLITE_FUNC_SUBTYPE ){
selectWindowRewriteEList(pParse, pMWin, pSrc, pArgs, pTab, &pSublist);
pWin->iArgCol = (pSublist ? pSublist->nExpr : 0);
pWin->bExprArgs = 1;
}else{
pWin->iArgCol = (pSublist ? pSublist->nExpr : 0);
pSublist = exprListAppendList(pParse, pSublist, pArgs, 0);
}
if( pWin->pFilter ){
Expr *pFilter = sqlite3ExprDup(db, pWin->pFilter, 0);
pSublist = sqlite3ExprListAppend(pParse, pSublist, pFilter);
@@ -984,7 +991,7 @@ int sqlite3WindowRewrite(Parse *pParse, Select *p){
*/
if( pSublist==0 ){
pSublist = sqlite3ExprListAppend(pParse, 0,
sqlite3ExprAlloc(db, TK_INTEGER, &sqlite3IntTokens[0], 0)
sqlite3Expr(db, TK_INTEGER, "0")
);
}
@@ -1401,102 +1408,6 @@ static int windowArgCount(Window *pWin){
return (pList ? pList->nExpr : 0);
}
/*
** Generate VM code to invoke either xStep() (if bInverse is 0) or
** xInverse (if bInverse is non-zero) for each window function in the
** linked list starting at pMWin. Or, for built-in window functions
** that do not use the standard function API, generate the required
** inline VM code.
**
** If argument csr is greater than or equal to 0, then argument reg is
** the first register in an array of registers guaranteed to be large
** enough to hold the array of arguments for each function. In this case
** the arguments are extracted from the current row of csr into the
** array of registers before invoking OP_AggStep or OP_AggInverse
**
** Or, if csr is less than zero, then the array of registers at reg is
** already populated with all columns from the current row of the sub-query.
**
** If argument regPartSize is non-zero, then it is a register containing the
** number of rows in the current partition.
*/
static void windowAggStep(
Parse *pParse,
Window *pMWin, /* Linked list of window functions */
int csr, /* Read arguments from this cursor */
int bInverse, /* True to invoke xInverse instead of xStep */
int reg /* Array of registers */
){
Vdbe *v = sqlite3GetVdbe(pParse);
Window *pWin;
for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
FuncDef *pFunc = pWin->pFunc;
int regArg;
int nArg = windowArgCount(pWin);
int i;
assert( bInverse==0 || pWin->eStart!=TK_UNBOUNDED );
for(i=0; i<nArg; i++){
if( i!=1 || pFunc->zName!=nth_valueName ){
sqlite3VdbeAddOp3(v, OP_Column, csr, pWin->iArgCol+i, reg+i);
}else{
sqlite3VdbeAddOp3(v, OP_Column, pMWin->iEphCsr, pWin->iArgCol+i, reg+i);
}
}
regArg = reg;
if( pMWin->regStartRowid==0
&& (pFunc->funcFlags & SQLITE_FUNC_MINMAX)
&& (pWin->eStart!=TK_UNBOUNDED)
){
int addrIsNull = sqlite3VdbeAddOp1(v, OP_IsNull, regArg);
VdbeCoverage(v);
if( bInverse==0 ){
sqlite3VdbeAddOp2(v, OP_AddImm, pWin->regApp+1, 1);
sqlite3VdbeAddOp2(v, OP_SCopy, regArg, pWin->regApp);
sqlite3VdbeAddOp3(v, OP_MakeRecord, pWin->regApp, 2, pWin->regApp+2);
sqlite3VdbeAddOp2(v, OP_IdxInsert, pWin->csrApp, pWin->regApp+2);
}else{
sqlite3VdbeAddOp4Int(v, OP_SeekGE, pWin->csrApp, 0, regArg, 1);
VdbeCoverageNeverTaken(v);
sqlite3VdbeAddOp1(v, OP_Delete, pWin->csrApp);
sqlite3VdbeJumpHere(v, sqlite3VdbeCurrentAddr(v)-2);
}
sqlite3VdbeJumpHere(v, addrIsNull);
}else if( pWin->regApp ){
assert( pFunc->zName==nth_valueName
|| pFunc->zName==first_valueName
);
assert( bInverse==0 || bInverse==1 );
sqlite3VdbeAddOp2(v, OP_AddImm, pWin->regApp+1-bInverse, 1);
}else if( pFunc->xSFunc!=noopStepFunc ){
int addrIf = 0;
if( pWin->pFilter ){
int regTmp;
assert( nArg==0 || nArg==pWin->pOwner->x.pList->nExpr );
assert( nArg || pWin->pOwner->x.pList==0 );
regTmp = sqlite3GetTempReg(pParse);
sqlite3VdbeAddOp3(v, OP_Column, csr, pWin->iArgCol+nArg,regTmp);
addrIf = sqlite3VdbeAddOp3(v, OP_IfNot, regTmp, 0, 1);
VdbeCoverage(v);
sqlite3ReleaseTempReg(pParse, regTmp);
}
if( pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL ){
CollSeq *pColl;
assert( nArg>0 );
pColl = sqlite3ExprNNCollSeq(pParse, pWin->pOwner->x.pList->a[0].pExpr);
sqlite3VdbeAddOp4(v, OP_CollSeq, 0,0,0, (const char*)pColl, P4_COLLSEQ);
}
sqlite3VdbeAddOp3(v, bInverse? OP_AggInverse : OP_AggStep,
bInverse, regArg, pWin->regAccum);
sqlite3VdbeAppendP4(v, pFunc, P4_FUNCDEF);
sqlite3VdbeChangeP5(v, (u8)nArg);
if( addrIf ) sqlite3VdbeJumpHere(v, addrIf);
}
}
}
typedef struct WindowCodeArg WindowCodeArg;
typedef struct WindowCsrAndReg WindowCsrAndReg;
@@ -1577,13 +1488,6 @@ struct WindowCodeArg {
WindowCsrAndReg end;
};
/*
** Values that may be passed as the second argument to windowCodeOp().
*/
#define WINDOW_RETURN_ROW 1
#define WINDOW_AGGINVERSE 2
#define WINDOW_AGGSTEP 3
/*
** Generate VM code to read the window frames peer values from cursor csr into
** an array of registers starting at reg.
@@ -1606,6 +1510,133 @@ static void windowReadPeerValues(
}
}
/*
** Generate VM code to invoke either xStep() (if bInverse is 0) or
** xInverse (if bInverse is non-zero) for each window function in the
** linked list starting at pMWin. Or, for built-in window functions
** that do not use the standard function API, generate the required
** inline VM code.
**
** If argument csr is greater than or equal to 0, then argument reg is
** the first register in an array of registers guaranteed to be large
** enough to hold the array of arguments for each function. In this case
** the arguments are extracted from the current row of csr into the
** array of registers before invoking OP_AggStep or OP_AggInverse
**
** Or, if csr is less than zero, then the array of registers at reg is
** already populated with all columns from the current row of the sub-query.
**
** If argument regPartSize is non-zero, then it is a register containing the
** number of rows in the current partition.
*/
static void windowAggStep(
WindowCodeArg *p,
Window *pMWin, /* Linked list of window functions */
int csr, /* Read arguments from this cursor */
int bInverse, /* True to invoke xInverse instead of xStep */
int reg /* Array of registers */
){
Parse *pParse = p->pParse;
Vdbe *v = sqlite3GetVdbe(pParse);
Window *pWin;
for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
FuncDef *pFunc = pWin->pFunc;
int regArg;
int nArg = pWin->bExprArgs ? 0 : windowArgCount(pWin);
int i;
assert( bInverse==0 || pWin->eStart!=TK_UNBOUNDED );
/* All OVER clauses in the same window function aggregate step must
** be the same. */
assert( pWin==pMWin || sqlite3WindowCompare(pParse,pWin,pMWin,0)==0 );
for(i=0; i<nArg; i++){
if( i!=1 || pFunc->zName!=nth_valueName ){
sqlite3VdbeAddOp3(v, OP_Column, csr, pWin->iArgCol+i, reg+i);
}else{
sqlite3VdbeAddOp3(v, OP_Column, pMWin->iEphCsr, pWin->iArgCol+i, reg+i);
}
}
regArg = reg;
if( pMWin->regStartRowid==0
&& (pFunc->funcFlags & SQLITE_FUNC_MINMAX)
&& (pWin->eStart!=TK_UNBOUNDED)
){
int addrIsNull = sqlite3VdbeAddOp1(v, OP_IsNull, regArg);
VdbeCoverage(v);
if( bInverse==0 ){
sqlite3VdbeAddOp2(v, OP_AddImm, pWin->regApp+1, 1);
sqlite3VdbeAddOp2(v, OP_SCopy, regArg, pWin->regApp);
sqlite3VdbeAddOp3(v, OP_MakeRecord, pWin->regApp, 2, pWin->regApp+2);
sqlite3VdbeAddOp2(v, OP_IdxInsert, pWin->csrApp, pWin->regApp+2);
}else{
sqlite3VdbeAddOp4Int(v, OP_SeekGE, pWin->csrApp, 0, regArg, 1);
VdbeCoverageNeverTaken(v);
sqlite3VdbeAddOp1(v, OP_Delete, pWin->csrApp);
sqlite3VdbeJumpHere(v, sqlite3VdbeCurrentAddr(v)-2);
}
sqlite3VdbeJumpHere(v, addrIsNull);
}else if( pWin->regApp ){
assert( pFunc->zName==nth_valueName
|| pFunc->zName==first_valueName
);
assert( bInverse==0 || bInverse==1 );
sqlite3VdbeAddOp2(v, OP_AddImm, pWin->regApp+1-bInverse, 1);
}else if( pFunc->xSFunc!=noopStepFunc ){
int addrIf = 0;
if( pWin->pFilter ){
int regTmp;
assert( pWin->bExprArgs || !nArg ||nArg==pWin->pOwner->x.pList->nExpr );
assert( pWin->bExprArgs || nArg ||pWin->pOwner->x.pList==0 );
regTmp = sqlite3GetTempReg(pParse);
sqlite3VdbeAddOp3(v, OP_Column, csr, pWin->iArgCol+nArg,regTmp);
addrIf = sqlite3VdbeAddOp3(v, OP_IfNot, regTmp, 0, 1);
VdbeCoverage(v);
sqlite3ReleaseTempReg(pParse, regTmp);
}
if( pWin->bExprArgs ){
int iStart = sqlite3VdbeCurrentAddr(v);
VdbeOp *pOp, *pEnd;
nArg = pWin->pOwner->x.pList->nExpr;
regArg = sqlite3GetTempRange(pParse, nArg);
sqlite3ExprCodeExprList(pParse, pWin->pOwner->x.pList, regArg, 0, 0);
pEnd = sqlite3VdbeGetOp(v, -1);
for(pOp=sqlite3VdbeGetOp(v, iStart); pOp<=pEnd; pOp++){
if( pOp->opcode==OP_Column && pOp->p1==pWin->iEphCsr ){
pOp->p1 = csr;
}
}
}
if( pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL ){
CollSeq *pColl;
assert( nArg>0 );
pColl = sqlite3ExprNNCollSeq(pParse, pWin->pOwner->x.pList->a[0].pExpr);
sqlite3VdbeAddOp4(v, OP_CollSeq, 0,0,0, (const char*)pColl, P4_COLLSEQ);
}
sqlite3VdbeAddOp3(v, bInverse? OP_AggInverse : OP_AggStep,
bInverse, regArg, pWin->regAccum);
sqlite3VdbeAppendP4(v, pFunc, P4_FUNCDEF);
sqlite3VdbeChangeP5(v, (u8)nArg);
if( pWin->bExprArgs ){
sqlite3ReleaseTempRange(pParse, regArg, nArg);
}
if( addrIf ) sqlite3VdbeJumpHere(v, addrIf);
}
}
}
/*
** Values that may be passed as the second argument to windowCodeOp().
*/
#define WINDOW_RETURN_ROW 1
#define WINDOW_AGGINVERSE 2
#define WINDOW_AGGSTEP 3
/*
** Generate VM code to invoke either xValue() (bFin==0) or xFinalize()
** (bFin==1) for each window function in the linked list starting at
@@ -1668,6 +1699,8 @@ static void windowFullScan(WindowCodeArg *p){
int addrNext;
int csr;
VdbeModuleComment((v, "windowFullScan begin"));
assert( pMWin!=0 );
csr = pMWin->csrApp;
nPeer = (pMWin->pOrderBy ? pMWin->pOrderBy->nExpr : 0);
@@ -1724,7 +1757,7 @@ static void windowFullScan(WindowCodeArg *p){
if( addrEq ) sqlite3VdbeJumpHere(v, addrEq);
}
windowAggStep(pParse, pMWin, csr, 0, p->regArg);
windowAggStep(p, pMWin, csr, 0, p->regArg);
sqlite3VdbeResolveLabel(v, lblNext);
sqlite3VdbeAddOp2(v, OP_Next, csr, addrNext);
@@ -1739,6 +1772,7 @@ static void windowFullScan(WindowCodeArg *p){
}
windowAggFinal(p, 1);
VdbeModuleComment((v, "windowFullScan end"));
}
/*
@@ -2069,9 +2103,7 @@ static int windowCodeOp(
Window *pMWin = p->pMWin;
int ret = 0;
Vdbe *v = p->pVdbe;
int addrIf = 0;
int addrContinue = 0;
int addrGoto = 0;
int bPeer = (pMWin->eFrmType!=TK_ROWS);
int lblDone = sqlite3VdbeMakeLabel(pParse);
@@ -2104,7 +2136,7 @@ static int windowCodeOp(
);
}
}else{
addrIf = sqlite3VdbeAddOp3(v, OP_IfPos, regCountdown, 0, 1);
sqlite3VdbeAddOp3(v, OP_IfPos, regCountdown, lblDone, 1);
VdbeCoverage(v);
}
}
@@ -2113,6 +2145,25 @@ static int windowCodeOp(
windowAggFinal(p, 0);
}
addrContinue = sqlite3VdbeCurrentAddr(v);
/* If this is a (RANGE BETWEEN a FOLLOWING AND b FOLLOWING) or
** (RANGE BETWEEN b PRECEDING AND a PRECEDING) frame, ensure the
** start cursor does not advance past the end cursor within the
** temporary table. It otherwise might, if (a>b). */
if( pMWin->eStart==pMWin->eEnd && regCountdown
&& pMWin->eFrmType==TK_RANGE && op==WINDOW_AGGINVERSE
){
int regRowid1 = sqlite3GetTempReg(pParse);
int regRowid2 = sqlite3GetTempReg(pParse);
sqlite3VdbeAddOp2(v, OP_Rowid, p->start.csr, regRowid1);
sqlite3VdbeAddOp2(v, OP_Rowid, p->end.csr, regRowid2);
sqlite3VdbeAddOp3(v, OP_Ge, regRowid2, lblDone, regRowid1);
VdbeCoverage(v);
sqlite3ReleaseTempReg(pParse, regRowid1);
sqlite3ReleaseTempReg(pParse, regRowid2);
assert( pMWin->eStart==TK_PRECEDING || pMWin->eStart==TK_FOLLOWING );
}
switch( op ){
case WINDOW_RETURN_ROW:
csr = p->current.csr;
@@ -2127,7 +2178,7 @@ static int windowCodeOp(
assert( pMWin->regEndRowid );
sqlite3VdbeAddOp2(v, OP_AddImm, pMWin->regStartRowid, 1);
}else{
windowAggStep(pParse, pMWin, csr, 1, p->regArg);
windowAggStep(p, pMWin, csr, 1, p->regArg);
}
break;
@@ -2139,7 +2190,7 @@ static int windowCodeOp(
assert( pMWin->regEndRowid );
sqlite3VdbeAddOp2(v, OP_AddImm, pMWin->regEndRowid, 1);
}else{
windowAggStep(pParse, pMWin, csr, 0, p->regArg);
windowAggStep(p, pMWin, csr, 0, p->regArg);
}
break;
}
@@ -2157,7 +2208,7 @@ static int windowCodeOp(
sqlite3VdbeAddOp2(v, OP_Next, csr, sqlite3VdbeCurrentAddr(v)+1+bPeer);
VdbeCoverage(v);
if( bPeer ){
addrGoto = sqlite3VdbeAddOp0(v, OP_Goto);
sqlite3VdbeAddOp2(v, OP_Goto, 0, lblDone);
}
}
@@ -2173,8 +2224,6 @@ static int windowCodeOp(
sqlite3VdbeAddOp2(v, OP_Goto, 0, addrNextRange);
}
sqlite3VdbeResolveLabel(v, lblDone);
if( addrGoto ) sqlite3VdbeJumpHere(v, addrGoto);
if( addrIf ) sqlite3VdbeJumpHere(v, addrIf);
return ret;
}
@@ -2190,6 +2239,7 @@ Window *sqlite3WindowDup(sqlite3 *db, Expr *pOwner, Window *p){
pNew = sqlite3DbMallocZero(db, sizeof(Window));
if( pNew ){
pNew->zName = sqlite3DbStrDup(db, p->zName);
pNew->zBase = sqlite3DbStrDup(db, p->zBase);
pNew->pFilter = sqlite3ExprDup(db, p->pFilter, 0);
pNew->pFunc = p->pFunc;
pNew->pPartition = sqlite3ExprListDup(db, p->pPartition, 0);
@@ -2202,6 +2252,7 @@ Window *sqlite3WindowDup(sqlite3 *db, Expr *pOwner, Window *p){
pNew->pStart = sqlite3ExprDup(db, p->pStart, 0);
pNew->pEnd = sqlite3ExprDup(db, p->pEnd, 0);
pNew->pOwner = pOwner;
pNew->bImplicitFrame = p->bImplicitFrame;
}
}
return pNew;
@@ -2525,7 +2576,7 @@ static int windowExprGtZero(Parse *pParse, Expr *pExpr){
** regEnd = <expr2>
** regStart = <expr1>
** }else{
** if( (csrEnd.key + regEnd) <= csrCurrent.key ){
** while( (csrEnd.key + regEnd) <= csrCurrent.key ){
** AGGSTEP
** }
** while( (csrStart.key + regStart) < csrCurrent.key ){
@@ -2598,8 +2649,6 @@ void sqlite3WindowCodeStep(
int addrGosubFlush = 0; /* Address of OP_Gosub to flush: */
int addrInteger = 0; /* Address of OP_Integer */
int addrEmpty; /* Address of OP_Rewind in flush: */
int regStart = 0; /* Value of <expr> PRECEDING */
int regEnd = 0; /* Value of <expr> FOLLOWING */
int regNew; /* Array of registers holding new input row */
int regRecord; /* regNew array in record form */
int regRowid; /* Rowid for regRecord in eph table */
@@ -2608,6 +2657,8 @@ void sqlite3WindowCodeStep(
int regFlushPart = 0; /* Register for "Gosub flush_partition" */
WindowCodeArg s; /* Context object for sub-routines */
int lblWhereEnd; /* Label just before sqlite3WhereEnd() code */
int regStart = 0; /* Value of <expr> PRECEDING */
int regEnd = 0; /* Value of <expr> FOLLOWING */
assert( pMWin->eStart==TK_PRECEDING || pMWin->eStart==TK_CURRENT
|| pMWin->eStart==TK_FOLLOWING || pMWin->eStart==TK_UNBOUNDED
@@ -2738,11 +2789,11 @@ void sqlite3WindowCodeStep(
if( regStart ){
sqlite3ExprCode(pParse, pMWin->pStart, regStart);
windowCheckValue(pParse, regStart, 0 + (pMWin->eFrmType==TK_RANGE ? 3 : 0));
windowCheckValue(pParse, regStart, 0 + (pMWin->eFrmType==TK_RANGE?3:0));
}
if( regEnd ){
sqlite3ExprCode(pParse, pMWin->pEnd, regEnd);
windowCheckValue(pParse, regEnd, 1 + (pMWin->eFrmType==TK_RANGE ? 3 : 0));
windowCheckValue(pParse, regEnd, 1 + (pMWin->eFrmType==TK_RANGE?3:0));
}
if( pMWin->eFrmType!=TK_RANGE && pMWin->eStart==pMWin->eEnd && regStart ){
+14 -9
View File
@@ -118,14 +118,19 @@ do_execsql_test 507 {
# 2019-08-30 ticket https://www.sqlite.org/src/info/40812aea1fde9594
#
do_execsql_test 600 {
DROP TABLE IF EXISTS t0;
CREATE TABLE t0(c0 REAL UNIQUE);
INSERT INTO t0(c0) VALUES (3175546974276630385);
SELECT 3175546974276630385 < c0 FROM t0;
} {1}
do_execsql_test 601 {
SELECT 1 FROM t0 WHERE 3175546974276630385 < c0;
} {1}
# Due to some differences in floating point computations, these tests do not
# work under valgrind.
#
if {![info exists ::G(valgrind)]} {
do_execsql_test 600 {
DROP TABLE IF EXISTS t0;
CREATE TABLE t0(c0 REAL UNIQUE);
INSERT INTO t0(c0) VALUES (3175546974276630385);
SELECT 3175546974276630385 < c0 FROM t0;
} {1}
do_execsql_test 601 {
SELECT 1 FROM t0 WHERE 3175546974276630385 < c0;
} {1}
}
finish_test
+10 -4
View File
@@ -377,11 +377,14 @@ do_test 4.0 {
| end crash-6b48ba69806134.db
}]} {}
set res {1 {database disk image is malformed}}
ifcapable oversize_cell_check {
set res {1 {no such table: t3}}
}
do_catchsql_test 4.1 {
PRAGMA writable_schema=ON; -- bypass improved sqlite_master consistency checking
INSERT INTO t3 SELECT * FROM t2;
} {1 {database disk image is malformed}}
} $res
#-------------------------------------------------------------------------
reset_db
@@ -835,11 +838,14 @@ do_test 8.0 {
| end a.db
}]} {}
set res {1 {database disk image is malformed}}
ifcapable oversize_cell_check {
set res {1 {no such table: t3}}
}
do_catchsql_test 8.1 {
PRAGMA writable_schema=ON; -- bypass improved sqlite_master consistency checking
INSERT INTO t3 SELECT * FROM t2;
} {1 {database disk image is malformed}}
} $res
#-------------------------------------------------------------------------
reset_db
+36 -52
View File
@@ -22,6 +22,16 @@ set testprefix corruptM
#
database_may_be_corrupt
proc open_db2_and_catchsql {sql} {
set rc [catch { sqlite3 db2 test.db } msg]
if {$rc} {
return [list $rc $msg]
}
set res [catchsql $sql db2]
db2 close
set res
}
db close
forcedelete test.db
sqlite3 db test.db
@@ -38,165 +48,139 @@ do_execsql_test corruptM-101 {
UPDATE sqlite_master SET tbl_name=NULL WHERE name='t1';
SELECT type, name, tbl_name, '|' FROM sqlite_master;
} {table t1 {} | index i1 t1 | view v2 v2 | trigger r1 t1 |}
sqlite3 db2 test.db
do_test corruptM-102 {
catchsql {
open_db2_and_catchsql {
PRAGMA quick_check;
} db2
}
} {1 {malformed database schema (t1)}}
db2 close
do_execsql_test corruptM-110 {
UPDATE sqlite_master SET tbl_name='tx' WHERE name='t1';
SELECT type, name, tbl_name, '|' FROM sqlite_master;
} {table t1 tx | index i1 t1 | view v2 v2 | trigger r1 t1 |}
sqlite3 db2 test.db
do_test corruptM-111 {
catchsql {
open_db2_and_catchsql {
PRAGMA quick_check;
} db2
}
} {1 {malformed database schema (t1)}}
db2 close
do_execsql_test corruptM-112 {
UPDATE sqlite_master SET tbl_name='t1', type='tabl' WHERE name='t1';
SELECT type, name, tbl_name, '|' FROM sqlite_master;
} {tabl t1 t1 | index i1 t1 | view v2 v2 | trigger r1 t1 |}
sqlite3 db2 test.db
do_test corruptM-113 {
catchsql {
open_db2_and_catchsql {
PRAGMA quick_check;
} db2
}
} {1 {malformed database schema (t1)}}
db2 close
do_execsql_test corruptM-114 {
UPDATE sqlite_master SET tbl_name='t9',type='table',name='t9'WHERE name='t1';
SELECT type, name, tbl_name, '|' FROM sqlite_master;
} {table t9 t9 | index i1 t1 | view v2 v2 | trigger r1 t1 |}
sqlite3 db2 test.db
do_test corruptM-114 {
catchsql {
open_db2_and_catchsql {
PRAGMA quick_check;
} db2
}
} {1 {malformed database schema (t9)}}
db2 close
do_execsql_test corruptM-120 {
UPDATE sqlite_master SET name='t1',tbl_name='T1' WHERE name='t9';
SELECT type, name, tbl_name, '|' FROM sqlite_master;
} {table t1 T1 | index i1 t1 | view v2 v2 | trigger r1 t1 |}
sqlite3 db2 test.db
do_test corruptM-121 {
catchsql {
open_db2_and_catchsql {
PRAGMA quick_check;
SELECT * FROM t1, v2;
} db2
}
} {0 {ok 111 222 333 15 22}}
db2 close
do_execsql_test corruptM-130 {
UPDATE sqlite_master SET type='view' WHERE name='t1';
SELECT type, name, tbl_name, '|' FROM sqlite_master;
} {view t1 T1 | index i1 t1 | view v2 v2 | trigger r1 t1 |}
sqlite3 db2 test.db
do_test corruptM-131 {
catchsql {
open_db2_and_catchsql {
PRAGMA quick_check;
SELECT * FROM t1, v2;
} db2
}
} {1 {malformed database schema (t1)}}
db2 close
do_execsql_test corruptM-140 {
UPDATE sqlite_master SET type='table', tbl_name='t1' WHERE name='t1';
UPDATE sqlite_master SET tbl_name='tx' WHERE name='i1';
SELECT type, name, tbl_name, '|' FROM sqlite_master;
} {table t1 t1 | index i1 tx | view v2 v2 | trigger r1 t1 |}
sqlite3 db2 test.db
do_test corruptM-141 {
catchsql {
open_db2_and_catchsql {
PRAGMA quick_check;
SELECT * FROM t1, v2;
} db2
}
} {1 {malformed database schema (i1)}}
db2 close
do_execsql_test corruptM-150 {
UPDATE sqlite_master SET type='table', tbl_name='t1' WHERE name='i1';
SELECT type, name, tbl_name, '|' FROM sqlite_master;
} {table t1 t1 | table i1 t1 | view v2 v2 | trigger r1 t1 |}
sqlite3 db2 test.db
do_test corruptM-151 {
catchsql {
open_db2_and_catchsql {
PRAGMA quick_check;
SELECT * FROM t1, v2;
} db2
}
} {1 {malformed database schema (i1)}}
db2 close
do_execsql_test corruptM-160 {
UPDATE sqlite_master SET type='view', tbl_name='t1' WHERE name='i1';
SELECT type, name, tbl_name, '|' FROM sqlite_master;
} {table t1 t1 | view i1 t1 | view v2 v2 | trigger r1 t1 |}
sqlite3 db2 test.db
do_test corruptM-161 {
catchsql {
open_db2_and_catchsql {
PRAGMA quick_check;
SELECT * FROM t1, v2;
} db2
}
} {1 {malformed database schema (i1)}}
db2 close
do_execsql_test corruptM-170 {
UPDATE sqlite_master SET type='index', tbl_name='t1' WHERE name='i1';
UPDATE sqlite_master SET type='table', tbl_name='v2' WHERE name='v2';
SELECT type, name, tbl_name, '|' FROM sqlite_master;
} {table t1 t1 | index i1 t1 | table v2 v2 | trigger r1 t1 |}
sqlite3 db2 test.db
do_test corruptM-171 {
catchsql {
open_db2_and_catchsql {
PRAGMA quick_check;
SELECT * FROM t1, v2;
} db2
}
} {1 {malformed database schema (v2)}}
db2 close
do_execsql_test corruptM-180 {
UPDATE sqlite_master SET type='view',name='v3',tbl_name='v3' WHERE name='v2';
SELECT type, name, tbl_name, '|' FROM sqlite_master;
} {table t1 t1 | index i1 t1 | view v3 v3 | trigger r1 t1 |}
sqlite3 db2 test.db
do_test corruptM-181 {
catchsql {
open_db2_and_catchsql {
PRAGMA quick_check;
SELECT * FROM t1, v2;
} db2
}
} {1 {malformed database schema (v3)}}
db2 close
do_execsql_test corruptM-190 {
UPDATE sqlite_master SET type='view',name='v2',tbl_name='v2' WHERE name='v3';
UPDATE sqlite_master SET type='view' WHERE name='r1';
SELECT type, name, tbl_name, '|' FROM sqlite_master;
} {table t1 t1 | index i1 t1 | view v2 v2 | view r1 t1 |}
sqlite3 db2 test.db
do_test corruptM-191 {
catchsql {
open_db2_and_catchsql {
PRAGMA quick_check;
SELECT * FROM t1, v2;
} db2
}
} {1 {malformed database schema (r1)}}
db2 close
do_execsql_test corruptM-192 {
UPDATE sqlite_master SET type='trigger',tbl_name='v2' WHERE name='r1';
SELECT type, name, tbl_name, '|' FROM sqlite_master;
} {table t1 t1 | index i1 t1 | view v2 v2 | trigger r1 v2 |}
sqlite3 db2 test.db
do_test corruptM-193 {
catchsql {
open_db2_and_catchsql {
PRAGMA quick_check;
SELECT * FROM t1, v2;
} db2
}
} {1 {malformed database schema (r1)}}
db2 close
finish_test
+64
View File
@@ -101,4 +101,68 @@ do_catchsql_test 2.3 {
SELECT sum(a) FILTER (WHERE 1 - count(a)) FROM t1
} {1 {misuse of aggregate function count()}}
#-------------------------------------------------------------------------
reset_db
do_execsql_test 3.0 {
CREATE TABLE t1(a,b);
INSERT INTO t1 VALUES(1, 1);
}
do_execsql_test 3.1 {
SELECT b, max(a) FILTER (WHERE b='x') FROM t1;
} {1 {}}
do_execsql_test 3.2 {
CREATE TABLE t2(a, b, c);
INSERT INTO t2 VALUES(1, 2, 3);
INSERT INTO t2 VALUES(1, 3, 4);
INSERT INTO t2 VALUES(2, 5, 6);
INSERT INTO t2 VALUES(2, 7, 8);
}
do_execsql_test 3.3 {
SELECT a, c, max(b) FILTER (WHERE c='x') FROM t2 GROUP BY a;
} {1 3 {} 2 6 {}}
do_execsql_test 3.4 {
DELETE FROM t2;
INSERT INTO t2 VALUES(1, 5, 'x');
INSERT INTO t2 VALUES(1, 2, 3);
INSERT INTO t2 VALUES(1, 4, 'x');
INSERT INTO t2 VALUES(2, 5, 6);
INSERT INTO t2 VALUES(2, 7, 8);
}
do_execsql_test 3.5 {
SELECT a, c, max(b) FILTER (WHERE c='x') FROM t2 GROUP BY a;
} {1 x 5 2 6 {}}
#-------------------------------------------------------------------------
reset_db
do_execsql_test 4.0 {
CREATE TABLE t1(a, b, c);
INSERT INTO t1 VALUES('a', 0, 5);
INSERT INTO t1 VALUES('a', 1, 10);
INSERT INTO t1 VALUES('a', 0, 15);
INSERT INTO t1 VALUES('b', 0, 5);
INSERT INTO t1 VALUES('b', 1, 1000);
INSERT INTO t1 VALUES('b', 0, 5);
INSERT INTO t1 VALUES('c', 0, 1);
INSERT INTO t1 VALUES('c', 1, 2);
INSERT INTO t1 VALUES('c', 0, 3);
}
do_execsql_test 4.1 {
SELECT avg(c) FILTER (WHERE b!=1) AS h FROM t1 GROUP BY a ORDER BY h;
} {2.0 5.0 10.0}
do_execsql_test 4.2 {
SELECT avg(c) FILTER (WHERE b!=1) AS h FROM t1 GROUP BY a ORDER BY (h+1.0);
} {2.0 5.0 10.0}
do_execsql_test 4.3 {
SELECT a, avg(c) FILTER (WHERE b!=1) AS h FROM t1 GROUP BY a ORDER BY avg(c);
} {c 2.0 a 10.0 b 5.0}
do_execsql_test 4.4 {
SELECT a, avg(c) FILTER (WHERE b!=1) FROM t1 GROUP BY a ORDER BY 2
} {c 2.0 b 5.0 a 10.0}
finish_test
+217
View File
@@ -5329,4 +5329,221 @@ do_catchsql_test 29.1 {
INSERT INTO t1(t1) SELECT x FROM t2;
} {1 {database disk image is malformed}}
#-------------------------------------------------------------------------
#
reset_db
do_test 30.0 {
sqlite3 db {}
db deserialize [decode_hexdb {
| size 28672 pagesize 4096 filename crash-e6e3857edf9b26.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 32 30 31 36 30 36 30 39 20 44 45 42 4#. 20160609 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 4c 45 1f 4a 53 4f 4e 31 20 45 4e 41 42 4c 49 BLE.JSON1 ENABLI
| 3008: 00 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 20 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 53 52 45 45 58 42 ..ENABLE RSREEXB
| 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 53 41 53 45 17 LE RTREEXNOSASE.
| 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 5a 53 35 58 42 49 NABLE MEMSZS5XBI
| 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 1a 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 4e f2 1e 4c NARY....)..EN..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: 52 54 52 49 4d 17 0c 05 00 23 0f 19 45 4e 41 42 RTRIM....#..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 43 4c 45 20 46 54 53 35 ..#..ENACLE 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 55 20 56 54 41 42 58 42 49 4e 41 52 59 1e TAU VTABXBINARY.
| 3856: 08 05 00 31 0f 19 45 4e 41 42 4c 45 20 44 42 53 ...1..ENABLE DBS
| 3872: 54 41 54 20 56 54 41 42 58 4e 4f 43 41 53 45 1d TAT VTABXNOCASE.
| 3888: 07 05 00 31 0f 17 45 4e 41 42 4c 45 20 44 42 53 ...1..ENABLE DBS
| 3904: 54 41 54 20 56 54 41 42 58 52 54 62 49 4d 11 06 TAT VTABXRTbIM..
| 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 54 45 42 55 47 58 4e 4f Y.......TEBUGXNO
| 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 30 36 ..0.%.....201606
| 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 6d 70 69 6c 65 72 03 25 02 00 00 ...compiler.%...
| 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 6e 73 69 6f .........xtensio
| 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 6f 6c 79 03 25 11 00 00 05 6a 73 6f .eopoly.%....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 f2 00 03 01 02 02 00 03 01 02 02 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 00 01 01 .en`ble?........
| 3488: ff f1 b1 00 00 02 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 6f 70 6f 6c 79 09 .........eopoly.
| 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 01 01 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 ................
| page 7 offset 24576
| 0: 01 6f 00 00 00 00 00 00 00 00 00 00 00 00 00 00 .o..............
| end crash-e6e3857edf9b26.db
}]} {}
do_execsql_test 30.1 {
UPDATE t1 SET b=a;
}
do_catchsql_test 30.2 {
SELECT (matchinfo(null)) FROM t1 WHERE t1 MATCH 'ee*e*e*e*e*e*e*Re*e*e*e**'
} {1 {database disk image is malformed}}
finish_test
+58
View File
@@ -0,0 +1,58 @@
# 2019 October 02
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
# May you find forgiveness for yourself and forgive others.
# May you share freely, never taking more than you give.
#
#*************************************************************************
# This file implements regression tests for SQLite library. The
# focus of this script is testing the FTS4 module.
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix fts4merge5
# If SQLITE_ENABLE_FTS3 is defined, omit this file.
ifcapable !fts3 {
finish_test
return
}
source $testdir/genesis.tcl
do_execsql_test 1.1 {
CREATE TABLE t1(docid, words);
}
fts_kjv_genesis
do_execsql_test 1.2 {
CREATE VIRTUAL TABLE x1 USING fts3;
INSERT INTO x1(x1) VALUES('nodesize=64');
INSERT INTO x1(x1) VALUES('maxpending=64');
}
do_execsql_test 1.3 {
INSERT INTO x1(docid, content) SELECT * FROM t1;
}
for {set tn 1} {1} {incr tn} {
set tc1 [db total_changes]
do_execsql_test 1.4.$tn.1 {
INSERT INTO x1(x1) VALUES('merge=1,2');
}
set tc2 [db total_changes]
if {($tc2 - $tc1)<2} break
do_execsql_test 1.4.$tn.1 {
INSERT INTO x1(x1) VALUES('integrity-check');
}
}
finish_test
+120
View File
@@ -0,0 +1,120 @@
# 2019 September 18
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
# May you find forgiveness for yourself and forgive others.
# May you share freely, never taking more than you give.
#
#*************************************************************************
# This file implements regression tests for SQLite library. The
# focus of this script is testing the FTS4 module.
#
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
source $testdir/fts3_common.tcl
set testprefix fts4record
# If SQLITE_ENABLE_FTS3 is defined, omit this file.
ifcapable !fts3 {
finish_test
return
}
sqlite3_fts3_may_be_corrupt 1
do_execsql_test 1.0 {
CREATE VIRTUAL TABLE t1 USING fts4(x);
INSERT INTO t1 VALUES('terma terma terma termb');
}
do_execsql_test 1.1 {
SELECT quote(root) FROM t1_segdir
} {
X'00057465726D6105010203030004016203010500'
}
proc make_record_wrapper {args} { make_fts3record $args }
db func record make_record_wrapper
do_execsql_test 1.2 {
select quote(
record(0, 5, 'terma', 5, 1, 2, 3, 3, 0,
4, 1, 'b' , 3, 1, 5, 0
) );
} {
X'00057465726D6105010203030004016203010500'
}
do_execsql_test 1.3.1 {
UPDATE t1_segdir SET root =
record(0, 5, 'terma', 5, 1, 2, 3, 3, 0,
4, 1, 'b' , 3, 1, 5,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0
);
}
do_catchsql_test 1.3.2 {
SELECT snippet(t1) FROM t1 WHERE t1 MATCH 'term*'
} {1 {database disk image is malformed}}
do_execsql_test 1.4.1 {
UPDATE t1_segdir SET root =
record(0, 5, 'terma', 5, 1, 2, 3, 3, 0,
4, 1, 'b' , 4, 1, 5,
256, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0
);
}
do_catchsql_test 1.4.2 {
SELECT snippet(t1) FROM t1 WHERE t1 MATCH 'term*'
} {1 {database disk image is malformed}}
do_execsql_test 1.4.3 {
SELECT quote(root) FROM t1_segdir
} {
X'00057465726D610501020303000401620401058002010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100'
}
do_execsql_test 1.5.1 {
UPDATE t1_segdir SET root =
record(0, 5, 'terma', 5, 1, 2, 3, 3, 0,
4, 1, 'b' , 4, 1, 5,
256, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0
);
}
do_catchsql_test 1.4.2 {
SELECT snippet(t1) FROM t1 WHERE t1 MATCH 'term*'
} {1 {database disk image is malformed}}
do_execsql_test 1.4.3 {
SELECT quote(root) FROM t1_segdir
} {
X'00057465726D610501020303000401620401058002010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100'
}
do_execsql_test 1.5.1 {
UPDATE t1_segdir SET root =
X'00057465726D61050102030300040162040105FF00010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100'
}
do_catchsql_test 1.5.2 {
SELECT snippet(t1) FROM t1 WHERE t1 MATCH 'term*'
} {1 {database disk image is malformed}}
do_catchsql_test 1.5.3 {
INSERT INTO t1(t1) VALUES('integrity-check');
} {1 {database disk image is malformed}}
finish_test
BIN
View File
Binary file not shown.
+19 -17
View File
@@ -463,22 +463,24 @@ do_execsql_test indexexpr-1700 {
# value, be sure to use the REAL value and not the INT value when
# computing the expression.
#
do_execsql_test indexexpr-1800 {
DROP TABLE IF EXISTS t0;
CREATE TABLE t0(c0 REAL, c1 TEXT);
CREATE INDEX i0 ON t0(+c0, c0);
INSERT INTO t0(c0) VALUES(0);
SELECT CAST(+ t0.c0 AS BLOB) LIKE 0 FROM t0;
} {0}
do_execsql_test indexexpr-1810 {
SELECT CAST(+ t0.c0 AS BLOB) LIKE '0.0' FROM t0;
} {1}
do_execsql_test indexexpr-1820 {
DROP TABLE IF EXISTS t1;
CREATE TABLE t1(x REAL);
CREATE INDEX t1x ON t1(x, +x);
INSERT INTO t1(x) VALUES(2);
SELECT +x FROM t1 WHERE x=2;
} {2.0}
ifcapable like_match_blobs {
do_execsql_test indexexpr-1800 {
DROP TABLE IF EXISTS t0;
CREATE TABLE t0(c0 REAL, c1 TEXT);
CREATE INDEX i0 ON t0(+c0, c0);
INSERT INTO t0(c0) VALUES(0);
SELECT CAST(+ t0.c0 AS BLOB) LIKE 0 FROM t0;
} {0}
do_execsql_test indexexpr-1810 {
SELECT CAST(+ t0.c0 AS BLOB) LIKE '0.0' FROM t0;
} {1}
do_execsql_test indexexpr-1820 {
DROP TABLE IF EXISTS t1;
CREATE TABLE t1(x REAL);
CREATE INDEX t1x ON t1(x, +x);
INSERT INTO t1(x) VALUES(2);
SELECT +x FROM t1 WHERE x=2;
} {2.0}
}
finish_test
+21
View File
@@ -257,4 +257,25 @@ do_execsql_test instr-1.64 {
SELECT instr(a, b) FROM x1;
} 0
# 2019-09-16 ticket https://www.sqlite.org/src/info/587791f92620090e
#
do_execsql_test instr-2.0 {
DROP TABLE IF EXISTS t0;
CREATE TABLE t0(c0 PRIMARY KEY, c1);
INSERT INTO t0(c0) VALUES (x'bb'), (0);
SELECT COUNT(*) FROM t0 WHERE INSTR(x'aabb', t0.c0) ORDER BY t0.c0, t0.c1;
} {1}
do_execsql_test instr-2.1 {
SELECT quote(c0) FROM t0 WHERE INSTR(x'aabb', t0.c0) ORDER BY t0.c0, t0.c1;
} {X'BB'}
do_execsql_test instr-2.2 {
DROP TABLE IF EXISTS t1;
CREATE TABLE t1(x);
INSERT INTO t1(x) VALUES('text'),(x'bb');
SELECT quote(x) FROM t1 WHERE instr(x'aabb',x);
} {X'BB'}
do_execsql_test instr-2.3 {
SELECT quote(x) FROM t1 WHERE x>'zzz' AND instr(x'aabb',x);
} {X'BB'}
finish_test
+13
View File
@@ -207,6 +207,19 @@ do_execsql_test like3-5.410 {
SELECT * FROM t0 WHERE t0.c0 LIKE '.1%';
} {.1%}
# 2019-09-03
# Ticket https://www.sqlite.org/src/info/0f0428096f
do_execsql_test like3-5.420 {
DROP TABLE IF EXISTS t0;
CREATE TABLE t0(c0 UNIQUE);
INSERT INTO t0(c0) VALUES(-1);
SELECT * FROM t0 WHERE t0.c0 GLOB '-*';
} {-1}
do_execsql_test like3-5.421 {
SELECT t0.c0 GLOB '-*' FROM t0;
} {1}
# 2019-02-27
# Verify that the LIKE optimization works with an ESCAPE clause when
+147
View File
@@ -0,0 +1,147 @@
# 2019-09-21
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
# May you find forgiveness for yourself and forgive others.
# May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.
#
# Specifically, it tests cases where the expressions in a GROUP BY
# clause are the same as those in the ORDER BY clause.
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
set ::testprefix orderbyA
proc do_sortcount_test {tn sql cnt res} {
set eqp [execsql "EXPLAIN QUERY PLAN $sql"]
set rcnt [regexp -all {USE TEMP} $eqp]
uplevel [list do_test $tn.1 [list set {} $rcnt] $cnt]
uplevel [list do_execsql_test $tn.2 $sql $res]
}
do_execsql_test 1.0 {
CREATE TABLE t1(a, b, c);
INSERT INTO t1 VALUES('one', 1, 11);
INSERT INTO t1 VALUES('three', 7, 11);
INSERT INTO t1 VALUES('one', 2, 11);
INSERT INTO t1 VALUES('one', 3, 11);
INSERT INTO t1 VALUES('two', 4, 11);
INSERT INTO t1 VALUES('two', 6, 11);
INSERT INTO t1 VALUES('three', 8, 11);
INSERT INTO t1 VALUES('two', 5, 11);
INSERT INTO t1 VALUES('three', 9, 11);
}
foreach {tn idx} {
1 {}
2 {CREATE INDEX i1 ON t1(a)}
3 {CREATE INDEX i1 ON t1(a DESC)}
} {
execsql { DROP INDEX IF EXISTS i1 }
execsql $idx
# $match is the number of temp-table sorts we expect if the GROUP BY
# can use the same sort order as the ORDER BY. $nomatch is the number
# of expected sorts if the GROUP BY and ORDER BY are not compatible.
set match 1
set nomatch 2
if {$tn>=2} {
set match 0
set nomatch 1
}
do_sortcount_test 1.$tn.1.1 {
SELECT a, sum(b) FROM t1 GROUP BY a ORDER BY a
} $match {one 6 three 24 two 15}
do_sortcount_test 1.$tn.1.2 {
SELECT a, sum(b) FROM t1 GROUP BY a ORDER BY a DESC
} $match {two 15 three 24 one 6}
do_sortcount_test 1.$tn.2.1 {
SELECT a, sum(b) FROM t1 GROUP BY a ORDER BY a||''
} $nomatch {one 6 three 24 two 15}
do_sortcount_test 1.$tn.2.2 {
SELECT a, sum(b) FROM t1 GROUP BY a ORDER BY a||'' DESC
} $nomatch {two 15 three 24 one 6}
do_sortcount_test 1.$tn.3.1 {
SELECT a, sum(b) FROM t1 GROUP BY a ORDER BY a NULLS LAST
} $nomatch {one 6 three 24 two 15}
do_sortcount_test 1.$tn.3.2 {
SELECT a, sum(b) FROM t1 GROUP BY a ORDER BY a DESC NULLS FIRST
} $nomatch {two 15 three 24 one 6}
}
#-------------------------------------------------------------------------
do_execsql_test 2.0 {
CREATE TABLE t2(a, b, c);
INSERT INTO t2 VALUES(1, 'one', 1);
INSERT INTO t2 VALUES(1, 'two', 2);
INSERT INTO t2 VALUES(1, 'one', 3);
INSERT INTO t2 VALUES(1, 'two', 4);
INSERT INTO t2 VALUES(1, 'one', 5);
INSERT INTO t2 VALUES(1, 'two', 6);
INSERT INTO t2 VALUES(2, 'one', 7);
INSERT INTO t2 VALUES(2, 'two', 8);
INSERT INTO t2 VALUES(2, 'one', 9);
INSERT INTO t2 VALUES(2, 'two', 10);
INSERT INTO t2 VALUES(2, 'one', 11);
INSERT INTO t2 VALUES(2, 'two', 12);
INSERT INTO t2 VALUES(NULL, 'one', 13);
INSERT INTO t2 VALUES(NULL, 'two', 14);
INSERT INTO t2 VALUES(NULL, 'one', 15);
INSERT INTO t2 VALUES(NULL, 'two', 16);
INSERT INTO t2 VALUES(NULL, 'one', 17);
INSERT INTO t2 VALUES(NULL, 'two', 18);
}
foreach {tn idx} {
1 {}
2 { CREATE INDEX i2 ON t2(a, b) }
3 { CREATE INDEX i2 ON t2(a DESC, b DESC) }
4 { CREATE INDEX i2 ON t2(a, b DESC) }
5 { CREATE INDEX i2 ON t2(a DESC, b) }
} {
execsql { DROP INDEX IF EXISTS i2 }
execsql $idx
set nSort [expr ($tn==2 || $tn==3) ? 0 : 1]
do_sortcount_test 2.$tn.1.1 {
SELECT a, b, sum(c) FROM t2 GROUP BY a, b ORDER BY a, b;
} $nSort {{} one 45 {} two 48 1 one 9 1 two 12 2 one 27 2 two 30}
do_sortcount_test 2.$tn.1.2 {
SELECT a, b, sum(c) FROM t2 GROUP BY a, b ORDER BY a DESC, b DESC;
} $nSort {2 two 30 2 one 27 1 two 12 1 one 9 {} two 48 {} one 45}
set nSort [expr ($tn==4 || $tn==5) ? 0 : 1]
do_sortcount_test 2.$tn.2.1 {
SELECT a, b, sum(c) FROM t2 GROUP BY a, b ORDER BY a, b DESC;
} $nSort { {} two 48 {} one 45 1 two 12 1 one 9 2 two 30 2 one 27 }
do_sortcount_test 2.$tn.2.2 {
SELECT a, b, sum(c) FROM t2 GROUP BY a, b ORDER BY a DESC, b;
} $nSort { 2 one 27 2 two 30 1 one 9 1 two 12 {} one 45 {} two 48 }
# ORDER BY can never piggyback on the GROUP BY sort if it uses
# non-standard NULLS behaviour.
set nSort [expr $tn==1 ? 2 : 1]
do_sortcount_test 2.$tn.3.1 {
SELECT a, b, sum(c) FROM t2 GROUP BY a, b ORDER BY a, b DESC NULLS FIRST;
} $nSort { {} two 48 {} one 45 1 two 12 1 one 9 2 two 30 2 one 27 }
do_sortcount_test 2.$tn.3.2 {
SELECT a, b, sum(c) FROM t2 GROUP BY a, b ORDER BY a DESC, b NULLS LAST;
} $nSort { 2 one 27 2 two 30 1 one 9 1 two 12 {} one 45 {} two 48 }
}
finish_test
+4 -3
View File
@@ -126,6 +126,7 @@ set allquicktests [test_set $alltests -exclude {
walcrash2.test e_fkey.test backup.test
fts4merge.test fts4merge2.test fts4merge4.test fts4check.test
fts4merge5.test
fts3cov.test fts3snippet.test fts3corrupt2.test fts3an.test
fts3defer.test fts4langid.test fts3sort.test fts5unicode.test
@@ -455,8 +456,8 @@ test_suite "coverage-analyze" -description {
Coverage tests for file analyze.c.
} -files {
analyze3.test analyze4.test analyze5.test analyze6.test
analyze7.test analyze8.test analyze9.test analyzeA.test
analyze.test analyzeB.test mallocA.test
analyze7.test analyze8.test analyze9.test
analyze.test mallocA.test
}
test_suite "coverage-sorter" -description {
@@ -624,7 +625,7 @@ test_suite "utf16" -description {
} -files {
alter.test alter3.test
analyze.test analyze3.test analyze4.test analyze5.test analyze6.test
analyze7.test analyze8.test analyze9.test analyzeA.test analyzeB.test
analyze7.test analyze8.test analyze9.test
auth.test bind.test blob.test capi2.test capi3.test collate1.test
collate2.test collate3.test collate4.test collate5.test collate6.test
conflict.test date.test delete.test expr.test fkey1.test func.test
+11 -5
View File
@@ -1859,10 +1859,11 @@ do_test 23.1 {
CREATE INDEX i1 ON t1(b,c);
CREATE INDEX i2 ON t1(c,d);
CREATE INDEX i2x ON t1(d COLLATE nocase, c DESC);
CREATE INDEX i3 ON t1(d,b+c,c);
CREATE TABLE t2(x INTEGER REFERENCES t1);
}
db2 eval {SELECT name FROM sqlite_master}
} {t1 i1 i2 i2x t2}
} {t1 i1 i2 i2x i3 t2}
do_test 23.2a {
db eval {
DROP INDEX i2;
@@ -1889,13 +1890,14 @@ do_test 23.2b {
# means left-most. Key columns come before auxiliary columns.)
#
# (The second column of output from PRAGMA index_xinfo is...)
# EVIDENCE-OF: R-40889-06838 The rank of the column within the table
# EVIDENCE-OF: R-06603-49335 The rank of the column within the table
# being indexed, or -1 if the index-column is the rowid of the table
# being indexed.
# being indexed and -2 if the index is on an expression.
#
# (The third column of output from PRAGMA index_xinfo is...)
# EVIDENCE-OF: R-22751-28901 The name of the column being indexed, or
# NULL if the index-column is the rowid of the table being indexed.
# EVIDENCE-OF: R-40641-22898 The name of the column being indexed, or
# NULL if the index-column is the rowid of the table being indexed or an
# expression.
#
# (The fourth column of output from PRAGMA index_xinfo is...)
# EVIDENCE-OF: R-11847-09179 1 if the index-column is sorted in reverse
@@ -1915,6 +1917,9 @@ do_test 23.2c {
do_test 23.2d {
db2 eval {PRAGMA index_xinfo(i2x)}
} {0 3 d 0 nocase 1 1 2 c 1 BINARY 1 2 -1 {} 0 BINARY 0}
do_test 23.2e {
db2 eval {PRAGMA index_xinfo(i3)}
} {0 3 d 0 BINARY 1 1 -2 {} 0 BINARY 1 2 2 c 0 BINARY 1 3 -1 {} 0 BINARY 0}
# EVIDENCE-OF: R-64103-17776 PRAGMA schema.index_list(table-name); This
# pragma returns one row for each index associated with the given table.
@@ -1936,6 +1941,7 @@ do_test 23.2d {
#
do_test 23.3 {
db eval {
DROP INDEX IF EXISTS i3;
CREATE INDEX i3 ON t1(d,b,c);
}
capture_pragma db2 out {PRAGMA index_list(t1)}
+2
View File
@@ -412,6 +412,8 @@ proc count_tests_and_errors {logfile rcVar errmsgVar} {
# skip over "value is outside range" errors
if {[regexp {value .* is outside the range of representable} $line]} {
# noop
} elseif {[regexp {overflow: .* cannot be represented} $line]} {
# noop
} else {
incr ::NERRCASE
if {$rc==0} {
+6 -2
View File
@@ -578,10 +578,14 @@ proc main_tests {args} {
puts "$config \"$target\""
if {$bNodebug==0 && $bNosynthetic==0} {
set iHas [string first SQLITE_DEBUG $::Configs($config)]
set dtarget test
if {$target=="tcltest"} {
set dtarget tcltest
}
if {$iHas>=0} {
puts "$config-ndebug \"test\""
puts "$config-ndebug \"$dtarget\""
} else {
puts "$config-debug \"test\""
puts "$config-debug \"$dtarget\""
}
}
}
+53
View File
@@ -0,0 +1,53 @@
# 2019 September 10
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
# May you find forgiveness for yourself and forgive others.
# May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library. In particular,
# that problems related to ticket [18458b1a] have been fixed.
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix tkt-18458b1a
foreach tn {1 2} {
reset_db
if {$tn==1} {
# Disable the flattener and push-down optimizations
optimization_control db query-flattener 0
optimization_control db push-down 0
} else {
# Enable them
optimization_control db query-flattener 1
optimization_control db push-down 1
}
db cache size 0
do_execsql_test $tn.1.1 {
CREATE TABLE t0(c0 COLLATE NOCASE);
INSERT INTO t0(c0) VALUES ('B');
CREATE VIEW v0(c0, c1) AS SELECT DISTINCT t0.c0, 'a' FROM t0;
}
do_execsql_test $tn.1.2 {
SELECT count(*) FROM v0 WHERE c1 >= c0;
} 1
do_execsql_test $tn.1.3 {
SELECT count(*) FROM v0 WHERE NOT NOT (c1 >= c0);
} 1
do_execsql_test $tn.1.4 {
SELECT count(*) FROM v0 WHERE ((c1 >= c0) OR 0+0);
} 1
}
finish_test
+15 -1
View File
@@ -1,4 +1,4 @@
# 2011 December 06
# 2011-12-06
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
@@ -68,5 +68,19 @@ do_execsql_test 2.2 {
)
} {FACTORING FACTOR SWIMMING SWIMM}
# Similar problem discovered by dbsqlfuzz on 2019-09-18
#
do_execsql_test 3.0 {
DROP TABLE IF EXISTS t1;
CREATE TABLE t1(i INT PRIMARY KEY, a, b);
INSERT INTO t1 VALUES(NULL,'one','i');
CREATE INDEX i1a ON t1(a);
CREATE INDEX i1b ON t1(b);
SELECT (SELECT 1
FROM (SELECT 1 FROM t1 WHERE a=1 OR b='i')
WHERE a='o'
OR b IN (SELECT a=('b' IN (SELECT 'a'))))
FROM t1;
} {{}}
finish_test
+5 -5
View File
@@ -59,27 +59,27 @@ foreach tn {1 2} {
do_execsql_test $tn.1.2.6 { SELECT a < B FROM v5 } 0
#-------------------------------------------------------------------------
do_execsql_test 2.0 {
do_execsql_test $tn.2.0 {
CREATE TABLE t5(a, b COLLATE NOCASE);
INSERT INTO t5 VALUES(1, 'XYZ');
}
# Result should be 0, as column "xyz" from the sub-query has implicit
# collation sequence BINARY.
do_execsql_test 2.1 {
do_execsql_test $tn.2.1 {
SELECT xyz==b FROM ( SELECT a, 'xyz' AS xyz FROM t5 ), t5;
} {0}
# Result should be 1, as literal 'xyz' has no collation sequence, so
# the comparison uses the implicit collation sequence of the RHS - NOCASE.
do_execsql_test 2.2 {
do_execsql_test $tn.2.2 {
SELECT 'xyz'==b FROM ( SELECT a, 'xyz' AS xyz FROM t5 ), t5;
} {1}
#-----------------------------------------------------------------------
# The test case submitted with the ticket.
#
do_execsql_test 3.0 {
do_execsql_test $tn.3.0 {
DROP TABLE t0;
DROP VIEW v2;
@@ -94,7 +94,7 @@ foreach tn {1 2} {
# The result is 1, as the collation used is the implicit collation sequence
# of v2.c1 - BINARY.
do_execsql_test 3.1 {
do_execsql_test $tn.3.1 {
SELECT v2.c1 BETWEEN v2.c0 AND v2.c1 as count FROM v2;
} 1
}
+1 -1
View File
@@ -60,7 +60,7 @@ foreach {tn q res eqp} [subst -nocommands {
{1 3 2 2 3 1} {$idxscan*$sort}
8 "SELECT * FROM t1 GROUP BY x, y ORDER BY x DESC, y DESC"
{3 1 2 2 1 3} {$idxscan*$sort}
{3 1 2 2 1 3} {$idxscan}
9 "SELECT * FROM t1 GROUP BY x, y ORDER BY x ASC, y ASC"
{1 3 2 2 3 1} {$idxscan}
+6 -2
View File
@@ -825,8 +825,13 @@ for {set i 0} {$i < [llength $argv]} {incr i} {
}
}
wapptest_init
for {set i 0} {$i < [llength $lTestArg]} {incr i} {
switch -- [lindex $lTestArg $i] {
set opt [lindex $lTestArg $i]
if {[string range $opt 0 1]=="--"} {
set opt [string range $opt 1 end]
}
switch -- $opt {
-platform {
if {$i==[llength $lTestArg]-1} { wapptest_usage }
incr i
@@ -882,7 +887,6 @@ for {set i 0} {$i < [llength $lTestArg]} {incr i} {
}
}
wapptest_init
if {$G(noui)==0} {
wapp-start $lWappArg
} else {
+15
View File
@@ -432,6 +432,21 @@ execsql_test 4.11 {
SELECT count(distinct a) FILTER (WHERE b='odd') FROM t1
}
==========
execsql_test 5.0 {
DROP TABLE IF EXISTS t1;
CREATE TABLE t1(x INTEGER, y INTEGER);
INSERT INTO t1 VALUES(10, 1);
INSERT INTO t1 VALUES(20, 2);
INSERT INTO t1 VALUES(3, 3);
INSERT INTO t1 VALUES(2, 4);
INSERT INTO t1 VALUES(1, 5);
}
execsql_float_test 5.1 {
SELECT avg(x) OVER (ORDER BY y) AS z FROM t1 ORDER BY z;
}
finish_test
+29
View File
@@ -901,4 +901,33 @@ do_execsql_test 4.11 {
SELECT count(distinct a) FILTER (WHERE b='odd') FROM t1
} {3}
#==========================================================================
do_execsql_test 5.0 {
DROP TABLE IF EXISTS t1;
CREATE TABLE t1(x INTEGER, y INTEGER);
INSERT INTO t1 VALUES(10, 1);
INSERT INTO t1 VALUES(20, 2);
INSERT INTO t1 VALUES(3, 3);
INSERT INTO t1 VALUES(2, 4);
INSERT INTO t1 VALUES(1, 5);
} {}
do_test 5.1 {
set myres {}
foreach r [db eval {SELECT avg(x) OVER (ORDER BY y) AS z FROM t1 ORDER BY z;}] {
lappend myres [format %.4f [set r]]
}
set res2 {7.2000 8.7500 10.0000 11.0000 15.0000}
set i 0
foreach r [set myres] r2 [set res2] {
if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} {
error "list element [set i] does not match: got=[set r] expected=[set r2]"
}
incr i
}
set {} {}
} {}
finish_test
+37
View File
@@ -195,5 +195,42 @@ do_execsql_test 6.2 {
BETWEEN 1 AND 1;
} {0}
#-------------------------------------------------------------------------
reset_db
do_execsql_test 7.0 {
DROP TABLE IF EXISTS t1;
CREATE TABLE t1(x, y);
INSERT INTO t1 VALUES(10, 1);
INSERT INTO t1 VALUES(20, 2);
INSERT INTO t1 VALUES(3, 3);
INSERT INTO t1 VALUES(2, 4);
INSERT INTO t1 VALUES(1, 5);
} {}
do_execsql_test 7.1 {
SELECT avg(x) OVER (ORDER BY y) AS z FROM t1 ORDER BY z
} {
7.2 8.75 10.0 11.0 15.0
}
do_execsql_test 7.2 {
SELECT avg(x) OVER (ORDER BY y) z FROM t1 ORDER BY (z IS y);
} {
10.0 15.0 11.0 8.75 7.2
}
do_execsql_test 7.3 {
SELECT avg(x) OVER (ORDER BY y) z FROM t1 ORDER BY (y IS z);
} {
10.0 15.0 11.0 8.75 7.2
}
do_execsql_test 7.4 {
SELECT avg(x) OVER (ORDER BY y) z FROM t1 ORDER BY z + 0.0;
} {
7.2 8.75 10.0 11.0 15.0
}
finish_test
+339
View File
@@ -0,0 +1,339 @@
# 2019-08-30
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
# May you find forgiveness for yourself and forgive others.
# May you share freely, never taking more than you give.
#
#***********************************************************************
# Test cases for RANGE BETWEEN and especially with NULLS LAST
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix windowB
ifcapable !windowfunc {
finish_test
return
}
do_execsql_test 1.0 {
CREATE TABLE t1(a, b);
INSERT INTO t1 VALUES(NULL, 1);
INSERT INTO t1 VALUES(NULL, 2);
INSERT INTO t1 VALUES(NULL, 3);
} {}
foreach {tn win} {
1 { ORDER BY a RANGE BETWEEN 1 PRECEDING AND 1 FOLLOWING }
2 { ORDER BY a NULLS LAST RANGE BETWEEN 1 PRECEDING AND 1 FOLLOWING }
3 { ORDER BY a DESC RANGE BETWEEN 1 PRECEDING AND 1 FOLLOWING }
4 { ORDER BY a DESC NULLS FIRST RANGE BETWEEN 1 PRECEDING AND 1 FOLLOWING }
5 { ORDER BY a NULLS LAST RANGE BETWEEN 1 FOLLOWING AND 2 FOLLOWING }
6 { ORDER BY a DESC NULLS FIRST RANGE BETWEEN 1 FOLLOWING AND 2 FOLLOWING }
7 { ORDER BY a NULLS LAST RANGE BETWEEN 2 PRECEDING AND 1 PRECEDING }
8 { ORDER BY a DESC NULLS FIRST RANGE BETWEEN 2 PRECEDING AND 1 PRECEDING }
} {
do_execsql_test 1.$tn "
SELECT sum(b) OVER win FROM t1
WINDOW win AS ( $win )
" {6 6 6}
}
do_execsql_test 1.2 {
SELECT sum(b) OVER win FROM t1
WINDOW win AS (
ORDER BY a DESC NULLS FIRST RANGE BETWEEN 1 PRECEDING AND 1 FOLLOWING
)
} {6 6 6}
#-------------------------------------------------------------------------
reset_db
do_execsql_test 2.0 {
CREATE TABLE t1(a, b);
INSERT INTO t1 VALUES(1, NULL);
INSERT INTO t1 VALUES(2, 45);
INSERT INTO t1 VALUES(3, 66.2);
INSERT INTO t1 VALUES(4, 'hello world');
INSERT INTO t1 VALUES(5, 'hello world');
INSERT INTO t1 VALUES(6, X'1234');
INSERT INTO t1 VALUES(7, X'1234');
INSERT INTO t1 VALUES(8, NULL);
}
foreach {tn win} {
1 "ORDER BY b RANGE BETWEEN 1 PRECEDING AND 2 PRECEDING"
2 "ORDER BY b RANGE BETWEEN 2 FOLLOWING AND 2 FOLLOWING"
3 "ORDER BY b NULLS LAST RANGE BETWEEN 1 PRECEDING AND 2 PRECEDING"
4 "ORDER BY b NULLS LAST RANGE BETWEEN 2 FOLLOWING AND 2 FOLLOWING"
} {
do_execsql_test 2.1.$tn "
SELECT a, sum(a) OVER win FROM t1
WINDOW win AS ( $win )
ORDER BY 1
" {1 9 2 {} 3 {} 4 9 5 9 6 13 7 13 8 9}
}
#-------------------------------------------------------------------------
ifcapable json1 {
reset_db
do_execsql_test 3.0 {
CREATE TABLE testjson(id INTEGER PRIMARY KEY, j TEXT, x TEXT);
INSERT INTO testjson VALUES(1, '{"a":1}', 'a');
INSERT INTO testjson VALUES(2, '{"b":2}', 'b');
INSERT INTO testjson VALUES(3, '{"c":3}', 'c');
INSERT INTO testjson VALUES(4, '{"d":4}', 'd');
}
do_execsql_test 3.1 {
SELECT json_group_array(json(j)) FROM testjson;
} {
{[{"a":1},{"b":2},{"c":3},{"d":4}]}
}
do_execsql_test 3.2 {
SELECT json_group_array(json(j)) OVER (ORDER BY id) FROM testjson;
} {
{[{"a":1}]}
{[{"a":1},{"b":2}]}
{[{"a":1},{"b":2},{"c":3}]}
{[{"a":1},{"b":2},{"c":3},{"d":4}]}
}
do_execsql_test 3.3 {
SELECT json_group_array(json(j)) OVER (
ORDER BY id RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
EXCLUDE TIES
) FROM testjson;
} {
{[{"a":1}]}
{[{"a":1},{"b":2}]}
{[{"a":1},{"b":2},{"c":3}]}
{[{"a":1},{"b":2},{"c":3},{"d":4}]}
}
do_execsql_test 3.4 {
SELECT json_group_array(json(j)) OVER (
ORDER BY id ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING
) FROM testjson;
} {
{[{"a":1},{"b":2}]}
{[{"a":1},{"b":2},{"c":3}]}
{[{"b":2},{"c":3},{"d":4}]}
{[{"c":3},{"d":4}]}
}
do_execsql_test 3.5 {
SELECT json_group_array(json(j)) OVER (
ORDER BY id ROWS BETWEEN 2 PRECEDING AND 1 PRECEDING
) FROM testjson;
} {
{[]}
{[{"a":1}]}
{[{"a":1},{"b":2}]}
{[{"b":2},{"c":3}]}
}
do_execsql_test 3.5a {
UPDATE testjson SET j = replace(j,char(125),',"e":9'||char(125));
SELECT j FROM testjson;
} {
{{"a":1,"e":9}}
{{"b":2,"e":9}}
{{"c":3,"e":9}}
{{"d":4,"e":9}}
}
do_execsql_test 3.5b {
SELECT group_concat(x,'') OVER (
ORDER BY id ROWS BETWEEN 1 FOLLOWING AND 2 FOLLOWING
) FROM testjson ORDER BY id;
} {bc cd d {}}
do_execsql_test 3.5c {
SELECT json_group_array(json(j)) OVER (
ORDER BY id ROWS BETWEEN 1 FOLLOWING AND 2 FOLLOWING
) FROM testjson;
} {
{[{"b":2,"e":9},{"c":3,"e":9}]}
{[{"c":3,"e":9},{"d":4,"e":9}]}
{[{"d":4,"e":9}]}
{[]}
}
do_execsql_test 3.5d {
SELECT json_group_object(x,json(j)) OVER (
ORDER BY id ROWS BETWEEN 1 FOLLOWING AND 2 FOLLOWING
) FROM testjson;
} {
{{"b":{"b":2,"e":9},"c":{"c":3,"e":9}}}
{{"c":{"c":3,"e":9},"d":{"d":4,"e":9}}}
{{"d":{"d":4,"e":9}}}
{{}}
}
do_execsql_test 3.7b {
SELECT group_concat(x,'') FILTER (WHERE id!=2) OVER (
ORDER BY id ROWS BETWEEN 2 PRECEDING AND 1 PRECEDING
) FROM testjson;
} {{} a a c}
do_execsql_test 3.7c {
SELECT json_group_array(json(j)) FILTER (WHERE id!=2) OVER (
ORDER BY id ROWS BETWEEN 2 PRECEDING AND 1 PRECEDING
) FROM testjson
} {
{[]}
{[{"a":1,"e":9}]}
{[{"a":1,"e":9}]}
{[{"c":3,"e":9}]}
}
do_execsql_test 3.7d {
SELECT json_group_object(x,json(j)) FILTER (WHERE id!=2) OVER (
ORDER BY id ROWS BETWEEN 2 PRECEDING AND 1 PRECEDING
) FROM testjson
} {
{{}}
{{"a":{"a":1,"e":9}}}
{{"a":{"a":1,"e":9}}}
{{"c":{"c":3,"e":9}}}
}
}
#-------------------------------------------------------------------------
reset_db
do_execsql_test 4.0 {
CREATE TABLE x(a);
INSERT INTO x VALUES(1);
INSERT INTO x VALUES(2);
}
do_execsql_test 4.1 {
WITH y AS (
SELECT Row_Number() OVER (win) FROM x WINDOW win AS (PARTITION BY a)
)
SELECT * FROM y;
} {
1 1
}
do_catchsql_test 4.2 {
WITH y AS (
SELECT Row_Number() OVER (win) FROM x WINDOW win AS (PARTITION
BY fake_column))
SELECT * FROM y;
} {1 {no such column: fake_column}}
do_catchsql_test 4.3 {
SELECT 1 WINDOW win AS (PARTITION BY fake_column);
} {0 1}
#-------------------------------------------------------------------------
reset_db
do_execsql_test 5.0 {
CREATE TABLE t1(a, c);
CREATE INDEX i1 ON t1(a);
INSERT INTO t1 VALUES(0, 421);
INSERT INTO t1 VALUES(1, 844);
INSERT INTO t1 VALUES(2, 1001);
}
do_execsql_test 5.1 {
SELECT a, sum(c) OVER (
ORDER BY a RANGE BETWEEN 0 PRECEDING AND 3 PRECEDING
) FROM t1;
} {0 {} 1 {} 2 {}}
do_execsql_test 5.2 {
INSERT INTO t1 VALUES(NULL, 123);
INSERT INTO t1 VALUES(NULL, 111);
INSERT INTO t1 VALUES('xyz', 222);
INSERT INTO t1 VALUES('xyz', 333);
SELECT a, sum(c) OVER (
ORDER BY a RANGE BETWEEN 0 PRECEDING AND 3 PRECEDING
) FROM t1;
} {{} 234 {} 234 0 {} 1 {} 2 {} xyz 555 xyz 555}
do_execsql_test 5.3 {
SELECT a, sum(c) OVER (
ORDER BY a RANGE BETWEEN 2 FOLLOWING AND 0 FOLLOWING
) FROM t1;
} {{} 234 {} 234 0 {} 1 {} 2 {} xyz 555 xyz 555}
do_execsql_test 5.4 {
SELECT a, sum(c) OVER (
ORDER BY a RANGE BETWEEN 0 PRECEDING AND 3 PRECEDING EXCLUDE NO OTHERS
) FROM t1;
} {{} 234 {} 234 0 {} 1 {} 2 {} xyz 555 xyz 555}
do_execsql_test 5.5 {
SELECT a, sum(c) OVER (
ORDER BY a RANGE BETWEEN 2 FOLLOWING AND 0 FOLLOWING EXCLUDE NO OTHERS
) FROM t1;
} {{} 234 {} 234 0 {} 1 {} 2 {} xyz 555 xyz 555}
#-------------------------------------------------------------------------
reset_db
do_execsql_test 6.0 {
CREATE TABLE t1(a, c);
CREATE INDEX i1 ON t1(a);
INSERT INTO t1 VALUES(7, 997);
INSERT INTO t1 VALUES(8, 997);
INSERT INTO t1 VALUES('abc', 1001);
}
do_execsql_test 6.1 {
SELECT a, sum(c) OVER (
ORDER BY a RANGE BETWEEN 2 FOLLOWING AND 0 FOLLOWING
) FROM t1;
} {7 {} 8 {} abc 1001}
do_execsql_test 6.2 {
SELECT a, sum(c) OVER (
ORDER BY a RANGE BETWEEN 2 FOLLOWING AND 0 FOLLOWING EXCLUDE NO OTHERS
) FROM t1;
} {7 {} 8 {} abc 1001}
#-------------------------------------------------------------------------
reset_db
do_execsql_test 7.0 {
CREATE TABLE t1(a, c);
CREATE INDEX i1 ON t1(a);
INSERT INTO t1 VALUES(NULL, 46);
INSERT INTO t1 VALUES(NULL, 45);
INSERT INTO t1 VALUES(7, 997);
INSERT INTO t1 VALUES(7, 1000);
INSERT INTO t1 VALUES(8, 997);
INSERT INTO t1 VALUES(8, 1000);
INSERT INTO t1 VALUES('abc', 1001);
INSERT INTO t1 VALUES('abc', 1004);
INSERT INTO t1 VALUES('xyz', 3333);
}
do_execsql_test 7.1 {
SELECT a, max(c) OVER (
ORDER BY a RANGE BETWEEN 2 FOLLOWING AND 0 FOLLOWING
) FROM t1;
} {{} 46 {} 46 7 {} 7 {} 8 {} 8 {} abc 1004 abc 1004 xyz 3333}
do_execsql_test 7.2 {
SELECT a, min(c) OVER (
ORDER BY a RANGE BETWEEN 2 FOLLOWING AND 0 FOLLOWING
) FROM t1;
} {{} 45 {} 45 7 {} 7 {} 8 {} 8 {} abc 1001 abc 1001 xyz 3333}
do_execsql_test 7.3 {
SELECT a, max(c) OVER (
ORDER BY a RANGE BETWEEN 0 PRECEDING AND 2 PRECEDING
) FROM t1;
} {{} 46 {} 46 7 {} 7 {} 8 {} 8 {} abc 1004 abc 1004 xyz 3333}
do_execsql_test 7.4 {
SELECT a, min(c) OVER (
ORDER BY a RANGE BETWEEN 0 PRECEDING AND 2 PRECEDING
) FROM t1;
} {{} 45 {} 45 7 {} 7 {} 8 {} 8 {} abc 1001 abc 1001 xyz 3333}
finish_test
+9 -5
View File
@@ -17,6 +17,10 @@ set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix without_rowid1
proc do_execsql_test_if_vtab {tn sql {res {}}} {
ifcapable vtab { uplevel [list do_execsql_test $tn $sql $res] }
}
# Create and query a WITHOUT ROWID table.
#
do_execsql_test without_rowid1-1.0 {
@@ -31,7 +35,7 @@ do_execsql_test without_rowid1-1.0 {
integrity_check without_rowid1-1.0ic
do_execsql_test without_rowid1-1.0ixi {
do_execsql_test_if_vtab without_rowid1-1.0ixi {
SELECT name, key FROM pragma_index_xinfo('t1');
} {c 1 a 1 b 0 d 0}
@@ -119,7 +123,7 @@ do_execsql_test 2.1.2 {
UPDATE t4 SET a = 'ABC';
SELECT * FROM t4;
} {ABC def}
do_execsql_test 2.1.3 {
do_execsql_test_if_vtab 2.1.3 {
SELECT name, coll, key FROM pragma_index_xinfo('t4');
} {a nocase 1 b BINARY 0}
@@ -135,7 +139,7 @@ do_execsql_test 2.2.2 {
SELECT * FROM t4;
} {xyz ABC}
do_execsql_test 2.2.3 {
do_execsql_test_if_vtab 2.2.3 {
SELECT name, coll, key FROM pragma_index_xinfo('t4');
} {a nocase 1 b BINARY 0}
@@ -146,7 +150,7 @@ do_execsql_test 2.3.1 {
UPDATE t5 SET a='abc', b='def';
} {}
do_execsql_test 2.3.2 {
do_execsql_test_if_vtab 2.3.2 {
SELECT name, coll, key FROM pragma_index_xinfo('t5');
} {b BINARY 1 a BINARY 1}
@@ -165,7 +169,7 @@ do_execsql_test 2.4.2 {
SELECT * FROM t6 ORDER BY c;
} {ABC def ghi ABC def ghi}
do_execsql_test 2.4.3 {
do_execsql_test_if_vtab 2.4.3 {
SELECT name, coll, key FROM pragma_index_xinfo('t6');
} {b BINARY 1 a nocase 1 c BINARY 0}
+7 -3
View File
@@ -16,6 +16,10 @@
set testdir [file dirname $argv0]
source $testdir/tester.tcl
proc do_execsql_test_if_vtab {tn sql {res {}}} {
ifcapable vtab { uplevel [list do_execsql_test $tn $sql $res] }
}
do_execsql_test without_rowid6-100 {
CREATE TABLE t1(a,b,c,d,e, PRIMARY KEY(a,b,c,a,b,c,d,a,b,c)) WITHOUT ROWID;
CREATE INDEX t1a ON t1(b, b);
@@ -24,7 +28,7 @@ do_execsql_test without_rowid6-100 {
INSERT INTO t1(a,b,c,d,e) SELECT i, i+1000, printf('x%dy',i), 0, 0 FROM c;
ANALYZE;
} {}
do_execsql_test without_rowid6-101 {
do_execsql_test_if_vtab without_rowid6-101 {
SELECT name, key FROM pragma_index_xinfo('t1');
} {a 1 b 1 c 1 d 1 e 0}
do_execsql_test without_rowid6-110 {
@@ -54,7 +58,7 @@ do_execsql_test without_rowid6-200 {
INSERT INTO t1(a,b,c) VALUES(1,8,3),(4,5,6),(7,2,9);
SELECT a FROM t1 WHERE b>3 ORDER BY b;
} {4 1}
do_execsql_test without_rowid6-201 {
do_execsql_test_if_vtab without_rowid6-201 {
SELECT name, key FROM pragma_index_xinfo('t1');
} {b 1 a 0 c 0}
do_execsql_test without_rowid6-210 {
@@ -111,7 +115,7 @@ do_execsql_test without_rowid6-500 {
INSERT INTO t1(a,b,c) VALUES(1,8,3),(4,5,6),(7,2,9);
SELECT a FROM t1 WHERE b>3 ORDER BY b;
} {4 1}
do_execsql_test without_rowid6-501 {
do_execsql_test_if_vtab without_rowid6-501 {
SELECT name, key FROM pragma_index_xinfo('t1');
} {b 1 c 1 a 0}
do_execsql_test without_rowid6-510 {
+6 -2
View File
@@ -15,6 +15,10 @@ set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix without_rowid7
proc do_execsql_test_if_vtab {tn sql {res {}}} {
ifcapable vtab { uplevel [list do_execsql_test $tn $sql $res] }
}
do_execsql_test 1.0 {
CREATE TABLE t1(a, b COLLATE nocase, PRIMARY KEY(a, a, b)) WITHOUT ROWID;
}
@@ -36,13 +40,13 @@ do_execsql_test 2.1 {
do_execsql_test 2.2a {
PRAGMA index_info(t2);
} {0 0 a 1 0 a}
do_execsql_test 2.2b {
do_execsql_test_if_vtab 2.2b {
SELECT *, '|' FROM pragma_index_info('t2');
} {0 0 a | 1 0 a |}
do_execsql_test 2.3a {
PRAGMA index_xinfo(t2);
} {0 0 a 0 nocase 1 1 0 a 0 BINARY 1 2 1 b 0 BINARY 0}
do_execsql_test 2.3b {
do_execsql_test_if_vtab 2.3b {
SELECT *, '|' FROM pragma_index_xinfo('t2');
} {0 0 a 0 nocase 1 | 1 0 a 0 BINARY 1 | 2 1 b 0 BINARY 0 |}
+1 -1
View File
@@ -4426,7 +4426,7 @@ void ReportTable(
}
i++;
}
if( j>0 ) fprintf(out, "\n"); lineno++;
if( j>0 ){ fprintf(out, "\n"); lineno++; }
fprintf(out, "};\n"); lineno++;
/* Output the yy_shift_ofst[] table */
+9
View File
@@ -65,6 +65,15 @@ while test "$1" != ""; do
--nomemstat)
SPEEDTEST_OPTS="$SPEEDTEST_OPTS $1"
;;
--multithread)
SPEEDTEST_OPTS="$SPEEDTEST_OPTS $1"
;;
--singlethread)
SPEEDTEST_OPTS="$SPEEDTEST_OPTS $1"
;;
--serialized)
SPEEDTEST_OPTS="$SPEEDTEST_OPTS $1"
;;
--temp)
SPEEDTEST_OPTS="$SPEEDTEST_OPTS --temp 6"
;;