Compare commits

..

67 Commits

Author SHA1 Message Date
drh f14c59bb11 Cache the most recently sqlite3_context used by OP_Function and reuse it on
subsequent calls, if appropriate. This gives a noticable performance boost.

FossilOrigin-Name: 2f31bdd1b2186659f57a705ecf0eaf590471c374
2015-06-26 13:31:02 +00:00
drh 39065c60b3 Simplify the pcache by not keeping continuous track of page 1 but instead
just loading page 1 on the rare occasions when it is actually needed.

FossilOrigin-Name: 015302f15e46a087ec92f3644c6741600dbf4306
2015-06-26 02:41:31 +00:00
drh 591909c344 Optimization to sqlite3_value_bytes() for the common case that does not
require a data transformation.

FossilOrigin-Name: 8d79f3a1443391bee204bb8c49240f44477168db
2015-06-25 23:52:48 +00:00
drh 2c8fb926da Simplifications and performance improvements in insertCell().
FossilOrigin-Name: 7d02e6c992ef92e1f77ebc13889e17c028454b06
2015-06-25 19:53:48 +00:00
drh b7580e84a8 More simplifications and performance improvements to cell allocation
logic associated with allocateSpace().

FossilOrigin-Name: 78da0f69cb3289e332018864004f319f2764a5c8
2015-06-25 18:36:13 +00:00
drh e674bf1648 Reorder the terms of a conditional for a small performance gain.
FossilOrigin-Name: d67b0ed1054cbb7ea2cdd74720d4d6e0227cec14
2015-06-25 16:01:44 +00:00
drh ae6cd72318 Remove a NEVER() that is in fact reachable.
FossilOrigin-Name: f824e66b0dc120bed227c7446e2663fcad7cc4f6
2015-06-25 15:21:52 +00:00
drh ded340e4fc Minor optimization to allocateSpace().
FossilOrigin-Name: d007bc339b9ea6d59a3dd2b0c5e77e9c801b16f6
2015-06-25 15:04:56 +00:00
drh 6918095d81 Enhance the Btree object to remember whether or not it is holding an
Incrblob cursor.  Use this knowledge to improve performance in the common
case where it does not.

FossilOrigin-Name: 476b11563c08c6d9c0abd69e4d865c4edcdd45f5
2015-06-25 13:03:10 +00:00
drh 526b17db13 Remove a line of code that doesn't do any useful work.
FossilOrigin-Name: 3ee888beb974e015bd11ae79381b208eaa310f6f
2015-06-25 02:26:45 +00:00
drh d4ddcbc121 Increase the default timeout on fuzzcheck to 120 seconds - sufficient for
running under valgrind on a slow workstation.

FossilOrigin-Name: fad0eacc64b1810f60cab73bc88ba380f99e4b2d
2015-06-25 02:25:28 +00:00
drh 92298637ca Add the --timeout option to fuzzcheck.
FossilOrigin-Name: a8f4f7fa99e5e4131c1b59c0ac0597d62cedc0cd
2015-06-24 23:44:30 +00:00
drh 780573510b Fix fuzzcheck so that it works with SQLITE_OMIT_PROGRESS_CALLBACK.
FossilOrigin-Name: 7a9c4eb30e6a834da20931b535c2894837d7d5d7
2015-06-24 23:17:35 +00:00
drh 619a111e05 Add "ON CONFLICT" handling to the spellfix module.
FossilOrigin-Name: 07937a81c6c90eb7491a843eb65183805f5b675e
2015-06-24 18:22:51 +00:00
dan 88d702e6bd Add "ON CONFLICT" handling to the spellfix module.
FossilOrigin-Name: 1d04def785b6031de68b7f199d400cbb5c76caea
2015-06-24 17:21:52 +00:00
drh d83e2831b7 In the fuzzcheck test program, use the progress handler to limit the number
of VDBE cycles to avoid getting stuck if the SQL under test contains an
infinite CTE loop.  Add the --limit-vdbe command-line option.

FossilOrigin-Name: fbf9c4325e98120914bb03bdf351b57643f7a8c8
2015-06-24 14:45:44 +00:00
drh 6cbbdb08f8 Fix the progress handler so that it does not fire too soon during an
sqlite3_step() call other than the first.

FossilOrigin-Name: b41ef5d6db107cac2b1b46a955e63414434ee976
2015-06-24 14:36:27 +00:00
drh c6e956f038 Fix a harmless compiler warning.
FossilOrigin-Name: 3b6fa95eebfa01703d9ef4f530674d17e965c512
2015-06-24 13:32:10 +00:00
drh 94701b048a Rig the fuzzcheck test program so that it times out after 10 seconds in case
of an infinite loop in the test case.

FossilOrigin-Name: 659cfc9d1e9db83db171d621f248a7c2a5b183f6
2015-06-24 13:25:34 +00:00
drh 45143e9d31 Update the database fuzz test cases to cover all recent findings.
FossilOrigin-Name: 47ba7d96b1b91858ef1b592374839bc820719b95
2015-06-24 13:05:18 +00:00
drh 9a64586864 Add the --rebuild object to fuzzcheck.
FossilOrigin-Name: db87664a224f44e01b85570a3f3b6ec1c81d6e0a
2015-06-24 12:44:42 +00:00
drh 9e7804dfd4 Prevent an infinite loop while searching a corrupt freelist.
FossilOrigin-Name: 4e5424fe89eed346f6cf26a05c72694d1eb9f58f
2015-06-24 12:24:03 +00:00
drh 672073a41b Strengthen the new balance_nonroot() code against various corrupt database
problems.

FossilOrigin-Name: 5ba983432069714afebbb2f0ef22d41be52f7a4c
2015-06-24 12:07:40 +00:00
drh 40a3cabe68 Adjustment to a malloc test so that it accepts a narrow range of values to
account for variations in malloc subsystems.

FossilOrigin-Name: e0195070f84f418c46698627a2dcbfcfb94d999c
2015-06-24 10:46:25 +00:00
drh b468ce1256 Remove an invalid NEVER() and add a test case to cover it.
FossilOrigin-Name: 14b73d201509d3c04f760a08d21f3c499f2870a8
2015-06-24 01:07:30 +00:00
drh 9c739e26da Performance optimization on balance_nonroot() and related routines.
2.6% faster overall with a size increase of less than 750 bytes.

FossilOrigin-Name: 25131e7062125e91c2d60ed2cadf134dd7609124
2015-06-24 00:05:45 +00:00
drh 2ec18a3cce Mark some branches as unreachable after the recent change that recognizes
mismatch result set sizes on compound SELECT statements sooner.

FossilOrigin-Name: c8d1f305b6e9dfc36b8e3f4ab92de4457884d903
2015-06-23 23:31:52 +00:00
drh ea82b37302 Testability improvement.
FossilOrigin-Name: eed6a3314518cdab809264284d7680385f0d5d2a
2015-06-23 21:35:28 +00:00
drh fe647dc9ee Multiple overflow cells are always adjacent and sequential. Exploit this
invariant for a small size reduction and performance increase and add
assert()s to prove the invariant.

FossilOrigin-Name: f77f2f48f48e374a72b6c054142f7a3ec0b1483c
2015-06-23 18:24:25 +00:00
drh 4f4bf7747a Faster loading of cell pointers into the b.apCell array in balance_nonroot.
FossilOrigin-Name: fda89b0512477f9da09fd0f4e548ed4b13efd49d
2015-06-23 17:09:53 +00:00
drh 008d64c23a Avoid unnecessary cachedCellSize() calls in the cell partition adjustment
phase of balance_nonroot().

FossilOrigin-Name: 6319ee1256b1f7c39dd39a536a39b77b3d10dcac
2015-06-23 16:00:24 +00:00
drh f783893b8d Change pageInsertArray() and pageFreeArray() so that they use the CellArray
object and compute cell sizes as needed, resulting in smaller and faster code.

FossilOrigin-Name: f7f41818119bb7bfbd1f1297d294b32f32769cd3
2015-06-23 15:36:34 +00:00
drh 4edfdd38fb Improvements to the way balance_nonroot() constructs the b.apCell array of
pointers to cells.

FossilOrigin-Name: ee44bb25b2a88e25ba2afe37cf03ba199692a3a0
2015-06-23 14:49:42 +00:00
drh a2306712f2 Merge the compound SELECT operator fix from trunk.
FossilOrigin-Name: a7be554f4b8534fc237fa4c6defc38fcd4049707
2015-06-23 13:02:10 +00:00
dan 923cadb1ae Test that the left and right sides of a compound SELECT operator have the same number of expressions in the expanded expression list before beginning to generate code.
FossilOrigin-Name: 4df852ce26c95d5d23c83dbe9c59d2c3435acddf
2015-06-23 12:19:55 +00:00
drh 1ffd247c0c Avoid computing cell sizes in balance_nonroot() until they are really needed.
This gives an overall 1.7% performance gain for about 1000 extra bytes of
code space.

FossilOrigin-Name: 43844537e8a372953386663f8177202901ba7566
2015-06-23 02:37:30 +00:00
drh 658873bdb3 Change the way that balance_nonroot() partitions cells between the sibling
pages such that a scan of the cell size array is not required.

FossilOrigin-Name: 168728715156d756ac8c0df45710d054eee027ec
2015-06-22 20:02:04 +00:00
drh 82c4f9b407 Update the fuzztest data using the latest test vectors discovered by AFL.
FossilOrigin-Name: b97f9cf73e503c7285ba3a801e1f932f222d96b2
2015-06-20 14:11:56 +00:00
drh 5f02ab0976 Make sure that the likelihood() function does not mess up generation of
result-set code when it is used (inappropropriately) in a result-set 
expression.

FossilOrigin-Name: 7cdbae625eb029538a693d2bebec465a6f65fb90
2015-06-20 13:18:34 +00:00
drh b11b0efde6 Performance improvements in btreeParseCell() by inlining the varint decoder.
FossilOrigin-Name: 172a864d14fd9f0e3e97d2a13b22222ae0fedd39
2015-06-19 20:31:02 +00:00
drh eeab2c63a9 Fix corner cases involving corrupt varint values in record headers.
FossilOrigin-Name: 3189116b42c5ecef5e30c8b317f4458bbf8b9086
2015-06-19 20:08:39 +00:00
drh 56cb04efc8 Performance improvements in btreeParseCell() by inlining the varint decoder.
FossilOrigin-Name: faab0ed928074f3ec7c25e1a2058414fbd9b013c
2015-06-19 18:24:37 +00:00
drh 5fa605142f Add the MemPage.xParseCell method and provide various implementations
(variations on the former btreeParseCellPtr()) depending on the page type.

FossilOrigin-Name: 41d03d883c4f7ca279eb9dd679f3ab81c8d957d9
2015-06-19 17:19:34 +00:00
drh 25ada07ab4 Make cellSizePtr() a method on the MemPage object, with alternative
implementations depending on the page type.  This results is a small performance
improvement and size reduction.

FossilOrigin-Name: 02f7e9d7d7b93d0b6bbd6cc0d0359b3b741b9931
2015-06-19 15:07:14 +00:00
drh 4307690b5c Further #ifdef changes in speedtest1.c in order to support SQLite back to
version 3.3.9 and perhaps even earlier.

FossilOrigin-Name: 9246eca54adaee571dab0c066afaa604fcf9c44f
2015-06-18 15:26:09 +00:00
drh 606f2344e9 Pervent the likelihood() function from moving ON clause terms of a LEFT JOIN
into the WHERE clause.
Fix for ticket [5f60b11fc8e23490e2]

FossilOrigin-Name: ed96e14adce4a4f94cc6838c46bc97937c4cb72a
2015-06-18 14:32:51 +00:00
drh b3d903ebe5 Show the values of Expr.flag in the AST of ".selecttrace"
FossilOrigin-Name: a84d1004cbee67f2b8ba1fd201e43af49ea67c1b
2015-06-18 14:09:13 +00:00
drh 5995e292e6 Add #ifdefs to some features speedtest1.c so that it compiles with
older versions of SQLite, going back to version 3.5.1.

FossilOrigin-Name: f50dd154d33c58d7a9aa1852fdc362c2e81feef2
2015-06-18 12:37:32 +00:00
drh 14e067455e Performance improvement in sqlite3VdbeMemShallowCopy() for the common
case where the receiver does not require prior resource deallocation.

FossilOrigin-Name: d718ea36dce8cf1684c8bcda457fee87f8f8c4e2
2015-06-17 23:28:03 +00:00
mistachkin 073664de88 Improve spacing and comment style for the shell. No changes to code.
FossilOrigin-Name: 5b547da00d131a494a6b348339af3d91dfa6e3b6
2015-06-17 18:57:37 +00:00
drh 00452196d8 Improved comments on the fuzzcheck.c test program. No changes to code.
FossilOrigin-Name: a7e27d19280048bcfff6d2e796eed72287b9dabe
2015-06-17 18:24:40 +00:00
drh bbe031f9f1 Fix a uninitialized variable use in the command-line shell when the
".open" command is invoked without any arguments.

FossilOrigin-Name: fc4f4d1eccec2e09b5d2e6c4da082204f4d5a016
2015-06-17 17:08:22 +00:00
drh b0870486aa Performance optimization and comment fixes for the LIKE and GLOB operators.
FossilOrigin-Name: c89d772628564a808173f6f73bc1798ec714276b
2015-06-17 13:20:54 +00:00
drh c5b41ac8ee Make getCellInfo() a real function instead of a macro, for a size reduction
and a 0.2% performance gain.

FossilOrigin-Name: 55c393ea14197ae5fa56ebca7a47e7d980511fa7
2015-06-17 02:11:46 +00:00
drh f1aabd6b78 Optimizations to two VDBE accessory routines for a 0.2% performance increase.
FossilOrigin-Name: 66d033b9c9a8c16b9a342be0b325bd85b8487c03
2015-06-17 01:31:28 +00:00
drh 0dd5cdaea5 Ensure that the CREATE TABLE AS statement correctly undoes partial changes
to the sqlite_master table if the SELECT on the right-hand side aborts with
an error.  Fix for ticket [873cae2b6e25b]

FossilOrigin-Name: 400e025e7c61efab71b891743c07a0862e5bb934
2015-06-16 16:39:01 +00:00
drh 07d694c750 Adjust ICU tests to account for recent changes in the official
Unicode definition of whitespace.

FossilOrigin-Name: 0816525386ac51454b7b09a507e45b6a2cb8bf6e
2015-06-15 16:40:38 +00:00
drh 3e24a34324 Fix a harmless comment typo. No code changes.
FossilOrigin-Name: ae6876521819e7a8ce473c8f96617cba35e2156d
2015-06-15 16:09:35 +00:00
drh f5ed7ad63e Fix harmless compiler warnings.
FossilOrigin-Name: b0badb99023e23bef0e2064cec58f2b279af0c0b
2015-06-15 14:43:25 +00:00
drh e4d38707ea Improved detection of database corruption in freeSpace().
FossilOrigin-Name: 29bcb56887f862a1f06677a7b4bfae6475d29732
2015-06-15 12:58:15 +00:00
drh c056e4b257 Comment typo fix. No code changes.
FossilOrigin-Name: 17f185adb960b1fa4faa13cdf685b92a20a52072
2015-06-15 10:49:01 +00:00
drh 74a043607e Omit mutex calls in pcache1 when the mutex is NULL, for a significant
performance improvement.

FossilOrigin-Name: caf8f574e5c64da461c6dfba8a06cf3fb18aaa42
2015-06-13 11:19:47 +00:00
drh 982215a2c5 Avoid unnecessary mutex usage in pcache1, for a significant speedup.
FossilOrigin-Name: dcf4fb8d764611de60afea27cda0a8548ba7ca82
2015-06-13 11:10:55 +00:00
drh 55a46c9b0e Add a fast-path implementation of pcache1Fetch() for the common case of
separate caches that do not use a mutex.

FossilOrigin-Name: 760700edb3ff1f5d6bf3058f874cc8e2808905c7
2015-06-12 13:49:26 +00:00
drh b230a52892 Minor performance optimization in pcache1.c.
FossilOrigin-Name: 2e8ad2ead9d146e312c693d9b967bbd5b92429d9
2015-06-12 13:04:51 +00:00
drh 36b80349b7 Add the OP_ColumnsUsed opcode (when compiled with
SQLITE_ENABLE_COLUMN_USED_MASK) as a hint to the b-tree layer as to which
columns of a btree cursor will be used.

FossilOrigin-Name: 711a176cbfad5dde6defa9648fba6d0d663af134
2015-06-12 12:54:15 +00:00
drh 97bae794c2 Add a new opcode to the VDBE that gives the b-tree a hint about the set
of columns in a table or index that are actually used by the query.

