mirror of
https://github.com/sqlite/sqlite.git
synced 2025-08-08 14:02:16 +03:00
Merge all the latest enhancements from trunk.
FossilOrigin-Name: 924f471291dfd458307a11819aa640cc1a02ac63
This commit is contained in:
@@ -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
|
||||
);
|
||||
}
|
||||
|
52
manifest
52
manifest
@@ -1,5 +1,5 @@
|
||||
C Merge\sall\srecent\senhancements\sand\sfixes\sfrom\strunk.
|
||||
D 2015-06-17T18:18:51.003
|
||||
C Merge\sall\sthe\slatest\senhancements\sfrom\strunk.
|
||||
D 2015-06-25T15:44:49.660
|
||||
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
||||
F Makefile.in 5f56f6186fdbd0fb33226e9d2279acde3b3fa88b
|
||||
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
||||
@@ -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
|
||||
@@ -211,9 +211,9 @@ F src/auth.c b56c78ebe40a2110fd361379f7e8162d23f92240
|
||||
F src/backup.c ff743689c4d6c5cb55ad42ed9d174b2b3e71f1e3
|
||||
F src/bitvec.c 5eb7958c3bf65210211cbcfc44eff86d0ded7c9d
|
||||
F src/btmutex.c 45a968cc85afed9b5e6cf55bf1f42f8d18107f79
|
||||
F src/btree.c 02caf39192ed1f5c7157a1aac0b2ff23389233de
|
||||
F src/btree.c cb50b3f00fec44481c4b0a7f9ab1e4bed2ffce18
|
||||
F src/btree.h 969adc948e89e449220ff0ff724c94bb2a52e9f1
|
||||
F src/btreeInt.h 973a22a6fd61350b454ad614832b1f0a5e25a1e4
|
||||
F src/btreeInt.h fdd1aff02fb2a63812bd95716e7f579fc3759107
|
||||
F src/build.c b3f15255d5b16e42dafeaa638fd4f8a47c94ed70
|
||||
F src/callback.c 7b44ce59674338ad48b0e84e7b72f935ea4f68b0
|
||||
F src/complete.c a5cf5b4b56390cfb7b8636e8f7ddef90258dd575
|
||||
@@ -221,7 +221,7 @@ F src/ctime.c 5a0b735dc95604766f5dac73973658eef782ee8b
|
||||
F src/date.c e4d50b3283696836ec1036b695ead9a19e37a5ac
|
||||
F src/dbstat.c f402e77e25089c6003d0c60b3233b9b3947d599a
|
||||
F src/delete.c b998fbc3c55e8331a5f40aa7ff80972254de8de1
|
||||
F src/expr.c fbde754df3fa10bbd3a1dcea08e77b0f1684d188
|
||||
F src/expr.c 32c836d9fa22c25371039febf074849dcefb3de9
|
||||
F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
|
||||
F src/fkey.c c9b63a217d86582c22121699a47f22f524608869
|
||||
F src/func.c a98ea5880dc50e9ca6dd6f57079a37b9cfcdecf1
|
||||
@@ -267,14 +267,14 @@ 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 45a814a755f90c1a6345164d2da4a8ef293da53d
|
||||
F src/shell.c 09565d8e9a2604e503f3d4e39b55ceaaea3446c7
|
||||
F src/select.c 9baeda79f93cfd180d471273a2f9c82c682a37a2
|
||||
F src/shell.c e4ad9031072a6d679b2c69a780014d30db62dc7f
|
||||
F src/sqlite.h.in 876ad21b9a6bb5034db7c44cdebd5df2292a5336
|
||||
F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad
|
||||
F src/sqlite3ext.h be1a718b7d2ce40ceba725ae92c8eb5f18003066
|
||||
F src/sqliteInt.h 152c1a4cf6858d9724aa79d8cf2e42377ee58194
|
||||
F src/sqliteInt.h dc4d9615bc38d5eaaaf95b7a5e98267615c51ee7
|
||||
F src/sqliteLimit.h 216557999cb45f2e3578ed53ebefe228d779cb46
|
||||
F src/status.c f266ad8a2892d659b74f0f50cb6a88b6e7c12179
|
||||
F src/table.c 51b46b2a62d1b3a959633d593b89bab5e2c9155e
|
||||
@@ -326,19 +326,19 @@ F src/test_vfstrace.c bab9594adc976cbe696ff3970728830b4c5ed698
|
||||
F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9
|
||||
F src/threads.c 6bbcc9fe50c917864d48287b4792d46d6e873481
|
||||
F src/tokenize.c 57cb3720f53f84d811def2069c2b169b6be539a5
|
||||
F src/treeview.c 84aa2d2ed26627ccc8dd3a2becfa18dc86ee4607
|
||||
F src/treeview.c c84b1a8ebc7f1d00cd76ce4958eeb3ae1021beed
|
||||
F src/trigger.c 322f23aad694e8f31d384dcfa386d52a48d3c52f
|
||||
F src/update.c 24dd6a45b8b3470e62702128ebf11be1f2693145
|
||||
F src/utf.c fc6b889ba0779b7722634cdeaa25f1930d93820c
|
||||
F src/util.c a6431c92803b975b7322724a7b433e538d243539
|
||||
F src/vacuum.c 2ddd5cad2a7b9cef7f9e431b8c7771634c6b1701
|
||||
F src/vdbe.c abef10c8329ae4a29f56e0f2d23e15cf6e8c5677
|
||||
F src/vdbe.c 60917660c84745cb644d4ddd750301fe0649ccd0
|
||||
F src/vdbe.h 218e957540f5e0866501d2b546ded647c86b8d84
|
||||
F src/vdbeInt.h 571977048ae46b947fb8bbbd1332e5d98f1ca845
|
||||
F src/vdbeapi.c a5d2e8afd53b4f81934f5ca59c04465cd1a6d50d
|
||||
F src/vdbeaux.c 73788765a2d43514822fbcb2a69068fb48f4dcdd
|
||||
F src/vdbeblob.c ab33f9b57cfce7dddb23853090186da614be4846
|
||||
F src/vdbemem.c 05e4f9302fb183c37373908bc33c04c8859015b5
|
||||
F src/vdbemem.c 9b6436ec92a4516df614f55c0ad7be2fc464527a
|
||||
F src/vdbesort.c f5009e7a35e3065635d8918b9a31f498a499976b
|
||||
F src/vdbetrace.c 8befe829faff6d9e6f6e4dee5a7d3f85cc85f1a0
|
||||
F src/vtab.c c535e80259ebe616467181a83a4263555b97c694
|
||||
@@ -476,7 +476,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
|
||||
@@ -676,10 +676,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 f4ca6fa92973501cec63ac5d1992ef88f6a78e7f
|
||||
F test/fuzzdata3.db 1d6044c33a114007f02b6e6846f1fa232f607bfd
|
||||
F test/fuzzer1.test d4c52aaf3ef923da293a2653cfab33d02f718a36
|
||||
F test/fuzzerfault.test 8792cd77fd5bce765b05d0c8e01b9edcf8af8536
|
||||
F test/genesis.tcl 1e2e2e8e5cc4058549a154ff1892fe5c9de19f98
|
||||
@@ -687,7 +687,7 @@ F test/hexlit.test 1d312fa816dfd3650a3bb488093bc09a0c927f67
|
||||
F test/hook.test aa41c095d26822b8a51aa4c82904a14347961be6
|
||||
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
|
||||
@@ -764,7 +764,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
|
||||
@@ -894,7 +894,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
|
||||
@@ -948,8 +948,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
|
||||
@@ -1229,7 +1229,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
|
||||
@@ -1306,7 +1306,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1
|
||||
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
|
||||
F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b
|
||||
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
|
||||
P c39cb0e2571f58c87053de009e2c135d71b2c3af fc4f4d1eccec2e09b5d2e6c4da082204f4d5a016
|
||||
R b0895354eaa33e80f7f008da5f4f3c57
|
||||
P 199bfb67fdf642cca6cd5d460fa4dc602b94837a f824e66b0dc120bed227c7446e2663fcad7cc4f6
|
||||
R b6a4a6a3d66ab4b5ed5e1b39669d179f
|
||||
U drh
|
||||
Z 0081592a2aae788aeca7ea387179f084
|
||||
Z d59c65de498941f5f2907132a991b726
|
||||
|
@@ -1 +1 @@
|
||||
199bfb67fdf642cca6cd5d460fa4dc602b94837a
|
||||
924f471291dfd458307a11819aa640cc1a02ac63
|
690
src/btree.c
690
src/btree.c
File diff suppressed because it is too large
Load Diff
@@ -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 */
|
||||
|
@@ -2855,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;
|
||||
}
|
||||
|
||||
|
@@ -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;
|
||||
|
36
src/select.c
36
src/select.c
@@ -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;
|
||||
}
|
||||
|
38
src/shell.c
38
src/shell.c
@@ -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)
|
||||
|
@@ -3582,6 +3582,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*);
|
||||
|
@@ -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);
|
||||
|
@@ -592,13 +592,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
|
||||
|
@@ -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);
|
||||
|
@@ -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 }
|
||||
|
161
test/fuzzcheck.c
161
test/fuzzcheck.c
@@ -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
|
||||
*/
|
||||
@@ -601,12 +696,15 @@ static void showHelp(void){
|
||||
" --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;
|
||||
@@ -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 */
|
||||
@@ -787,6 +911,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();
|
||||
|
Binary file not shown.
Binary file not shown.
20
test/in.test
20
test/in.test
@@ -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
|
||||
|
||||
|
||||
|
@@ -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}] \
|
||||
|
@@ -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
|
||||
|
||||
|
||||
|
@@ -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 );
|
||||
|
@@ -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
|
||||
|
||||
|
@@ -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
|
||||
|
Reference in New Issue
Block a user