1
0
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:
drh
2015-06-25 15:44:49 +00:00
23 changed files with 969 additions and 324 deletions

View File

@@ -2655,6 +2655,31 @@ static int spellfix1Rowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
return SQLITE_OK; 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. ** The xUpdate() method.
*/ */
@@ -2686,6 +2711,7 @@ static int spellfix1Update(
char *zK1, *zK2; char *zK1, *zK2;
int i; int i;
char c; char c;
const char *zConflict = spellfix1GetConflict(db);
if( zWord==0 ){ if( zWord==0 ){
/* Inserts of the form: INSERT INTO table(command) VALUES('xyzzy'); /* Inserts of the form: INSERT INTO table(command) VALUES('xyzzy');
@@ -2746,10 +2772,10 @@ static int spellfix1Update(
}else{ }else{
newRowid = sqlite3_value_int64(argv[1]); newRowid = sqlite3_value_int64(argv[1]);
spellfix1DbExec(&rc, db, spellfix1DbExec(&rc, db,
"INSERT INTO \"%w\".\"%w_vocab\"(id,rank,langid,word,k1,k2) " "INSERT OR %s INTO \"%w\".\"%w_vocab\"(id,rank,langid,word,k1,k2) "
"VALUES(%lld,%d,%d,%Q,%Q,%Q)", "VALUES(%lld,%d,%d,%Q,%Q,%Q)",
p->zDbName, p->zTableName, zConflict, p->zDbName, p->zTableName,
newRowid, iRank, iLang, zWord, zK1, zK2 newRowid, iRank, iLang, zWord, zK1, zK2
); );
} }
*pRowid = sqlite3_last_insert_rowid(db); *pRowid = sqlite3_last_insert_rowid(db);
@@ -2757,9 +2783,9 @@ static int spellfix1Update(
rowid = sqlite3_value_int64(argv[0]); rowid = sqlite3_value_int64(argv[0]);
newRowid = *pRowid = sqlite3_value_int64(argv[1]); newRowid = *pRowid = sqlite3_value_int64(argv[1]);
spellfix1DbExec(&rc, db, 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", " 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 zWord, zK1, zK2, rowid
); );
} }

View File

@@ -1,5 +1,5 @@
C Merge\sall\srecent\senhancements\sand\sfixes\sfrom\strunk. C Merge\sall\sthe\slatest\senhancements\sfrom\strunk.
D 2015-06-17T18:18:51.003 D 2015-06-25T15:44:49.660
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in 5f56f6186fdbd0fb33226e9d2279acde3b3fa88b F Makefile.in 5f56f6186fdbd0fb33226e9d2279acde3b3fa88b
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -118,7 +118,7 @@ F ext/misc/percentile.c bcbee3c061b884eccb80e21651daaae8e1e43c63
F ext/misc/regexp.c af92cdaa5058fcec1451e49becc7ba44dba023dc F ext/misc/regexp.c af92cdaa5058fcec1451e49becc7ba44dba023dc
F ext/misc/rot13.c 1ac6f95f99b575907b9b09c81a349114cf9be45a F ext/misc/rot13.c 1ac6f95f99b575907b9b09c81a349114cf9be45a
F ext/misc/showauth.c 732578f0fe4ce42d577e1c86dc89dd14a006ab52 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/totype.c 4a167594e791abeed95e0a8db028822b5e8fe512
F ext/misc/vfslog.c fe40fab5c077a40477f7e5eba994309ecac6cc95 F ext/misc/vfslog.c fe40fab5c077a40477f7e5eba994309ecac6cc95
F ext/misc/vtshim.c babb0dc2bf116029e3e7c9a618b8a1377045303e F ext/misc/vtshim.c babb0dc2bf116029e3e7c9a618b8a1377045303e
@@ -211,9 +211,9 @@ F src/auth.c b56c78ebe40a2110fd361379f7e8162d23f92240
F src/backup.c ff743689c4d6c5cb55ad42ed9d174b2b3e71f1e3 F src/backup.c ff743689c4d6c5cb55ad42ed9d174b2b3e71f1e3
F src/bitvec.c 5eb7958c3bf65210211cbcfc44eff86d0ded7c9d F src/bitvec.c 5eb7958c3bf65210211cbcfc44eff86d0ded7c9d
F src/btmutex.c 45a968cc85afed9b5e6cf55bf1f42f8d18107f79 F src/btmutex.c 45a968cc85afed9b5e6cf55bf1f42f8d18107f79
F src/btree.c 02caf39192ed1f5c7157a1aac0b2ff23389233de F src/btree.c cb50b3f00fec44481c4b0a7f9ab1e4bed2ffce18
F src/btree.h 969adc948e89e449220ff0ff724c94bb2a52e9f1 F src/btree.h 969adc948e89e449220ff0ff724c94bb2a52e9f1
F src/btreeInt.h 973a22a6fd61350b454ad614832b1f0a5e25a1e4 F src/btreeInt.h fdd1aff02fb2a63812bd95716e7f579fc3759107
F src/build.c b3f15255d5b16e42dafeaa638fd4f8a47c94ed70 F src/build.c b3f15255d5b16e42dafeaa638fd4f8a47c94ed70
F src/callback.c 7b44ce59674338ad48b0e84e7b72f935ea4f68b0 F src/callback.c 7b44ce59674338ad48b0e84e7b72f935ea4f68b0
F src/complete.c a5cf5b4b56390cfb7b8636e8f7ddef90258dd575 F src/complete.c a5cf5b4b56390cfb7b8636e8f7ddef90258dd575
@@ -221,7 +221,7 @@ F src/ctime.c 5a0b735dc95604766f5dac73973658eef782ee8b
F src/date.c e4d50b3283696836ec1036b695ead9a19e37a5ac F src/date.c e4d50b3283696836ec1036b695ead9a19e37a5ac
F src/dbstat.c f402e77e25089c6003d0c60b3233b9b3947d599a F src/dbstat.c f402e77e25089c6003d0c60b3233b9b3947d599a
F src/delete.c b998fbc3c55e8331a5f40aa7ff80972254de8de1 F src/delete.c b998fbc3c55e8331a5f40aa7ff80972254de8de1
F src/expr.c fbde754df3fa10bbd3a1dcea08e77b0f1684d188 F src/expr.c 32c836d9fa22c25371039febf074849dcefb3de9
F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
F src/fkey.c c9b63a217d86582c22121699a47f22f524608869 F src/fkey.c c9b63a217d86582c22121699a47f22f524608869
F src/func.c a98ea5880dc50e9ca6dd6f57079a37b9cfcdecf1 F src/func.c a98ea5880dc50e9ca6dd6f57079a37b9cfcdecf1
@@ -267,14 +267,14 @@ F src/pragma.h b8632d7cdda7b25323fa580e3e558a4f0d4502cc
F src/prepare.c 82e5db1013846a819f198336fed72c44c974e7b1 F src/prepare.c 82e5db1013846a819f198336fed72c44c974e7b1
F src/printf.c db11b5960105ee661dcac690f2ae6276e49bf251 F src/printf.c db11b5960105ee661dcac690f2ae6276e49bf251
F src/random.c ba2679f80ec82c4190062d756f22d0c358180696 F src/random.c ba2679f80ec82c4190062d756f22d0c358180696
F src/resolve.c 84c571794e3ee5806274d95158a4c0177c6c4708 F src/resolve.c 2d47554370de8de6dd5be060cef9559eec315005
F src/rowset.c eccf6af6d620aaa4579bd3b72c1b6395d9e9fa1e F src/rowset.c eccf6af6d620aaa4579bd3b72c1b6395d9e9fa1e
F src/select.c 45a814a755f90c1a6345164d2da4a8ef293da53d F src/select.c 9baeda79f93cfd180d471273a2f9c82c682a37a2
F src/shell.c 09565d8e9a2604e503f3d4e39b55ceaaea3446c7 F src/shell.c e4ad9031072a6d679b2c69a780014d30db62dc7f
F src/sqlite.h.in 876ad21b9a6bb5034db7c44cdebd5df2292a5336 F src/sqlite.h.in 876ad21b9a6bb5034db7c44cdebd5df2292a5336
F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad
F src/sqlite3ext.h be1a718b7d2ce40ceba725ae92c8eb5f18003066 F src/sqlite3ext.h be1a718b7d2ce40ceba725ae92c8eb5f18003066
F src/sqliteInt.h 152c1a4cf6858d9724aa79d8cf2e42377ee58194 F src/sqliteInt.h dc4d9615bc38d5eaaaf95b7a5e98267615c51ee7
F src/sqliteLimit.h 216557999cb45f2e3578ed53ebefe228d779cb46 F src/sqliteLimit.h 216557999cb45f2e3578ed53ebefe228d779cb46
F src/status.c f266ad8a2892d659b74f0f50cb6a88b6e7c12179 F src/status.c f266ad8a2892d659b74f0f50cb6a88b6e7c12179
F src/table.c 51b46b2a62d1b3a959633d593b89bab5e2c9155e F src/table.c 51b46b2a62d1b3a959633d593b89bab5e2c9155e
@@ -326,19 +326,19 @@ F src/test_vfstrace.c bab9594adc976cbe696ff3970728830b4c5ed698
F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9
F src/threads.c 6bbcc9fe50c917864d48287b4792d46d6e873481 F src/threads.c 6bbcc9fe50c917864d48287b4792d46d6e873481
F src/tokenize.c 57cb3720f53f84d811def2069c2b169b6be539a5 F src/tokenize.c 57cb3720f53f84d811def2069c2b169b6be539a5
F src/treeview.c 84aa2d2ed26627ccc8dd3a2becfa18dc86ee4607 F src/treeview.c c84b1a8ebc7f1d00cd76ce4958eeb3ae1021beed
F src/trigger.c 322f23aad694e8f31d384dcfa386d52a48d3c52f F src/trigger.c 322f23aad694e8f31d384dcfa386d52a48d3c52f
F src/update.c 24dd6a45b8b3470e62702128ebf11be1f2693145 F src/update.c 24dd6a45b8b3470e62702128ebf11be1f2693145
F src/utf.c fc6b889ba0779b7722634cdeaa25f1930d93820c F src/utf.c fc6b889ba0779b7722634cdeaa25f1930d93820c
F src/util.c a6431c92803b975b7322724a7b433e538d243539 F src/util.c a6431c92803b975b7322724a7b433e538d243539
F src/vacuum.c 2ddd5cad2a7b9cef7f9e431b8c7771634c6b1701 F src/vacuum.c 2ddd5cad2a7b9cef7f9e431b8c7771634c6b1701
F src/vdbe.c abef10c8329ae4a29f56e0f2d23e15cf6e8c5677 F src/vdbe.c 60917660c84745cb644d4ddd750301fe0649ccd0
F src/vdbe.h 218e957540f5e0866501d2b546ded647c86b8d84 F src/vdbe.h 218e957540f5e0866501d2b546ded647c86b8d84
F src/vdbeInt.h 571977048ae46b947fb8bbbd1332e5d98f1ca845 F src/vdbeInt.h 571977048ae46b947fb8bbbd1332e5d98f1ca845
F src/vdbeapi.c a5d2e8afd53b4f81934f5ca59c04465cd1a6d50d F src/vdbeapi.c a5d2e8afd53b4f81934f5ca59c04465cd1a6d50d
F src/vdbeaux.c 73788765a2d43514822fbcb2a69068fb48f4dcdd F src/vdbeaux.c 73788765a2d43514822fbcb2a69068fb48f4dcdd
F src/vdbeblob.c ab33f9b57cfce7dddb23853090186da614be4846 F src/vdbeblob.c ab33f9b57cfce7dddb23853090186da614be4846
F src/vdbemem.c 05e4f9302fb183c37373908bc33c04c8859015b5 F src/vdbemem.c 9b6436ec92a4516df614f55c0ad7be2fc464527a
F src/vdbesort.c f5009e7a35e3065635d8918b9a31f498a499976b F src/vdbesort.c f5009e7a35e3065635d8918b9a31f498a499976b
F src/vdbetrace.c 8befe829faff6d9e6f6e4dee5a7d3f85cc85f1a0 F src/vdbetrace.c 8befe829faff6d9e6f6e4dee5a7d3f85cc85f1a0
F src/vtab.c c535e80259ebe616467181a83a4263555b97c694 F src/vtab.c c535e80259ebe616467181a83a4263555b97c694
@@ -476,7 +476,7 @@ F test/corruptE.test 193b4ca4e927e77c1d5f4f56203ddc998432a7ee
F test/corruptF.test be9fde98e4c93648f1ba52b74e5318edc8f59fe4 F test/corruptF.test be9fde98e4c93648f1ba52b74e5318edc8f59fe4
F test/corruptG.test 1ab3bf97ee7bdba70e0ff3ba2320657df55d1804 F test/corruptG.test 1ab3bf97ee7bdba70e0ff3ba2320657df55d1804
F test/corruptH.test 5dd4fa98c6c1ed33b178f9e8a48c4fdd3cfc9067 F test/corruptH.test 5dd4fa98c6c1ed33b178f9e8a48c4fdd3cfc9067
F test/corruptI.test ddf8c7146db0bc6080eedced67453b4cc69b5340 F test/corruptI.test f2b10e4fec2a4315bca2b936ffa52ccbffac3422
F test/corruptJ.test 9e29e7a81ee3b6ac50f77ea7a9e2f3fa03f32d91 F test/corruptJ.test 9e29e7a81ee3b6ac50f77ea7a9e2f3fa03f32d91
F test/cost.test 19d314526616ce4473eb4e4e450fcb94499ce318 F test/cost.test 19d314526616ce4473eb4e4e450fcb94499ce318
F test/count.test cb2e0f934c6eb33670044520748d2ecccd46259c F test/count.test cb2e0f934c6eb33670044520748d2ecccd46259c
@@ -676,10 +676,10 @@ F test/fuzz2.test 76dc35b32b6d6f965259508508abce75a6c4d7e1
F test/fuzz3.test efd384b896c647b61a2c1848ba70d42aad60a7b3 F test/fuzz3.test efd384b896c647b61a2c1848ba70d42aad60a7b3
F test/fuzz_common.tcl a87dfbb88c2a6b08a38e9a070dabd129e617b45b F test/fuzz_common.tcl a87dfbb88c2a6b08a38e9a070dabd129e617b45b
F test/fuzz_malloc.test 328f70aaca63adf29b4c6f06505ed0cf57ca7c26 F test/fuzz_malloc.test 328f70aaca63adf29b4c6f06505ed0cf57ca7c26
F test/fuzzcheck.c a60f926e3fa86c8d33908406d75eec868c22b9ca F test/fuzzcheck.c b973b06b500e6fc052d7059257cdf70df1f3a986
F test/fuzzdata1.db b60254eeb6bc11474071b883059662a73c48da7f F test/fuzzdata1.db 7ee3227bad0e7ccdeb08a9e6822916777073c664
F test/fuzzdata2.db f03a420d3b822cc82e4f894ca957618fbe9c4973 F test/fuzzdata2.db f03a420d3b822cc82e4f894ca957618fbe9c4973
F test/fuzzdata3.db f4ca6fa92973501cec63ac5d1992ef88f6a78e7f F test/fuzzdata3.db 1d6044c33a114007f02b6e6846f1fa232f607bfd
F test/fuzzer1.test d4c52aaf3ef923da293a2653cfab33d02f718a36 F test/fuzzer1.test d4c52aaf3ef923da293a2653cfab33d02f718a36
F test/fuzzerfault.test 8792cd77fd5bce765b05d0c8e01b9edcf8af8536 F test/fuzzerfault.test 8792cd77fd5bce765b05d0c8e01b9edcf8af8536
F test/genesis.tcl 1e2e2e8e5cc4058549a154ff1892fe5c9de19f98 F test/genesis.tcl 1e2e2e8e5cc4058549a154ff1892fe5c9de19f98
@@ -687,7 +687,7 @@ F test/hexlit.test 1d312fa816dfd3650a3bb488093bc09a0c927f67
F test/hook.test aa41c095d26822b8a51aa4c82904a14347961be6 F test/hook.test aa41c095d26822b8a51aa4c82904a14347961be6
F test/icu.test 70df4faca133254c042d02ae342c0a141f2663f4 F test/icu.test 70df4faca133254c042d02ae342c0a141f2663f4
F test/imposter1.test c3f1db2d3db2c24611a6596a3fc0ffc14f1466c8 F test/imposter1.test c3f1db2d3db2c24611a6596a3fc0ffc14f1466c8
F test/in.test b52fa96bcf6cebc5c8829c822315d0f87af9c6c2 F test/in.test 61a24ae38d4b64ec69f06ccdf022992f68a98176
F test/in2.test 5d4c61d17493c832f7d2d32bef785119e87bde75 F test/in2.test 5d4c61d17493c832f7d2d32bef785119e87bde75
F test/in3.test 3cbf58c87f4052cee3a58b37b6389777505aa0c0 F test/in3.test 3cbf58c87f4052cee3a58b37b6389777505aa0c0
F test/in4.test d2b38cba404bc4320f4fe1b595b3d163f212c068 F test/in4.test d2b38cba404bc4320f4fe1b595b3d163f212c068
@@ -764,7 +764,7 @@ F test/make-where7.tcl 05c16b5d4f5d6512881dfec560cb793915932ef9
F test/malloc.test 21c213365f2cca95ab2d7dc078dc8525f96065f8 F test/malloc.test 21c213365f2cca95ab2d7dc078dc8525f96065f8
F test/malloc3.test e3b32c724b5a124b57cb0ed177f675249ad0c66a F test/malloc3.test e3b32c724b5a124b57cb0ed177f675249ad0c66a
F test/malloc4.test 957337613002b7058a85116493a262f679f3a261 F test/malloc4.test 957337613002b7058a85116493a262f679f3a261
F test/malloc5.test 79182b8bffd6d62f77b1a5a8ba8e6bf0e5053b8e F test/malloc5.test e9a9116f80ab6b7a9ca258876c6f3dedb08cb08b
F test/malloc6.test 2f039d9821927eacae43e1831f815e157659a151 F test/malloc6.test 2f039d9821927eacae43e1831f815e157659a151
F test/malloc7.test 7c68a32942858bc715284856c5507446bba88c3a F test/malloc7.test 7c68a32942858bc715284856c5507446bba88c3a
F test/malloc8.test 9b7a3f8cb9cf0b12fff566e80a980b1767bd961d F test/malloc8.test 9b7a3f8cb9cf0b12fff566e80a980b1767bd961d
@@ -894,7 +894,7 @@ F test/select3.test 2ce595f8fb8e2ac10071d3b4e424cadd4634a054
F test/select4.test 6d5bc6d178a367e8b48fa1c1d3ea12cae9c2d650 F test/select4.test 6d5bc6d178a367e8b48fa1c1d3ea12cae9c2d650
F test/select5.test e758b8ef94f69b111df4cb819008856655dcd535 F test/select5.test e758b8ef94f69b111df4cb819008856655dcd535
F test/select6.test 39eac4a5c03650b2b473c532882273283ee8b7a0 F test/select6.test 39eac4a5c03650b2b473c532882273283ee8b7a0
F test/select7.test 7fd2ef598cfabb6b9ff6ac13973b91d0527df49d F test/select7.test 71f06cd37cb6f65bb08ba1ccf8e2f5818c09329f
F test/select8.test 8c8f5ae43894c891efc5755ed905467d1d67ad5d F test/select8.test 8c8f5ae43894c891efc5755ed905467d1d67ad5d
F test/select9.test aebc2bb0c3bc44606125033cbcaac2c8d1f33a95 F test/select9.test aebc2bb0c3bc44606125033cbcaac2c8d1f33a95
F test/selectA.test e452bdb975f488ea46d091382a9185b5853ed2c7 F test/selectA.test e452bdb975f488ea46d091382a9185b5853ed2c7
@@ -948,8 +948,8 @@ F test/speed3.test d32043614c08c53eafdc80f33191d5bd9b920523
F test/speed4.test abc0ad3399dcf9703abed2fff8705e4f8e416715 F test/speed4.test abc0ad3399dcf9703abed2fff8705e4f8e416715
F test/speed4p.explain 6b5f104ebeb34a038b2f714150f51d01143e59aa F test/speed4p.explain 6b5f104ebeb34a038b2f714150f51d01143e59aa
F test/speed4p.test 0e51908951677de5a969b723e03a27a1c45db38b F test/speed4p.test 0e51908951677de5a969b723e03a27a1c45db38b
F test/speedtest1.c 9f1b745c24886cced3f70ffc666300152a39013c F test/speedtest1.c f42fd04a34a0c1dc289cbe536ef62d706227a736
F test/spellfix.test 24f676831acddd2f4056a598fd731a72c6311f49 F test/spellfix.test 0597065ff57042df1f138e6a2611ae19c2698135
F test/sqldiff1.test 8f6bc7c6a5b3585d350d779c6078869ba402f8f5 F test/sqldiff1.test 8f6bc7c6a5b3585d350d779c6078869ba402f8f5
F test/sqllimits1.test e05786eaed7950ff6a2d00031d001d8a26131e68 F test/sqllimits1.test e05786eaed7950ff6a2d00031d001d8a26131e68
F test/stat.test 8de91498c99f5298b303f70f1d1f3b9557af91bf F test/stat.test 8de91498c99f5298b303f70f1d1f3b9557af91bf
@@ -1229,7 +1229,7 @@ F test/whereC.test cae295158703cb3fc23bf1a108a9ab730efff0f6
F test/whereD.test 9eba1f9b18e5b19a0b0bcaae5e8c037260195f2b F test/whereD.test 9eba1f9b18e5b19a0b0bcaae5e8c037260195f2b
F test/whereE.test b3a055eef928c992b0a33198a7b8dc10eea5ad2f F test/whereE.test b3a055eef928c992b0a33198a7b8dc10eea5ad2f
F test/whereF.test 5b2ba0dbe8074aa13e416b37c753991f0a2492d7 F test/whereF.test 5b2ba0dbe8074aa13e416b37c753991f0a2492d7
F test/whereG.test 69f5ec4b15760a8c860f80e2d55525669390aab3 F test/whereG.test dde4c52a97385a55be6a7cd46be8373f0cf35501
F test/whereH.test e4b07f7a3c2f5d31195cd33710054c78667573b2 F test/whereH.test e4b07f7a3c2f5d31195cd33710054c78667573b2
F test/whereI.test 1d89199697919d4930be05a71e7fe620f114e622 F test/whereI.test 1d89199697919d4930be05a71e7fe620f114e622
F test/whereJ.test 55a3221706a7ab706293f17cc8f96da563bf0767 F test/whereJ.test 55a3221706a7ab706293f17cc8f96da563bf0767
@@ -1306,7 +1306,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
P c39cb0e2571f58c87053de009e2c135d71b2c3af fc4f4d1eccec2e09b5d2e6c4da082204f4d5a016 P 199bfb67fdf642cca6cd5d460fa4dc602b94837a f824e66b0dc120bed227c7446e2663fcad7cc4f6
R b0895354eaa33e80f7f008da5f4f3c57 R b6a4a6a3d66ab4b5ed5e1b39669d179f
U drh U drh
Z 0081592a2aae788aeca7ea387179f084 Z d59c65de498941f5f2907132a991b726

View File

@@ -1 +1 @@
199bfb67fdf642cca6cd5d460fa4dc602b94837a 924f471291dfd458307a11819aa640cc1a02ac63

File diff suppressed because it is too large Load Diff

View File

@@ -231,6 +231,7 @@
/* Forward declarations */ /* Forward declarations */
typedef struct MemPage MemPage; typedef struct MemPage MemPage;
typedef struct BtLock BtLock; typedef struct BtLock BtLock;
typedef struct CellInfo CellInfo;
/* /*
** This is a magic string that appears at the beginning of every ** 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 *aDataEnd; /* One byte past the end of usable data */
u8 *aCellIdx; /* The cell index area */ u8 *aCellIdx; /* The cell index area */
DbPage *pDbPage; /* Pager page handle */ 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 */ Pgno pgno; /* Page number for this page */
}; };
@@ -350,6 +353,7 @@ struct Btree {
u8 inTrans; /* TRANS_NONE, TRANS_READ or TRANS_WRITE */ u8 inTrans; /* TRANS_NONE, TRANS_READ or TRANS_WRITE */
u8 sharable; /* True if we can share pBt with another db */ u8 sharable; /* True if we can share pBt with another db */
u8 locked; /* True if db currently has pBt locked */ 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 wantToLock; /* Number of nested calls to sqlite3BtreeEnter() */
int nBackup; /* Number of backup operations reading this btree */ int nBackup; /* Number of backup operations reading this btree */
u32 iDataVersion; /* Combines with pBt->pPager->iDataVersion */ u32 iDataVersion; /* Combines with pBt->pPager->iDataVersion */
@@ -460,7 +464,6 @@ struct BtShared {
** about a cell. The parseCellPtr() function fills in this structure ** about a cell. The parseCellPtr() function fills in this structure
** based on information extract from the raw disk page. ** based on information extract from the raw disk page.
*/ */
typedef struct CellInfo CellInfo;
struct CellInfo { struct CellInfo {
i64 nKey; /* The key for INTKEY tables, or nPayload otherwise */ i64 nKey; /* The key for INTKEY tables, or nPayload otherwise */
u8 *pPayload; /* Pointer to the start of payload */ u8 *pPayload; /* Pointer to the start of payload */

View File

@@ -2855,7 +2855,7 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){
*/ */
if( pDef->funcFlags & SQLITE_FUNC_UNLIKELY ){ if( pDef->funcFlags & SQLITE_FUNC_UNLIKELY ){
assert( nFarg>=1 ); assert( nFarg>=1 );
sqlite3ExprCode(pParse, pFarg->a[0].pExpr, target); inReg = sqlite3ExprCodeTarget(pParse, pFarg->a[0].pExpr, target);
break; break;
} }

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 /* Advance to the next term of the compound
*/ */
p = p->pPrior; p = p->pPrior;

View File

@@ -366,6 +366,12 @@ static void setJoinExpr(Expr *p, int iTable){
assert( !ExprHasProperty(p, EP_TokenOnly|EP_Reduced) ); assert( !ExprHasProperty(p, EP_TokenOnly|EP_Reduced) );
ExprSetVVAProperty(p, EP_NoReduce); ExprSetVVAProperty(p, EP_NoReduce);
p->iRightJoinTable = (i16)iTable; 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); setJoinExpr(p->pLeft, iTable);
p = p->pRight; p = p->pRight;
} }
@@ -1386,10 +1392,13 @@ static const char *columnTypeImpl(
** of the SELECT statement. Return the declaration type and origin ** of the SELECT statement. Return the declaration type and origin
** data for the result-set column of the sub-select. ** 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 /* If iCol is less than zero, then the expression requests the
** rowid of the sub-select or view. This expression is legal (see ** rowid of the sub-select or view. This expression is legal (see
** test case misc2.2.2) - it always evaluates to NULL. ** 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; NameContext sNC;
Expr *p = pS->pEList->a[iCol].pExpr; Expr *p = pS->pEList->a[iCol].pExpr;
@@ -1868,7 +1877,10 @@ static CollSeq *multiSelectCollSeq(Parse *pParse, Select *p, int iCol){
pRet = 0; pRet = 0;
} }
assert( iCol>=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); pRet = sqlite3ExprCollSeq(pParse, p->pEList->a[iCol].pExpr);
} }
return pRet; return pRet;
@@ -2087,7 +2099,7 @@ static int multiSelectOrderBy(
** Error message for when two or more terms of a compound select have different ** Error message for when two or more terms of a compound select have different
** size result sets. ** size result sets.
*/ */
static void selectWrongNumTermsError(Parse *pParse, Select *p){ void sqlite3SelectWrongNumTermsError(Parse *pParse, Select *p){
if( p->selFlags & SF_Values ){ if( p->selFlags & SF_Values ){
sqlite3ErrorMsg(pParse, "all VALUES must have the same number of terms"); sqlite3ErrorMsg(pParse, "all VALUES must have the same number of terms");
}else{ }else{
@@ -2113,7 +2125,6 @@ static int multiSelectValues(
SelectDest *pDest /* What to do with query results */ SelectDest *pDest /* What to do with query results */
){ ){
Select *pPrior; Select *pPrior;
int nExpr = p->pEList->nExpr;
int nRow = 1; int nRow = 1;
int rc = 0; int rc = 0;
assert( p->selFlags & SF_MultiValue ); 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->op==TK_ALL || (p->op==TK_SELECT && p->pPrior==0) );
assert( p->pLimit==0 ); assert( p->pLimit==0 );
assert( p->pOffset==0 ); assert( p->pOffset==0 );
if( p->pEList->nExpr!=nExpr ){ assert( p->pNext==0 || p->pEList->nExpr==p->pNext->pEList->nExpr );
selectWrongNumTermsError(pParse, p);
return 1;
}
if( p->pPrior==0 ) break; if( p->pPrior==0 ) break;
assert( p->pPrior->pNext==p ); assert( p->pPrior->pNext==p );
p = p->pPrior; p = p->pPrior;
@@ -2234,11 +2242,7 @@ static int multiSelect(
** in their result sets. ** in their result sets.
*/ */
assert( p->pEList && pPrior->pEList ); assert( p->pEList && pPrior->pEList );
if( p->pEList->nExpr!=pPrior->pEList->nExpr ){ assert( p->pEList->nExpr==pPrior->pEList->nExpr );
selectWrongNumTermsError(pParse, p);
rc = 1;
goto multi_select_end;
}
#ifndef SQLITE_OMIT_CTE #ifndef SQLITE_OMIT_CTE
if( p->selFlags & SF_Recursive ){ if( p->selFlags & SF_Recursive ){
@@ -2857,9 +2861,7 @@ static int multiSelectOrderBy(
struct ExprList_item *pItem; struct ExprList_item *pItem;
for(i=0, pItem=pOrderBy->a; i<nOrderBy; i++, pItem++){ for(i=0, pItem=pOrderBy->a; i<nOrderBy; i++, pItem++){
assert( pItem->u.x.iOrderByCol>0 ); assert( pItem->u.x.iOrderByCol>0 );
/* assert( pItem->u.x.iOrderByCol<=p->pEList->nExpr ) is also true assert( pItem->u.x.iOrderByCol<=p->pEList->nExpr );
** but only for well-formed SELECT statements. */
testcase( pItem->u.x.iOrderByCol > p->pEList->nExpr );
aPermute[i] = pItem->u.x.iOrderByCol - 1; aPermute[i] = pItem->u.x.iOrderByCol - 1;
} }
pKeyMerge = multiSelectOrderByKeyInfo(pParse, p, 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_Distinct );
testcase( (pSub1->selFlags & (SF_Distinct|SF_Aggregate))==SF_Aggregate ); testcase( (pSub1->selFlags & (SF_Distinct|SF_Aggregate))==SF_Aggregate );
assert( pSub->pSrc!=0 ); assert( pSub->pSrc!=0 );
assert( pSub->pEList->nExpr==pSub1->pEList->nExpr );
if( (pSub1->selFlags & (SF_Distinct|SF_Aggregate))!=0 if( (pSub1->selFlags & (SF_Distinct|SF_Aggregate))!=0
|| (pSub1->pPrior && pSub1->op!=TK_ALL) || (pSub1->pPrior && pSub1->op!=TK_ALL)
|| pSub1->pSrc->nSrc<1 || pSub1->pSrc->nSrc<1
|| pSub->pEList->nExpr!=pSub1->pEList->nExpr
){ ){
return 0; return 0;
} }

View File

@@ -101,28 +101,26 @@
#if defined(_WIN32) || defined(WIN32) #if defined(_WIN32) || defined(WIN32)
# include <io.h> # include <io.h>
# include <fcntl.h> # include <fcntl.h>
#define isatty(h) _isatty(h) # define isatty(h) _isatty(h)
#ifndef access # ifndef access
# define access(f,m) _access((f),(m)) # define access(f,m) _access((f),(m))
#endif # endif
#undef popen # undef popen
#define popen _popen # define popen _popen
#undef pclose # undef pclose
#define pclose _pclose # define pclose _pclose
#else #else
/* Make sure isatty() has a prototype. /* Make sure isatty() has a prototype. */
*/ extern int isatty(int);
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
# 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 #endif
#if defined(_WIN32_WCE) #if defined(_WIN32_WCE)

View File

@@ -3582,6 +3582,7 @@ void sqlite3NestedParse(Parse*, const char*, ...);
void sqlite3ExpirePreparedStatements(sqlite3*); void sqlite3ExpirePreparedStatements(sqlite3*);
int sqlite3CodeSubselect(Parse *, Expr *, int, int); int sqlite3CodeSubselect(Parse *, Expr *, int, int);
void sqlite3SelectPrep(Parse*, Select*, NameContext*); void sqlite3SelectPrep(Parse*, Select*, NameContext*);
void sqlite3SelectWrongNumTermsError(Parse *pParse, Select *p);
int sqlite3MatchSpanName(const char*, const char*, const char*, const char*); int sqlite3MatchSpanName(const char*, const char*, const char*, const char*);
int sqlite3ResolveExprNames(NameContext*, Expr*); int sqlite3ResolveExprNames(NameContext*, Expr*);
void sqlite3ResolveSelectNames(Parse*, Select*, NameContext*); void sqlite3ResolveSelectNames(Parse*, Select*, NameContext*);

View File

@@ -178,25 +178,31 @@ void sqlite3TreeViewSelect(TreeView *pView, const Select *p, u8 moreToFollow){
void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 moreToFollow){ void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 moreToFollow){
const char *zBinOp = 0; /* Binary operator */ const char *zBinOp = 0; /* Binary operator */
const char *zUniOp = 0; /* Unary operator */ const char *zUniOp = 0; /* Unary operator */
char zFlgs[30];
pView = sqlite3TreeViewPush(pView, moreToFollow); pView = sqlite3TreeViewPush(pView, moreToFollow);
if( pExpr==0 ){ if( pExpr==0 ){
sqlite3TreeViewLine(pView, "nil"); sqlite3TreeViewLine(pView, "nil");
sqlite3TreeViewPop(pView); sqlite3TreeViewPop(pView);
return; return;
} }
if( pExpr->flags ){
sqlite3_snprintf(sizeof(zFlgs),zFlgs," flags=0x%x",pExpr->flags);
}else{
zFlgs[0] = 0;
}
switch( pExpr->op ){ switch( pExpr->op ){
case TK_AGG_COLUMN: { case TK_AGG_COLUMN: {
sqlite3TreeViewLine(pView, "AGG{%d:%d}", sqlite3TreeViewLine(pView, "AGG{%d:%d}%s",
pExpr->iTable, pExpr->iColumn); pExpr->iTable, pExpr->iColumn, zFlgs);
break; break;
} }
case TK_COLUMN: { case TK_COLUMN: {
if( pExpr->iTable<0 ){ if( pExpr->iTable<0 ){
/* This only happens when coding check constraints */ /* This only happens when coding check constraints */
sqlite3TreeViewLine(pView, "COLUMN(%d)", pExpr->iColumn); sqlite3TreeViewLine(pView, "COLUMN(%d)%s", pExpr->iColumn, zFlgs);
}else{ }else{
sqlite3TreeViewLine(pView, "{%d:%d}", sqlite3TreeViewLine(pView, "{%d:%d}%s",
pExpr->iTable, pExpr->iColumn); pExpr->iTable, pExpr->iColumn, zFlgs);
} }
break; break;
} }
@@ -389,11 +395,11 @@ void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 moreToFollow){
} }
} }
if( zBinOp ){ if( zBinOp ){
sqlite3TreeViewLine(pView, "%s", zBinOp); sqlite3TreeViewLine(pView, "%s%s", zBinOp, zFlgs);
sqlite3TreeViewExpr(pView, pExpr->pLeft, 1); sqlite3TreeViewExpr(pView, pExpr->pLeft, 1);
sqlite3TreeViewExpr(pView, pExpr->pRight, 0); sqlite3TreeViewExpr(pView, pExpr->pRight, 0);
}else if( zUniOp ){ }else if( zUniOp ){
sqlite3TreeViewLine(pView, "%s", zUniOp); sqlite3TreeViewLine(pView, "%s%s", zUniOp, zFlgs);
sqlite3TreeViewExpr(pView, pExpr->pLeft, 0); sqlite3TreeViewExpr(pView, pExpr->pLeft, 0);
} }
sqlite3TreeViewPop(pView); sqlite3TreeViewPop(pView);

View File

@@ -592,13 +592,9 @@ int sqlite3VdbeExec(
sqlite3VdbeIOTraceSql(p); sqlite3VdbeIOTraceSql(p);
#ifndef SQLITE_OMIT_PROGRESS_CALLBACK #ifndef SQLITE_OMIT_PROGRESS_CALLBACK
if( db->xProgress ){ if( db->xProgress ){
u32 iPrior = p->aCounter[SQLITE_STMTSTATUS_VM_STEP];
assert( 0 < db->nProgressOps ); assert( 0 < db->nProgressOps );
nProgressLimit = (unsigned)p->aCounter[SQLITE_STMTSTATUS_VM_STEP]; nProgressLimit = db->nProgressOps - (iPrior % db->nProgressOps);
if( nProgressLimit==0 ){
nProgressLimit = db->nProgressOps;
}else{
nProgressLimit %= (unsigned)db->nProgressOps;
}
} }
#endif #endif
#ifdef SQLITE_DEBUG #ifdef SQLITE_DEBUG

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 ** 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). ** 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){ void sqlite3VdbeMemShallowCopy(Mem *pTo, const Mem *pFrom, int srcType){
assert( (pFrom->flags & MEM_RowSet)==0 ); assert( (pFrom->flags & MEM_RowSet)==0 );
assert( pTo->db==pFrom->db ); assert( pTo->db==pFrom->db );
if( VdbeMemDynamic(pTo) ) vdbeMemClearExternAndSetNull(pTo); if( VdbeMemDynamic(pTo) ){ vdbeClrCopy(pTo,pFrom,srcType); return; }
memcpy(pTo, pFrom, MEMCELLSIZE); memcpy(pTo, pFrom, MEMCELLSIZE);
if( (pFrom->flags&MEM_Static)==0 ){ if( (pFrom->flags&MEM_Static)==0 ){
pTo->flags &= ~(MEM_Dyn|MEM_Static|MEM_Ephem); pTo->flags &= ~(MEM_Dyn|MEM_Static|MEM_Ephem);

View File

@@ -204,7 +204,7 @@ do_execsql_test 6.0 {
} {} } {}
do_test 6.1 { do_test 6.1 {
db close db close
hexio_write test.db 616 EAFFFFFF0202 hexio_write test.db 616 8FFFFFFF7F02
sqlite3 db test.db sqlite3 db test.db
breakpoint breakpoint
execsql { DELETE FROM t1 WHERE rowid=2 } execsql { DELETE FROM t1 WHERE rowid=2 }

View File

@@ -10,8 +10,8 @@
** **
************************************************************************* *************************************************************************
** **
** This is a utility program designed to aid running regressions tests ** This is a utility program designed to aid running regressions tests on
** on SQLite library using data from an external fuzzer, such as American ** the SQLite library using data from an external fuzzer, such as American
** Fuzzy Lop (AFL) (http://lcamtuf.coredump.cx/afl/). ** Fuzzy Lop (AFL) (http://lcamtuf.coredump.cx/afl/).
** **
** This program reads content from an SQLite database file with the following ** This program reads content from an SQLite database file with the following
@@ -25,16 +25,44 @@
** sqlid INTEGER PRIMARY KEY, -- SQL script id ** sqlid INTEGER PRIMARY KEY, -- SQL script id
** sqltext TEXT -- Text of SQL statements to run ** 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 ** 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, ** is run against that database. All README.MSG values are printed prior
** assertion faults, and/or memory leaks. No attempt is made to verify ** to the start of the test (unless the --quiet option is used). If the
** the output. The assumption is that either all of the database files ** DB table is empty, then all entries in XSQL are run against an empty
** or all of the SQL statements are malformed inputs, generated by a fuzzer, ** in-memory database.
** that need to be checked to make sure they do not present a security risk. **
** 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 ** 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 <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@@ -43,6 +71,11 @@
#include <ctype.h> #include <ctype.h>
#include "sqlite3.h" #include "sqlite3.h"
#ifdef __unix__
# include <signal.h>
# include <unistd.h>
#endif
/* /*
** Files in the virtual file system. ** Files in the virtual file system.
*/ */
@@ -111,6 +144,43 @@ static void fatalError(const char *zFormat, ...){
exit(1); 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. ** 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 ** Print sketchy documentation for this utility program
*/ */
@@ -598,15 +693,18 @@ static void showHelp(void){
"Options:\n" "Options:\n"
" --cell-size-check Set the PRAGMA cell_size_check=ON\n" " --cell-size-check Set the PRAGMA cell_size_check=ON\n"
" --dbid N Use only the database where dbid=N\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" " -q Reduced output\n"
" --quiet 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-sql ARGS... Load SQL scripts fro files into SOURCE-DB\n"
" --load-db ARGS... Load template databases from 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" " -m TEXT Add a description to the database\n"
" --native-vfs Use the native VFS for initially empty database files\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" " --result-trace Show the results of each SQL command\n"
" --sqlid N Use only SQL where sqlid=N\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" " -v Increased output\n"
" --verbose Increased output\n" " --verbose Increased output\n"
); );
@@ -627,6 +725,9 @@ int main(int argc, char **argv){
int onlySqlid = -1; /* --sqlid */ int onlySqlid = -1; /* --sqlid */
int onlyDbid = -1; /* --dbid */ int onlyDbid = -1; /* --dbid */
int nativeFlag = 0; /* --native-vfs */ 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() */ int runFlags = 0; /* Flags sent to runSql() */
char *zMsg = 0; /* Add this message */ char *zMsg = 0; /* Add this message */
int nSrcDb = 0; /* Number of source databases */ 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 */ char *zDbName = ""; /* Appreviated name of a source database */
const char *zFailCode = 0; /* Value of the TEST_FAILURE environment variable */ const char *zFailCode = 0; /* Value of the TEST_FAILURE environment variable */
int cellSzCkFlag = 0; /* --cell-size-check */ 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(); iBegin = timeOfDay();
#ifdef __unix__
signal(SIGALRM, timeoutHandler);
#endif
g.zArgv0 = argv[0]; g.zArgv0 = argv[0];
zFailCode = getenv("TEST_FAILURE"); zFailCode = getenv("TEST_FAILURE");
for(i=1; i<argc; i++){ for(i=1; i<argc; i++){
@@ -656,6 +762,9 @@ int main(int argc, char **argv){
showHelp(); showHelp();
return 0; return 0;
}else }else
if( strcmp(z,"limit-vdbe")==0 ){
vdbeLimitFlag = 1;
}else
if( strcmp(z,"load-sql")==0 ){ if( strcmp(z,"load-sql")==0 ){
zInsSql = "INSERT INTO xsql(sqltext) VALUES(CAST(readfile(?1) AS text))"; zInsSql = "INSERT INTO xsql(sqltext) VALUES(CAST(readfile(?1) AS text))";
iFirstInsArg = i+1; iFirstInsArg = i+1;
@@ -677,6 +786,9 @@ int main(int argc, char **argv){
quietFlag = 1; quietFlag = 1;
verboseFlag = 0; verboseFlag = 0;
}else }else
if( strcmp(z,"rebuild")==0 ){
rebuildFlag = 1;
}else
if( strcmp(z,"result-trace")==0 ){ if( strcmp(z,"result-trace")==0 ){
runFlags |= SQL_OUTPUT; runFlags |= SQL_OUTPUT;
}else }else
@@ -684,6 +796,16 @@ int main(int argc, char **argv){
if( i>=argc-1 ) fatalError("missing arguments on %s", argv[i]); if( i>=argc-1 ) fatalError("missing arguments on %s", argv[i]);
onlySqlid = atoi(argv[++i]); onlySqlid = atoi(argv[++i]);
}else }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 ){ if( strcmp(z,"verbose")==0 || strcmp(z,"v")==0 ){
quietFlag = 0; quietFlag = 0;
verboseFlag = 1; verboseFlag = 1;
@@ -715,7 +837,7 @@ int main(int argc, char **argv){
fatalError("cannot open source database %s - %s", fatalError("cannot open source database %s - %s",
azSrcDb[iSrcDb], sqlite3_errmsg(db)); azSrcDb[iSrcDb], sqlite3_errmsg(db));
} }
rc = sqlite3_exec(db, rc = sqlite3_exec(db,
"CREATE TABLE IF NOT EXISTS db(\n" "CREATE TABLE IF NOT EXISTS db(\n"
" dbid INTEGER PRIMARY KEY, -- database id\n" " dbid INTEGER PRIMARY KEY, -- database id\n"
" dbcontent BLOB -- database disk file image\n" " dbcontent BLOB -- database disk file image\n"
@@ -753,6 +875,7 @@ int main(int argc, char **argv){
sqlite3_finalize(pStmt); sqlite3_finalize(pStmt);
rc = sqlite3_exec(db, "COMMIT", 0, 0, 0); rc = sqlite3_exec(db, "COMMIT", 0, 0, 0);
if( rc ) fatalError("cannot commit the transaction: %s", sqlite3_errmsg(db)); if( rc ) fatalError("cannot commit the transaction: %s", sqlite3_errmsg(db));
rebuild_database(db);
sqlite3_close(db); sqlite3_close(db);
return 0; return 0;
} }
@@ -771,6 +894,7 @@ int main(int argc, char **argv){
g.pFirstDb->id = 1; g.pFirstDb->id = 1;
g.pFirstDb->seq = 0; g.pFirstDb->seq = 0;
g.nDb = 1; g.nDb = 1;
sqlFuzz = 1;
} }
/* Print the description, if there is one */ /* Print the description, if there is one */
@@ -786,6 +910,16 @@ int main(int argc, char **argv){
} }
sqlite3_finalize(pStmt); 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 /* Close the source database. Verify that no SQLite memory allocations are
** outstanding. ** outstanding.
@@ -831,7 +965,16 @@ int main(int argc, char **argv){
rc = sqlite3_open_v2("main.db", &db, openFlags, zVfs); rc = sqlite3_open_v2("main.db", &db, openFlags, zVfs);
if( rc ) fatalError("cannot open inmem database"); if( rc ) fatalError("cannot open inmem database");
if( cellSzCkFlag ) runSql(db, "PRAGMA cell_size_check=ON", runFlags); 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); sqlite3_close(db);
if( sqlite3_memory_used()>0 ) fatalError("memory leak"); if( sqlite3_memory_used()>0 ) fatalError("memory leak");
reformatVfs(); reformatVfs();

Binary file not shown.

Binary file not shown.

View File

@@ -450,28 +450,42 @@ do_test in-12.10 {
SELECT a FROM t3 UNION ALL SELECT a, b FROM t2 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 { do_test in-12.11 {
catchsql { catchsql {
SELECT * FROM t2 WHERE a IN ( SELECT * FROM t2 WHERE a IN (
SELECT a FROM t3 UNION SELECT a, b FROM t2 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 { do_test in-12.12 {
catchsql { catchsql {
SELECT * FROM t2 WHERE a IN ( SELECT * FROM t2 WHERE a IN (
SELECT a FROM t3 EXCEPT SELECT a, b FROM t2 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 { do_test in-12.13 {
catchsql { catchsql {
SELECT * FROM t2 WHERE a IN ( SELECT * FROM t2 WHERE a IN (
SELECT a FROM t3 INTERSECT SELECT a, b FROM t2 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}} } {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 }; #ifcapable compound

View File

@@ -189,8 +189,8 @@ do_test malloc5-3.1 {
BEGIN; BEGIN;
SELECT * FROM def; SELECT * FROM def;
} db2 } db2
sqlite3_release_memory value_in_range [expr $::pgalloc*2] 0.99 [sqlite3_release_memory]
} [expr $::pgalloc * 2] } [value_in_range [expr $::pgalloc * 2] 0.99]
do_test malloc5-3.2 { do_test malloc5-3.2 {
concat \ concat \
[execsql {SELECT * FROM abc; COMMIT}] \ [execsql {SELECT * FROM abc; COMMIT}] \

View File

@@ -15,6 +15,7 @@
set testdir [file dirname $argv0] set testdir [file dirname $argv0]
source $testdir/tester.tcl source $testdir/tester.tcl
set testprefix select7
ifcapable compound { ifcapable compound {
@@ -201,4 +202,23 @@ do_test select7-7.7 {
} }
} {text 123} } {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 finish_test

View File

@@ -43,6 +43,9 @@ static const char zHelp[] =
#include <string.h> #include <string.h>
#include <ctype.h> #include <ctype.h>
#if SQLITE_VERSION_NUMBER<3005000
# define sqlite3_int64 sqlite_int64
#endif
#ifdef SQLITE_ENABLE_OTA #ifdef SQLITE_ENABLE_OTA
# include "sqlite3ota.h" # include "sqlite3ota.h"
#endif #endif
@@ -143,6 +146,9 @@ static int integerValue(const char *zArg){
/* Return the current wall-clock time, in milliseconds */ /* Return the current wall-clock time, in milliseconds */
sqlite3_int64 speedtest1_timestamp(void){ sqlite3_int64 speedtest1_timestamp(void){
#if SQLITE_VERSION_NUMBER<3005000
return 0;
#else
static sqlite3_vfs *clockVfs = 0; static sqlite3_vfs *clockVfs = 0;
sqlite3_int64 t; sqlite3_int64 t;
if( clockVfs==0 ) clockVfs = sqlite3_vfs_find(0); if( clockVfs==0 ) clockVfs = sqlite3_vfs_find(0);
@@ -157,6 +163,7 @@ sqlite3_int64 speedtest1_timestamp(void){
t = (sqlite3_int64)(r*86400000.0); t = (sqlite3_int64)(r*86400000.0);
} }
return t; return t;
#endif
} }
/* Return a pseudo-random unsigned integer */ /* Return a pseudo-random unsigned integer */
@@ -306,7 +313,7 @@ static void printSql(const char *zSql){
if( g.bExplain ) printf("EXPLAIN "); if( g.bExplain ) printf("EXPLAIN ");
printf("%.*s;\n", n, zSql); printf("%.*s;\n", n, zSql);
if( g.bExplain if( g.bExplain
#if SQLITE_VERSION_NUMBER>=3007010 #if SQLITE_VERSION_NUMBER>=3007017
&& ( sqlite3_strglob("CREATE *", zSql)==0 && ( sqlite3_strglob("CREATE *", zSql)==0
|| sqlite3_strglob("DROP *", zSql)==0 || sqlite3_strglob("DROP *", zSql)==0
|| sqlite3_strglob("ALTER *", zSql)==0 || sqlite3_strglob("ALTER *", zSql)==0
@@ -374,12 +381,15 @@ void speedtest1_run(void){
} }
} }
} }
#if SQLITE_VERSION_NUMBER>=3006001
if( g.bReprepare ){ if( g.bReprepare ){
sqlite3_stmt *pNew; sqlite3_stmt *pNew;
sqlite3_prepare_v2(g.db, sqlite3_sql(g.pStmt), -1, &pNew, 0); sqlite3_prepare_v2(g.db, sqlite3_sql(g.pStmt), -1, &pNew, 0);
sqlite3_finalize(g.pStmt); sqlite3_finalize(g.pStmt);
g.pStmt = pNew; g.pStmt = pNew;
}else{ }else
#endif
{
sqlite3_reset(g.pStmt); sqlite3_reset(g.pStmt);
} }
} }
@@ -1273,6 +1283,7 @@ int main(int argc, char **argv){
fatal_error(zHelp, argv[0]); fatal_error(zHelp, argv[0]);
} }
#endif #endif
#if SQLITE_VERSION_NUMBER>=3006001
if( nHeap>0 ){ if( nHeap>0 ){
pHeap = malloc( nHeap ); pHeap = malloc( nHeap );
if( pHeap==0 ) fatal_error("cannot allocate %d-byte heap\n", 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 ){ if( nLook>0 ){
sqlite3_config(SQLITE_CONFIG_LOOKASIDE, 0, 0); sqlite3_config(SQLITE_CONFIG_LOOKASIDE, 0, 0);
} }
#endif
/* Open the database and the input file */ /* Open the database and the input file */
if( sqlite3_open(zDbName, &g.db) ){ if( sqlite3_open(zDbName, &g.db) ){
fatal_error("Cannot open database file: %s\n", zDbName); fatal_error("Cannot open database file: %s\n", zDbName);
} }
#if SQLITE_VERSION_NUMBER>=3006001
if( nLook>0 && szLook>0 ){ if( nLook>0 && szLook>0 ){
pLook = malloc( nLook*szLook ); pLook = malloc( nLook*szLook );
rc = sqlite3_db_config(g.db, SQLITE_DBCONFIG_LOOKASIDE, pLook, szLook,nLook); rc = sqlite3_db_config(g.db, SQLITE_DBCONFIG_LOOKASIDE, pLook, szLook,nLook);
if( rc ) fatal_error("lookaside configuration failed: %d\n", rc); if( rc ) fatal_error("lookaside configuration failed: %d\n", rc);
} }
#endif
/* Set database connection options */ /* Set database connection options */
sqlite3_create_function(g.db, "random", 0, SQLITE_UTF8, 0, randomFunc, 0, 0); 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); sqlite3_close(g.db);
#if SQLITE_VERSION_NUMBER>=3006001
/* Global memory usage statistics printed after the database connection /* Global memory usage statistics printed after the database connection
** has closed. Memory usage should be zero at this point. */ ** has closed. Memory usage should be zero at this point. */
if( showStats ){ if( showStats ){
@@ -1407,6 +1422,7 @@ int main(int argc, char **argv){
sqlite3_status(SQLITE_STATUS_SCRATCH_SIZE, &iCur, &iHi, 0); sqlite3_status(SQLITE_STATUS_SCRATCH_SIZE, &iCur, &iHi, 0);
printf("-- Largest Scratch Allocation: %d bytes\n", iHi); printf("-- Largest Scratch Allocation: %d bytes\n", iHi);
} }
#endif
/* Release memory */ /* Release memory */
free( pLook ); free( pLook );

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 finish_test

View File

@@ -230,4 +230,41 @@ do_eqp_test 5.3.3 {
SELECT * FROM t1 WHERE likely(a=?) SELECT * FROM t1 WHERE likely(a=?)
} {0 0 0 {SCAN TABLE t1}} } {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 finish_test