FossilOrigin-Name: f167bba446b78dd7538d0b2bae3e6678f3b1ba28
2015-06-05 15:59:57 +00:00
47 changed files with 1515 additions and 717 deletions
+7 -6
View File
@@ -240,12 +240,13 @@ static int icuNext(
** The set of routines that implement the simple tokenizer
*/
static const sqlite3_tokenizer_module icuTokenizerModule = {
0, /* iVersion */
icuCreate, /* xCreate */
icuDestroy, /* xCreate */
icuOpen, /* xOpen */
icuClose, /* xClose */
icuNext, /* xNext */
0, /* iVersion */
icuCreate, /* xCreate */
icuDestroy, /* xCreate */
icuOpen, /* xOpen */
icuClose, /* xClose */
icuNext, /* xNext */
0, /* xLanguageid */
};
/*
+1 -1
View File
@@ -83,7 +83,6 @@ static int icuLikeCompare(
/* Read (and consume) the next character from the input pattern. */
UChar32 uPattern;
U8_NEXT_UNSAFE(zPattern, iPattern, uPattern);
assert(uPattern!=0);
/* There are now 4 possibilities:
**
@@ -422,6 +421,7 @@ static void icuLoadCollation(
int rc; /* Return code from sqlite3_create_collation_x() */
assert(nArg==2);
(void)nArg; /* Unused parameter */
zLocale = (const char *)sqlite3_value_text(apArg[0]);
zName = (const char *)sqlite3_value_text(apArg[1]);
+32 -6
View File
@@ -2655,6 +2655,31 @@ static int spellfix1Rowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
return SQLITE_OK;
}
/*
** This function is called by the xUpdate() method. It returns a string
** containing the conflict mode that xUpdate() should use for the current
** operation. One of: "ROLLBACK", "IGNORE", "ABORT" or "REPLACE".
*/
static const char *spellfix1GetConflict(sqlite3 *db){
static const char *azConflict[] = {
/* Note: Instead of "FAIL" - "ABORT". */
"ROLLBACK", "IGNORE", "ABORT", "ABORT", "REPLACE"
};
int eConflict = sqlite3_vtab_on_conflict(db);
assert( eConflict==SQLITE_ROLLBACK || eConflict==SQLITE_IGNORE
|| eConflict==SQLITE_FAIL || eConflict==SQLITE_ABORT
|| eConflict==SQLITE_REPLACE
);
assert( SQLITE_ROLLBACK==1 );
assert( SQLITE_IGNORE==2 );
assert( SQLITE_FAIL==3 );
assert( SQLITE_ABORT==4 );
assert( SQLITE_REPLACE==5 );
return azConflict[eConflict-1];
}
/*
** The xUpdate() method.
*/
@@ -2686,6 +2711,7 @@ static int spellfix1Update(
char *zK1, *zK2;
int i;
char c;
const char *zConflict = spellfix1GetConflict(db);
if( zWord==0 ){
/* Inserts of the form: INSERT INTO table(command) VALUES('xyzzy');
@@ -2746,10 +2772,10 @@ static int spellfix1Update(
}else{
newRowid = sqlite3_value_int64(argv[1]);
spellfix1DbExec(&rc, db,
"INSERT INTO \"%w\".\"%w_vocab\"(id,rank,langid,word,k1,k2) "
"VALUES(%lld,%d,%d,%Q,%Q,%Q)",
p->zDbName, p->zTableName,
newRowid, iRank, iLang, zWord, zK1, zK2
"INSERT OR %s INTO \"%w\".\"%w_vocab\"(id,rank,langid,word,k1,k2) "
"VALUES(%lld,%d,%d,%Q,%Q,%Q)",
zConflict, p->zDbName, p->zTableName,
newRowid, iRank, iLang, zWord, zK1, zK2
);
}
*pRowid = sqlite3_last_insert_rowid(db);
@@ -2757,9 +2783,9 @@ static int spellfix1Update(
rowid = sqlite3_value_int64(argv[0]);
newRowid = *pRowid = sqlite3_value_int64(argv[1]);
spellfix1DbExec(&rc, db,
"UPDATE \"%w\".\"%w_vocab\" SET id=%lld, rank=%d, langid=%d,"
"UPDATE OR %s \"%w\".\"%w_vocab\" SET id=%lld, rank=%d, langid=%d,"
" word=%Q, k1=%Q, k2=%Q WHERE id=%lld",
p->zDbName, p->zTableName, newRowid, iRank, iLang,
zConflict, p->zDbName, p->zTableName, newRowid, iRank, iLang,
zWord, zK1, zK2, rowid
);
}
+53 -50
View File
@@ -1,5 +1,5 @@
C Merge\strunk\sfixes.
D 2015-06-11T17:58:27.864
C Cache\sthe\smost\srecently\ssqlite3_context\sused\sby\sOP_Function\sand\sreuse\sit\son\nsubsequent\scalls,\sif\sappropriate.\sThis\sgives\sa\snoticable\sperformance\sboost.
D 2015-06-26T13:31:02.230
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in 1063c58075b7400d93326b0eb332b48a54f53025
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -85,7 +85,7 @@ F ext/fts3/fts3_aux.c 9edc3655fcb287f0467d0a4b886a01c6185fe9f1
F ext/fts3/fts3_expr.c 71c063da9c2a4167fb54aec089dd5ef33a58c9cb
F ext/fts3/fts3_hash.c 29b986e43f4e9dd40110eafa377dc0d63c422c60
F ext/fts3/fts3_hash.h 39cf6874dc239d6b4e30479b1975fe5b22a3caaf
F ext/fts3/fts3_icu.c e319e108661147bcca8dd511cd562f33a1ba81b5
F ext/fts3/fts3_icu.c deb46f7020d87ea7a14a433fb7a7f4bef42a9652
F ext/fts3/fts3_porter.c 3565faf04b626cddf85f03825e86056a4562c009
F ext/fts3/fts3_snippet.c 68ae118b0f834ea53d2b89e4087fc0f0b8c4ee4e
F ext/fts3/fts3_term.c 88c55a6fa1a51ab494e33dced0401a6c28791fd7
@@ -104,7 +104,7 @@ F ext/fts3/unicode/CaseFolding.txt 8c678ca52ecc95e16bc7afc2dbf6fc9ffa05db8c
F ext/fts3/unicode/UnicodeData.txt cd07314edb62d49fde34debdaf92fa2aa69011e7
F ext/fts3/unicode/mkunicode.tcl a2567f9d6ad6779879a2e394c120ad8718557e65
F ext/icu/README.txt d9fbbad0c2f647c3fdf715fc9fd64af53aedfc43
F ext/icu/icu.c d415ccf984defeb9df2c0e1afcfaa2f6dc05eacb
F ext/icu/icu.c b2732aef0b076e4276d9b39b5a33cec7a05e1413
F ext/icu/sqliteicu.h 728867a802baa5a96de7495e9689a8e01715ef37
F ext/misc/amatch.c 27b9b601fb1453084e18a3432ea0240d7af8decb
F ext/misc/closure.c 636024302cde41b2bf0c542f81c40c624cfb7012
@@ -118,7 +118,7 @@ F ext/misc/percentile.c bcbee3c061b884eccb80e21651daaae8e1e43c63
F ext/misc/regexp.c af92cdaa5058fcec1451e49becc7ba44dba023dc
F ext/misc/rot13.c 1ac6f95f99b575907b9b09c81a349114cf9be45a
F ext/misc/showauth.c 732578f0fe4ce42d577e1c86dc89dd14a006ab52
F ext/misc/spellfix.c 25810dda37fc904b0772a13efd8ca072fb09e355
F ext/misc/spellfix.c de9181ec188294dd2a1087b329ca55cfaa76a29d
F ext/misc/totype.c 4a167594e791abeed95e0a8db028822b5e8fe512
F ext/misc/vfslog.c fe40fab5c077a40477f7e5eba994309ecac6cc95
F ext/misc/vtshim.c babb0dc2bf116029e3e7c9a618b8a1377045303e
@@ -192,20 +192,20 @@ F src/auth.c b56c78ebe40a2110fd361379f7e8162d23f92240
F src/backup.c ff743689c4d6c5cb55ad42ed9d174b2b3e71f1e3
F src/bitvec.c 5eb7958c3bf65210211cbcfc44eff86d0ded7c9d
F src/btmutex.c 45a968cc85afed9b5e6cf55bf1f42f8d18107f79
F src/btree.c 5166c27883c24768c2f7f53479714f03ef34c612
F src/btree.c 40e98c10725c2cec5429068e21c17924f4bf06cc
F src/btree.h 969adc948e89e449220ff0ff724c94bb2a52e9f1
F src/btreeInt.h 973a22a6fd61350b454ad614832b1f0a5e25a1e4
F src/build.c 6770b74ccb51cb485e81057c625f77455d5ddc06
F src/btreeInt.h fdd1aff02fb2a63812bd95716e7f579fc3759107
F src/build.c b3f15255d5b16e42dafeaa638fd4f8a47c94ed70
F src/callback.c 7b44ce59674338ad48b0e84e7b72f935ea4f68b0
F src/complete.c a5cf5b4b56390cfb7b8636e8f7ddef90258dd575
F src/ctime.c 5a0b735dc95604766f5dac73973658eef782ee8b
F src/date.c e4d50b3283696836ec1036b695ead9a19e37a5ac
F src/dbstat.c f402e77e25089c6003d0c60b3233b9b3947d599a
F src/delete.c 81fc0453b0e95275bef8c2091636fcafc7229e91
F src/expr.c 710c764c1974b15a0e56b004ff9f5e6ceab3a854
F src/delete.c 8857a6f27560718f65d43bdbec86c967ae1f8dfa
F src/expr.c 32c836d9fa22c25371039febf074849dcefb3de9
F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
F src/fkey.c 6c5a2dbf8333303b033a2219e18ce8a9f99981c2
F src/func.c 5b8b8e77a0fb644eaf8947d413804622e32692b6
F src/fkey.c c9b63a217d86582c22121699a47f22f524608869
F src/func.c a98ea5880dc50e9ca6dd6f57079a37b9cfcdecf1
F src/global.c 4f77cadbc5427d00139ba43d0f3979804cbb700e
F src/hash.c 4263fbc955f26c2e8cdc0cf214bc42435aa4e4f5
F src/hash.h c8f3c31722cf3277d03713909761e152a5b81094
@@ -214,8 +214,8 @@ F src/insert.c b5f8b35a1b7924020e48cade5b2b5017bca7906b
F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d
F src/legacy.c ba1863ea58c4c840335a84ec276fc2b25e22bc4e
F src/lempar.c 7274c97d24bb46631e504332ccd3bd1b37841770
F src/loadext.c 29255bbe1cfb2ce9bbff2526a5ecfddcb49b9271
F src/main.c 3a610587018485d9a12e38899dd8b8129b04d836
F src/loadext.c e722f4b832f923744788365df5fb8515c0bc8a47
F src/main.c c0061a4f8ba86f957534be93b7026dab324f12c2
F src/malloc.c 908c780fdddd472163c2d1b1820ae4081f01ad20
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
F src/mem1.c abe6ee469b6c5a35c7f22bfeb9c9bac664a1c987
@@ -224,7 +224,7 @@ F src/mem3.c 61c9d47b792908c532ca3a62b999cf21795c6534
F src/mem5.c 61eeb90134f9a5be6c2e68d8daae7628b25953fb
F src/memjournal.c 3eb2c0b51adbd869cb6a44780323f05fa904dc85
F src/msvc.h d9ba56c6851227ab44b3f228a35f3f5772296495
F src/mutex.c 19bf9acba69ca2f367c3761080f8a9f0cf4670a8
F src/mutex.c 529e95739f815300a33c73fd8a7d6bdf0c24bd18
F src/mutex.h 779d588e3b7756ec3ecf7d78cde1d84aba414f85
F src/mutex_noop.c 529bab0743c3321c940f32c3464de494fd38cfa9
F src/mutex_unix.c 5cf676464bd19e0a866297515d146e8bf1669dfb
@@ -240,22 +240,22 @@ F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca
F src/pager.c 9bc918a009285f96ec6dac62dd764c7063552455
F src/pager.h c3476e7c89cdf1c6914e50a11f3714e30b4e0a77
F src/parse.y 6d60dda8f8d418b6dc034f1fbccd816c459983a8
F src/pcache.c 10539fb959849ad6efff80050541cab3d25089d4
F src/pcache.c d8b19632706dd6b81b03d0c5fd1e6bab8c13d0b9
F src/pcache.h b44658c9c932d203510279439d891a2a83e12ba8
F src/pcache1.c 69d137620a305f814398bd29a0c998038c0695e9
F src/pcache1.c 8e3799b33c41d517d86444d4abefc80d4f02adca
F src/pragma.c c1f4d012ea9f6b1ce52d341b2cd0ad72d560afd7
F src/pragma.h b8632d7cdda7b25323fa580e3e558a4f0d4502cc
F src/prepare.c 82e5db1013846a819f198336fed72c44c974e7b1
F src/printf.c db11b5960105ee661dcac690f2ae6276e49bf251
F src/random.c ba2679f80ec82c4190062d756f22d0c358180696
F src/resolve.c 84c571794e3ee5806274d95158a4c0177c6c4708
F src/resolve.c 2d47554370de8de6dd5be060cef9559eec315005
F src/rowset.c eccf6af6d620aaa4579bd3b72c1b6395d9e9fa1e
F src/select.c ecd8562e686b968511abbad6d6810fa30fda2952
F src/shell.c 07dda7cd692911d2f22269953418d049f2e2c0ee
F src/sqlite.h.in d165beeceb6b40af60f352a4d4e37e02d9af7df0
F src/select.c 9baeda79f93cfd180d471273a2f9c82c682a37a2
F src/shell.c 8af3cced094aebb5f57a8ad739b9dafc7867eed7
F src/sqlite.h.in 76d2f5637eb795b6300d9dd3c3ec3632ffafd721
F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad
F src/sqlite3ext.h 2ebeb634e751a61a6f0eebfa0f4669f46a42f6cd
F src/sqliteInt.h e389c788cd9f0af14528dfcddefc9ccece17d385
F src/sqlite3ext.h be1a718b7d2ce40ceba725ae92c8eb5f18003066
F src/sqliteInt.h d5df694bc33870e77fb08f389d12309597fe3059
F src/sqliteLimit.h 216557999cb45f2e3578ed53ebefe228d779cb46
F src/status.c f266ad8a2892d659b74f0f50cb6a88b6e7c12179
F src/table.c 51b46b2a62d1b3a959633d593b89bab5e2c9155e
@@ -306,20 +306,20 @@ F src/test_vfs.c 3b65d42e18b262805716bd96178c81da8f2d9283
F src/test_vfstrace.c bab9594adc976cbe696ff3970728830b4c5ed698
F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9
F src/threads.c 6bbcc9fe50c917864d48287b4792d46d6e873481
F src/tokenize.c baa0e550dfa76a8d781732a7bfb1f0aa094942f2
F src/treeview.c 84aa2d2ed26627ccc8dd3a2becfa18dc86ee4607
F src/tokenize.c 57cb3720f53f84d811def2069c2b169b6be539a5
F src/treeview.c c84b1a8ebc7f1d00cd76ce4958eeb3ae1021beed
F src/trigger.c 322f23aad694e8f31d384dcfa386d52a48d3c52f
F src/update.c 831a657bcfffcb44b25f3551909efcf4977e57c5
F src/update.c 487747b328b7216bb7f6af0695d6937d5c9e605f
F src/utf.c fc6b889ba0779b7722634cdeaa25f1930d93820c
F src/util.c a6431c92803b975b7322724a7b433e538d243539
F src/vacuum.c 2ddd5cad2a7b9cef7f9e431b8c7771634c6b1701
F src/vdbe.c 0a6a1df5c31415a0e974e74e7bd412616889453d
F src/vdbe.h 7e538ecf47dccb307ea2d087c3ddc2dd8d70e79d
F src/vdbeInt.h f0ccddac48583d5f762dc554a9f79e85ea8807e0
F src/vdbe.c 592957316d7bced599384e7897f6ee7728af5a61
F src/vdbe.h 90048aea1910f9df93e6044592bd4a466dc9c5e7
F src/vdbeInt.h 20295e482121d13437f69985f77db211cdc8bac1
F src/vdbeapi.c 6a0d7757987018ff6b1b81bc5293219cd26bb299
F src/vdbeaux.c 46f9bc4b32866082eb87a36b461e487a0bbdbe8e
F src/vdbeaux.c 4c82d6f686f72ea7d266d26d528a171b728626f7
F src/vdbeblob.c 4f2e8e075d238392df98c5e03a64342465b03f90
F src/vdbemem.c 67b302dc6df64b4d6785881c5d22bd4f9b17739d
F src/vdbemem.c ae38a0d35ae71cf604381a887c170466ba518090
F src/vdbesort.c f5009e7a35e3065635d8918b9a31f498a499976b
F src/vdbetrace.c 8befe829faff6d9e6f6e4dee5a7d3f85cc85f1a0
F src/vtab.c c535e80259ebe616467181a83a4263555b97c694
@@ -327,9 +327,9 @@ F src/vxworks.h c18586c8edc1bddbc15c004fa16aeb1e1342b4fb
F src/wal.c ce2cb2d06faab54d1bce3e739bec79e063dd9113
F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4
F src/walker.c c253b95b4ee44b21c406e2a1052636c31ea27804
F src/where.c aa26f4b0a3ad9c586f3315cb499d2dc813e14f01
F src/where.c 909eba3b6db984eb2adfbca9de2c237ee7056adb
F src/whereInt.h 5f87e3c4b0551747d119730dfebddd3c54f04047
F src/wherecode.c 3f3152ecf4224413bd0491ea4210883b85fe95d1
F src/wherecode.c 0669481cabaf5caf934b6bb825df15bc57f60d40
F src/whereexpr.c 9ce1c9cfedbf80c93c7d899497025ec8256ce652
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd
@@ -457,7 +457,7 @@ F test/corruptE.test 193b4ca4e927e77c1d5f4f56203ddc998432a7ee
F test/corruptF.test be9fde98e4c93648f1ba52b74e5318edc8f59fe4
F test/corruptG.test 1ab3bf97ee7bdba70e0ff3ba2320657df55d1804
F test/corruptH.test 5dd4fa98c6c1ed33b178f9e8a48c4fdd3cfc9067
F test/corruptI.test ddf8c7146db0bc6080eedced67453b4cc69b5340
F test/corruptI.test f2b10e4fec2a4315bca2b936ffa52ccbffac3422
F test/corruptJ.test 9e29e7a81ee3b6ac50f77ea7a9e2f3fa03f32d91
F test/cost.test 19d314526616ce4473eb4e4e450fcb94499ce318
F test/count.test cb2e0f934c6eb33670044520748d2ecccd46259c
@@ -517,7 +517,7 @@ F test/enc.test e54531cd6bf941ee6760be041dff19a104c7acea
F test/enc2.test 83437a79ba1545a55fb549309175c683fb334473
F test/enc3.test 90683ad0e6ea587b9d5542ca93568af9a9858c40
F test/enc4.test c8f1ce3618508fd0909945beb8b8831feef2c020
F test/eqp.test bd139ceea2ebc6ebb01c50f55f7c6f79473af6e5
F test/eqp.test 85873fa5816c48915c82c4e74cb5c35a5b48160f
F test/errmsg.test f31592a594b44ee121371d25ddd5d63497bb3401
F test/eval.test a64c9105d6ff163df7cf09d6ac29cdad5922078c
F test/exclusive.test c7ebbc756eacf544c108b15eed64d7d4e5f86b75
@@ -644,7 +644,7 @@ F test/fts4merge2.test 5faa558d1b672f82b847d2a337465fa745e46891
F test/fts4merge3.test aab02a09f50fe6baaddc2e159c3eabc116d45fc7
F test/fts4merge4.test d895b1057a7798b67e03455d0fa50e9ea836c47b
F test/fts4noti.test 524807f0c36d49deea7920cdd4cd687408b58849
F test/fts4unicode.test 01ec3fe2a7c3cfff3b4c0581b83caa11b33efa36
F test/fts4unicode.test 27378af76394542cf490cf001d8d1505fe55f6a9
F test/full.test 6b3c8fb43c6beab6b95438c1675374b95fab245d
F test/func.test ae97561957aba6ca9e3a7b8a13aac41830d701ef
F test/func2.test 772d66227e4e6684b86053302e2d74a2500e1e0f
@@ -657,10 +657,10 @@ F test/fuzz2.test 76dc35b32b6d6f965259508508abce75a6c4d7e1
F test/fuzz3.test efd384b896c647b61a2c1848ba70d42aad60a7b3
F test/fuzz_common.tcl a87dfbb88c2a6b08a38e9a070dabd129e617b45b
F test/fuzz_malloc.test 328f70aaca63adf29b4c6f06505ed0cf57ca7c26
F test/fuzzcheck.c a60f926e3fa86c8d33908406d75eec868c22b9ca
F test/fuzzdata1.db b60254eeb6bc11474071b883059662a73c48da7f
F test/fuzzcheck.c b973b06b500e6fc052d7059257cdf70df1f3a986
F test/fuzzdata1.db 7ee3227bad0e7ccdeb08a9e6822916777073c664
F test/fuzzdata2.db f03a420d3b822cc82e4f894ca957618fbe9c4973
F test/fuzzdata3.db a6e9bf75b8bfad0b7e60e57038908f4237b9c5d2
F test/fuzzdata3.db 1d6044c33a114007f02b6e6846f1fa232f607bfd
F test/fuzzer1.test d4c52aaf3ef923da293a2653cfab33d02f718a36
F test/fuzzerfault.test 8792cd77fd5bce765b05d0c8e01b9edcf8af8536
F test/genesis.tcl 1e2e2e8e5cc4058549a154ff1892fe5c9de19f98
@@ -668,7 +668,7 @@ F test/hexlit.test 1d312fa816dfd3650a3bb488093bc09a0c927f67
F test/hook.test 162d7cef7a2d2b04839fe14402934e6a1b79442f
F test/icu.test 70df4faca133254c042d02ae342c0a141f2663f4
F test/imposter1.test c3f1db2d3db2c24611a6596a3fc0ffc14f1466c8
F test/in.test b52fa96bcf6cebc5c8829c822315d0f87af9c6c2
F test/in.test 61a24ae38d4b64ec69f06ccdf022992f68a98176
F test/in2.test 5d4c61d17493c832f7d2d32bef785119e87bde75
F test/in3.test 3cbf58c87f4052cee3a58b37b6389777505aa0c0
F test/in4.test d2b38cba404bc4320f4fe1b595b3d163f212c068
@@ -745,7 +745,7 @@ F test/make-where7.tcl 05c16b5d4f5d6512881dfec560cb793915932ef9
F test/malloc.test 21c213365f2cca95ab2d7dc078dc8525f96065f8
F test/malloc3.test e3b32c724b5a124b57cb0ed177f675249ad0c66a
F test/malloc4.test 957337613002b7058a85116493a262f679f3a261
F test/malloc5.test 79182b8bffd6d62f77b1a5a8ba8e6bf0e5053b8e
F test/malloc5.test e9a9116f80ab6b7a9ca258876c6f3dedb08cb08b
F test/malloc6.test 2f039d9821927eacae43e1831f815e157659a151
F test/malloc7.test 7c68a32942858bc715284856c5507446bba88c3a
F test/malloc8.test 9b7a3f8cb9cf0b12fff566e80a980b1767bd961d
@@ -875,7 +875,7 @@ F test/select3.test 2ce595f8fb8e2ac10071d3b4e424cadd4634a054
F test/select4.test 6d5bc6d178a367e8b48fa1c1d3ea12cae9c2d650
F test/select5.test e758b8ef94f69b111df4cb819008856655dcd535
F test/select6.test 39eac4a5c03650b2b473c532882273283ee8b7a0
F test/select7.test 7fd2ef598cfabb6b9ff6ac13973b91d0527df49d
F test/select7.test 71f06cd37cb6f65bb08ba1ccf8e2f5818c09329f
F test/select8.test 8c8f5ae43894c891efc5755ed905467d1d67ad5d
F test/select9.test aebc2bb0c3bc44606125033cbcaac2c8d1f33a95
F test/selectA.test e452bdb975f488ea46d091382a9185b5853ed2c7
@@ -928,8 +928,8 @@ F test/speed3.test d32043614c08c53eafdc80f33191d5bd9b920523
F test/speed4.test abc0ad3399dcf9703abed2fff8705e4f8e416715
F test/speed4p.explain 6b5f104ebeb34a038b2f714150f51d01143e59aa
F test/speed4p.test 0e51908951677de5a969b723e03a27a1c45db38b
F test/speedtest1.c 9f1b745c24886cced3f70ffc666300152a39013c
F test/spellfix.test 24f676831acddd2f4056a598fd731a72c6311f49
F test/speedtest1.c f42fd04a34a0c1dc289cbe536ef62d706227a736
F test/spellfix.test 0597065ff57042df1f138e6a2611ae19c2698135
F test/sqldiff1.test 8f6bc7c6a5b3585d350d779c6078869ba402f8f5
F test/sqllimits1.test e05786eaed7950ff6a2d00031d001d8a26131e68
F test/stat.test 8de91498c99f5298b303f70f1d1f3b9557af91bf
@@ -943,7 +943,7 @@ F test/superlock.test 1cde669f68d2dd37d6c9bd35eee1d95491ae3fc2
F test/sync.test a34cd43e98b7fb84eabbf38f7ed8f7349b3f3d85
F test/syscall.test d2fdaad713f103ac611fe7ef9b724c7b69f8149c
F test/sysfault.test fa776e60bf46bdd3ae69f0b73e46ee3977a58ae6
F test/table.test bd841e8df69b99172ce9c7d53587463913d711ca
F test/table.test 33bf0d1fd07f304582695184b8e6feb017303816
F test/tableapi.test 2674633fa95d80da917571ebdd759a14d9819126
F test/tableopts.test dba698ba97251017b7c80d738c198d39ab747930
F test/tclsqlite.test 7fb866443c7deceed22b63948ccd6f76b52ad054
@@ -1209,7 +1209,7 @@ F test/whereC.test cae295158703cb3fc23bf1a108a9ab730efff0f6
F test/whereD.test 9eba1f9b18e5b19a0b0bcaae5e8c037260195f2b
F test/whereE.test b3a055eef928c992b0a33198a7b8dc10eea5ad2f
F test/whereF.test 5b2ba0dbe8074aa13e416b37c753991f0a2492d7
F test/whereG.test 69f5ec4b15760a8c860f80e2d55525669390aab3
F test/whereG.test dde4c52a97385a55be6a7cd46be8373f0cf35501
F test/whereH.test e4b07f7a3c2f5d31195cd33710054c78667573b2
F test/whereI.test 1d89199697919d4930be05a71e7fe620f114e622
F test/whereJ.test 55a3221706a7ab706293f17cc8f96da563bf0767
@@ -1284,9 +1284,12 @@ F tool/varint.c 5d94cb5003db9dbbcbcc5df08d66f16071aee003
F tool/vdbe-compress.tcl 5926c71f9c12d2ab73ef35c29376e756eb68361c
F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32
F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
P 0e23a079bd648f9778c857ec51e39acfd30a4040 afc6db9b105f32110112b877f06091757888a5f2
R 66f6090af762e2af727925054063787e
P 015302f15e46a087ec92f3644c6741600dbf4306
R 7832174f14c22d1eacdad67bafdfeaa7
T *branch * function-ctx-cache
T *sym-function-ctx-cache *
T -sym-trunk *
U drh
Z 15f99ba3f20685296cbae74ff03f5eca
Z e48fb4a345ac7f54e42bdc087583de4b
+1 -1
View File
@@ -1 +1 @@
1df8cbbea66f303029737752f37cf2a6db98fcd4
2f31bdd1b2186659f57a705ecf0eaf590471c374
+514 -281
View File
File diff suppressed because it is too large Load Diff
+4 -1
View File
@@ -231,6 +231,7 @@
/* Forward declarations */
typedef struct MemPage MemPage;
typedef struct BtLock BtLock;
typedef struct CellInfo CellInfo;
/*
** This is a magic string that appears at the beginning of every
@@ -295,6 +296,8 @@ struct MemPage {
u8 *aDataEnd; /* One byte past the end of usable data */
u8 *aCellIdx; /* The cell index area */
DbPage *pDbPage; /* Pager page handle */
u16 (*xCellSize)(MemPage*,u8*); /* cellSizePtr method */
void (*xParseCell)(MemPage*,u8*,CellInfo*); /* btreeParseCell method */
Pgno pgno; /* Page number for this page */
};
@@ -350,6 +353,7 @@ struct Btree {
u8 inTrans; /* TRANS_NONE, TRANS_READ or TRANS_WRITE */
u8 sharable; /* True if we can share pBt with another db */
u8 locked; /* True if db currently has pBt locked */
u8 hasIncrblobCur; /* True if there are one or more Incrblob cursors */
int wantToLock; /* Number of nested calls to sqlite3BtreeEnter() */
int nBackup; /* Number of backup operations reading this btree */
u32 iDataVersion; /* Combines with pBt->pPager->iDataVersion */
@@ -460,7 +464,6 @@ struct BtShared {
** about a cell. The parseCellPtr() function fills in this structure
** based on information extract from the raw disk page.
*/
typedef struct CellInfo CellInfo;
struct CellInfo {
i64 nKey; /* The key for INTKEY tables, or nPayload otherwise */
u8 *pPayload; /* Pointer to the start of payload */
+2 -1
View File
@@ -976,7 +976,7 @@ void sqlite3StartTable(
int j1;
int fileFormat;
int reg1, reg2, reg3;
sqlite3BeginWriteOperation(pParse, 0, iDb);
sqlite3BeginWriteOperation(pParse, 1, iDb);
#ifndef SQLITE_OMIT_VIRTUALTABLE
if( isVirtual ){
@@ -1924,6 +1924,7 @@ void sqlite3EndTable(
regRec = ++pParse->nMem;
regRowid = ++pParse->nMem;
assert(pParse->nTab==1);
sqlite3MayAbort(pParse);
sqlite3VdbeAddOp3(v, OP_OpenWrite, 1, pParse->regRoot, iDb);
sqlite3VdbeChangeP5(v, OPFLAG_P2ISREG);
pParse->nTab = 2;
+1 -1
View File
@@ -397,7 +397,7 @@ void sqlite3DeleteFrom(
/* Construct a query to find the rowid or primary key for every row
** to be deleted, based on the WHERE clause.
*/
pWInfo = sqlite3WhereBegin(pParse, 0, pTabList, pWhere, 0, 0,
pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0, 0,
WHERE_ONEPASS_DESIRED|WHERE_DUPLICATES_OK,
iTabCur+1);
if( pWInfo==0 ) goto delete_from_cleanup;
+3 -18
View File
@@ -2208,17 +2208,6 @@ static void sqlite3ExprCodeIN(
}
#endif /* SQLITE_OMIT_SUBQUERY */
/*
** Duplicate an 8-byte value
*/
static char *dup8bytes(Vdbe *v, const char *in){
char *out = sqlite3DbMallocRaw(sqlite3VdbeDb(v), 8);
if( out ){
memcpy(out, in, 8);
}
return out;
}
#ifndef SQLITE_OMIT_FLOATING_POINT
/*
** Generate an instruction that will put the floating point
@@ -2231,12 +2220,10 @@ static char *dup8bytes(Vdbe *v, const char *in){
static void codeReal(Vdbe *v, const char *z, int negateFlag, int iMem){
if( ALWAYS(z!=0) ){
double value;
char *zV;
sqlite3AtoF(z, &value, sqlite3Strlen30(z), SQLITE_UTF8);
assert( !sqlite3IsNaN(value) ); /* The new AtoF never returns NaN */
if( negateFlag ) value = -value;
zV = dup8bytes(v, (char*)&value);
sqlite3VdbeAddOp4(v, OP_Real, 0, iMem, 0, zV, P4_REAL);
sqlite3VdbeAddOp4Dup8(v, OP_Real, 0, iMem, 0, (u8*)&value, P4_REAL);
}
}
#endif
@@ -2262,10 +2249,8 @@ static void codeInteger(Parse *pParse, Expr *pExpr, int negFlag, int iMem){
assert( z!=0 );
c = sqlite3DecOrHexToI64(z, &value);
if( c==0 || (c==2 && negFlag) ){
char *zV;
if( negFlag ){ value = c==2 ? SMALLEST_INT64 : -value; }
zV = dup8bytes(v, (char*)&value);
sqlite3VdbeAddOp4(v, OP_Int64, 0, iMem, 0, zV, P4_INT64);
sqlite3VdbeAddOp4Dup8(v, OP_Int64, 0, iMem, 0, (u8*)&value, P4_INT64);
}else{
#ifdef SQLITE_OMIT_FLOATING_POINT
sqlite3ErrorMsg(pParse, "oversized integer: %s%s", negFlag ? "-" : "", z);
@@ -2870,7 +2855,7 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){
*/
if( pDef->funcFlags & SQLITE_FUNC_UNLIKELY ){
assert( nFarg>=1 );
sqlite3ExprCode(pParse, pFarg->a[0].pExpr, target);
inReg = sqlite3ExprCodeTarget(pParse, pFarg->a[0].pExpr, target);
break;
}
+1 -1
View File
@@ -631,7 +631,7 @@ static void fkScanChildren(
/* Create VDBE to loop through the entries in pSrc that match the WHERE
** clause. For each row found, increment either the deferred or immediate
** foreign key constraint counter. */
pWInfo = sqlite3WhereBegin(pParse, 0, pSrc, pWhere, 0, 0, 0, 0);
pWInfo = sqlite3WhereBegin(pParse, pSrc, pWhere, 0, 0, 0, 0);
sqlite3VdbeAddOp2(v, OP_FkCounter, pFKey->isDeferred, nIncr);
if( pWInfo ){
sqlite3WhereEnd(pWInfo);
+10 -13
View File
@@ -575,17 +575,15 @@ struct compareInfo {
/*
** For LIKE and GLOB matching on EBCDIC machines, assume that every
** character is exactly one byte in size. Also, all characters are
** able to participate in upper-case-to-lower-case mappings in EBCDIC
** whereas only characters less than 0x80 do in ASCII.
** character is exactly one byte in size. Also, provde the Utf8Read()
** macro for fast reading of the next character in the common case where
** the next character is ASCII.
*/
#if defined(SQLITE_EBCDIC)
# define sqlite3Utf8Read(A) (*((*A)++))
# define GlobUpperToLower(A) A = sqlite3UpperToLower[A]
# define GlobUpperToLowerAscii(A) A = sqlite3UpperToLower[A]
# define Utf8Read(A) (*(A++))
#else
# define GlobUpperToLower(A) if( A<=0x7f ){ A = sqlite3UpperToLower[A]; }
# define GlobUpperToLowerAscii(A) A = sqlite3UpperToLower[A]
# define Utf8Read(A) (A[0]<0x80?*(A++):sqlite3Utf8Read(&A))
#endif
static const struct compareInfo globInfo = { '*', '?', '[', 0 };
@@ -627,7 +625,7 @@ static const struct compareInfo likeInfoAlt = { '%', '_', 0, 0 };
** Ec Where E is the "esc" character and c is any other
** character, including '%', '_', and esc, match exactly c.
**
** The comments through this routine usually assume glob matching.
** The comments within this routine usually assume glob matching.
**
** This routine is usually quick, but can be N**2 in the worst case.
*/
@@ -651,13 +649,12 @@ static int patternCompare(
*/
matchOther = esc ? esc : pInfo->matchSet;
while( (c = sqlite3Utf8Read(&zPattern))!=0 ){
while( (c = Utf8Read(zPattern))!=0 ){
if( c==matchAll ){ /* Match "*" */
/* Skip over multiple "*" characters in the pattern. If there
** are also "?" characters, skip those as well, but consume a
** single character of the input string for each "?" skipped */
while( (c=sqlite3Utf8Read(&zPattern)) == matchAll
|| c == matchOne ){
while( (c=Utf8Read(zPattern)) == matchAll || c == matchOne ){
if( c==matchOne && sqlite3Utf8Read(&zString)==0 ){
return 0;
}
@@ -702,7 +699,7 @@ static int patternCompare(
if( patternCompare(zPattern,zString,pInfo,esc) ) return 1;
}
}else{
while( (c2 = sqlite3Utf8Read(&zString))!=0 ){
while( (c2 = Utf8Read(zString))!=0 ){
if( c2!=c ) continue;
if( patternCompare(zPattern,zString,pInfo,esc) ) return 1;
}
@@ -748,7 +745,7 @@ static int patternCompare(
continue;
}
}
c2 = sqlite3Utf8Read(&zString);
c2 = Utf8Read(zString);
if( c==c2 ) continue;
if( noCase && c<0x80 && c2<0x80 && sqlite3Tolower(c)==sqlite3Tolower(c2) ){
continue;
+4 -1
View File
@@ -402,7 +402,10 @@ static const sqlite3_api_routines sqlite3Apis = {
sqlite3_reset_auto_extension,
sqlite3_result_blob64,
sqlite3_result_text64,
sqlite3_strglob
sqlite3_strglob,
/* Version 3.8.11 and later */
(sqlite3_value*(*)(const sqlite3_value*))sqlite3_value_dup,
sqlite3_value_free
};
/*
+5 -1
View File
@@ -2082,9 +2082,11 @@ int sqlite3TempInMemory(const sqlite3 *db){
return ( db->temp_store!=1 );
#endif
#if SQLITE_TEMP_STORE==3
UNUSED_PARAMETER(db);
return 1;
#endif
#if SQLITE_TEMP_STORE<1 || SQLITE_TEMP_STORE>3
UNUSED_PARAMETER(db);
return 0;
#endif
}
@@ -3356,7 +3358,9 @@ int sqlite3_file_control(sqlite3 *db, const char *zDbName, int op, void *pArg){
*/
int sqlite3_test_control(int op, ...){
int rc = 0;
#ifndef SQLITE_OMIT_BUILTIN_TEST
#ifdef SQLITE_OMIT_BUILTIN_TEST
UNUSED_PARAMETER(op);
#else
va_list ap;
va_start(ap, op);
switch( op ){
+8 -3
View File
@@ -45,9 +45,14 @@ int sqlite3MutexInit(void){
}else{
pFrom = sqlite3NoopMutex();
}
memcpy(pTo, pFrom, offsetof(sqlite3_mutex_methods, xMutexAlloc));
memcpy(&pTo->xMutexFree, &pFrom->xMutexFree,
sizeof(*pTo) - offsetof(sqlite3_mutex_methods, xMutexFree));
pTo->xMutexInit = pFrom->xMutexInit;
pTo->xMutexEnd = pFrom->xMutexEnd;
pTo->xMutexFree = pFrom->xMutexFree;
pTo->xMutexEnter = pFrom->xMutexEnter;
pTo->xMutexTry = pFrom->xMutexTry;
pTo->xMutexLeave = pFrom->xMutexLeave;
pTo->xMutexHeld = pFrom->xMutexHeld;
pTo->xMutexNotheld = pFrom->xMutexNotheld;
pTo->xMutexAlloc = pFrom->xMutexAlloc;
}
rc = sqlite3GlobalConfig.mutex.xMutexInit();
+8 -14
View File
@@ -28,7 +28,6 @@ struct PCache {
int (*xStress)(void*,PgHdr*); /* Call to try make a page clean */
void *pStress; /* Argument to xStress */
sqlite3_pcache *pCache; /* Pluggable cache module */
PgHdr *pPage1; /* Reference to page 1 */
};
/********************************** Linked List Management ********************/
@@ -106,9 +105,6 @@ static void pcacheManageDirtyList(PgHdr *pPage, u8 addRemove){
*/
static void pcacheUnpin(PgHdr *p){
if( p->pCache->bPurgeable ){
if( p->pgno==1 ){
p->pCache->pPage1 = 0;
}
sqlite3GlobalConfig.pcache2.xUnpin(p->pCache->pCache, p->pPage, 0);
}
}
@@ -201,7 +197,6 @@ int sqlite3PcacheSetPageSize(PCache *pCache, int szPage){
sqlite3GlobalConfig.pcache2.xDestroy(pCache->pCache);
}
pCache->pCache = pNew;
pCache->pPage1 = 0;
pCache->szPage = szPage;
}
return SQLITE_OK;
@@ -359,9 +354,6 @@ PgHdr *sqlite3PcacheFetchFinish(
pCache->nRef++;
}
pPgHdr->nRef++;
if( pgno==1 ){
pCache->pPage1 = pPgHdr;
}
return pPgHdr;
}
@@ -402,9 +394,6 @@ void sqlite3PcacheDrop(PgHdr *p){
pcacheManageDirtyList(p, PCACHE_DIRTYLIST_REMOVE);
}
p->pCache->nRef--;
if( p->pgno==1 ){
p->pCache->pPage1 = 0;
}
sqlite3GlobalConfig.pcache2.xUnpin(p->pCache->pCache, p->pPage, 1);
}
@@ -495,9 +484,14 @@ void sqlite3PcacheTruncate(PCache *pCache, Pgno pgno){
sqlite3PcacheMakeClean(p);
}
}
if( pgno==0 && pCache->pPage1 ){
memset(pCache->pPage1->pData, 0, pCache->szPage);
pgno = 1;
if( pgno==0 && pCache->nRef ){
sqlite3_pcache_page *pPage1;
pPage1 = sqlite3GlobalConfig.pcache2.xFetch(pCache->pCache,1,0);
if( ALWAYS(pPage1) ){ /* Page 1 is always available in cache, because
** pCache->nRef>0 */
memset(pPage1->pBuf, 0, pCache->szPage);
pgno = 1;
}
}
sqlite3GlobalConfig.pcache2.xTruncate(pCache->pCache, pgno+1);
}
+72 -24
View File
@@ -148,8 +148,15 @@ static SQLITE_WSD struct PCacheGlobal {
/*
** Macros to enter and leave the PCache LRU mutex.
*/
#define pcache1EnterMutex(X) sqlite3_mutex_enter((X)->mutex)
#define pcache1LeaveMutex(X) sqlite3_mutex_leave((X)->mutex)
#if !defined(SQLITE_ENABLE_MEMORY_MANAGEMENT) || SQLITE_THREADSAFE==0
# define pcache1EnterMutex(X) assert((X)->mutex==0)
# define pcache1LeaveMutex(X) assert((X)->mutex==0)
# define PCACHE1_MIGHT_USE_GROUP_MUTEX 0
#else
# define pcache1EnterMutex(X) sqlite3_mutex_enter((X)->mutex)
# define pcache1LeaveMutex(X) sqlite3_mutex_leave((X)->mutex)
# define PCACHE1_MIGHT_USE_GROUP_MUTEX 1
#endif
/******************************************************************************/
/******** Page Allocation/SQLITE_CONFIG_PCACHE Related Functions **************/
@@ -425,31 +432,30 @@ static void pcache1ResizeHash(PCache1 *p){
**
** The PGroup mutex must be held when this function is called.
*/
static void pcache1PinPage(PgHdr1 *pPage){
static PgHdr1 *pcache1PinPage(PgHdr1 *pPage){
PCache1 *pCache;
PGroup *pGroup;
assert( pPage!=0 );
assert( pPage->isPinned==0 );
pCache = pPage->pCache;
pGroup = pCache->pGroup;
assert( pPage->pLruNext || pPage==pGroup->pLruTail );
assert( pPage->pLruPrev || pPage==pGroup->pLruHead );
assert( sqlite3_mutex_held(pGroup->mutex) );
assert( pPage->pLruNext || pPage==pCache->pGroup->pLruTail );
assert( pPage->pLruPrev || pPage==pCache->pGroup->pLruHead );
assert( sqlite3_mutex_held(pCache->pGroup->mutex) );
if( pPage->pLruPrev ){
pPage->pLruPrev->pLruNext = pPage->pLruNext;
}else{
pGroup->pLruHead = pPage->pLruNext;
pCache->pGroup->pLruHead = pPage->pLruNext;
}
if( pPage->pLruNext ){
pPage->pLruNext->pLruPrev = pPage->pLruPrev;
}else{
pGroup->pLruTail = pPage->pLruPrev;
pCache->pGroup->pLruTail = pPage->pLruPrev;
}
pPage->pLruNext = 0;
pPage->pLruPrev = 0;
pPage->isPinned = 1;
pCache->nRecyclable--;
return pPage;
}
@@ -530,10 +536,12 @@ static int pcache1Init(void *NotUsed){
UNUSED_PARAMETER(NotUsed);
assert( pcache1.isInit==0 );
memset(&pcache1, 0, sizeof(pcache1));
#if SQLITE_THREADSAFE
if( sqlite3GlobalConfig.bCoreMutex ){
pcache1.grp.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_LRU);
pcache1.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_PMEM);
}
#endif
pcache1.grp.mxPinned = 10;
pcache1.isInit = 1;
return SQLITE_OK;
@@ -729,9 +737,9 @@ static SQLITE_NOINLINE PgHdr1 *pcache1FetchStage2(
** attempt to allocate a new one.
*/
if( !pPage ){
if( createFlag==1 ) sqlite3BeginBenignMalloc();
if( createFlag==1 ){ sqlite3BeginBenignMalloc(); }
pPage = pcache1AllocPage(pCache);
if( createFlag==1 ) sqlite3EndBenignMalloc();
if( createFlag==1 ){ sqlite3EndBenignMalloc(); }
}
if( pPage ){
@@ -805,8 +813,13 @@ static SQLITE_NOINLINE PgHdr1 *pcache1FetchStage2(
** proceed to step 5.
**
** 5. Otherwise, allocate and return a new page buffer.
**
** There are two versions of this routine. pcache1FetchWithMutex() is
** the general case. pcache1FetchNoMutex() is a faster implementation for
** the common case where pGroup->mutex is NULL. The pcache1Fetch() wrapper
** invokes the appropriate routine.
*/
static sqlite3_pcache_page *pcache1Fetch(
static PgHdr1 *pcache1FetchNoMutex(
sqlite3_pcache *p,
unsigned int iKey,
int createFlag
@@ -814,28 +827,63 @@ static sqlite3_pcache_page *pcache1Fetch(
PCache1 *pCache = (PCache1 *)p;
PgHdr1 *pPage = 0;
assert( offsetof(PgHdr1,page)==0 );
assert( pCache->bPurgeable || createFlag!=1 );
assert( pCache->bPurgeable || pCache->nMin==0 );
assert( pCache->bPurgeable==0 || pCache->nMin==10 );
assert( pCache->nMin==0 || pCache->bPurgeable );
assert( pCache->nHash>0 );
pcache1EnterMutex(pCache->pGroup);
/* Step 1: Search the hash table for an existing entry. */
pPage = pCache->apHash[iKey % pCache->nHash];
while( pPage && pPage->iKey!=iKey ){ pPage = pPage->pNext; }
/* Step 2: Abort if no existing page is found and createFlag is 0 */
if( pPage ){
if( !pPage->isPinned ) pcache1PinPage(pPage);
if( !pPage->isPinned ){
return pcache1PinPage(pPage);
}else{
return pPage;
}
}else if( createFlag ){
/* Steps 3, 4, and 5 implemented by this subroutine */
pPage = pcache1FetchStage2(pCache, iKey, createFlag);
return pcache1FetchStage2(pCache, iKey, createFlag);
}else{
return 0;
}
}
#if PCACHE1_MIGHT_USE_GROUP_MUTEX
static PgHdr1 *pcache1FetchWithMutex(
sqlite3_pcache *p,
unsigned int iKey,
int createFlag
){
PCache1 *pCache = (PCache1 *)p;
PgHdr1 *pPage;
pcache1EnterMutex(pCache->pGroup);
pPage = pcache1FetchNoMutex(p, iKey, createFlag);
assert( pPage==0 || pCache->iMaxKey>=iKey );
pcache1LeaveMutex(pCache->pGroup);
return (sqlite3_pcache_page*)pPage;
return pPage;
}
#endif
static sqlite3_pcache_page *pcache1Fetch(
sqlite3_pcache *p,
unsigned int iKey,
int createFlag
){
#if PCACHE1_MIGHT_USE_GROUP_MUTEX || defined(SQLITE_DEBUG)
PCache1 *pCache = (PCache1 *)p;
#endif
assert( offsetof(PgHdr1,page)==0 );
assert( pCache->bPurgeable || createFlag!=1 );
assert( pCache->bPurgeable || pCache->nMin==0 );
assert( pCache->bPurgeable==0 || pCache->nMin==10 );
assert( pCache->nMin==0 || pCache->bPurgeable );
assert( pCache->nHash>0 );
#if PCACHE1_MIGHT_USE_GROUP_MUTEX
if( pCache->pGroup->mutex ){
return (sqlite3_pcache_page*)pcache1FetchWithMutex(p, iKey, createFlag);
}else
#endif
{
return (sqlite3_pcache_page*)pcache1FetchNoMutex(p, iKey, createFlag);
}
}
+7
View File
@@ -1331,6 +1331,13 @@ static int resolveSelectStep(Walker *pWalker, Select *p){
}
}
/* If this is part of a compound SELECT, check that it has the right
** number of expressions in the select list. */
if( p->pNext && p->pEList->nExpr!=p->pNext->pEList->nExpr ){
sqlite3SelectWrongNumTermsError(pParse, p->pNext);
return WRC_Abort;
}
/* Advance to the next term of the compound
*/
p = p->pPrior;
+124 -140
View File
@@ -366,6 +366,12 @@ static void setJoinExpr(Expr *p, int iTable){
assert( !ExprHasProperty(p, EP_TokenOnly|EP_Reduced) );
ExprSetVVAProperty(p, EP_NoReduce);
p->iRightJoinTable = (i16)iTable;
if( p->op==TK_FUNCTION && p->x.pList ){
int i;
for(i=0; i<p->x.pList->nExpr; i++){
setJoinExpr(p->x.pList->a[i].pExpr, iTable);
}
}
setJoinExpr(p->pLeft, iTable);
p = p->pRight;
}
@@ -1386,10 +1392,13 @@ static const char *columnTypeImpl(
** of the SELECT statement. Return the declaration type and origin
** data for the result-set column of the sub-select.
*/
if( iCol>=0 && iCol<pS->pEList->nExpr ){
if( iCol>=0 && ALWAYS(iCol<pS->pEList->nExpr) ){
/* If iCol is less than zero, then the expression requests the
** rowid of the sub-select or view. This expression is legal (see
** test case misc2.2.2) - it always evaluates to NULL.
**
** The ALWAYS() is because iCol>=pS->pEList->nExpr will have been
** caught already by name resolution.
*/
NameContext sNC;
Expr *p = pS->pEList->a[iCol].pExpr;
@@ -1868,7 +1877,10 @@ static CollSeq *multiSelectCollSeq(Parse *pParse, Select *p, int iCol){
pRet = 0;
}
assert( iCol>=0 );
if( pRet==0 && iCol<p->pEList->nExpr ){
/* iCol must be less than p->pEList->nExpr. Otherwise an error would
** have been thrown during name resolution and we would not have gotten
** this far */
if( pRet==0 && ALWAYS(iCol<p->pEList->nExpr) ){
pRet = sqlite3ExprCollSeq(pParse, p->pEList->a[iCol].pExpr);
}
return pRet;
@@ -2087,7 +2099,7 @@ static int multiSelectOrderBy(
** Error message for when two or more terms of a compound select have different
** size result sets.
*/
static void selectWrongNumTermsError(Parse *pParse, Select *p){
void sqlite3SelectWrongNumTermsError(Parse *pParse, Select *p){
if( p->selFlags & SF_Values ){
sqlite3ErrorMsg(pParse, "all VALUES must have the same number of terms");
}else{
@@ -2113,7 +2125,6 @@ static int multiSelectValues(
SelectDest *pDest /* What to do with query results */
){
Select *pPrior;
int nExpr = p->pEList->nExpr;
int nRow = 1;
int rc = 0;
assert( p->selFlags & SF_MultiValue );
@@ -2122,10 +2133,7 @@ static int multiSelectValues(
assert( p->op==TK_ALL || (p->op==TK_SELECT && p->pPrior==0) );
assert( p->pLimit==0 );
assert( p->pOffset==0 );
if( p->pEList->nExpr!=nExpr ){
selectWrongNumTermsError(pParse, p);
return 1;
}
assert( p->pNext==0 || p->pEList->nExpr==p->pNext->pEList->nExpr );
if( p->pPrior==0 ) break;
assert( p->pPrior->pNext==p );
p = p->pPrior;
@@ -2234,11 +2242,7 @@ static int multiSelect(
** in their result sets.
*/
assert( p->pEList && pPrior->pEList );
if( p->pEList->nExpr!=pPrior->pEList->nExpr ){
selectWrongNumTermsError(pParse, p);
rc = 1;
goto multi_select_end;
}
assert( p->pEList->nExpr==pPrior->pEList->nExpr );
#ifndef SQLITE_OMIT_CTE
if( p->selFlags & SF_Recursive ){
@@ -2857,9 +2861,7 @@ static int multiSelectOrderBy(
struct ExprList_item *pItem;
for(i=0, pItem=pOrderBy->a; i<nOrderBy; i++, pItem++){
assert( pItem->u.x.iOrderByCol>0 );
/* assert( pItem->u.x.iOrderByCol<=p->pEList->nExpr ) is also true
** but only for well-formed SELECT statements. */
testcase( pItem->u.x.iOrderByCol > p->pEList->nExpr );
assert( pItem->u.x.iOrderByCol<=p->pEList->nExpr );
aPermute[i] = pItem->u.x.iOrderByCol - 1;
}
pKeyMerge = multiSelectOrderByKeyInfo(pParse, p, 1);
@@ -3429,10 +3431,10 @@ static int flattenSubquery(
testcase( (pSub1->selFlags & (SF_Distinct|SF_Aggregate))==SF_Distinct );
testcase( (pSub1->selFlags & (SF_Distinct|SF_Aggregate))==SF_Aggregate );
assert( pSub->pSrc!=0 );
assert( pSub->pEList->nExpr==pSub1->pEList->nExpr );
if( (pSub1->selFlags & (SF_Distinct|SF_Aggregate))!=0
|| (pSub1->pPrior && pSub1->op!=TK_ALL)
|| pSub1->pSrc->nSrc<1
|| pSub->pEList->nExpr!=pSub1->pEList->nExpr
){
return 0;
}
@@ -3788,121 +3790,6 @@ static int pushDownWhereTerms(
}
#endif /* !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) */
/*
** Generate code for all sub-queries in the FROM clause
*/
#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW)
void sqlite3ManifestSubqueries(
Parse *pParse, /* Parsing context */
Select *p, /* SELECT statement being generated */
SrcList *pTabList /* The FROM clause */
){
int i;
sqlite3 *db = pParse->db;
Vdbe *v = pParse->pVdbe;
for(i=0; i<pTabList->nSrc; i++){
struct SrcList_item *pItem = &pTabList->a[i];
SelectDest dest;
Select *pSub = pItem->pSelect;
if( pSub==0 ) continue;
/* Sometimes the code for a subquery will be generated more than
** once, if the subquery is part of the WHERE clause in a LEFT JOIN,
** for example. In that case, do not regenerate the code to manifest
** a view or the co-routine to implement a view. The first instance
** is sufficient, though the subroutine to manifest the view does need
** to be invoked again. */
if( pItem->addrFillSub ){
if( pItem->viaCoroutine==0 ){
sqlite3VdbeAddOp2(v, OP_Gosub, pItem->regReturn, pItem->addrFillSub);
}
continue;
}
/* Increment Parse.nHeight by the height of the largest expression
** tree referred to by this, the parent select. The child select
** may contain expression trees of at most
** (SQLITE_MAX_EXPR_DEPTH-Parse.nHeight) height. This is a bit
** more conservative than necessary, but much easier than enforcing
** an exact limit.
*/
pParse->nHeight += sqlite3SelectExprHeight(p);
/* Make copies of constant WHERE-clause terms in the outer query down
** inside the subquery. This can help the subquery to run more efficiently.
*/
if( (pItem->jointype & JT_OUTER)==0
&& pushDownWhereTerms(db, pSub, p->pWhere, pItem->iCursor)
){
#if SELECTTRACE_ENABLED
if( sqlite3SelectTrace & 0x100 ){
SELECTTRACE(0x100,pParse,p,("After WHERE-clause push-down:\n"));
sqlite3TreeViewSelect(0, p, 0);
}
#endif
}
/* Generate code to implement the subquery
*/
if( pTabList->nSrc==1
&& (p->selFlags & SF_All)==0
&& OptimizationEnabled(db, SQLITE_SubqCoroutine)
){
/* Implement a co-routine that will return a single row of the result
** set on each invocation.
*/
int addrTop = sqlite3VdbeCurrentAddr(v)+1;
pItem->regReturn = ++pParse->nMem;
sqlite3VdbeAddOp3(v, OP_InitCoroutine, pItem->regReturn, 0, addrTop);
VdbeComment((v, "%s", pItem->pTab->zName));
pItem->addrFillSub = addrTop;
sqlite3SelectDestInit(&dest, SRT_Coroutine, pItem->regReturn);
explainSetInteger(pItem->iSelectId, (u8)pParse->iNextSelectId);
sqlite3Select(pParse, pSub, &dest);
pItem->pTab->nRowLogEst = sqlite3LogEst(pSub->nSelectRow);
pItem->viaCoroutine = 1;
pItem->regResult = dest.iSdst;
sqlite3VdbeAddOp1(v, OP_EndCoroutine, pItem->regReturn);
sqlite3VdbeJumpHere(v, addrTop-1);
sqlite3ClearTempRegCache(pParse);
}else{
/* Generate a subroutine that will fill an ephemeral table with
** the content of this subquery. pItem->addrFillSub will point
** to the address of the generated subroutine. pItem->regReturn
** is a register allocated to hold the subroutine return address
*/
int topAddr;
int onceAddr = 0;
int retAddr;
assert( pItem->addrFillSub==0 );
pItem->regReturn = ++pParse->nMem;
topAddr = sqlite3VdbeAddOp2(v, OP_Integer, 0, pItem->regReturn);
pItem->addrFillSub = topAddr+1;
if( pItem->isCorrelated==0 ){
/* If the subquery is not correlated and if we are not inside of
** a trigger, then we only need to compute the value of the subquery
** once. */
onceAddr = sqlite3CodeOnce(pParse); VdbeCoverage(v);
VdbeComment((v, "materialize \"%s\"", pItem->pTab->zName));
}else{
VdbeNoopComment((v, "materialize \"%s\"", pItem->pTab->zName));
}
sqlite3SelectDestInit(&dest, SRT_EphemTab, pItem->iCursor);
explainSetInteger(pItem->iSelectId, (u8)pParse->iNextSelectId);
sqlite3Select(pParse, pSub, &dest);
pItem->pTab->nRowLogEst = sqlite3LogEst(pSub->nSelectRow);
if( onceAddr ) sqlite3VdbeJumpHere(v, onceAddr);
retAddr = sqlite3VdbeAddOp1(v, OP_Return, pItem->regReturn);
VdbeComment((v, "end %s", pItem->pTab->zName));
sqlite3VdbeChangeP1(v, topAddr, retAddr);
sqlite3ClearTempRegCache(pParse);
}
if( db->mallocFailed ) break;
pParse->nHeight -= sqlite3SelectExprHeight(p);
}
}
#endif
/*
** Based on the contents of the AggInfo structure indicated by the first
** argument, this function checks if the following are true:
@@ -4999,13 +4886,110 @@ int sqlite3Select(
}
#endif
if( !OptimizationEnabled(db, SQLITE_LateSubquery) ){
/* Manifest the subqueries. This needs to be done before calling
** sqlite3WhereBegin() so that the Table.nRowLogEst value can be set
** correctly for the subqueries. */
sqlite3ManifestSubqueries(pParse, p, pTabList);
/* Generate code for all sub-queries in the FROM clause
*/
#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW)
for(i=0; i<pTabList->nSrc; i++){
struct SrcList_item *pItem = &pTabList->a[i];
SelectDest dest;
Select *pSub = pItem->pSelect;
if( pSub==0 ) continue;
/* Sometimes the code for a subquery will be generated more than
** once, if the subquery is part of the WHERE clause in a LEFT JOIN,
** for example. In that case, do not regenerate the code to manifest
** a view or the co-routine to implement a view. The first instance
** is sufficient, though the subroutine to manifest the view does need
** to be invoked again. */
if( pItem->addrFillSub ){
if( pItem->viaCoroutine==0 ){
sqlite3VdbeAddOp2(v, OP_Gosub, pItem->regReturn, pItem->addrFillSub);
}
continue;
}
/* Increment Parse.nHeight by the height of the largest expression
** tree referred to by this, the parent select. The child select
** may contain expression trees of at most
** (SQLITE_MAX_EXPR_DEPTH-Parse.nHeight) height. This is a bit
** more conservative than necessary, but much easier than enforcing
** an exact limit.
*/
pParse->nHeight += sqlite3SelectExprHeight(p);
/* Make copies of constant WHERE-clause terms in the outer query down
** inside the subquery. This can help the subquery to run more efficiently.
*/
if( (pItem->jointype & JT_OUTER)==0
&& pushDownWhereTerms(db, pSub, p->pWhere, pItem->iCursor)
){
#if SELECTTRACE_ENABLED
if( sqlite3SelectTrace & 0x100 ){
SELECTTRACE(0x100,pParse,p,("After WHERE-clause push-down:\n"));
sqlite3TreeViewSelect(0, p, 0);
}
#endif
}
/* Generate code to implement the subquery
*/
if( pTabList->nSrc==1
&& (p->selFlags & SF_All)==0
&& OptimizationEnabled(db, SQLITE_SubqCoroutine)
){
/* Implement a co-routine that will return a single row of the result
** set on each invocation.
*/
int addrTop = sqlite3VdbeCurrentAddr(v)+1;
pItem->regReturn = ++pParse->nMem;
sqlite3VdbeAddOp3(v, OP_InitCoroutine, pItem->regReturn, 0, addrTop);
VdbeComment((v, "%s", pItem->pTab->zName));
pItem->addrFillSub = addrTop;
sqlite3SelectDestInit(&dest, SRT_Coroutine, pItem->regReturn);
explainSetInteger(pItem->iSelectId, (u8)pParse->iNextSelectId);
sqlite3Select(pParse, pSub, &dest);
pItem->pTab->nRowLogEst = sqlite3LogEst(pSub->nSelectRow);
pItem->viaCoroutine = 1;
pItem->regResult = dest.iSdst;
sqlite3VdbeAddOp1(v, OP_EndCoroutine, pItem->regReturn);
sqlite3VdbeJumpHere(v, addrTop-1);
sqlite3ClearTempRegCache(pParse);
}else{
/* Generate a subroutine that will fill an ephemeral table with
** the content of this subquery. pItem->addrFillSub will point
** to the address of the generated subroutine. pItem->regReturn
** is a register allocated to hold the subroutine return address
*/
int topAddr;
int onceAddr = 0;
int retAddr;
assert( pItem->addrFillSub==0 );
pItem->regReturn = ++pParse->nMem;
topAddr = sqlite3VdbeAddOp2(v, OP_Integer, 0, pItem->regReturn);
pItem->addrFillSub = topAddr+1;
if( pItem->isCorrelated==0 ){
/* If the subquery is not correlated and if we are not inside of
** a trigger, then we only need to compute the value of the subquery
** once. */
onceAddr = sqlite3CodeOnce(pParse); VdbeCoverage(v);
VdbeComment((v, "materialize \"%s\"", pItem->pTab->zName));
}else{
VdbeNoopComment((v, "materialize \"%s\"", pItem->pTab->zName));
}
sqlite3SelectDestInit(&dest, SRT_EphemTab, pItem->iCursor);
explainSetInteger(pItem->iSelectId, (u8)pParse->iNextSelectId);
sqlite3Select(pParse, pSub, &dest);
pItem->pTab->nRowLogEst = sqlite3LogEst(pSub->nSelectRow);
if( onceAddr ) sqlite3VdbeJumpHere(v, onceAddr);
retAddr = sqlite3VdbeAddOp1(v, OP_Return, pItem->regReturn);
VdbeComment((v, "end %s", pItem->pTab->zName));
sqlite3VdbeChangeP1(v, topAddr, retAddr);
sqlite3ClearTempRegCache(pParse);
}
if( db->mallocFailed ) goto select_end;
pParse->nHeight -= sqlite3SelectExprHeight(p);
}
#endif
/* Various elements of the SELECT copied into local variables for
** convenience */
@@ -5104,7 +5088,7 @@ int sqlite3Select(
u16 wctrlFlags = (sDistinct.isTnct ? WHERE_WANT_DISTINCT : 0);
/* Begin the database scan. */
pWInfo = sqlite3WhereBegin(pParse, p, pTabList, pWhere, sSort.pOrderBy,
pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, sSort.pOrderBy,
p->pEList, wctrlFlags, 0);
if( pWInfo==0 ) goto select_end;
if( sqlite3WhereOutputRowCount(pWInfo) < p->nSelectRow ){
@@ -5260,7 +5244,7 @@ int sqlite3Select(
** in the right order to begin with.
*/
sqlite3VdbeAddOp2(v, OP_Gosub, regReset, addrReset);
pWInfo = sqlite3WhereBegin(pParse, p, pTabList, pWhere, pGroupBy, 0,
pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pGroupBy, 0,
WHERE_GROUPBY | (orderByGrp ? WHERE_SORTBYGROUP : 0), 0
);
if( pWInfo==0 ) goto select_end;
@@ -5555,7 +5539,7 @@ int sqlite3Select(
** of output.
*/
resetAccumulator(pParse, &sAggInfo);
pWInfo = sqlite3WhereBegin(pParse,p,pTabList, pWhere, pMinMax,0,flag,0);
pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pMinMax,0,flag,0);
if( pWInfo==0 ){
sqlite3ExprListDelete(db, pDel);
goto select_end;
+32 -30
View File
@@ -101,28 +101,26 @@
#if defined(_WIN32) || defined(WIN32)
# include <io.h>
# include <fcntl.h>
#define isatty(h) _isatty(h)
#ifndef access
# define access(f,m) _access((f),(m))
#endif
#undef popen
#define popen _popen
#undef pclose
#define pclose _pclose
# define isatty(h) _isatty(h)
# ifndef access
# define access(f,m) _access((f),(m))
# endif
# undef popen
# define popen _popen
# undef pclose
# define pclose _pclose
#else
/* Make sure isatty() has a prototype.
*/
extern int isatty(int);
#if !defined(__RTP__) && !defined(_WRS_KERNEL)
/* popen and pclose are not C89 functions and so are sometimes omitted from
** the <stdio.h> header */
extern FILE *popen(const char*,const char*);
extern int pclose(FILE*);
#else
# define SQLITE_OMIT_POPEN 1
#endif
/* Make sure isatty() has a prototype. */
extern int isatty(int);
# if !defined(__RTP__) && !defined(_WRS_KERNEL)
/* popen and pclose are not C89 functions and so are
** sometimes omitted from the <stdio.h> header */
extern FILE *popen(const char*,const char*);
extern int pclose(FILE*);
# else
# define SQLITE_OMIT_POPEN 1
# endif
#endif
#if defined(_WIN32_WCE)
@@ -1331,7 +1329,10 @@ static void display_scanstats(
sqlite3 *db, /* Database to query */
ShellState *pArg /* Pointer to ShellState */
){
#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
#ifndef SQLITE_ENABLE_STMT_SCANSTATUS
UNUSED_PARAMETER(db);
UNUSED_PARAMETER(pArg);
#else
int i, k, n, mx;
fprintf(pArg->out, "-------- scanstats --------\n");
mx = 0;
@@ -1866,6 +1867,7 @@ static void readfileFunc(
long nIn;
void *pBuf;
UNUSED_PARAMETER(argc);
zName = (const char*)sqlite3_value_text(argv[0]);
if( zName==0 ) return;
in = fopen(zName, "rb");
@@ -1898,6 +1900,7 @@ static void writefileFunc(
sqlite3_int64 rc;
const char *zFile;
UNUSED_PARAMETER(argc);
zFile = (const char*)sqlite3_value_text(argv[0]);
if( zFile==0 ) return;
out = fopen(zFile, "wb");
@@ -2577,7 +2580,7 @@ static int shell_dbinfo_command(ShellState *p, int nArg, char **azArg){
fprintf(p->out, "%-20s %d\n", "write format:", aHdr[18]);
fprintf(p->out, "%-20s %d\n", "read format:", aHdr[19]);
fprintf(p->out, "%-20s %d\n", "reserved bytes:", aHdr[20]);
for(i=0; i<sizeof(aField)/sizeof(aField[0]); i++){
for(i=0; i<ArraySize(aField); i++){
int ofst = aField[i].ofst;
unsigned int val = get4byteInt(aHdr + ofst);
fprintf(p->out, "%-20s %u", aField[i].zName, val);
@@ -2597,7 +2600,7 @@ static int shell_dbinfo_command(ShellState *p, int nArg, char **azArg){
}else{
zSchemaTab = sqlite3_mprintf("\"%w\".sqlite_master", zDb);
}
for(i=0; i<sizeof(aQuery)/sizeof(aQuery[0]); i++){
for(i=0; i<ArraySize(aQuery); i++){
char *zSql = sqlite3_mprintf(aQuery[i].zSql, zSchemaTab);
int val = db_int(p, zSql);
sqlite3_free(zSql);
@@ -3228,7 +3231,7 @@ static int do_meta_command(char *zLine, ShellState *p){
int i, n2;
open_db(p, 0);
if( nArg==1 ){
for(i=0; i<sizeof(aLimit)/sizeof(aLimit[0]); i++){
for(i=0; i<ArraySize(aLimit); i++){
printf("%20s %d\n", aLimit[i].zLimitName,
sqlite3_limit(p->db, aLimit[i].limitCode, -1));
}
@@ -3239,7 +3242,7 @@ static int do_meta_command(char *zLine, ShellState *p){
}else{
int iLimit = -1;
n2 = strlen30(azArg[1]);
for(i=0; i<sizeof(aLimit)/sizeof(aLimit[0]); i++){
for(i=0; i<ArraySize(aLimit); i++){
if( sqlite3_strnicmp(aLimit[i].zLimitName, azArg[1], n2)==0 ){
if( iLimit<0 ){
iLimit = i;
@@ -3349,9 +3352,8 @@ static int do_meta_command(char *zLine, ShellState *p){
const char *zSavedFilename = p->zDbFilename;
char *zNewFilename = 0;
p->db = 0;
if( nArg>=2 ){
p->zDbFilename = zNewFilename = sqlite3_mprintf("%s", azArg[1]);
}
if( nArg>=2 ) zNewFilename = sqlite3_mprintf("%s", azArg[1]);
p->zDbFilename = zNewFilename;
open_db(p, 1);
if( p->db!=0 ){
sqlite3_close(savedDb);
@@ -3815,7 +3817,7 @@ static int do_meta_command(char *zLine, ShellState *p){
/* convert testctrl text option to value. allow any unique prefix
** of the option name, or a numerical value. */
n2 = strlen30(azArg[1]);
for(i=0; i<(int)(sizeof(aCtrl)/sizeof(aCtrl[0])); i++){
for(i=0; i<ArraySize(aCtrl); i++){
if( strncmp(azArg[1], aCtrl[i].zCtrlName, n2)==0 ){
if( testctrl<0 ){
testctrl = aCtrl[i].ctrlCode;
@@ -4792,7 +4794,7 @@ int SQLITE_CDECL main(int argc, char **argv){
sqlite3_snprintf(nHistory, zHistory,"%s/.sqlite_history", zHome);
}
}
if( zHistory ) shell_read_history(zHistory);
if( zHistory ){ shell_read_history(zHistory); }
rc = process_input(&data, 0);
if( zHistory ){
shell_stifle_history(100);
+1 -1
View File
@@ -23,7 +23,7 @@
**
** The official C-language API documentation for SQLite is derived
** from comments in this file. This file is the authoritative source
** on how SQLite interfaces are suppose to operate.
** on how SQLite interfaces are supposed to operate.
**
** The name of this file under configuration management is "sqlite.h.in".
** The makefile makes some minor changes to this file (such as inserting
+2 -1
View File
@@ -267,7 +267,8 @@ struct sqlite3_api_routines {
void (*result_text64)(sqlite3_context*,const char*,sqlite3_uint64,
void(*)(void*), unsigned char);
int (*strglob)(const char*,const char*);
sqlite3_value (*value_dup)(const sqlite3_value*);
/* Version 3.8.11 and later */
sqlite3_value *(*value_dup)(const sqlite3_value*);
void (*value_free)(sqlite3_value*);
};
+10 -4
View File
@@ -1273,7 +1273,6 @@ struct sqlite3 {
#define SQLITE_Transitive 0x0200 /* Transitive constraints */
#define SQLITE_OmitNoopJoin 0x0400 /* Omit unused tables in joins */
#define SQLITE_Stat34 0x0800 /* Use STAT3 or STAT4 data */
#define SQLITE_LateSubquery 0x1000 /* Plan main Q before rendering subQ */
#define SQLITE_AllOpts 0xffff /* All optimizations */
/*
@@ -3067,7 +3066,9 @@ int sqlite3CantopenError(int);
# define sqlite3Isxdigit(x) isxdigit((unsigned char)(x))
# define sqlite3Tolower(x) tolower((unsigned char)(x))
#endif
#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS
int sqlite3IsIdChar(u8);
#endif
/*
** Internal function prototypes
@@ -3095,7 +3096,9 @@ void sqlite3ScratchFree(void*);
void *sqlite3PageMalloc(int);
void sqlite3PageFree(void*);
void sqlite3MemSetDefault(void);
#ifndef SQLITE_OMIT_BUILTIN_TEST
void sqlite3BenignMallocHooks(void (*)(void), void (*)(void));
#endif
int sqlite3HeapNearlyFull(void);
/*
@@ -3239,7 +3242,9 @@ int sqlite3BitvecSet(Bitvec*, u32);
void sqlite3BitvecClear(Bitvec*, u32, void*);
void sqlite3BitvecDestroy(Bitvec*);
u32 sqlite3BitvecSize(Bitvec*);
#ifndef SQLITE_OMIT_BUILTIN_TEST
int sqlite3BitvecBuiltinTest(int,int*);
#endif
RowSet *sqlite3RowSetInit(sqlite3*, void*, unsigned int);
void sqlite3RowSetClear(RowSet*);
@@ -3286,7 +3291,6 @@ Index *sqlite3AllocateIndexObject(sqlite3*,i16,int,char**);
Index *sqlite3CreateIndex(Parse*,Token*,Token*,SrcList*,ExprList*,int,Token*,
Expr*, int, int);
void sqlite3DropIndex(Parse*, SrcList*, int);
void sqlite3ManifestSubqueries(Parse*, Select*, SrcList*);
int sqlite3Select(Parse*, Select*, SelectDest*);
Select *sqlite3SelectNew(Parse*,ExprList*,SrcList*,Expr*,ExprList*,
Expr*,ExprList*,u16,Expr*,Expr*);
@@ -3299,8 +3303,7 @@ Expr *sqlite3LimitWhere(Parse*,SrcList*,Expr*,ExprList*,Expr*,Expr*,char*);
#endif
void sqlite3DeleteFrom(Parse*, SrcList*, Expr*);
void sqlite3Update(Parse*, SrcList*, ExprList*, Expr*, int);
WhereInfo *sqlite3WhereBegin(Parse*,Select*,SrcList*,Expr*,ExprList*,
ExprList*,u16,int);
WhereInfo *sqlite3WhereBegin(Parse*,SrcList*,Expr*,ExprList*,ExprList*,u16,int);
void sqlite3WhereEnd(WhereInfo*);
u64 sqlite3WhereOutputRowCount(WhereInfo*);
int sqlite3WhereIsDistinct(WhereInfo*);
@@ -3346,8 +3349,10 @@ void sqlite3ExprAnalyzeAggregates(NameContext*, Expr*);
void sqlite3ExprAnalyzeAggList(NameContext*,ExprList*);
int sqlite3FunctionUsesThisSrc(Expr*, SrcList*);
Vdbe *sqlite3GetVdbe(Parse*);
#ifndef SQLITE_OMIT_BUILTIN_TEST
void sqlite3PrngSaveState(void);
void sqlite3PrngRestoreState(void);
#endif
void sqlite3RollbackAll(sqlite3*,int);
void sqlite3CodeVerifySchema(Parse*, int);
void sqlite3CodeVerifyNamedSchema(Parse*, const char *zDb);
@@ -3565,6 +3570,7 @@ void sqlite3NestedParse(Parse*, const char*, ...);
void sqlite3ExpirePreparedStatements(sqlite3*);
int sqlite3CodeSubselect(Parse *, Expr *, int, int);
void sqlite3SelectPrep(Parse*, Select*, NameContext*);
void sqlite3SelectWrongNumTermsError(Parse *pParse, Select *p);
int sqlite3MatchSpanName(const char*, const char*, const char*, const char*);
int sqlite3ResolveExprNames(NameContext*, Expr*);
void sqlite3ResolveSelectNames(Parse*, Select*, NameContext*);
+4
View File
@@ -102,7 +102,11 @@ const char sqlite3IsEbcdicIdChar[] = {
};
#define IdChar(C) (((c=C)>=0x42 && sqlite3IsEbcdicIdChar[c-0x40]))
#endif
/* Make the IdChar function accessible from ctime.c */
#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS
int sqlite3IsIdChar(u8 c){ return IdChar(c); }
#endif
/*
+13 -7
View File
@@ -178,25 +178,31 @@ void sqlite3TreeViewSelect(TreeView *pView, const Select *p, u8 moreToFollow){
void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 moreToFollow){
const char *zBinOp = 0; /* Binary operator */
const char *zUniOp = 0; /* Unary operator */
char zFlgs[30];
pView = sqlite3TreeViewPush(pView, moreToFollow);
if( pExpr==0 ){
sqlite3TreeViewLine(pView, "nil");
sqlite3TreeViewPop(pView);
return;
}
if( pExpr->flags ){
sqlite3_snprintf(sizeof(zFlgs),zFlgs," flags=0x%x",pExpr->flags);
}else{
zFlgs[0] = 0;
}
switch( pExpr->op ){
case TK_AGG_COLUMN: {
sqlite3TreeViewLine(pView, "AGG{%d:%d}",
pExpr->iTable, pExpr->iColumn);
sqlite3TreeViewLine(pView, "AGG{%d:%d}%s",
pExpr->iTable, pExpr->iColumn, zFlgs);
break;
}
case TK_COLUMN: {
if( pExpr->iTable<0 ){
/* This only happens when coding check constraints */
sqlite3TreeViewLine(pView, "COLUMN(%d)", pExpr->iColumn);
sqlite3TreeViewLine(pView, "COLUMN(%d)%s", pExpr->iColumn, zFlgs);
}else{
sqlite3TreeViewLine(pView, "{%d:%d}",
pExpr->iTable, pExpr->iColumn);
sqlite3TreeViewLine(pView, "{%d:%d}%s",
pExpr->iTable, pExpr->iColumn, zFlgs);
}
break;
}
@@ -389,11 +395,11 @@ void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 moreToFollow){
}
}
if( zBinOp ){
sqlite3TreeViewLine(pView, "%s", zBinOp);
sqlite3TreeViewLine(pView, "%s%s", zBinOp, zFlgs);
sqlite3TreeViewExpr(pView, pExpr->pLeft, 1);
sqlite3TreeViewExpr(pView, pExpr->pRight, 0);
}else if( zUniOp ){
sqlite3TreeViewLine(pView, "%s", zUniOp);
sqlite3TreeViewLine(pView, "%s%s", zUniOp, zFlgs);
sqlite3TreeViewExpr(pView, pExpr->pLeft, 0);
}
sqlite3TreeViewPop(pView);
+2 -2
View File
@@ -347,7 +347,7 @@ void sqlite3Update(
if( HasRowid(pTab) ){
sqlite3VdbeAddOp3(v, OP_Null, 0, regRowSet, regOldRowid);
pWInfo = sqlite3WhereBegin(
pParse, 0, pTabList, pWhere, 0, 0, WHERE_ONEPASS_DESIRED, iIdxCur
pParse, pTabList, pWhere, 0, 0, WHERE_ONEPASS_DESIRED, iIdxCur
);
if( pWInfo==0 ) goto update_cleanup;
okOnePass = sqlite3WhereOkOnePass(pWInfo, aiCurOnePass);
@@ -376,7 +376,7 @@ void sqlite3Update(
sqlite3VdbeAddOp2(v, OP_Null, 0, iPk);
addrOpen = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, iEph, nPk);
sqlite3VdbeSetP4KeyInfo(pParse, pPk);
pWInfo = sqlite3WhereBegin(pParse, 0, pTabList, pWhere, 0, 0,
pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0, 0,
WHERE_ONEPASS_DESIRED, iIdxCur);
if( pWInfo==0 ) goto update_cleanup;
okOnePass = sqlite3WhereOkOnePass(pWInfo, aiCurOnePass);
+66 -38
View File
@@ -562,6 +562,9 @@ int sqlite3VdbeExec(
#ifdef VDBE_PROFILE
u64 start; /* CPU clock count at start of opcode */
#endif
Op *pCtxOp = 0; /* Opcode for which ctx is initialized */
sqlite3_context ctx; /* Function call context */
/*** INSERT STACK UNION HERE ***/
assert( p->magic==VDBE_MAGIC_RUN ); /* sqlite3_step() verifies this */
@@ -582,13 +585,9 @@ int sqlite3VdbeExec(
sqlite3VdbeIOTraceSql(p);
#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
if( db->xProgress ){
u32 iPrior = p->aCounter[SQLITE_STMTSTATUS_VM_STEP];
assert( 0 < db->nProgressOps );
nProgressLimit = (unsigned)p->aCounter[SQLITE_STMTSTATUS_VM_STEP];
if( nProgressLimit==0 ){
nProgressLimit = db->nProgressOps;
}else{
nProgressLimit %= (unsigned)db->nProgressOps;
}
nProgressLimit = db->nProgressOps - (iPrior % db->nProgressOps);
}
#endif
#ifdef SQLITE_DEBUG
@@ -947,6 +946,7 @@ case OP_Halt: {
aOp = p->aOp;
aMem = p->aMem;
pOp = &aOp[pcx];
pCtxOp = 0;
break;
}
p->rc = pOp->p1;
@@ -1570,35 +1570,39 @@ case OP_CollSeq: {
case OP_Function: {
int i;
Mem *pArg;
sqlite3_context ctx;
sqlite3_value **apVal;
int n;
n = pOp->p5;
apVal = p->apArg;
assert( apVal || n==0 );
assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) );
ctx.pOut = &aMem[pOp->p3];
memAboutToChange(p, ctx.pOut);
if( pOp!=pCtxOp ){
apVal = p->apArg;
assert( apVal || n==0 );
assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) );
ctx.pOut = &aMem[pOp->p3];
assert( n==0 || (pOp->p2>0 && pOp->p2+n<=(p->nMem-p->nCursor)+1) );
assert( pOp->p3<pOp->p2 || pOp->p3>=pOp->p2+n );
pArg = &aMem[pOp->p2];
for(i=0; i<n; i++, pArg++){
assert( memIsValid(pArg) );
apVal[i] = pArg;
Deephemeralize(pArg);
REGISTER_TRACE(pOp->p2+i, pArg);
assert( n==0 || (pOp->p2>0 && pOp->p2+n<=(p->nMem-p->nCursor)+1) );
assert( pOp->p3<pOp->p2 || pOp->p3>=pOp->p2+n );
pArg = &aMem[pOp->p2];
for(i=0; i<n; i++, pArg++){
apVal[i] = pArg;
}
assert( pOp->p4type==P4_FUNCDEF );
ctx.pFunc = pOp->p4.pFunc;
ctx.iOp = (int)(pOp - aOp);
ctx.pVdbe = p;
pCtxOp = pOp;
}
assert( pOp->p4type==P4_FUNCDEF );
ctx.pFunc = pOp->p4.pFunc;
ctx.iOp = (int)(pOp - aOp);
ctx.pVdbe = p;
#ifdef SQLITE_DEBUG
for(i=0; i<n; i++){
assert( memIsValid(p->apArg[i]) );
REGISTER_TRACE(pOp->p2+i, p->apArg[i]);
}
#endif
memAboutToChange(p, ctx.pOut);
MemSetTypeFlag(ctx.pOut, MEM_Null);
ctx.fErrorOrAux = 0;
db->lastRowid = lastRowid;
(*ctx.pFunc->xFunc)(&ctx, n, apVal); /* IMP: R-24505-23230 */
(*ctx.pFunc->xFunc)(&ctx, n, p->apArg); /* IMP: R-24505-23230 */
lastRowid = db->lastRowid; /* Remember rowid changes made by xFunc */
/* If the function returned an error, throw an exception */
@@ -3511,6 +3515,26 @@ case OP_Close: {
break;
}
#ifdef SQLITE_ENABLE_COLUMN_USED_MASK
/* Opcode: ColumnsUsed P1 * * P4 *
**
** This opcode (which only exists if SQLite was compiled with
** SQLITE_ENABLE_COLUMN_USED_MASK) identifies which columns of the
** table or index for cursor P1 are used. P4 is a 64-bit integer
** (P4_INT64) in which the first 63 bits are one for each of the
** first 63 columns of the table or index that are actually used
** by the cursor. The high-order bit is set if any column after
** the 64th is used.
*/
case OP_ColumnsUsed: {
VdbeCursor *pC;
pC = p->apCsr[pOp->p1];
assert( pC->pCursor );
pC->maskUsed = *(u64*)pOp->p4.pI64;
break;
}
#endif
/* Opcode: SeekGE P1 P2 P3 P4 *
** Synopsis: key=r[P3@P4]
**
@@ -5488,6 +5512,7 @@ case OP_Program: { /* jump */
p->nCursor = (u16)pFrame->nChildCsr;
p->apCsr = (VdbeCursor **)&aMem[p->nMem+1];
p->aOp = aOp = pProgram->aOp;
pCtxOp = 0;
p->nOp = pProgram->nOp;
p->aOnceFlag = (u8 *)&p->apCsr[p->nCursor];
p->nOnceFlag = pProgram->nOnce;
@@ -5698,12 +5723,13 @@ case OP_AggStep: {
Mem *pMem;
Mem *pRec;
Mem t;
sqlite3_context ctx;
sqlite3_context actx;
sqlite3_value **apVal;
n = pOp->p5;
assert( n>=0 );
pRec = &aMem[pOp->p2];
pCtxOp = 0;
apVal = p->apArg;
assert( apVal || n==0 );
for(i=0; i<n; i++, pRec++){
@@ -5711,22 +5737,22 @@ case OP_AggStep: {
apVal[i] = pRec;
memAboutToChange(p, pRec);
}
ctx.pFunc = pOp->p4.pFunc;
actx.pFunc = pOp->p4.pFunc;
assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) );
ctx.pMem = pMem = &aMem[pOp->p3];
actx.pMem = pMem = &aMem[pOp->p3];
pMem->n++;
sqlite3VdbeMemInit(&t, db, MEM_Null);
ctx.pOut = &t;
ctx.isError = 0;
ctx.pVdbe = p;
ctx.iOp = (int)(pOp - aOp);
ctx.skipFlag = 0;
(ctx.pFunc->xStep)(&ctx, n, apVal); /* IMP: R-24505-23230 */
if( ctx.isError ){
actx.pOut = &t;
actx.isError = 0;
actx.pVdbe = p;
actx.iOp = (int)(pOp - aOp);
actx.skipFlag = 0;
(actx.pFunc->xStep)(&actx, n, apVal); /* IMP: R-24505-23230 */
if( actx.isError ){
sqlite3VdbeError(p, "%s", sqlite3_value_text(&t));
rc = ctx.isError;
rc = actx.isError;
}
if( ctx.skipFlag ){
if( actx.skipFlag ){
assert( pOp[-1].opcode==OP_CollSeq );
i = pOp[-1].p1;
if( i ) sqlite3VdbeMemSetInt64(&aMem[i], 1);
@@ -6156,6 +6182,7 @@ case OP_VFilter: { /* jump */
for(i = 0; i<nArg; i++){
apArg[i] = &pArgc[i+1];
}
pCtxOp = 0;
rc = pModule->xFilter(pVtabCursor, iQuery, pOp->p4.z, nArg, apArg);
sqlite3VtabImportErrmsg(p, pVtab);
if( rc==SQLITE_OK ){
@@ -6339,6 +6366,7 @@ case OP_VUpdate: {
if( ALWAYS(pModule->xUpdate) ){
u8 vtabOnConflict = db->vtabOnConflict;
apArg = p->apArg;
pCtxOp = 0;
pX = &aMem[pOp->p3];
for(i=0; i<nArg; i++){
assert( memIsValid(pX) );
+1
View File
@@ -169,6 +169,7 @@ int sqlite3VdbeAddOp1(Vdbe*,int,int);
int sqlite3VdbeAddOp2(Vdbe*,int,int,int);
int sqlite3VdbeAddOp3(Vdbe*,int,int,int,int);
int sqlite3VdbeAddOp4(Vdbe*,int,int,int,int,const char *zP4,int);
int sqlite3VdbeAddOp4Dup8(Vdbe*,int,int,int,int,const u8*,int);
int sqlite3VdbeAddOp4Int(Vdbe*,int,int,int,int,int);
int sqlite3VdbeAddOpList(Vdbe*, int nOp, VdbeOpList const *aOp, int iLineno);
void sqlite3VdbeAddParseSchemaOp(Vdbe*,int,char*);
+3
View File
@@ -83,6 +83,9 @@ struct VdbeCursor {
i64 seqCount; /* Sequence counter */
i64 movetoTarget; /* Argument to the deferred sqlite3BtreeMoveto() */
VdbeSorter *pSorter; /* Sorter object for OP_SorterOpen cursors */
#ifdef SQLITE_ENABLE_COLUMN_USED_MASK
u64 maskUsed; /* Mask of columns used by this cursor */
#endif
/* Cached information about the header for the data record that the
** cursor is currently pointing to. Only valid if cacheStatus matches
+29 -3
View File
@@ -233,6 +233,23 @@ int sqlite3VdbeAddOp4(
return addr;
}
/*
** Add an opcode that includes the p4 value with a P4_INT64 type.
*/
int sqlite3VdbeAddOp4Dup8(
Vdbe *p, /* Add the opcode to this VM */
int op, /* The new opcode */
int p1, /* The P1 operand */
int p2, /* The P2 operand */
int p3, /* The P3 operand */
const u8 *zP4, /* The P4 operand */
int p4type /* P4 operand type */
){
char *p4copy = sqlite3DbMallocRaw(sqlite3VdbeDb(p), 8);
if( p4copy ) memcpy(p4copy, zP4, 8);
return sqlite3VdbeAddOp4(p, op, p1, p2, p3, p4copy, p4type);
}
/*
** Add an OP_ParseSchema opcode. This routine is broken out from
** sqlite3VdbeAddOp4() since it needs to also needs to mark all btrees
@@ -397,6 +414,7 @@ static Op *opIterNext(VdbeOpIter *p){
** * OP_VUpdate
** * OP_VRename
** * OP_FkCounter with P2==0 (immediate foreign key constraint)
** * OP_CreateTable and OP_InitCoroutine (for CREATE TABLE AS SELECT ...)
**
** Then check that the value of Parse.mayAbort is true if an
** ABORT may be thrown, or false otherwise. Return true if it does
@@ -408,6 +426,8 @@ static Op *opIterNext(VdbeOpIter *p){
int sqlite3VdbeAssertMayAbort(Vdbe *v, int mayAbort){
int hasAbort = 0;
int hasFkCounter = 0;
int hasCreateTable = 0;
int hasInitCoroutine = 0;
Op *pOp;
VdbeOpIter sIter;
memset(&sIter, 0, sizeof(sIter));
@@ -422,6 +442,8 @@ int sqlite3VdbeAssertMayAbort(Vdbe *v, int mayAbort){
hasAbort = 1;
break;
}
if( opcode==OP_CreateTable ) hasCreateTable = 1;
if( opcode==OP_InitCoroutine ) hasInitCoroutine = 1;
#ifndef SQLITE_OMIT_FOREIGN_KEY
if( opcode==OP_FkCounter && pOp->p1==0 && pOp->p2==1 ){
hasFkCounter = 1;
@@ -435,7 +457,8 @@ int sqlite3VdbeAssertMayAbort(Vdbe *v, int mayAbort){
** through all opcodes and hasAbort may be set incorrectly. Return
** true for this case to prevent the assert() in the callers frame
** from failing. */
return ( v->db->mallocFailed || hasAbort==mayAbort || hasFkCounter );
return ( v->db->mallocFailed || hasAbort==mayAbort || hasFkCounter
|| (hasCreateTable && hasInitCoroutine) );
}
#endif /* SQLITE_DEBUG - the sqlite3AssertMayAbort() function */
@@ -1218,12 +1241,11 @@ void sqlite3VdbeEnter(Vdbe *p){
/*
** Unlock all of the btrees previously locked by a call to sqlite3VdbeEnter().
*/
void sqlite3VdbeLeave(Vdbe *p){
static SQLITE_NOINLINE void vdbeLeave(Vdbe *p){
int i;
sqlite3 *db;
Db *aDb;
int nDb;
if( DbMaskAllZero(p->lockMask) ) return; /* The common case */
db = p->db;
aDb = db->aDb;
nDb = db->nDb;
@@ -1233,6 +1255,10 @@ void sqlite3VdbeLeave(Vdbe *p){
}
}
}
void sqlite3VdbeLeave(Vdbe *p){
if( DbMaskAllZero(p->lockMask) ) return; /* The common case */
vdbeLeave(p);
}
#endif
#if defined(VDBE_PROFILE) || defined(SQLITE_DEBUG)
+46 -21
View File
@@ -777,10 +777,15 @@ void sqlite3VdbeMemAboutToChange(Vdbe *pVdbe, Mem *pMem){
** pFrom->z is used, then pTo->z points to the same thing as pFrom->z
** and flags gets srcType (either MEM_Ephem or MEM_Static).
*/
static SQLITE_NOINLINE void vdbeClrCopy(Mem *pTo, const Mem *pFrom, int eType){
vdbeMemClearExternAndSetNull(pTo);
assert( !VdbeMemDynamic(pTo) );
sqlite3VdbeMemShallowCopy(pTo, pFrom, eType);
}
void sqlite3VdbeMemShallowCopy(Mem *pTo, const Mem *pFrom, int srcType){
assert( (pFrom->flags & MEM_RowSet)==0 );
assert( pTo->db==pFrom->db );
if( VdbeMemDynamic(pTo) ) vdbeMemClearExternAndSetNull(pTo);
if( VdbeMemDynamic(pTo) ){ vdbeClrCopy(pTo,pFrom,srcType); return; }
memcpy(pTo, pFrom, MEMCELLSIZE);
if( (pFrom->flags&MEM_Static)==0 ){
pTo->flags &= ~(MEM_Dyn|MEM_Static|MEM_Ephem);
@@ -946,6 +951,32 @@ int sqlite3VdbeMemSetStr(
** If this routine fails for any reason (malloc returns NULL or unable
** to read from the disk) then the pMem is left in an inconsistent state.
*/
static SQLITE_NOINLINE int vdbeMemFromBtreeResize(
BtCursor *pCur, /* Cursor pointing at record to retrieve. */
u32 offset, /* Offset from the start of data to return bytes from. */
u32 amt, /* Number of bytes to return. */
int key, /* If true, retrieve from the btree key, not data. */
Mem *pMem /* OUT: Return data in this Mem structure. */
){
int rc;
pMem->flags = MEM_Null;
if( SQLITE_OK==(rc = sqlite3VdbeMemClearAndResize(pMem, amt+2)) ){
if( key ){
rc = sqlite3BtreeKey(pCur, offset, amt, pMem->z);
}else{
rc = sqlite3BtreeData(pCur, offset, amt, pMem->z);
}
if( rc==SQLITE_OK ){
pMem->z[amt] = 0;
pMem->z[amt+1] = 0;
pMem->flags = MEM_Blob|MEM_Term;
pMem->n = (int)amt;
}else{
sqlite3VdbeMemRelease(pMem);
}
}
return rc;
}
int sqlite3VdbeMemFromBtree(
BtCursor *pCur, /* Cursor pointing at record to retrieve. */
u32 offset, /* Offset from the start of data to return bytes from. */
@@ -975,22 +1006,7 @@ int sqlite3VdbeMemFromBtree(
pMem->flags = MEM_Blob|MEM_Ephem;
pMem->n = (int)amt;
}else{
pMem->flags = MEM_Null;
if( SQLITE_OK==(rc = sqlite3VdbeMemClearAndResize(pMem, amt+2)) ){
if( key ){
rc = sqlite3BtreeKey(pCur, offset, amt, pMem->z);
}else{
rc = sqlite3BtreeData(pCur, offset, amt, pMem->z);
}
if( rc==SQLITE_OK ){
pMem->z[amt] = 0;
pMem->z[amt+1] = 0;
pMem->flags = MEM_Blob|MEM_Term;
pMem->n = (int)amt;
}else{
sqlite3VdbeMemRelease(pMem);
}
}
rc = vdbeMemFromBtreeResize(pCur, offset, amt, key, pMem);
}
return rc;
@@ -1678,17 +1694,26 @@ void sqlite3ValueFree(sqlite3_value *v){
}
/*
** Return the number of bytes in the sqlite3_value object assuming
** that it uses the encoding "enc"
** The sqlite3ValueBytes() routine returns the number of bytes in the
** sqlite3_value object assuming that it uses the encoding "enc".
** The valueBytes() routine is a helper function.
*/
static SQLITE_NOINLINE int valueBytes(sqlite3_value *pVal, u8 enc){
return valueToText(pVal, enc)!=0 ? pVal->n : 0;
}
int sqlite3ValueBytes(sqlite3_value *pVal, u8 enc){
Mem *p = (Mem*)pVal;
if( (p->flags & MEM_Blob)!=0 || sqlite3ValueText(pVal, enc) ){
assert( (p->flags & MEM_Null)==0 || (p->flags & (MEM_Str|MEM_Blob))==0 );
if( (p->flags & MEM_Str)!=0 && pVal->enc==enc ){
return p->n;
}
if( (p->flags & MEM_Blob)!=0 ){
if( p->flags & MEM_Zero ){
return p->n + p->u.nZero;
}else{
return p->n;
}
}
return 0;
if( p->flags & MEM_Null ) return 0;
return valueBytes(pVal, enc);
}
+22 -15
View File
@@ -2555,16 +2555,15 @@ static int whereLoopAddBtree(
/* TUNING: One-time cost for computing the automatic index is
** estimated to be X*N*log2(N) where N is the number of rows in
** the table being indexed and where X is 7 (LogEst=28) for normal
** tables or 0.3333 (LogEst=-16) for views and subqueries. The value
** tables or 1.375 (LogEst=4) for views and subqueries. The value
** of X is smaller for views and subqueries so that the query planner
** will be more aggressive about generating automatic indexes for
** those objects, since there is no opportunity to add schema
** indexes on subqueries and views. */
pNew->rSetup = rLogSize + rSize - 16;
pNew->rSetup = rLogSize + rSize + 4;
if( pTab->pSelect==0 && (pTab->tabFlags & TF_Ephemeral)==0 ){
pNew->rSetup += 44;
pNew->rSetup += 24;
}
if( pNew->rSetup<1 ) pNew->rSetup = 1;
ApplyCostMultiplier(pNew->rSetup, pTab->costMult);
/* TUNING: Each index lookup yields 20 rows in the table. This
** is more than the usual guess of 10 rows, since we have no way
@@ -3897,7 +3896,6 @@ static int whereShortCut(WhereLoopBuilder *pBuilder){
*/
WhereInfo *sqlite3WhereBegin(
Parse *pParse, /* The parser context */
Select *pSelect, /* SELECT stmt that owns this WHERE. Might be NULL */
SrcList *pTabList, /* FROM clause: A list of all tables to be scanned */
Expr *pWhere, /* The WHERE clause */
ExprList *pOrderBy, /* An ORDER BY (or GROUP BY) clause, or NULL */
@@ -4172,16 +4170,6 @@ WhereInfo *sqlite3WhereBegin(
}
}
/* If this WHERE clause is part of a SELECT statement, then there
** might be subqueries in the FROM clause that need to be manifested.
** This works mostly - except the Table.nRowLogEst value is not set
** correctly for the subquery, resulting in a bad plan in some cases.
*/
if( OptimizationEnabled(db, SQLITE_LateSubquery) && pSelect!=0 ){
sqlite3ManifestSubqueries(pParse, pSelect, pTabList);
if( db->mallocFailed ) goto whereBeginError;
}
/* Open all tables in the pTabList and any indices selected for
** searching those tables.
*/
@@ -4225,6 +4213,10 @@ WhereInfo *sqlite3WhereBegin(
SQLITE_INT_TO_PTR(n), P4_INT32);
assert( n<=pTab->nCol );
}
#ifdef SQLITE_ENABLE_COLUMN_USED_MASK
sqlite3VdbeAddOp4Dup8(v, OP_ColumnsUsed, pTabItem->iCursor, 0, 0,
(const u8*)&pTabItem->colUsed, P4_INT64);
#endif
}else{
sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName);
}
@@ -4270,6 +4262,21 @@ WhereInfo *sqlite3WhereBegin(
sqlite3VdbeChangeP5(v, OPFLAG_SEEKEQ); /* Hint to COMDB2 */
}
VdbeComment((v, "%s", pIx->zName));
#ifdef SQLITE_ENABLE_COLUMN_USED_MASK
{
u64 colUsed = 0;
int ii, jj;
for(ii=0; ii<pIx->nColumn; ii++){
jj = pIx->aiColumn[ii];
if( jj<0 ) continue;
if( jj>63 ) jj = 63;
if( (pTabItem->colUsed & MASKBIT(jj))==0 ) continue;
colUsed |= ((u64)1)<<(ii<63 ? ii : 63);
}
sqlite3VdbeAddOp4Dup8(v, OP_ColumnsUsed, iIndexCur, 0, 0,
(u8*)&colUsed, P4_INT64);
}
#endif /* SQLITE_ENABLE_COLUMN_USED_MASK */
}
}
if( iDb>=0 ) sqlite3CodeVerifySchema(pParse, iDb);
+1 -1
View File
@@ -1265,7 +1265,7 @@ Bitmask sqlite3WhereCodeOneLoopStart(
}
/* Loop through table entries that match term pOrTerm. */
WHERETRACE(0xffff, ("Subplan for OR-clause:\n"));
pSubWInfo = sqlite3WhereBegin(pParse, 0, pOrTab, pOrExpr, 0, 0,
pSubWInfo = sqlite3WhereBegin(pParse, pOrTab, pOrExpr, 0, 0,
wctrlFlags, iCovCur);
assert( pSubWInfo || pParse->nErr || db->mallocFailed );
if( pSubWInfo ){
+1 -1
View File
@@ -204,7 +204,7 @@ do_execsql_test 6.0 {
} {}
do_test 6.1 {
db close
hexio_write test.db 616 EAFFFFFF0202
hexio_write test.db 616 8FFFFFFF7F02
sqlite3 db test.db
breakpoint
execsql { DELETE FROM t1 WHERE rowid=2 }
+10 -10
View File
@@ -81,31 +81,31 @@ do_eqp_test 1.6 {
do_eqp_test 1.7 {
SELECT * FROM t3 JOIN (SELECT 1)
} {
0 0 0 {SCAN TABLE t3}
0 1 1 {SCAN SUBQUERY 1}
0 0 1 {SCAN SUBQUERY 1}
0 1 0 {SCAN TABLE t3}
}
do_eqp_test 1.8 {
SELECT * FROM t3 JOIN (SELECT 1 UNION SELECT 2)
} {
1 0 0 {COMPOUND SUBQUERIES 2 AND 3 USING TEMP B-TREE (UNION)}
0 0 0 {SCAN TABLE t3}
0 1 1 {SCAN SUBQUERY 1}
0 0 1 {SCAN SUBQUERY 1}
0 1 0 {SCAN TABLE t3}
}
do_eqp_test 1.9 {
SELECT * FROM t3 JOIN (SELECT 1 EXCEPT SELECT a FROM t3 LIMIT 17)
} {
3 0 0 {SCAN TABLE t3}
1 0 0 {COMPOUND SUBQUERIES 2 AND 3 USING TEMP B-TREE (EXCEPT)}
0 0 0 {SCAN TABLE t3}
0 1 1 {SCAN SUBQUERY 1}
0 0 1 {SCAN SUBQUERY 1}
0 1 0 {SCAN TABLE t3}
}
do_eqp_test 1.10 {
SELECT * FROM t3 JOIN (SELECT 1 INTERSECT SELECT a FROM t3 LIMIT 17)
} {
3 0 0 {SCAN TABLE t3}
1 0 0 {COMPOUND SUBQUERIES 2 AND 3 USING TEMP B-TREE (INTERSECT)}
0 0 0 {SCAN TABLE t3}
0 1 1 {SCAN SUBQUERY 1}
0 0 1 {SCAN SUBQUERY 1}
0 1 0 {SCAN TABLE t3}
}
do_eqp_test 1.11 {
@@ -113,8 +113,8 @@ do_eqp_test 1.11 {
} {
3 0 0 {SCAN TABLE t3}
1 0 0 {COMPOUND SUBQUERIES 2 AND 3 (UNION ALL)}
0 0 0 {SCAN TABLE t3}
0 1 1 {SCAN SUBQUERY 1}
0 0 1 {SCAN SUBQUERY 1}
0 1 0 {SCAN TABLE t3}
}
#-------------------------------------------------------------------------
+12 -2
View File
@@ -362,11 +362,17 @@ ifcapable icu { lappend tokenizers icu }
# Some tests to check that the tokenizers can both identify white-space
# codepoints. All codepoints tested below are of type "Zs" in the
# UnicodeData.txt file.
#
# Note that codepoint 6158 has changed from Zs to Cf in recent versions
# of UnicodeData.txt. So take that into account for the "icu" tests.
#
foreach T $tokenizers {
do_isspace_test 6.$T.1 $T 32
do_isspace_test 6.$T.2 $T 160
do_isspace_test 6.$T.3 $T 5760
do_isspace_test 6.$T.4 $T 6158
if {$T!="icu"} {
do_isspace_test 6.$T.4 $T 6158
}
do_isspace_test 6.$T.5 $T 8192
do_isspace_test 6.$T.6 $T 8193
do_isspace_test 6.$T.7 $T 8194
@@ -382,7 +388,11 @@ foreach T $tokenizers {
do_isspace_test 6.$T.17 $T 8287
do_isspace_test 6.$T.18 $T 12288
do_isspace_test 6.$T.19 $T {32 160 5760 6158}
if {$T!="icu"} {
do_isspace_test 6.$T.19 $T {32 160 5760 6158}
} else {
do_isspace_test 6.$T.19 $T {32 160 5760 8192}
}
do_isspace_test 6.$T.20 $T {8192 8193 8194 8195}
do_isspace_test 6.$T.21 $T {8196 8197 8198 8199}
do_isspace_test 6.$T.22 $T {8200 8201 8202 8239}
+154 -11
View File
@@ -10,8 +10,8 @@
**
*************************************************************************
**
** This is a utility program designed to aid running regressions tests
** on SQLite library using data from an external fuzzer, such as American
** This is a utility program designed to aid running regressions tests on
** the SQLite library using data from an external fuzzer, such as American
** Fuzzy Lop (AFL) (http://lcamtuf.coredump.cx/afl/).
**
** This program reads content from an SQLite database file with the following
@@ -25,16 +25,44 @@
** sqlid INTEGER PRIMARY KEY, -- SQL script id
** sqltext TEXT -- Text of SQL statements to run
** );
** CREATE TABLE IF NOT EXISTS readme(
** msg TEXT -- Human-readable description of this test collection
** );
**
** For each database file in the DB table, the SQL text in the XSQL table
** is run against that database. This program is looking for crashes,
** assertion faults, and/or memory leaks. No attempt is made to verify
** the output. The assumption is that either all of the database files
** or all of the SQL statements are malformed inputs, generated by a fuzzer,
** that need to be checked to make sure they do not present a security risk.
** is run against that database. All README.MSG values are printed prior
** to the start of the test (unless the --quiet option is used). If the
** DB table is empty, then all entries in XSQL are run against an empty
** in-memory database.
**
** This program is looking for crashes, assertion faults, and/or memory leaks.
** No attempt is made to verify the output. The assumption is that either all
** of the database files or all of the SQL statements are malformed inputs,
** generated by a fuzzer, that need to be checked to make sure they do not
** present a security risk.
**
** This program also includes some command-line options to help with
** creation and maintenance of the source content database.
** creation and maintenance of the source content database. The command
**
** ./fuzzcheck database.db --load-sql FILE...
**
** Loads all FILE... arguments into the XSQL table. The --load-db option
** works the same but loads the files into the DB table. The -m option can
** be used to initialize the README table. The "database.db" file is created
** if it does not previously exist. Example:
**
** ./fuzzcheck new.db --load-sql *.sql
** ./fuzzcheck new.db --load-db *.db
** ./fuzzcheck new.db -m 'New test cases'
**
** The three commands above will create the "new.db" file and initialize all
** tables. Then do "./fuzzcheck new.db" to run the tests.
**
** DEBUGGING HINTS:
**
** If fuzzcheck does crash, it can be run in the debugger and the content
** of the global variable g.zTextName[] will identify the specific XSQL and
** DB values that were running when the crash occurred.
*/
#include <stdio.h>
#include <stdlib.h>
@@ -43,6 +71,11 @@
#include <ctype.h>
#include "sqlite3.h"
#ifdef __unix__
# include <signal.h>
# include <unistd.h>
#endif
/*
** Files in the virtual file system.
*/
@@ -111,6 +144,43 @@ static void fatalError(const char *zFormat, ...){
exit(1);
}
/*
** Timeout handler
*/
#ifdef __unix__
static void timeoutHandler(int NotUsed){
(void)NotUsed;
fatalError("timeout\n");
}
#endif
/*
** Set the an alarm to go off after N seconds. Disable the alarm
** if N==0
*/
static void setAlarm(int N){
#ifdef __unix__
alarm(N);
#else
(void)N;
#endif
}
#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
/*
** This an SQL progress handler. After an SQL statement has run for
** many steps, we want to interrupt it. This guards against infinite
** loops from recursive common table expressions.
**
** *pVdbeLimitFlag is true if the --limit-vdbe command-line option is used.
** In that case, hitting the progress handler is a fatal error.
*/
static int progressHandler(void *pVdbeLimitFlag){
if( *(int*)pVdbeLimitFlag ) fatalError("too many VDBE cycles");
return 1;
}
#endif
/*
** Reallocate memory. Show and error and quit if unable.
*/
@@ -587,6 +657,31 @@ static void runSql(sqlite3 *db, const char *zSql, unsigned runFlags){
}
}
/*
** Rebuild the database file.
**
** (1) Remove duplicate entries
** (2) Put all entries in order
** (3) Vacuum
*/
static void rebuild_database(sqlite3 *db){
int rc;
rc = sqlite3_exec(db,
"BEGIN;\n"
"CREATE TEMP TABLE dbx AS SELECT DISTINCT dbcontent FROM db;\n"
"DELETE FROM db;\n"
"INSERT INTO db(dbid, dbcontent) SELECT NULL, dbcontent FROM dbx ORDER BY 2;\n"
"DROP TABLE dbx;\n"
"CREATE TEMP TABLE sx AS SELECT DISTINCT sqltext FROM xsql;\n"
"DELETE FROM xsql;\n"
"INSERT INTO xsql(sqlid,sqltext) SELECT NULL, sqltext FROM sx ORDER BY 2;\n"
"DROP TABLE sx;\n"
"COMMIT;\n"
"PRAGMA page_size=1024;\n"
"VACUUM;\n", 0, 0, 0);
if( rc ) fatalError("cannot rebuild: %s", sqlite3_errmsg(db));
}
/*
** Print sketchy documentation for this utility program
*/
@@ -598,15 +693,18 @@ static void showHelp(void){
"Options:\n"
" --cell-size-check Set the PRAGMA cell_size_check=ON\n"
" --dbid N Use only the database where dbid=N\n"
" --help Show this help text\n"
" --help Show this help text\n"
" -q Reduced output\n"
" --quiet Reduced output\n"
" --limit-vdbe Panic if an sync SQL runs for more than 100,000 cycles\n"
" --load-sql ARGS... Load SQL scripts fro files into SOURCE-DB\n"
" --load-db ARGS... Load template databases from files into SOURCE_DB\n"
" -m TEXT Add a description to the database\n"
" --native-vfs Use the native VFS for initially empty database files\n"
" --rebuild Rebuild and vacuum the database file\n"
" --result-trace Show the results of each SQL command\n"
" --sqlid N Use only SQL where sqlid=N\n"
" --timeline N Abort if any single test case needs more than N seconds\n"
" -v Increased output\n"
" --verbose Increased output\n"
);
@@ -627,6 +725,9 @@ int main(int argc, char **argv){
int onlySqlid = -1; /* --sqlid */
int onlyDbid = -1; /* --dbid */
int nativeFlag = 0; /* --native-vfs */
int rebuildFlag = 0; /* --rebuild */
int vdbeLimitFlag = 0; /* --limit-vdbe */
int timeoutTest = 0; /* undocumented --timeout-test flag */
int runFlags = 0; /* Flags sent to runSql() */
char *zMsg = 0; /* Add this message */
int nSrcDb = 0; /* Number of source databases */
@@ -636,8 +737,13 @@ int main(int argc, char **argv){
char *zDbName = ""; /* Appreviated name of a source database */
const char *zFailCode = 0; /* Value of the TEST_FAILURE environment variable */
int cellSzCkFlag = 0; /* --cell-size-check */
int sqlFuzz = 0; /* True for SQL fuzz testing. False for DB fuzz */
int iTimeout = 120; /* Default 120-second timeout */
iBegin = timeOfDay();
#ifdef __unix__
signal(SIGALRM, timeoutHandler);
#endif
g.zArgv0 = argv[0];
zFailCode = getenv("TEST_FAILURE");
for(i=1; i<argc; i++){
@@ -656,6 +762,9 @@ int main(int argc, char **argv){
showHelp();
return 0;
}else
if( strcmp(z,"limit-vdbe")==0 ){
vdbeLimitFlag = 1;
}else
if( strcmp(z,"load-sql")==0 ){
zInsSql = "INSERT INTO xsql(sqltext) VALUES(CAST(readfile(?1) AS text))";
iFirstInsArg = i+1;
@@ -677,6 +786,9 @@ int main(int argc, char **argv){
quietFlag = 1;
verboseFlag = 0;
}else
if( strcmp(z,"rebuild")==0 ){
rebuildFlag = 1;
}else
if( strcmp(z,"result-trace")==0 ){
runFlags |= SQL_OUTPUT;
}else
@@ -684,6 +796,16 @@ int main(int argc, char **argv){
if( i>=argc-1 ) fatalError("missing arguments on %s", argv[i]);
onlySqlid = atoi(argv[++i]);
}else
if( strcmp(z,"timeout")==0 ){
if( i>=argc-1 ) fatalError("missing arguments on %s", argv[i]);
iTimeout = atoi(argv[++i]);
}else
if( strcmp(z,"timeout-test")==0 ){
timeoutTest = 1;
#ifndef __unix__
fatalError("timeout is not available on non-unix systems");
#endif
}else
if( strcmp(z,"verbose")==0 || strcmp(z,"v")==0 ){
quietFlag = 0;
verboseFlag = 1;
@@ -715,7 +837,7 @@ int main(int argc, char **argv){
fatalError("cannot open source database %s - %s",
azSrcDb[iSrcDb], sqlite3_errmsg(db));
}
rc = sqlite3_exec(db,
rc = sqlite3_exec(db,
"CREATE TABLE IF NOT EXISTS db(\n"
" dbid INTEGER PRIMARY KEY, -- database id\n"
" dbcontent BLOB -- database disk file image\n"
@@ -753,6 +875,7 @@ int main(int argc, char **argv){
sqlite3_finalize(pStmt);
rc = sqlite3_exec(db, "COMMIT", 0, 0, 0);
if( rc ) fatalError("cannot commit the transaction: %s", sqlite3_errmsg(db));
rebuild_database(db);
sqlite3_close(db);
return 0;
}
@@ -771,6 +894,7 @@ int main(int argc, char **argv){
g.pFirstDb->id = 1;
g.pFirstDb->seq = 0;
g.nDb = 1;
sqlFuzz = 1;
}
/* Print the description, if there is one */
@@ -786,6 +910,16 @@ int main(int argc, char **argv){
}
sqlite3_finalize(pStmt);
}
/* Rebuild the database, if requested */
if( rebuildFlag ){
if( !quietFlag ){
printf("%s: rebuilding... ", zDbName);
fflush(stdout);
}
rebuild_database(db);
if( !quietFlag ) printf("done\n");
}
/* Close the source database. Verify that no SQLite memory allocations are
** outstanding.
@@ -831,7 +965,16 @@ int main(int argc, char **argv){
rc = sqlite3_open_v2("main.db", &db, openFlags, zVfs);
if( rc ) fatalError("cannot open inmem database");
if( cellSzCkFlag ) runSql(db, "PRAGMA cell_size_check=ON", runFlags);
runSql(db, (char*)pSql->a, runFlags);
setAlarm(iTimeout);
#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
if( sqlFuzz || vdbeLimitFlag ){
sqlite3_progress_handler(db, 100000, progressHandler, &vdbeLimitFlag);
}
#endif
do{
runSql(db, (char*)pSql->a, runFlags);
}while( timeoutTest );
setAlarm(0);
sqlite3_close(db);
if( sqlite3_memory_used()>0 ) fatalError("memory leak");
reformatVfs();
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
+17 -3
View File
@@ -450,28 +450,42 @@ do_test in-12.10 {
SELECT a FROM t3 UNION ALL SELECT a, b FROM t2
);
}
} {1 {only a single result allowed for a SELECT that is part of an expression}}
} {1 {SELECTs to the left and right of UNION ALL do not have the same number of result columns}}
do_test in-12.11 {
catchsql {
SELECT * FROM t2 WHERE a IN (
SELECT a FROM t3 UNION SELECT a, b FROM t2
);
}
} {1 {only a single result allowed for a SELECT that is part of an expression}}
} {1 {SELECTs to the left and right of UNION do not have the same number of result columns}}
do_test in-12.12 {
catchsql {
SELECT * FROM t2 WHERE a IN (
SELECT a FROM t3 EXCEPT SELECT a, b FROM t2
);
}
} {1 {only a single result allowed for a SELECT that is part of an expression}}
} {1 {SELECTs to the left and right of EXCEPT do not have the same number of result columns}}
do_test in-12.13 {
catchsql {
SELECT * FROM t2 WHERE a IN (
SELECT a FROM t3 INTERSECT SELECT a, b FROM t2
);
}
} {1 {SELECTs to the left and right of INTERSECT do not have the same number of result columns}}
do_test in-12.14 {
catchsql {
SELECT * FROM t2 WHERE a IN (
SELECT a, b FROM t3 UNION ALL SELECT a, b FROM t2
);
}
} {1 {only a single result allowed for a SELECT that is part of an expression}}
do_test in-12.15 {
catchsql {
SELECT * FROM t2 WHERE a IN (
SELECT a, b FROM t3 UNION ALL SELECT a FROM t2
);
}
} {1 {SELECTs to the left and right of UNION ALL do not have the same number of result columns}}
}; #ifcapable compound
+2 -2
View File
@@ -189,8 +189,8 @@ do_test malloc5-3.1 {
BEGIN;
SELECT * FROM def;
} db2
sqlite3_release_memory
} [expr $::pgalloc * 2]
value_in_range [expr $::pgalloc*2] 0.99 [sqlite3_release_memory]
} [value_in_range [expr $::pgalloc * 2] 0.99]
do_test malloc5-3.2 {
concat \
[execsql {SELECT * FROM abc; COMMIT}] \
+20
View File
@@ -15,6 +15,7 @@
set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix select7
ifcapable compound {
@@ -201,4 +202,23 @@ do_test select7-7.7 {
}
} {text 123}
do_execsql_test 8.0 {
CREATE TABLE t01(x, y);
CREATE TABLE t02(x, y);
}
do_catchsql_test 8.1 {
SELECT * FROM (
SELECT * FROM t01 UNION SELECT x FROM t02
) WHERE y=1
} {1 {SELECTs to the left and right of UNION do not have the same number of result columns}}
do_catchsql_test 8.2 {
CREATE VIEW v0 as SELECT x, y FROM t01 UNION SELECT x FROM t02;
EXPLAIN QUERY PLAN SELECT * FROM v0 WHERE x='0' OR y;
} {1 {SELECTs to the left and right of UNION do not have the same number of result columns}}
finish_test
+18 -2
View File
@@ -43,6 +43,9 @@ static const char zHelp[] =
#include <string.h>
#include <ctype.h>
#if SQLITE_VERSION_NUMBER<3005000
# define sqlite3_int64 sqlite_int64
#endif
#ifdef SQLITE_ENABLE_OTA
# include "sqlite3ota.h"
#endif
@@ -143,6 +146,9 @@ static int integerValue(const char *zArg){
/* Return the current wall-clock time, in milliseconds */
sqlite3_int64 speedtest1_timestamp(void){
#if SQLITE_VERSION_NUMBER<3005000
return 0;
#else
static sqlite3_vfs *clockVfs = 0;
sqlite3_int64 t;
if( clockVfs==0 ) clockVfs = sqlite3_vfs_find(0);
@@ -157,6 +163,7 @@ sqlite3_int64 speedtest1_timestamp(void){
t = (sqlite3_int64)(r*86400000.0);
}
return t;
#endif
}
/* Return a pseudo-random unsigned integer */
@@ -306,7 +313,7 @@ static void printSql(const char *zSql){
if( g.bExplain ) printf("EXPLAIN ");
printf("%.*s;\n", n, zSql);
if( g.bExplain
#if SQLITE_VERSION_NUMBER>=3007010
#if SQLITE_VERSION_NUMBER>=3007017
&& ( sqlite3_strglob("CREATE *", zSql)==0
|| sqlite3_strglob("DROP *", zSql)==0
|| sqlite3_strglob("ALTER *", zSql)==0
@@ -374,12 +381,15 @@ void speedtest1_run(void){
}
}
}
#if SQLITE_VERSION_NUMBER>=3006001
if( g.bReprepare ){
sqlite3_stmt *pNew;
sqlite3_prepare_v2(g.db, sqlite3_sql(g.pStmt), -1, &pNew, 0);
sqlite3_finalize(g.pStmt);
g.pStmt = pNew;
}else{
}else
#endif
{
sqlite3_reset(g.pStmt);
}
}
@@ -1273,6 +1283,7 @@ int main(int argc, char **argv){
fatal_error(zHelp, argv[0]);
}
#endif
#if SQLITE_VERSION_NUMBER>=3006001
if( nHeap>0 ){
pHeap = malloc( nHeap );
if( pHeap==0 ) fatal_error("cannot allocate %d-byte heap\n", nHeap);
@@ -1296,16 +1307,19 @@ int main(int argc, char **argv){
if( nLook>0 ){
sqlite3_config(SQLITE_CONFIG_LOOKASIDE, 0, 0);
}
#endif
/* Open the database and the input file */
if( sqlite3_open(zDbName, &g.db) ){
fatal_error("Cannot open database file: %s\n", zDbName);
}
#if SQLITE_VERSION_NUMBER>=3006001
if( nLook>0 && szLook>0 ){
pLook = malloc( nLook*szLook );
rc = sqlite3_db_config(g.db, SQLITE_DBCONFIG_LOOKASIDE, pLook, szLook,nLook);
if( rc ) fatal_error("lookaside configuration failed: %d\n", rc);
}
#endif
/* Set database connection options */
sqlite3_create_function(g.db, "random", 0, SQLITE_UTF8, 0, randomFunc, 0, 0);
@@ -1387,6 +1401,7 @@ int main(int argc, char **argv){
sqlite3_close(g.db);
#if SQLITE_VERSION_NUMBER>=3006001
/* Global memory usage statistics printed after the database connection
** has closed. Memory usage should be zero at this point. */
if( showStats ){
@@ -1407,6 +1422,7 @@ int main(int argc, char **argv){
sqlite3_status(SQLITE_STATUS_SCRATCH_SIZE, &iCur, &iHi, 0);
printf("-- Largest Scratch Allocation: %d bytes\n", iHi);
}
#endif
/* Release memory */
free( pLook );
+117
View File
@@ -283,7 +283,124 @@ ifcapable trace {
}
}
#-------------------------------------------------------------------------
# Test that the spellfix1 table supports conflict handling (OR REPLACE
# and so on).
#
do_execsql_test 7.1 {
CREATE VIRTUAL TABLE t4 USING spellfix1;
PRAGMA table_info = t4;
} {
0 word {} 0 {} 0
1 rank {} 0 {} 0
2 distance {} 0 {} 0
3 langid {} 0 {} 0
4 score {} 0 {} 0
5 matchlen {} 0 {} 0
}
do_execsql_test 7.2.1 {
INSERT INTO t4(rowid, word) VALUES(1, 'Archilles');
INSERT INTO t4(rowid, word) VALUES(2, 'Pluto');
INSERT INTO t4(rowid, word) VALUES(3, 'Atrides');
INSERT OR REPLACE INTO t4(rowid, word) VALUES(2, 'Apollo');
SELECT rowid, word FROM t4;
} {
1 Archilles 2 Apollo 3 Atrides
}
do_catchsql_test 7.2.2 {
INSERT OR ABORT INTO t4(rowid, word) VALUES(1, 'Leto');
} {1 {constraint failed}}
do_catchsql_test 7.2.3 {
INSERT OR ROLLBACK INTO t4(rowid, word) VALUES(3, 'Zeus');
} {1 {constraint failed}}
do_catchsql_test 7.2.4 {
INSERT OR FAIL INTO t4(rowid, word) VALUES(3, 'Zeus');
} {1 {constraint failed}}
do_execsql_test 7.2.5 {
INSERT OR IGNORE INTO t4(rowid, word) VALUES(3, 'Zeus');
SELECT rowid, word FROM t4;
} {
1 Archilles 2 Apollo 3 Atrides
}
do_execsql_test 7.3.1 {
UPDATE OR REPLACE t4 SET rowid=3 WHERE rowid=1;
SELECT rowid, word FROM t4;
} {2 Apollo 3 Archilles}
do_catchsql_test 7.3.2 {
UPDATE OR ABORT t4 SET rowid=3 WHERE rowid=2;
} {1 {constraint failed}}
do_catchsql_test 7.3.3 {
UPDATE OR ROLLBACK t4 SET rowid=3 WHERE rowid=2;
} {1 {constraint failed}}
do_catchsql_test 7.3.4 {
UPDATE OR FAIL t4 SET rowid=3 WHERE rowid=2;
} {1 {constraint failed}}
do_execsql_test 7.3.5 {
UPDATE OR IGNORE t4 SET rowid=3 WHERE rowid=2;
SELECT rowid, word FROM t4;
} {2 Apollo 3 Archilles}
do_execsql_test 7.4.1 {
DELETE FROM t4;
INSERT INTO t4(rowid, word) VALUES(10, 'Agamemnon');
INSERT INTO t4(rowid, word) VALUES(20, 'Patroclus');
INSERT INTO t4(rowid, word) VALUES(30, 'Chryses');
CREATE TABLE t5(i, w);
INSERT INTO t5 VALUES(5, 'Poseidon');
INSERT INTO t5 VALUES(20, 'Chronos');
INSERT INTO t5 VALUES(30, 'Hera');
}
db_save_and_close
foreach {tn conflict err bRollback res} {
0 "" {1 {constraint failed}} 0
{10 Agamemnon 20 Patroclus 30 Chryses}
1 "OR REPLACE" {0 {}} 0
{5 Poseidon 10 Agamemnon 20 Chronos 30 Hera}
2 "OR ABORT" {1 {constraint failed}} 0
{10 Agamemnon 20 Patroclus 30 Chryses}
3 "OR ROLLBACK" {1 {constraint failed}} 1
{10 Agamemnon 20 Patroclus 30 Chryses}
5 "OR IGNORE" {0 {}} 0
{5 Poseidon 10 Agamemnon 20 Patroclus 30 Chryses}
} {
db_restore_and_reopen
load_static_extension db spellfix nextchar
execsql BEGIN
set sql "INSERT $conflict INTO t4(rowid, word) SELECT i, w FROM t5"
do_catchsql_test 7.4.2.$tn.1 $sql $err
do_execsql_test 7.4.2.$tn.2 { SELECT rowid, word FROM t4 } $res
do_test 7.4.2.$tn.3 { sqlite3_get_autocommit db } $bRollback
catchsql ROLLBACK
}
foreach {tn conflict err bRollback res} {
0 "" {1 {constraint failed}} 0
{10 Agamemnon 20 Patroclus 30 Chryses}
1 "OR REPLACE" {0 {}} 0
{15 Agamemnon 45 Chryses}
2 "OR ABORT" {1 {constraint failed}} 0
{10 Agamemnon 20 Patroclus 30 Chryses}
3 "OR ROLLBACK" {1 {constraint failed}} 1
{10 Agamemnon 20 Patroclus 30 Chryses}
5 "OR IGNORE" {0 {}} 0
{15 Agamemnon 20 Patroclus 45 Chryses}
} {
db_restore_and_reopen
load_static_extension db spellfix nextchar
execsql BEGIN
set sql "UPDATE $conflict t4 SET rowid=rowid + (rowid/2)"
do_catchsql_test 7.5.2.$tn.1 $sql $err
do_execsql_test 7.5.2.$tn.2 { SELECT rowid, word FROM t4 } $res
do_test 7.5.2.$tn.3 { sqlite3_get_autocommit db } $bRollback
catchsql ROLLBACK
}
finish_test
+16
View File
@@ -808,4 +808,20 @@ do_execsql_test table-17.1 {
SELECT p, q, '|' FROM t3 ORDER BY p;
} {1 1 | 2 2 |}
# 2015-06-16
# Ticket [https://www.sqlite.org/src/tktview/873cae2b6e25b1991ce5e9b782f9cd0409b96063]
# Make sure a CREATE TABLE AS statement correctly rolls back partial changes to the
# sqlite_master table when the SELECT on the right-hand side aborts.
#
do_catchsql_test table-18.1 {
DROP TABLE IF EXISTS t1;
BEGIN;
CREATE TABLE t1 AS SELECT zeroblob(2e20);
} {1 {string or blob too big}}
do_execsql_test table-18.2 {
COMMIT;
PRAGMA integrity_check;
} {ok}
finish_test
+37
View File
@@ -230,4 +230,41 @@ do_eqp_test 5.3.3 {
SELECT * FROM t1 WHERE likely(a=?)
} {0 0 0 {SCAN TABLE t1}}
# 2015-06-18
# Ticket [https://www.sqlite.org/see/tktview/472f0742a1868fb58862bc588ed70]
#
do_execsql_test 6.0 {
DROP TABLE IF EXISTS t1;
CREATE TABLE t1(i int, x, y, z);
INSERT INTO t1 VALUES (1,1,1,1), (2,2,2,2), (3,3,3,3), (4,4,4,4);
DROP TABLE IF EXISTS t2;
CREATE TABLE t2(i int, bool char);
INSERT INTO t2 VALUES(1,'T'), (2,'F');
SELECT count(*) FROM t1 LEFT JOIN t2 ON t1.i=t2.i AND bool='T';
SELECT count(*) FROM t1 LEFT JOIN t2 ON likely(t1.i=t2.i) AND bool='T';
} {4 4}
# 2015-06-20
# Crash discovered by AFL
#
do_execsql_test 7.0 {
DROP TABLE IF EXISTS t1;
CREATE TABLE t1(a, b, PRIMARY KEY(a,b));
INSERT INTO t1 VALUES(9,1),(1,2);
DROP TABLE IF EXISTS t2;
CREATE TABLE t2(x, y, PRIMARY KEY(x,y));
INSERT INTO t2 VALUES(3,3),(4,4);
SELECT likely(a), x FROM t1, t2 ORDER BY 1, 2;
} {1 3 1 4 9 3 9 4}
do_execsql_test 7.1 {
SELECT unlikely(a), x FROM t1, t2 ORDER BY 1, 2;
} {1 3 1 4 9 3 9 4}
do_execsql_test 7.2 {
SELECT likelihood(a,0.5), x FROM t1, t2 ORDER BY 1, 2;
} {1 3 1 4 9 3 9 4}
do_execsql_test 7.3 {
SELECT coalesce(a,a), x FROM t1, t2 ORDER BY 1, 2;
} {1 3 1 4 9 3 9 4}
finish_test
+22
View File
@@ -9,6 +9,28 @@ echo '********** No optimizations. Includes FTS4 and RTREE *********'
gcc -c -Wshadow -Wall -Wextra -pedantic-errors -Wno-long-long -std=c89 \
-ansi -DHAVE_STDINT_H -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_RTREE \
sqlite3.c
echo '********** Android configuration ******************************'
gcc -c \
-DHAVE_USLEEP=1 \
-DSQLITE_HAVE_ISNAN \
-DSQLITE_DEFAULT_JOURNAL_SIZE_LIMIT=1048576 \
-DSQLITE_THREADSAFE=2 \
-DSQLITE_TEMP_STORE=3 \
-DSQLITE_POWERSAFE_OVERWRITE=1 \
-DSQLITE_DEFAULT_FILE_FORMAT=4 \
-DSQLITE_DEFAULT_AUTOVACUUM=1 \
-DSQLITE_ENABLE_MEMORY_MANAGEMENT=1 \
-DSQLITE_ENABLE_FTS3 \
-DSQLITE_ENABLE_FTS3_BACKWARDS \
-DSQLITE_ENABLE_FTS4 \
-DSQLITE_OMIT_BUILTIN_TEST \
-DSQLITE_OMIT_COMPILEOPTION_DIAGS \
-DSQLITE_OMIT_LOAD_EXTENSION \
-DSQLITE_DEFAULT_FILE_PERMISSIONS=0600 \
-DSQLITE_ENABLE_ICU \
-DUSE_PREAD64 \
-Wshadow -Wall -Wextra \
-Os sqlite3.c shell.c
echo '********** No optimizations. ENABLE_STAT4. THREADSAFE=0 *******'
gcc -c -Wshadow -Wall -Wextra -pedantic-errors -Wno-long-long -std=c89 \
-ansi -DSQLITE_ENABLE_STAT4 -DSQLITE_THREADSAFE=0 \