Merge the latest trunk enhancements into the begin-concurrent branch.
FossilOrigin-Name: eedf6bed2abdaa8a245a4871f9455e3660a7dfeb3bd5f2631d3305cb41591aeb
This commit is contained in:
@@ -446,7 +446,7 @@ static void fts3SnippetDetails(
|
||||
}
|
||||
mCover |= mPhrase;
|
||||
|
||||
for(j=0; j<pPhrase->nToken; j++){
|
||||
for(j=0; j<pPhrase->nToken && j<pIter->nSnippet; j++){
|
||||
mHighlight |= (mPos>>j);
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -499,7 +499,7 @@ static void icuLoadCollation(
|
||||
{ "QUARTERNARY", UCOL_QUATERNARY },
|
||||
{ "IDENTICAL", UCOL_IDENTICAL },
|
||||
};
|
||||
int i;
|
||||
unsigned int i;
|
||||
for(i=0; i<sizeof(aStrength)/sizeof(aStrength[0]); i++){
|
||||
if( sqlite3_stricmp(zOption,aStrength[i].zName)==0 ){
|
||||
ucol_setStrength(pUCollator, aStrength[i].val);
|
||||
|
||||
+19
-5
@@ -494,6 +494,15 @@ static void dbdataValue(
|
||||
}
|
||||
}
|
||||
|
||||
/* This macro is a copy of the MX_CELL() macro in the SQLite core. Given
|
||||
** a page-size, it returns the maximum number of cells that may be present
|
||||
** on the page. */
|
||||
#define DBDATA_MX_CELL(pgsz) ((pgsz-8)/6)
|
||||
|
||||
/* Maximum number of fields that may appear in a single record. This is
|
||||
** the "hard-limit", according to comments in sqliteLimit.h. */
|
||||
#define DBDATA_MX_FIELD 32676
|
||||
|
||||
/*
|
||||
** Move an sqlite_dbdata or sqlite_dbptr cursor to the next entry.
|
||||
*/
|
||||
@@ -522,6 +531,9 @@ static int dbdataNext(sqlite3_vtab_cursor *pCursor){
|
||||
assert( iOff+3+2<=pCsr->nPage );
|
||||
pCsr->iCell = pTab->bPtr ? -2 : 0;
|
||||
pCsr->nCell = get_uint16(&pCsr->aPage[iOff+3]);
|
||||
if( pCsr->nCell>DBDATA_MX_CELL(pCsr->nPage) ){
|
||||
pCsr->nCell = DBDATA_MX_CELL(pCsr->nPage);
|
||||
}
|
||||
}
|
||||
|
||||
if( pTab->bPtr ){
|
||||
@@ -566,19 +578,19 @@ static int dbdataNext(sqlite3_vtab_cursor *pCursor){
|
||||
if( pCsr->iCell>=pCsr->nCell ){
|
||||
bNextPage = 1;
|
||||
}else{
|
||||
int iCellPtr = iOff + 8 + nPointer + pCsr->iCell*2;
|
||||
|
||||
iOff += 8 + nPointer + pCsr->iCell*2;
|
||||
if( iOff>pCsr->nPage ){
|
||||
if( iCellPtr>pCsr->nPage ){
|
||||
bNextPage = 1;
|
||||
}else{
|
||||
iOff = get_uint16(&pCsr->aPage[iOff]);
|
||||
iOff = get_uint16(&pCsr->aPage[iCellPtr]);
|
||||
}
|
||||
|
||||
/* For an interior node cell, skip past the child-page number */
|
||||
iOff += nPointer;
|
||||
|
||||
/* Load the "byte of payload including overflow" field */
|
||||
if( bNextPage || iOff>pCsr->nPage ){
|
||||
if( bNextPage || iOff>pCsr->nPage || iOff<=iCellPtr ){
|
||||
bNextPage = 1;
|
||||
}else{
|
||||
iOff += dbdataGetVarintU32(&pCsr->aPage[iOff], &nPayload);
|
||||
@@ -661,7 +673,9 @@ static int dbdataNext(sqlite3_vtab_cursor *pCursor){
|
||||
pCsr->iField++;
|
||||
if( pCsr->iField>0 ){
|
||||
sqlite3_int64 iType;
|
||||
if( pCsr->pHdrPtr>&pCsr->pRec[pCsr->nRec] ){
|
||||
if( pCsr->pHdrPtr>=&pCsr->pRec[pCsr->nRec]
|
||||
|| pCsr->iField>=DBDATA_MX_FIELD
|
||||
){
|
||||
bNextPage = 1;
|
||||
}else{
|
||||
int szField = 0;
|
||||
|
||||
@@ -524,5 +524,33 @@ do_test 7.1 {
|
||||
list [catch { $R finish } msg] $msg
|
||||
} {1 {file is not a database}}
|
||||
|
||||
reset_db
|
||||
breakpoint
|
||||
do_test 8.0 {
|
||||
sqlite3 db {}
|
||||
db deserialize [decode_hexdb {
|
||||
| size 8192 pagesize 4096 filename db.sqlite
|
||||
| page 1 offset 0
|
||||
| 0: ac ae b3 76 74 65 20 66 6f 72 6d 61 74 20 33 00 ...vte format 3.
|
||||
| 16: 10 00 01 01 00 40 20 20 00 00 00 01 00 00 00 02 .....@ ........
|
||||
| 32: 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 04 ................
|
||||
| 48: 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 ................
|
||||
| 80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 ................
|
||||
| 96: 00 2e 76 8a 0d ff ff ff 1e 0f cb 00 0f cb 00 00 ..v.............
|
||||
| 4032: 00 00 00 00 00 00 00 00 00 00 00 33 01 06 17 19 ...........3....
|
||||
| 4048: 19 01 43 74 61 62 6c 65 54 61 62 6c 65 30 54 61 ..CtableTable0Ta
|
||||
| 4064: 62 6c 65 30 02 43 52 45 41 54 45 20 54 41 42 4c ble0.CREATE TABL
|
||||
| 4080: 45 20 54 61 62 6c 65 30 20 28 43 6f 6c 30 20 29 E Table0 (Col0 )
|
||||
| page 2 offset 4096
|
||||
| 0: 0d 00 00 00 00 10 00 00 00 00 00 00 00 00 00 00 ................
|
||||
| end db.sqlite
|
||||
}]} {}
|
||||
|
||||
do_test 8.1 {
|
||||
set R [sqlite3_recover_init db main test.db2]
|
||||
catch { $R run }
|
||||
list [catch { $R finish } msg] $msg
|
||||
} {0 {}}
|
||||
|
||||
finish_test
|
||||
|
||||
|
||||
@@ -1189,7 +1189,7 @@ static int recoverWriteSchema1(sqlite3_recover *p){
|
||||
if( bTable && !bVirtual ){
|
||||
if( SQLITE_ROW==sqlite3_step(pTblname) ){
|
||||
const char *zTbl = (const char*)sqlite3_column_text(pTblname, 0);
|
||||
recoverAddTable(p, zTbl, iRoot);
|
||||
if( zTbl ) recoverAddTable(p, zTbl, iRoot);
|
||||
}
|
||||
recoverReset(p, pTblname);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
C Merge\sthe\slatest\strunk\senhancements\sinto\sthe\sbegin-concurrent\sbranch.
|
||||
D 2024-04-05T14:46:00.940
|
||||
D 2024-04-15T14:36:02.295
|
||||
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
||||
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
||||
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
|
||||
@@ -75,7 +75,7 @@ F ext/fts3/fts3_hash.c 8b6e31bfb0844c27dc6092c2620bdb1fca17ed613072db057d96952c6
|
||||
F ext/fts3/fts3_hash.h 39cf6874dc239d6b4e30479b1975fe5b22a3caaf
|
||||
F ext/fts3/fts3_icu.c 305ce7fb6036484085b5556a9c8e62acdc7763f0f4cdf5fd538212a9f3720116
|
||||
F ext/fts3/fts3_porter.c e19807ce0ae31c1c6e9898e89ecc93183d7ec224ea101af039722a4f49e5f2b8
|
||||
F ext/fts3/fts3_snippet.c 4d6523e3eddeb7b46e7a82b3476a0a86a0c04821e0e2b8dd40f45ee28057cb13
|
||||
F ext/fts3/fts3_snippet.c 610328fe128c047c6b0eba77768982ccf3933daae095d497949a75c9dfd47409
|
||||
F ext/fts3/fts3_term.c 845f0e2456b1be42f7f1bec1da1dfc05bc347531eff90775ffc6698902c281de
|
||||
F ext/fts3/fts3_test.c d8d7b2734f894e8a489987447658e374cdd3a3bc8575c401decf1911cb7c6454
|
||||
F ext/fts3/fts3_tokenize_vtab.c 7fd9ef364f257b97218b9c331f2378e307375c592f70fd541f714e747d944962
|
||||
@@ -249,7 +249,7 @@ F ext/fts5/tool/loadfts5.tcl 95b03429ee6b138645703c6ca192c3ac96eaf093
|
||||
F ext/fts5/tool/mkfts5c.tcl 3eba8e9bee4221ed165f3304b51b2a74a705f4ec5df3d044573a2be539534af8
|
||||
F ext/fts5/tool/showfts5.tcl d54da0e067306663e2d5d523965ca487698e722c
|
||||
F ext/icu/README.txt 7ab7ced8ae78e3a645b57e78570ff589d4c672b71370f5aa9e1cd7024f400fc9
|
||||
F ext/icu/icu.c 5c858611fd11d65caf8a04acd836af9193880a724ba75cee63f9da75ce4a469d
|
||||
F ext/icu/icu.c 3add8197e0a86c1761771a39500ebae749438bcf1836160b407a56b4eaa8721c
|
||||
F ext/icu/sqliteicu.h fa373836ed5a1ee7478bdf8a1650689294e41d0c89c1daab26e9ae78a32075a8
|
||||
F ext/intck/intck1.test f3a3cba14b6aeff145ffa5515546dd22f7510dad91512e519f43b92b56514012
|
||||
F ext/intck/intck2.test d2457c7e5e5b688046d15ebe08a1e1427cc5e7a6dc8d6af215f42e8bcaf67304
|
||||
@@ -479,13 +479,13 @@ F ext/rbu/rbuvacuum4.test ffccd22f67e2d0b380d2889685742159dfe0d19a3880ca3d2d1d69
|
||||
F ext/rbu/sqlite3rbu.c 4a3376c0fb9a844a799ac529fb81260523f6b13c9f629bc270c632dbae5fc1f8
|
||||
F ext/rbu/sqlite3rbu.h 9d923eb135c5d04aa6afd7c39ca47b0d1d0707c100e02f19fdde6a494e414304
|
||||
F ext/rbu/test_rbu.c ee6ede75147bc081fe9bc3931e6b206277418d14d3fbceea6fdc6216d9b47055
|
||||
F ext/recover/dbdata.c b7746c2ec801b453840831311be4b31f8c8f9dd97791060a69bbf12392c78949
|
||||
F ext/recover/dbdata.c d2e00d3cac74319c9c6def2e56ab2146b4f4ba5d820ab275e8da24e9766c247e
|
||||
F ext/recover/recover1.test c484d01502239f11b61f23c1cee9f5dd19fa17617f8974e42e74d64639c524cf
|
||||
F ext/recover/recover_common.tcl a61306c1eb45c0c3fc45652c35b2d4ec19729e340bdf65a272ce4c229cefd85a
|
||||
F ext/recover/recoverbuild.test c74170e0f7b02456af41838afeb5353fdb985a48cc2331d661bbabbca7c6b8e3
|
||||
F ext/recover/recoverclobber.test 3ba6c0c373c5c63d17e82eced64c05c57ccaf26c1abe1ca7141334022a79f32e
|
||||
F ext/recover/recovercorrupt.test 64c081ad1200ae77b447da99eb724785d6bf71715f394543dc7689642e92bf49
|
||||
F ext/recover/recovercorrupt2.test b9b974f006340a1300b5a7e687bd6097c5238498181c6f92d87406a77ece430b
|
||||
F ext/recover/recovercorrupt2.test 1418f1710debc24ff38276cedfcea234beb37a34205708e7e3e6d76cc4a979db
|
||||
F ext/recover/recoverfault.test 9d9f88eeb222615a25e7514f234c950d46bee20d24cd8db49d8fff8d650dcfe1
|
||||
F ext/recover/recoverfault2.test 730e7371bcda769554d15460cb23126abba1be8eca9539ccabf63623e7bb7e09
|
||||
F ext/recover/recoverold.test 68db3d6f85dd2b98e785b6c4da4f5eea4bbe52ccf6674d9a94c7506dc92596aa
|
||||
@@ -493,7 +493,7 @@ F ext/recover/recoverpgsz.test 3658ab8e68475b1bb87d6af88baa04551c84b73280a566a1b
|
||||
F ext/recover/recoverrowid.test f948bf4024a5f41b0e21b8af80c60564c5b5d78c05a8d64fc00787715ff9f45f
|
||||
F ext/recover/recoverslowidx.test 5205a9742dd9490ee99950dabb622307355ef1662dea6a3a21030057bfd81411
|
||||
F ext/recover/recoversql.test e66d01f95302a223bcd3fd42b5ee58dc2b53d70afa90b0d00e41e4b8eab20486
|
||||
F ext/recover/sqlite3recover.c e6eb20c469bcdb96f297f2241860bccabf9f036bfa7f3d47bcc6ca1191b108dc
|
||||
F ext/recover/sqlite3recover.c 65ef0f56301a16c0536c9839fb7e23540c9c4f75da0afe3b7b4d163c8f624404
|
||||
F ext/recover/sqlite3recover.h 011c799f02deb70ab685916f6f538e6bb32c4e0025e79bfd0e24ff9c74820959
|
||||
F ext/recover/test_recover.c fd871a40f2238022bedcbdf3cb493b91225edaa94d6ae8892af97a10e7ccc4ba
|
||||
F ext/repair/README.md 92f5e8aae749a4dae14f02eea8e1bb42d4db2b6ce5e83dbcdd6b1446997e0c15
|
||||
@@ -694,7 +694,7 @@ F src/auth.c 19b7ccacae3dfba23fc6f1d0af68134fa216e9040e53b0681b4715445ea030b4
|
||||
F src/backup.c 5c97e8023aab1ce14a42387eb3ae00ba5a0644569e3476f38661fa6f824c3523
|
||||
F src/bitvec.c 501daeef838fa82a9fb53540d72f29e3d9172c8867f1e19f94f681e2e20b966e
|
||||
F src/btmutex.c 79a43670447eacc651519a429f6ece9fd638563cf95b469d6891185ddae2b522
|
||||
F src/btree.c ea6f38398e28cc4ae70a0d55e94d14e61ddaa05705e40796c542aaf6e8ae0b6f
|
||||
F src/btree.c e841f070323b6c5fbc480b02cc3f5f2e9e27d3bf84bdf9bd16cf9550673ec683
|
||||
F src/btree.h bdeeb35614caa33526b603138f04c8d07a3f90a1300b5ade76848b755edf2027
|
||||
F src/btreeInt.h 8efd30e75e35a3c6a1c4dad7410d4ddfcd560f5f46401b208fa79eceef34525a
|
||||
F src/build.c c02fca1b600267120d1492f15a8301d48c59d37094c363eb5c12cca08d9133b8
|
||||
@@ -705,7 +705,7 @@ F src/date.c 126ba2ab10aeb2e7ba6e089b5f07b747c0625b8287f78b60da346eda8d23c875
|
||||
F src/dbpage.c 80e46e1df623ec40486da7a5086cb723b0275a6e2a7b01d9f9b5da0f04ba2782
|
||||
F src/dbstat.c 3b677254d512fcafd4d0b341bf267b38b235ccfddbef24f9154e19360fa22e43
|
||||
F src/delete.c cb766727c78e715f9fb7ec8a7d03658ed2a3016343ca687acfcec9083cdca500
|
||||
F src/expr.c cd46ce2ebe46a30e63087dbe8aff7d6e34ba8acc8c658e8e18fcaa35f2711391
|
||||
F src/expr.c 36071487e377356f1dd62e1e35870ed36a7212cb34ab1578b75d4a27ecdbfcb8
|
||||
F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007
|
||||
F src/fkey.c a47610f0a5c6cb0ad79f8fcef039c01833dec0c751bb695f28dc0ec6a4c3ba00
|
||||
F src/func.c a37134215de0da2744d99df69f4742c1e858a5734161b22d5a309b77cced3c6e
|
||||
@@ -714,7 +714,7 @@ F src/hash.c 9ee4269fb1d6632a6fecfb9479c93a1f29271bddbbaf215dd60420bcb80c7220
|
||||
F src/hash.h 3340ab6e1d13e725571d7cee6d3e3135f0779a7d8e76a9ce0a85971fa3953c51
|
||||
F src/hwtime.h f9c2dfb84dce7acf95ce6d289e46f5f9d3d1afd328e53da8f8e9008e3b3caae6
|
||||
F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71
|
||||
F src/insert.c bc4d172b52a6167cd28797397a464c2cca9607dc047dfa0b5cf61687962e6964
|
||||
F src/insert.c 4bd7c7e54a1062dcd0214b7a6296f7194eb10fb14d3ddca1ed20b01c2a86a18c
|
||||
F src/json.c e2e40760d6689134c3e2ece38c6a496b34ff5e2661a8f238444a119af666fdce
|
||||
F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa
|
||||
F src/loadext.c 7432c944ff197046d67a1207790a1b13eec4548c85a9457eb0896bb3641dfb36
|
||||
@@ -742,7 +742,7 @@ F src/os_setup.h 6011ad7af5db4e05155f385eb3a9b4470688de6f65d6166b8956e58a3d87210
|
||||
F src/os_unix.c a31c14ba25e87757809853f58d1573ff8cb422e3543093582e523809d96738e0
|
||||
F src/os_win.c 6ff43bac175bd9ed79e7c0f96840b139f2f51d01689a638fd05128becf94908a
|
||||
F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a
|
||||
F src/pager.c f7db1a855ce8fea25365fa47f0917cee693259d8c8eb2c8b06cf9bae15d7a1b5
|
||||
F src/pager.c f620722c6f5fbd0c36c9a5cec9a2a3463fb1841490bb2fd50ef756c09dd4d89e
|
||||
F src/pager.h e2df6b92e0402bc8d516016f361da82758b7d7769ef1a18e2abeadece18103e0
|
||||
F src/parse.y 08247e876d6508e7bcf624d48f4993f4051899e1e73400fe7da9de34af755a90
|
||||
F src/pcache.c 040b165f30622a21b7a9a77c6f2e4877a32fb7f22d4c7f0d2a6fa6833a156a75
|
||||
@@ -753,14 +753,14 @@ F src/pragma.h 6ebbdee90ed56a892d2c728e27fd9c1ce48c8a28841888d0c6c147946b38cb25
|
||||
F src/prepare.c 371f6115cb69286ebc12c6f2d7511279c2e47d9f54f475d46a554d687a3b312c
|
||||
F src/printf.c 87b67bba3662a0523f39ae6b084a3907109702f717c654d6cecb838af5cd57f1
|
||||
F src/random.c a3e70f8515721ff24d2c0e6afd83923e8faab5ab79ececea4c1bf9fe4049fbb2
|
||||
F src/resolve.c eb1860b134fb044fd819c4347105c148d5aac7c6498032be2829e5cc95619b28
|
||||
F src/resolve.c 6310bdfed32184cd3a5d6ba203dfee1ea323051cb38a6c2e80a5b79c069f4e87
|
||||
F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97
|
||||
F src/select.c 41e2d88aa372dd0dae4f8044cf128c2845b130d224da671e8fc6e33d94aaf161
|
||||
F src/select.c c7d2945000205580e6da1128b16fbd72af4aebd8f1c75f6d860b6a31eee66011
|
||||
F src/shell.c.in 0354ca51eee5fbf6af394a7ef9f5ef6823ef45b743db65431f6777e4d5be2199
|
||||
F src/sqlite.h.in 8fa422820b1226e7c67ff5ba1f81868c0a66e463b48a49933b8d069c2b82f103
|
||||
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
|
||||
F src/sqlite3ext.h 3f046c04ea3595d6bfda99b781926b17e672fd6d27da2ba6d8d8fc39981dcb54
|
||||
F src/sqliteInt.h 9198f2dcd1c145e657a8c01691942f20542a0b85cd4f0386b86ce28d37a83d84
|
||||
F src/sqliteInt.h 6a40d25c01675425584f8c3982b3312daa187c93a6224f9a86006bdc06ed1908
|
||||
F src/sqliteLimit.h 6878ab64bdeb8c24a1d762d45635e34b96da21132179023338c93f820eee6728
|
||||
F src/status.c cb11f8589a6912af2da3bb1ec509a94dd8ef27df4d4c1a97e0bcf2309ece972b
|
||||
F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1
|
||||
@@ -840,9 +840,9 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9
|
||||
F src/wal.c 7a63ccb09c364d941bee07c9e6f0d7f081679d6d21331e0b7fef2e7493a3e16e
|
||||
F src/wal.h e9aeb67102d9b9a0b089b80bd6136a16dd6360ac3daa731f2b71c6d4f8341717
|
||||
F src/walker.c 7c7ea0115345851c3da4e04e2e239a29983b61fb5b038b94eede6aba462640e2
|
||||
F src/where.c 9982128f010a699560fb5be37633801c7641ac3540f49db43cec878025929a0e
|
||||
F src/where.c 09253e913dc1a93aa6e0e1a5d25a392b8fa39096cc30d230dd302264b3be0661
|
||||
F src/whereInt.h 82a13766f13d1a53b05387c2e60726289ef26404bc7b9b1f7770204d97357fb8
|
||||
F src/wherecode.c 5d77db30a2a3dd532492ae882de114edba2fae672622056b1c7fd61f5917a8f1
|
||||
F src/wherecode.c e033875570f5d65b99fdb5189e597d91c8bc34f4196089fd50e6086d174035e7
|
||||
F src/whereexpr.c 7b64295f1d82ad0928df435925dd7bbd5997b44a026153113eace0d9e71ff435
|
||||
F src/window.c 5d95122dd330bfaebd732358c8ef067c5a9394a53ac249470d611d0ce2c52be2
|
||||
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
|
||||
@@ -1216,7 +1216,7 @@ F test/fts3rank.test cd99bc83a3c923c8d52afd90d86979cf05fc41849f892faeac3988055ef
|
||||
F test/fts3rnd.test 1320d8826a845e38a96e769562bf83d7a92a15d0
|
||||
F test/fts3shared.test 57e26a801f21027b7530da77db54286a6fe4997e
|
||||
F test/fts3snippet.test 0887196d67cffbe365edde535b95ecc642a532ce8551ccd9a73aab5999c3ffae
|
||||
F test/fts3snippet2.test e79afeb1f673713f96d7fc5655726081975399d11e659d15553207be43301dc4
|
||||
F test/fts3snippet2.test 03f6738ab3897bea2ba6be424a0613872e167acbf37a66200d655d737b470f65
|
||||
F test/fts3sort.test ed34c716a11cc2009a35210e84ad5f9c102362ca
|
||||
F test/fts3tok1.test a663f4cac22a9505400bc22aacb818d7055240409c28729669ea7d4cc2120d15
|
||||
F test/fts3tok_err.test 52273cd193b9036282f7bacb43da78c6be87418d
|
||||
@@ -1262,7 +1262,7 @@ F test/fuzz3.test 9c813e6613b837cb7a277b0383cd66bfa07042b4cf0317157c35852f30043c
|
||||
F test/fuzz4.test c229bcdb45518a89e1d208a21343e061503460ac69fae1539320a89f572eb634
|
||||
F test/fuzz_common.tcl b7197de6ed1ee8250a4f82d67876f4561b42ee8cbbfc6160dcb66331bad3f830
|
||||
F test/fuzz_malloc.test f348276e732e814802e39f042b1f6da6362a610af73a528d8f76898fde6b22f2
|
||||
F test/fuzzcheck.c e6a40f53ac5624aa5b7c4f31c385f09ba088d524cecc4512fd3057caeed8f530
|
||||
F test/fuzzcheck.c dc159967609d00b0cfe619e735cbbf8482570aca85711397034b0662b6c18fc7
|
||||
F test/fuzzdata1.db 3e86d9cf5aea68ddb8e27c02d7dfdaa226347426c7eb814918e4d95475bf8517
|
||||
F test/fuzzdata2.db 128b3feeb78918d075c9b14b48610145a0dd4c8d6f1ca7c2870c7e425f5bf31f
|
||||
F test/fuzzdata3.db c6586d3e3cef0fbc18108f9bb649aa77bfc38aba
|
||||
@@ -1274,7 +1274,7 @@ F test/fuzzdata8.db 4a53b6d077c6a5c23b609d8d3ac66996fa55ba3f8d02f9b6efdd0214a767
|
||||
F test/fuzzer1.test 3d4c4b7e547aba5e5511a2991e3e3d07166cfbb8
|
||||
F test/fuzzer2.test a85ef814ce071293bce1ad8dffa217cbbaad4c14
|
||||
F test/fuzzerfault.test f64c4aef4c9e9edf1d6dc0d3f1e65dcc81e67c996403c88d14f09b74807a42bc
|
||||
F test/fuzzinvariants.c 4355043e98cd8555c62462fcbba91c17c6492b0b017bbbe68656d5f2208f6444
|
||||
F test/fuzzinvariants.c 0729b9d8ed77ad0f8c5c7601168a707d5803087d2da030ede9057c51c809cc6c
|
||||
F test/gcfault.test 4ea410ac161e685f17b19e1f606f58514a2850e806c65b846d05f60d436c5b0d
|
||||
F test/gencol1.test e169bdfa11c7ed5e9f322a98a7db3afe9e66235750b68c923efee8e1876b46ec
|
||||
F test/genesis.tcl 1e2e2e8e5cc4058549a154ff1892fe5c9de19f98
|
||||
@@ -1526,7 +1526,7 @@ F test/printf.test 685fec5a0c5af2490ab0632775a301554361d674211d690f5bee0a97b0533
|
||||
F test/printf2.test 3f55c1871a5a65507416076f6eb97e738d5210aeda7595a74ee895f2224cce60
|
||||
F test/progress.test ebab27f670bd0d4eb9d20d49cef96e68141d92fb
|
||||
F test/ptrchng.test ef1aa72d6cf35a2bbd0869a649b744e9d84977fc
|
||||
F test/pushdown.test 1495a09837a1cedfc0adf07ba42dc6b83be05a2c15de331b67c39a0e22078238
|
||||
F test/pushdown.test 3330746a897ea271b1021bc1e7e57c6f8d49bcb8ca7d58a823d01aa64a303cc7
|
||||
F test/queryonly.test 5f653159e0f552f0552d43259890c1089391dcca
|
||||
F test/quick.test 1681febc928d686362d50057c642f77a02c62e57
|
||||
F test/quickcheck.test a4b7e878cd97e46108291c409b0bf8214f29e18fddd68a42bc5c1375ad1fb80a
|
||||
@@ -1545,7 +1545,7 @@ F test/regexp2.test 55ed41da802b0e284ac7e2fe944be3948f93ff25abbca0361a609acfed13
|
||||
F test/reindex.test cd9d6021729910ece82267b4f5e1b5ac2911a7566c43b43c176a6a4732e2118d
|
||||
F test/resetdb.test 54c06f18bc832ac6d6319e5ab23d5c8dd49fdbeec7c696d791682a8006bd5fc3
|
||||
F test/resolver01.test f4022acafda7f4d40eca94dbf16bc5fc4ac30ceb
|
||||
F test/returning1.test 3ead782eddf51f573cdd43bcbb10d1b485ac095a19a76d16c43fd159ea9b7466
|
||||
F test/returning1.test b27646c5e25431dd47cf72f525d1b2d5ad4ae14e21d9cf3d65769f05e48f64f3
|
||||
F test/returningfault.test ae4c4b5e8745813287a359d9ccdb9d5c883c2e68afb18fb0767937d5de5692a4
|
||||
F test/rollback.test 06680159bc6746d0f26276e339e3ae2f951c64812468308838e0a3362d911eaa
|
||||
F test/rollback2.test 3f3a4e20401825017df7e7671e9f31b6de5fae5620c2b9b49917f52f8c160a8f
|
||||
@@ -1706,7 +1706,7 @@ F test/temptable2.test 76821347810ecc88203e6ef0dd6897b6036ac788e9dd3e6b04fd4d163
|
||||
F test/temptable3.test d11a0974e52b347e45ee54ef1923c91ed91e4637
|
||||
F test/temptrigger.test 38f0ca479b1822d3117069e014daabcaacefffcc
|
||||
F test/tester.tcl fe617b88c7eb08bdf983d2aaa31c20fbf439eee7b8e0d61ca636fcd0c305bbbf
|
||||
F test/testrunner.tcl b48a8fc17e3b200244f53d60348afa7fe9482400d164e95709890743af9536d0
|
||||
F test/testrunner.tcl 1386667c04207d0a540ce1a9bc5ee0b734f7a3ba856c14a03943fb4f32de55bb
|
||||
F test/testrunner_data.tcl 3d36660cfd55ea5e20e661e8f94c0520feebcb437848f9b98b33c483cc479c0c
|
||||
F test/thread001.test a0985c117eab62c0c65526e9fa5d1360dd1cac5b03bde223902763274ce21899
|
||||
F test/thread002.test c24c83408e35ba5a952a3638b7ac03ccdf1ce4409289c54a050ac4c5f1de7502
|
||||
@@ -1923,7 +1923,7 @@ F test/upfrom2.test 66f3ebf721b3cebd922faee5c386bf244f816d416b57c000753ff51af623
|
||||
F test/upfrom3.test 6130f24ebf97f5ea865e5d2a14a2d543fe5428a62e87cc60f62d875e45c1f5f0
|
||||
F test/upfrom4.test 78f742a6577c91a7a55c64edb8811004e7c6aa99b8d57b2320f70a918c357807
|
||||
F test/upfromfault.test 3a10075a0043f0c4fad6614b2c371f88a8ba5a4acab68b907438413865d6a8d6
|
||||
F test/upsert1.test a512e2f884d3a36159fce2e45108c236f78ae38e35bda55f4050db580ceb25d3
|
||||
F test/upsert1.test beba4316fbd4b7b9d76784313f6129a548cfe7abea04d46db33e2efce1ab0ac2
|
||||
F test/upsert2.test 720e94d09f7362a282bc69b3c6b83d51daeaaf0440eb4920a08b86518b8c7496
|
||||
F test/upsert3.test 88d7d590a1948a9cb6eac1b54b0642f67a9f35a1fc0f19b200e97d5d39e3179c
|
||||
F test/upsert4.test 25d2a1da92f149331ae0c51ca6e3eee78189577585eab92de149900d62994fa5
|
||||
@@ -1933,7 +1933,7 @@ F test/uri.test c1abaaaa28e9422d61e5f3f9cbc8ef993ec49fe802f581520731708561d49384
|
||||
F test/uri2.test 9d3ba7a53ee167572d53a298ee4a5d38ec4a8fb7
|
||||
F test/userauth01.test e740a2697a7b40d7c5003a7d7edaee16acd349a9
|
||||
F test/utf16align.test 9fde0bb5d3a821594aa68c6829ab9c5453a084384137ebb9f6153e2d678039da
|
||||
F test/vacuum-into.test 35dc6f79b563f91c61822f61797363e97fed1bf28f1f722688b98d43f1980d76
|
||||
F test/vacuum-into.test 77845cee98770c416dae9b0da6bb3229753861f2da65c11b4f9715d081712d8a
|
||||
F test/vacuum.test ce91c39f7f91a4273bf620efad21086b5aa6ef1d
|
||||
F test/vacuum2.test 9fd45ce6ce29f5614c249e03938d3567c06a9e772d4f155949f8eafe2d8af520
|
||||
F test/vacuum3.test d9d9a04ee58c485b94694fd4f68cffaba49c32234fdefe1ac1a622c5e17d4ce3
|
||||
@@ -2201,8 +2201,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
|
||||
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
||||
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
||||
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
||||
P 9e6b64decb42dfebd3b882fd93f3bbfec11eca83b754514cc72c90616ca6f9dd 4484ec6d26b31305e31de89bdbae26344d8083a7e7de20861430d31737d9979c
|
||||
R 15624cf878e0a524616232dc95af170f
|
||||
P 4ff83342415db6c1a55f877481df77dbc671673ff46bd0afa1826481bb67380d b40580be719a129ecd1aa3c69d1086c967d063920fdd48617c864e73c059abc1
|
||||
R 30f8f8d6f74fe58524a5cb4796e1b64c
|
||||
U drh
|
||||
Z 0e6901fbd5cc5b4092f74129cd600369
|
||||
Z 7549b0a77b031bb2c3549bb86ed115b2
|
||||
# Remove this line to create a well-formed Fossil manifest.
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
4ff83342415db6c1a55f877481df77dbc671673ff46bd0afa1826481bb67380d
|
||||
eedf6bed2abdaa8a245a4871f9455e3660a7dfeb3bd5f2631d3305cb41591aeb
|
||||
+25
-14
@@ -5603,6 +5603,10 @@ static int accessPayload(
|
||||
memset(pCur->aOverflow, 0, nOvfl*sizeof(Pgno));
|
||||
pCur->curFlags |= BTCF_ValidOvfl;
|
||||
}else{
|
||||
/* Sanity check the validity of the overflow page cache */
|
||||
assert( pCur->aOverflow[0]==nextPage || pCur->aOverflow[0]==0 );
|
||||
assert( pCur->aOverflow[0]!=0 || pCur->aOverflow[offset/ovflSize]==0 );
|
||||
|
||||
/* If the overflow page-list cache has been allocated and the
|
||||
** entry for the first required overflow page is valid, skip
|
||||
** directly to it.
|
||||
@@ -6092,6 +6096,23 @@ int sqlite3BtreeFirst(BtCursor *pCur, int *pRes){
|
||||
return rc;
|
||||
}
|
||||
|
||||
#ifdef SQLITE_DEBUG
|
||||
/* The cursors is CURSOR_VALID and has BTCF_AtLast set. Verify that
|
||||
** this flags are true for a consistent database.
|
||||
**
|
||||
** This routine is is called from within assert() statements only.
|
||||
** It is an internal verification routine and does not appear in production
|
||||
** builds.
|
||||
*/
|
||||
static int cursorIsAtLastEntry(BtCursor *pCur){
|
||||
int ii;
|
||||
for(ii=0; ii<pCur->iPage; ii++){
|
||||
if( pCur->aiIdx[ii]!=pCur->apPage[ii]->nCell ) return 0;
|
||||
}
|
||||
return pCur->ix==pCur->pPage->nCell-1 && pCur->pPage->leaf!=0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Move the cursor to the last entry in the table. Return SQLITE_OK
|
||||
** on success. Set *pRes to 0 if the cursor actually points to something
|
||||
** or set *pRes to 1 if the table is empty.
|
||||
@@ -6120,18 +6141,7 @@ int sqlite3BtreeLast(BtCursor *pCur, int *pRes){
|
||||
|
||||
/* If the cursor already points to the last entry, this is a no-op. */
|
||||
if( CURSOR_VALID==pCur->eState && (pCur->curFlags & BTCF_AtLast)!=0 ){
|
||||
#ifdef SQLITE_DEBUG
|
||||
/* This block serves to assert() that the cursor really does point
|
||||
** to the last entry in the b-tree. */
|
||||
int ii;
|
||||
for(ii=0; ii<pCur->iPage; ii++){
|
||||
assert( pCur->aiIdx[ii]==pCur->apPage[ii]->nCell );
|
||||
}
|
||||
assert( pCur->ix==pCur->pPage->nCell-1 || CORRUPT_DB );
|
||||
testcase( pCur->ix!=pCur->pPage->nCell-1 );
|
||||
/* ^-- dbsqlfuzz b92b72e4de80b5140c30ab71372ca719b8feb618 */
|
||||
assert( pCur->pPage->leaf );
|
||||
#endif
|
||||
assert( cursorIsAtLastEntry(pCur) || CORRUPT_DB );
|
||||
*pRes = 0;
|
||||
return SQLITE_OK;
|
||||
}
|
||||
@@ -6184,6 +6194,7 @@ int sqlite3BtreeTableMoveto(
|
||||
}
|
||||
if( pCur->info.nKey<intKey ){
|
||||
if( (pCur->curFlags & BTCF_AtLast)!=0 ){
|
||||
assert( cursorIsAtLastEntry(pCur) || CORRUPT_DB );
|
||||
*pRes = -1;
|
||||
return SQLITE_OK;
|
||||
}
|
||||
@@ -10001,7 +10012,7 @@ int sqlite3BtreeInsert(
|
||||
}else if( loc<0 && pPage->nCell>0 ){
|
||||
assert( pPage->leaf );
|
||||
idx = ++pCur->ix;
|
||||
pCur->curFlags &= ~BTCF_ValidNKey;
|
||||
pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl);
|
||||
}else{
|
||||
assert( pPage->leaf );
|
||||
}
|
||||
@@ -10031,7 +10042,7 @@ int sqlite3BtreeInsert(
|
||||
*/
|
||||
if( pPage->nOverflow ){
|
||||
assert( rc==SQLITE_OK );
|
||||
pCur->curFlags &= ~(BTCF_ValidNKey);
|
||||
pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl);
|
||||
rc = balance(pCur);
|
||||
|
||||
/* Must make sure nOverflow is reset to zero even if the balance()
|
||||
|
||||
+50
-12
@@ -2500,7 +2500,7 @@ static int exprNodeIsConstant(Walker *pWalker, Expr *pExpr){
|
||||
return WRC_Continue;
|
||||
}
|
||||
}
|
||||
static int exprIsConst(Parse *pParse, Expr *p, int initFlag, int iCur){
|
||||
static int exprIsConst(Parse *pParse, Expr *p, int initFlag){
|
||||
Walker w;
|
||||
w.eCode = initFlag;
|
||||
w.pParse = pParse;
|
||||
@@ -2509,7 +2509,6 @@ static int exprIsConst(Parse *pParse, Expr *p, int initFlag, int iCur){
|
||||
#ifdef SQLITE_DEBUG
|
||||
w.xSelectCallback2 = sqlite3SelectWalkAssert2;
|
||||
#endif
|
||||
w.u.iCur = iCur;
|
||||
sqlite3WalkExpr(&w, p);
|
||||
return w.eCode;
|
||||
}
|
||||
@@ -2529,7 +2528,7 @@ static int exprIsConst(Parse *pParse, Expr *p, int initFlag, int iCur){
|
||||
** function and on its parameters.
|
||||
*/
|
||||
int sqlite3ExprIsConstant(Parse *pParse, Expr *p){
|
||||
return exprIsConst(pParse, p, 1, 0);
|
||||
return exprIsConst(pParse, p, 1);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -2546,7 +2545,23 @@ int sqlite3ExprIsConstant(Parse *pParse, Expr *p){
|
||||
** the prepared statement starts up. See sqlite3ExprCodeRunJustOnce().
|
||||
*/
|
||||
static int sqlite3ExprIsConstantNotJoin(Parse *pParse, Expr *p){
|
||||
return exprIsConst(pParse, p, 2, 0);
|
||||
return exprIsConst(pParse, p, 2);
|
||||
}
|
||||
|
||||
/*
|
||||
** This routine examines sub-SELECT statements as an expression is being
|
||||
** walked as part of sqlite3ExprIsTableConstant(). Sub-SELECTs are considered
|
||||
** constant as long as they are uncorrelated - meaning that they do not
|
||||
** contain any terms from outer contexts.
|
||||
*/
|
||||
static int exprSelectWalkTableConstant(Walker *pWalker, Select *pSelect){
|
||||
assert( pSelect!=0 );
|
||||
assert( pWalker->eCode==3 || pWalker->eCode==0 );
|
||||
if( (pSelect->selFlags & SF_Correlated)!=0 ){
|
||||
pWalker->eCode = 0;
|
||||
return WRC_Abort;
|
||||
}
|
||||
return WRC_Prune;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -2554,9 +2569,26 @@ static int sqlite3ExprIsConstantNotJoin(Parse *pParse, Expr *p){
|
||||
** for any single row of the table with cursor iCur. In other words, the
|
||||
** expression must not refer to any non-deterministic function nor any
|
||||
** table other than iCur.
|
||||
**
|
||||
** Consider uncorrelated subqueries to be constants if the bAllowSubq
|
||||
** parameter is true.
|
||||
*/
|
||||
int sqlite3ExprIsTableConstant(Expr *p, int iCur){
|
||||
return exprIsConst(0, p, 3, iCur);
|
||||
static int sqlite3ExprIsTableConstant(Expr *p, int iCur, int bAllowSubq){
|
||||
Walker w;
|
||||
w.eCode = 3;
|
||||
w.pParse = 0;
|
||||
w.xExprCallback = exprNodeIsConstant;
|
||||
if( bAllowSubq ){
|
||||
w.xSelectCallback = exprSelectWalkTableConstant;
|
||||
}else{
|
||||
w.xSelectCallback = sqlite3SelectWalkFail;
|
||||
#ifdef SQLITE_DEBUG
|
||||
w.xSelectCallback2 = sqlite3SelectWalkAssert2;
|
||||
#endif
|
||||
}
|
||||
w.u.iCur = iCur;
|
||||
sqlite3WalkExpr(&w, p);
|
||||
return w.eCode;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -2574,7 +2606,10 @@ int sqlite3ExprIsTableConstant(Expr *p, int iCur){
|
||||
**
|
||||
** (1) pExpr cannot refer to any table other than pSrc->iCursor.
|
||||
**
|
||||
** (2) pExpr cannot use subqueries or non-deterministic functions.
|
||||
** (2a) pExpr cannot use subqueries unless the bAllowSubq parameter is
|
||||
** true and the subquery is non-correlated
|
||||
**
|
||||
** (2b) pExpr cannot use non-deterministic functions.
|
||||
**
|
||||
** (3) pSrc cannot be part of the left operand for a RIGHT JOIN.
|
||||
** (Is there some way to relax this constraint?)
|
||||
@@ -2603,7 +2638,8 @@ int sqlite3ExprIsTableConstant(Expr *p, int iCur){
|
||||
int sqlite3ExprIsSingleTableConstraint(
|
||||
Expr *pExpr, /* The constraint */
|
||||
const SrcList *pSrcList, /* Complete FROM clause */
|
||||
int iSrc /* Which element of pSrcList to use */
|
||||
int iSrc, /* Which element of pSrcList to use */
|
||||
int bAllowSubq /* Allow non-correlated subqueries */
|
||||
){
|
||||
const SrcItem *pSrc = &pSrcList->a[iSrc];
|
||||
if( pSrc->fg.jointype & JT_LTORJ ){
|
||||
@@ -2628,7 +2664,8 @@ int sqlite3ExprIsSingleTableConstraint(
|
||||
}
|
||||
}
|
||||
}
|
||||
return sqlite3ExprIsTableConstant(pExpr, pSrc->iCursor); /* rules (1), (2) */
|
||||
/* Rules (1), (2a), and (2b) handled by the following: */
|
||||
return sqlite3ExprIsTableConstant(pExpr, pSrc->iCursor, bAllowSubq);
|
||||
}
|
||||
|
||||
|
||||
@@ -2713,7 +2750,7 @@ int sqlite3ExprIsConstantOrGroupBy(Parse *pParse, Expr *p, ExprList *pGroupBy){
|
||||
*/
|
||||
int sqlite3ExprIsConstantOrFunction(Expr *p, u8 isInit){
|
||||
assert( isInit==0 || isInit==1 );
|
||||
return exprIsConst(0, p, 4+isInit, 0);
|
||||
return exprIsConst(0, p, 4+isInit);
|
||||
}
|
||||
|
||||
#ifdef SQLITE_ENABLE_CURSOR_HINTS
|
||||
@@ -5031,8 +5068,9 @@ expr_code_doover:
|
||||
if( !ExprHasProperty(pExpr, EP_Collate) ){
|
||||
/* A TK_COLLATE Expr node without the EP_Collate tag is a so-called
|
||||
** "SOFT-COLLATE" that is added to constraints that are pushed down
|
||||
** from outer queries into sub-queries by the push-down optimization.
|
||||
** Clear subtypes as subtypes may not cross a subquery boundary.
|
||||
** from outer queries into sub-queries by the WHERE-clause push-down
|
||||
** optimization. Clear subtypes as subtypes may not cross a subquery
|
||||
** boundary.
|
||||
*/
|
||||
assert( pExpr->pLeft );
|
||||
sqlite3ExprCode(pParse, pExpr->pLeft, target);
|
||||
|
||||
+4
-1
@@ -3182,7 +3182,10 @@ static int xferOptimization(
|
||||
}
|
||||
}
|
||||
#ifndef SQLITE_OMIT_CHECK
|
||||
if( pDest->pCheck && sqlite3ExprListCompare(pSrc->pCheck,pDest->pCheck,-1) ){
|
||||
if( pDest->pCheck
|
||||
&& (db->mDbFlags & DBFLAG_Vacuum)==0
|
||||
&& sqlite3ExprListCompare(pSrc->pCheck,pDest->pCheck,-1)
|
||||
){
|
||||
return 0; /* Tables have different CHECK constraints. Ticket #2252 */
|
||||
}
|
||||
#endif
|
||||
|
||||
+1
-1
@@ -7261,7 +7261,7 @@ sqlite3_file *sqlite3PagerFile(Pager *pPager){
|
||||
** This will be either the rollback journal or the WAL file.
|
||||
*/
|
||||
sqlite3_file *sqlite3PagerJrnlFile(Pager *pPager){
|
||||
#if SQLITE_OMIT_WAL
|
||||
#ifdef SQLITE_OMIT_WAL
|
||||
return pPager->jfd;
|
||||
#else
|
||||
return pPager->pWal ? sqlite3WalFile(pPager->pWal) : pPager->jfd;
|
||||
|
||||
@@ -632,6 +632,11 @@ static int lookupName(
|
||||
&& ALWAYS(VisibleRowid(pMatch->pTab) || pMatch->fg.isNestedFrom)
|
||||
){
|
||||
cnt = cntTab;
|
||||
#if SQLITE_ALLOW_ROWID_IN_VIEW+0==2
|
||||
if( pMatch->pTab!=0 && IsView(pMatch->pTab) ){
|
||||
eNewExprOp = TK_NULL;
|
||||
}
|
||||
#endif
|
||||
if( pMatch->fg.isNestedFrom==0 ) pExpr->iColumn = -1;
|
||||
pExpr->affExpr = SQLITE_AFF_INTEGER;
|
||||
}
|
||||
@@ -1349,6 +1354,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
|
||||
testcase( pNC->ncFlags & NC_PartIdx );
|
||||
testcase( pNC->ncFlags & NC_IdxExpr );
|
||||
testcase( pNC->ncFlags & NC_GenCol );
|
||||
assert( pExpr->x.pSelect );
|
||||
if( pNC->ncFlags & NC_SelfRef ){
|
||||
notValidImpl(pParse, pNC, "subqueries", pExpr, pExpr);
|
||||
}else{
|
||||
@@ -1357,6 +1363,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
|
||||
assert( pNC->nRef>=nRef );
|
||||
if( nRef!=pNC->nRef ){
|
||||
ExprSetProperty(pExpr, EP_VarSelect);
|
||||
pExpr->x.pSelect->selFlags |= SF_Correlated;
|
||||
}
|
||||
pNC->ncFlags |= NC_Subquery;
|
||||
}
|
||||
|
||||
+18
-6
@@ -5060,6 +5060,18 @@ static int pushDownWindowCheck(Parse *pParse, Select *pSubq, Expr *pExpr){
|
||||
** The hope is that the terms added to the inner query will make it more
|
||||
** efficient.
|
||||
**
|
||||
** NAME AMBIGUITY
|
||||
**
|
||||
** This optimization is called the "WHERE-clause push-down optimization".
|
||||
**
|
||||
** Do not confuse this optimization with another unrelated optimization
|
||||
** with a similar name: The "MySQL push-down optimization" causes WHERE
|
||||
** clause terms that can be evaluated using only the index and without
|
||||
** reference to the table are run first, so that if they are false,
|
||||
** unnecessary table seeks are avoided.
|
||||
**
|
||||
** RULES
|
||||
**
|
||||
** Do not attempt this optimization if:
|
||||
**
|
||||
** (1) (** This restriction was removed on 2017-09-29. We used to
|
||||
@@ -5125,10 +5137,10 @@ static int pushDownWindowCheck(Parse *pParse, Select *pSubq, Expr *pExpr){
|
||||
** (9c) There is a RIGHT JOIN (or FULL JOIN) in between the ON/USING
|
||||
** clause and the subquery.
|
||||
**
|
||||
** Without this restriction, the push-down optimization might move
|
||||
** the ON/USING filter expression from the left side of a RIGHT JOIN
|
||||
** over to the right side, which leads to incorrect answers. See
|
||||
** also restriction (6) in sqlite3ExprIsSingleTableConstraint().
|
||||
** Without this restriction, the WHERE-clause push-down optimization
|
||||
** might move the ON/USING filter expression from the left side of a
|
||||
** RIGHT JOIN over to the right side, which leads to incorrect answers.
|
||||
** See also restriction (6) in sqlite3ExprIsSingleTableConstraint().
|
||||
**
|
||||
** (10) The inner query is not the right-hand table of a RIGHT JOIN.
|
||||
**
|
||||
@@ -5260,7 +5272,7 @@ static int pushDownWhereTerms(
|
||||
}
|
||||
#endif
|
||||
|
||||
if( sqlite3ExprIsSingleTableConstraint(pWhere, pSrcList, iSrc) ){
|
||||
if( sqlite3ExprIsSingleTableConstraint(pWhere, pSrcList, iSrc, 1) ){
|
||||
nChng++;
|
||||
pSubq->selFlags |= SF_PushDown;
|
||||
while( pSubq ){
|
||||
@@ -7689,7 +7701,7 @@ int sqlite3Select(
|
||||
#endif
|
||||
assert( pItem->pSelect && (pItem->pSelect->selFlags & SF_PushDown)!=0 );
|
||||
}else{
|
||||
TREETRACE(0x4000,pParse,p,("Push-down not possible\n"));
|
||||
TREETRACE(0x4000,pParse,p,("WHERE-lcause push-down not possible\n"));
|
||||
}
|
||||
|
||||
/* Convert unused result columns of the subquery into simple NULL
|
||||
|
||||
+4
-4
@@ -1927,7 +1927,7 @@ struct sqlite3 {
|
||||
#define SQLITE_CursorHints 0x00000400 /* Add OP_CursorHint opcodes */
|
||||
#define SQLITE_Stat4 0x00000800 /* Use STAT4 data */
|
||||
/* TH3 expects this value ^^^^^^^^^^ to be 0x0000800. Don't change it */
|
||||
#define SQLITE_PushDown 0x00001000 /* The push-down optimization */
|
||||
#define SQLITE_PushDown 0x00001000 /* WHERE-clause push-down opt */
|
||||
#define SQLITE_SimplifyJoin 0x00002000 /* Convert LEFT JOIN to JOIN */
|
||||
#define SQLITE_SkipScan 0x00004000 /* Skip-scans */
|
||||
#define SQLITE_PropagateConst 0x00008000 /* The constant propagation opt */
|
||||
@@ -3601,11 +3601,12 @@ struct Select {
|
||||
#define SF_View 0x0200000 /* SELECT statement is a view */
|
||||
#define SF_NoopOrderBy 0x0400000 /* ORDER BY is ignored for this query */
|
||||
#define SF_UFSrcCheck 0x0800000 /* Check pSrc as required by UPDATE...FROM */
|
||||
#define SF_PushDown 0x1000000 /* SELECT has be modified by push-down opt */
|
||||
#define SF_PushDown 0x1000000 /* Modified by WHERE-clause push-down opt */
|
||||
#define SF_MultiPart 0x2000000 /* Has multiple incompatible PARTITIONs */
|
||||
#define SF_CopyCte 0x4000000 /* SELECT statement is a copy of a CTE */
|
||||
#define SF_OrderByReqd 0x8000000 /* The ORDER BY clause may not be omitted */
|
||||
#define SF_UpdateFrom 0x10000000 /* Query originates with UPDATE FROM */
|
||||
#define SF_Correlated 0x20000000 /* True if references the outer context */
|
||||
|
||||
/* True if S exists and has SF_NestedFrom */
|
||||
#define IsNestedFrom(S) ((S)!=0 && ((S)->selFlags&SF_NestedFrom)!=0)
|
||||
@@ -5104,8 +5105,7 @@ int sqlite3ExprTruthValue(const Expr*);
|
||||
int sqlite3ExprIsConstant(Parse*,Expr*);
|
||||
int sqlite3ExprIsConstantOrFunction(Expr*, u8);
|
||||
int sqlite3ExprIsConstantOrGroupBy(Parse*, Expr*, ExprList*);
|
||||
int sqlite3ExprIsTableConstant(Expr*,int);
|
||||
int sqlite3ExprIsSingleTableConstraint(Expr*,const SrcList*,int);
|
||||
int sqlite3ExprIsSingleTableConstraint(Expr*,const SrcList*,int,int);
|
||||
#ifdef SQLITE_ENABLE_CURSOR_HINTS
|
||||
int sqlite3ExprContainsSubquery(Expr*);
|
||||
#endif
|
||||
|
||||
+2
-2
@@ -942,7 +942,7 @@ static SQLITE_NOINLINE void constructAutomaticIndex(
|
||||
** WHERE clause (or the ON clause of a LEFT join) that constrain which
|
||||
** rows of the target table (pSrc) that can be used. */
|
||||
if( (pTerm->wtFlags & TERM_VIRTUAL)==0
|
||||
&& sqlite3ExprIsSingleTableConstraint(pExpr, pTabList, pLevel->iFrom)
|
||||
&& sqlite3ExprIsSingleTableConstraint(pExpr, pTabList, pLevel->iFrom, 0)
|
||||
){
|
||||
pPartial = sqlite3ExprAnd(pParse, pPartial,
|
||||
sqlite3ExprDup(pParse->db, pExpr, 0));
|
||||
@@ -1211,7 +1211,7 @@ static SQLITE_NOINLINE void sqlite3ConstructBloomFilter(
|
||||
for(pTerm=pWInfo->sWC.a; pTerm<pWCEnd; pTerm++){
|
||||
Expr *pExpr = pTerm->pExpr;
|
||||
if( (pTerm->wtFlags & TERM_VIRTUAL)==0
|
||||
&& sqlite3ExprIsSingleTableConstraint(pExpr, pTabList, iSrc)
|
||||
&& sqlite3ExprIsSingleTableConstraint(pExpr, pTabList, iSrc, 0)
|
||||
){
|
||||
sqlite3ExprIfFalse(pParse, pTerm->pExpr, addrCont, SQLITE_JUMPIFNULL);
|
||||
}
|
||||
|
||||
@@ -2474,6 +2474,12 @@ Bitmask sqlite3WhereCodeOneLoopStart(
|
||||
** iLoop==3: Code all remaining expressions.
|
||||
**
|
||||
** An effort is made to skip unnecessary iterations of the loop.
|
||||
**
|
||||
** This optimization of causing simple query restrictions to occur before
|
||||
** more complex one is call the "push-down" optimization in MySQL. Here
|
||||
** in SQLite, the name is "MySQL push-down", since there is also another
|
||||
** totally unrelated optimization called "WHERE-clause push-down".
|
||||
** Sometimes the qualifier is omitted, resulting in an ambiguity, so beware.
|
||||
*/
|
||||
iLoop = (pIdx ? 1 : 2);
|
||||
do{
|
||||
|
||||
@@ -55,5 +55,16 @@ do_execsql_test 2.2 {
|
||||
'(def AND (one NEAR abc)) OR one'
|
||||
} {<b>one</b>}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
|
||||
do_execsql_test 3.0 {
|
||||
CREATE VIRTUAL TABLE f USING fts3(a,b);
|
||||
INSERT INTO f VALUES (101,x'056522650565056505650d051e056505650565286505650565056505056505650565056505650565056505650565056505650565056505656505650565056505650d05650505656505650565ef65056505844c746e65650565056505650565056505650565056505650565058405800565056505650565056505651e650565056505650565056505650d056505056565056505650565056505840580056505650565056f05650565056505650565056505650565050565056505640565056505650565056505651e05650565056505650565056505650505656565056505650565056505651e0565056505650565056505650565052265056505650569056505650565056505650565056505650565056505650500406505650565056505650565056505000101e5c501014b010101c501c5c501010101f5010201010101014101017373737373737373737373737373737373737373737373737373737330737373737373737373737373737365056505650d051e05650565056528056505650d05650505656505650565650565056505650565056505e505650565056505656505650565056505650d05650505656505650565ef65056505844c746e65650565056505650565056505650565056505650565058405800565056505650565056505651e650565056505650565056505650d056505056565056505650565056505840580056505650565286505c705650565050565059494949494949494949494949494949494949494949494949494949494949494949494650565056505650565056505650565056505650565056505656505650565056505650d05650505656505650565ef650565058405056505650565056505650565056505650565056505650565058405800565056505650565056505651e650565056505650565056505650d056505056565056505650565056505840580056505650565056505650565056505650505650565056505650565056505650565056500000000000000000000000000000000000000000000000000000000000000000565056505656505650565056505650d056500000000000000000000000000000000000000000000000000000000000000000100000000000000ed0000000000ffffffffffffffffffffff0007ffffff0001c5c50001c5c50001c5c50001c5c50001c5c50001c5c50001e5c50001c5c50001c5c50001c5c50001c5c50001c5c5000100000014720000000000000016dac5c50001c5c50001c5c50001c5c50001c5c50001c5c50d0505656505650565ef650565058405056505650565056505650565056505650565056505650565058405800465056505650565056505651e650565056505650565056505650d05650505656505650565050565650584058005650565056505650565056505650565056522650565056505650d051e056505650561286505c70565056505056505650565056505650565056505650565056505650565056505656505650565056505650d05650505656505650565ef650565058405056505650565056505650565056505650565056505650565058405800565056505650565056505651e650565056505650565056505650d056505056565056505650565056505840580056505650565056505650565056505650565226505737373737373737373737373737373737373737373737373737373737373737373737373737373737373737373737373733a73737373737373737373737373737373737373737373737373737373737373737373737373737373737c7373737365056505650d051e05650565056528650565056505650505650565056505650565056505650565056505e505650565056505656505650565056505650d05650505656505650565ef65056505');
|
||||
}
|
||||
|
||||
do_execsql_test 3.1 {
|
||||
SELECT length(snippet(f)) FROM f WHERE b MATCH x'0565056505650565056505650565056505650565058405800565056505650565056505651e650565056505650565056505650d056505056565056505650565056505840580056505650565056505650565056505650565056505650565050565056505640565056505650565056505651e05650565056522650565056505650d051e056505650565286505650565056505056505650565056505650565056505650565056505650565056505656505650565056505650d05650505656505650565ef65056505844c746e65650565056505650565056505650565056505650565058405800565056505650565056505651e650565056505650565056505650d056505056565056505650565056505840580056505650565056f05650565056505650565056505650565050565056505640565056505650565056505651e05650565056505650565056505650505656565056505650565056505651e0565056505650565056505650565052265056505650569056505650565056505650565056505650565056505650500406505650565056505650565056505000101e5c501014b010101c501c5c501010101f50102010101010141010141010001017bf15905000000000017';
|
||||
} {192}
|
||||
|
||||
set sqlite_fts3_enable_parentheses 0
|
||||
finish_test
|
||||
|
||||
+11
-5
@@ -979,7 +979,8 @@ extern int fuzz_invariant(
|
||||
int iRow, /* The row number for pStmt */
|
||||
int nRow, /* Total number of output rows */
|
||||
int *pbCorrupt, /* IN/OUT: Flag indicating a corrupt database file */
|
||||
int eVerbosity /* How much debugging output */
|
||||
int eVerbosity, /* How much debugging output */
|
||||
unsigned int dbOpt /* Default optimization flags */
|
||||
);
|
||||
|
||||
/* Implementation of sqlite_dbdata and sqlite_dbptr */
|
||||
@@ -1031,7 +1032,12 @@ static int recoverDatabase(sqlite3 *db){
|
||||
/*
|
||||
** Run the SQL text
|
||||
*/
|
||||
static int runDbSql(sqlite3 *db, const char *zSql, unsigned int *pBtsFlags){
|
||||
static int runDbSql(
|
||||
sqlite3 *db, /* Run SQL on this database connection */
|
||||
const char *zSql, /* The SQL to be run */
|
||||
unsigned int *pBtsFlags,
|
||||
unsigned int dbOpt /* Default optimization flags */
|
||||
){
|
||||
int rc;
|
||||
sqlite3_stmt *pStmt;
|
||||
int bCorrupt = 0;
|
||||
@@ -1107,7 +1113,7 @@ static int runDbSql(sqlite3 *db, const char *zSql, unsigned int *pBtsFlags){
|
||||
iRow++;
|
||||
for(iCnt=0; iCnt<99999; iCnt++){
|
||||
rc = fuzz_invariant(db, pStmt, iCnt, iRow, nRow,
|
||||
&bCorrupt, eVerbosity);
|
||||
&bCorrupt, eVerbosity, dbOpt);
|
||||
if( rc==SQLITE_DONE ) break;
|
||||
if( rc!=SQLITE_ERROR ) g.nInvariant++;
|
||||
if( eVerbosity>0 ){
|
||||
@@ -1330,7 +1336,7 @@ int runCombinedDbSqlInput(
|
||||
char cSaved = zSql[i+1];
|
||||
zSql[i+1] = 0;
|
||||
if( sqlite3_complete(zSql+j) ){
|
||||
rc = runDbSql(cx.db, zSql+j, &btsFlags);
|
||||
rc = runDbSql(cx.db, zSql+j, &btsFlags, dbOpt);
|
||||
j = i+1;
|
||||
}
|
||||
zSql[i+1] = cSaved;
|
||||
@@ -1340,7 +1346,7 @@ int runCombinedDbSqlInput(
|
||||
}
|
||||
}
|
||||
if( j<i ){
|
||||
runDbSql(cx.db, zSql+j, &btsFlags);
|
||||
runDbSql(cx.db, zSql+j, &btsFlags, dbOpt);
|
||||
}
|
||||
}
|
||||
testrun_finished:
|
||||
|
||||
+24
-15
@@ -30,7 +30,13 @@
|
||||
/* Forward references */
|
||||
static char *fuzz_invariant_sql(sqlite3_stmt*, int);
|
||||
static int sameValue(sqlite3_stmt*,int,sqlite3_stmt*,int,sqlite3_stmt*);
|
||||
static void reportInvariantFailed(sqlite3_stmt*,sqlite3_stmt*,int);
|
||||
static void reportInvariantFailed(
|
||||
sqlite3_stmt *pOrig, /* The original query */
|
||||
sqlite3_stmt *pTest, /* The alternative test query with a missing row */
|
||||
int iRow, /* Row number in pOrig */
|
||||
unsigned int dbOpt, /* Optimization flags on pOrig */
|
||||
int noOpt /* True if opt flags inverted for pTest */
|
||||
);
|
||||
|
||||
/*
|
||||
** Do an invariant check on pStmt. iCnt determines which invariant check to
|
||||
@@ -68,7 +74,8 @@ int fuzz_invariant(
|
||||
int iRow, /* Current row number */
|
||||
int nRow, /* Number of output rows from pStmt */
|
||||
int *pbCorrupt, /* IN/OUT: Flag indicating a corrupt database file */
|
||||
int eVerbosity /* How much debugging output */
|
||||
int eVerbosity, /* How much debugging output */
|
||||
unsigned int dbOpt /* Default optimization flags */
|
||||
){
|
||||
char *zTest;
|
||||
sqlite3_stmt *pTestStmt = 0;
|
||||
@@ -76,13 +83,20 @@ int fuzz_invariant(
|
||||
int i;
|
||||
int nCol;
|
||||
int nParam;
|
||||
int noOpt = (iCnt%3)==0;
|
||||
|
||||
if( *pbCorrupt ) return SQLITE_DONE;
|
||||
nParam = sqlite3_bind_parameter_count(pStmt);
|
||||
if( nParam>100 ) return SQLITE_DONE;
|
||||
zTest = fuzz_invariant_sql(pStmt, iCnt);
|
||||
if( zTest==0 ) return SQLITE_DONE;
|
||||
if( noOpt ){
|
||||
sqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS, db, ~dbOpt);
|
||||
}
|
||||
rc = sqlite3_prepare_v2(db, zTest, -1, &pTestStmt, 0);
|
||||
if( noOpt ){
|
||||
sqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS, db, dbOpt);
|
||||
}
|
||||
if( rc ){
|
||||
if( eVerbosity ){
|
||||
printf("invariant compile failed: %s\n%s\n",
|
||||
@@ -212,7 +226,7 @@ int fuzz_invariant(
|
||||
}
|
||||
sqlite3_finalize(pCk);
|
||||
if( rc==SQLITE_DONE ){
|
||||
reportInvariantFailed(pStmt, pTestStmt, iRow);
|
||||
reportInvariantFailed(pStmt, pTestStmt, iRow, dbOpt, noOpt);
|
||||
return SQLITE_INTERNAL;
|
||||
}else if( eVerbosity>0 ){
|
||||
printf("invariant-error ignored due to the use of virtual tables\n");
|
||||
@@ -223,7 +237,6 @@ not_a_fault:
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Generate SQL used to test a statement invariant.
|
||||
**
|
||||
@@ -296,14 +309,6 @@ static char *fuzz_invariant_sql(sqlite3_stmt *pStmt, int iCnt){
|
||||
** WHERE clause. */
|
||||
continue;
|
||||
}
|
||||
#ifdef SQLITE_ALLOW_ROWID_IN_VIEW
|
||||
if( sqlite3_strlike("%rowid%",zColName,0)==0
|
||||
|| sqlite3_strlike("%oid%",zColName,0)==0
|
||||
){
|
||||
/* ROWID values are unreliable if SQLITE_ALLOW_ROWID_IN_VIEW is used */
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
for(j=0; j<i; j++){
|
||||
const char *zPrior = sqlite3_column_name(pBase, j);
|
||||
if( sqlite3_stricmp(zPrior, zColName)==0 ) break;
|
||||
@@ -497,13 +502,17 @@ static void printRow(sqlite3_stmt *pStmt, int iRow){
|
||||
static void reportInvariantFailed(
|
||||
sqlite3_stmt *pOrig, /* The original query */
|
||||
sqlite3_stmt *pTest, /* The alternative test query with a missing row */
|
||||
int iRow /* Row number in pOrig */
|
||||
int iRow, /* Row number in pOrig */
|
||||
unsigned int dbOpt, /* Optimization flags on pOrig */
|
||||
int noOpt /* True if opt flags inverted for pTest */
|
||||
){
|
||||
int iTestRow = 0;
|
||||
printf("Invariant check failed on row %d.\n", iRow);
|
||||
printf("Original query --------------------------------------------------\n");
|
||||
printf("Original query (opt-flags: 0x%08x) --------------------------\n",
|
||||
dbOpt);
|
||||
printf("%s\n", sqlite3_expanded_sql(pOrig));
|
||||
printf("Alternative query -----------------------------------------------\n");
|
||||
printf("Alternative query (opt-flags: 0x%08x) -----------------------\n",
|
||||
noOpt ? ~dbOpt : dbOpt);
|
||||
printf("%s\n", sqlite3_expanded_sql(pTest));
|
||||
printf("Result row that is missing from the alternative -----------------\n");
|
||||
printRow(pOrig, iRow);
|
||||
|
||||
+109
-4
@@ -1,4 +1,4 @@
|
||||
# 2017 April 29
|
||||
# 2017-04-29
|
||||
#
|
||||
# The author disclaims copyright to this source code. In place of
|
||||
# a legal notice, here is a blessing:
|
||||
@@ -8,6 +8,26 @@
|
||||
# May you share freely, never taking more than you give.
|
||||
#
|
||||
#***********************************************************************
|
||||
#
|
||||
# Test cases for the push-down optimizations.
|
||||
#
|
||||
#
|
||||
# There are two different meanings for "push-down optimization".
|
||||
#
|
||||
# (1) "MySQL push-down" means that WHERE clause terms that can be
|
||||
# evaluated using only the index and without reference to the
|
||||
# table are run first, so that if they are false, unnecessary table
|
||||
# seeks are avoided. See https://sqlite.org/src/info/d7bb79ed3a40419d
|
||||
# from 2017-04-29.
|
||||
#
|
||||
# (2) "WHERE-clause pushdown" means to push WHERE clause terms in
|
||||
# outer queries down into subqueries. See
|
||||
# https://sqlite.org/src/info/6df18e949d367629 from 2015-06-02.
|
||||
#
|
||||
# This module started out as tests for MySQL push-down only. But because
|
||||
# of naming ambiguity, it has picked up test cases for WHERE-clause push-down
|
||||
# over the years.
|
||||
#
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
@@ -87,8 +107,8 @@ do_test 2.2 {
|
||||
} {three}
|
||||
|
||||
# 2022-11-25 dbsqlfuzz crash-3a548de406a50e896c1bf7142692d35d339d697f
|
||||
# Disable the push-down optimization for compound subqueries if any
|
||||
# arm of the compound has an incompatible affinity.
|
||||
# Disable the WHERE-clause push-down optimization for compound subqueries
|
||||
# if any arm of the compound has an incompatible affinity.
|
||||
#
|
||||
reset_db
|
||||
do_execsql_test 3.1 {
|
||||
@@ -185,7 +205,7 @@ do_eqp_test 3.8 {
|
||||
# SELECT (SELECT count(*) FROM t1)+(SELECT count(*) FROM t2)
|
||||
|
||||
# 2023-05-09 https://sqlite.org/forum/forumpost/a7d4be7fb6
|
||||
# Restriction (9) on the push-down optimization.
|
||||
# Restriction (9) on the WHERE-clause push-down optimization.
|
||||
#
|
||||
reset_db
|
||||
db null -
|
||||
@@ -227,4 +247,89 @@ do_execsql_test 5.0 {
|
||||
WHERE e>0;
|
||||
} {- - 3 4 5}
|
||||
|
||||
|
||||
# 2024-04-05
|
||||
# Allow push-down of operators of the form "expr IN table".
|
||||
#
|
||||
reset_db
|
||||
do_execsql_test 6.0 {
|
||||
CREATE TABLE t01(w,x,y,z);
|
||||
CREATE TABLE t02(w,x,y,z);
|
||||
CREATE VIEW t0(w,x,y,z) AS
|
||||
SELECT w,x,y,z FROM t01 UNION ALL SELECT w,x,y,z FROM t02;
|
||||
CREATE INDEX t01x ON t01(w,x,y);
|
||||
CREATE INDEX t02x ON t02(w,x,y);
|
||||
CREATE VIEW v1(k) AS VALUES(77),(88),(99);
|
||||
CREATE TABLE k1(k);
|
||||
INSERT INTO k1 SELECT * FROM v1;
|
||||
}
|
||||
do_eqp_test 6.1 {
|
||||
WITH k(n) AS (VALUES(77),(88),(99))
|
||||
SELECT max(z) FROM t0 WHERE w=123 AND x IN k AND y BETWEEN 44 AND 55;
|
||||
} {
|
||||
QUERY PLAN
|
||||
|--CO-ROUTINE t0
|
||||
| `--COMPOUND QUERY
|
||||
| |--LEFT-MOST SUBQUERY
|
||||
| | |--SEARCH t01 USING INDEX t01x (w=? AND x=? AND y>? AND y<?)
|
||||
| | `--LIST SUBQUERY xxxxxx
|
||||
| | |--MATERIALIZE k
|
||||
| | | `--SCAN 3 CONSTANT ROWS
|
||||
| | `--SCAN k
|
||||
| `--UNION ALL
|
||||
| |--SEARCH t02 USING INDEX t02x (w=? AND x=? AND y>? AND y<?)
|
||||
| `--LIST SUBQUERY xxxxxx
|
||||
| `--SCAN k
|
||||
|--SEARCH t0
|
||||
`--LIST SUBQUERY xxxxxx
|
||||
`--SCAN k
|
||||
}
|
||||
# ^^^^--- The key feature above is that the SEARCH for each subquery
|
||||
# uses all three fields of the index w, x, and y. Prior to the push-down
|
||||
# of "expr IN table", only the w term of the index would be used. Similar
|
||||
# for the following tests:
|
||||
#
|
||||
do_eqp_test 6.2 {
|
||||
SELECT max(z) FROM t0 WHERE w=123 AND x IN v1 AND y BETWEEN 44 AND 55;
|
||||
} {
|
||||
QUERY PLAN
|
||||
|--CO-ROUTINE t0
|
||||
| `--COMPOUND QUERY
|
||||
| |--LEFT-MOST SUBQUERY
|
||||
| | |--SEARCH t01 USING INDEX t01x (w=? AND x=? AND y>? AND y<?)
|
||||
| | `--LIST SUBQUERY xxxxxx
|
||||
| | |--CO-ROUTINE v1
|
||||
| | | `--SCAN 3 CONSTANT ROWS
|
||||
| | `--SCAN v1
|
||||
| `--UNION ALL
|
||||
| |--SEARCH t02 USING INDEX t02x (w=? AND x=? AND y>? AND y<?)
|
||||
| `--LIST SUBQUERY xxxxxx
|
||||
| |--CO-ROUTINE v1
|
||||
| | `--SCAN 3 CONSTANT ROWS
|
||||
| `--SCAN v1
|
||||
|--SEARCH t0
|
||||
`--LIST SUBQUERY xxxxxx
|
||||
|--CO-ROUTINE v1
|
||||
| `--SCAN 3 CONSTANT ROWS
|
||||
`--SCAN v1
|
||||
}
|
||||
do_eqp_test 6.3 {
|
||||
SELECT max(z) FROM t0 WHERE w=123 AND x IN k1 AND y BETWEEN 44 AND 55;
|
||||
} {
|
||||
QUERY PLAN
|
||||
|--CO-ROUTINE t0
|
||||
| `--COMPOUND QUERY
|
||||
| |--LEFT-MOST SUBQUERY
|
||||
| | |--SEARCH t01 USING INDEX t01x (w=? AND x=? AND y>? AND y<?)
|
||||
| | `--LIST SUBQUERY xxxxxx
|
||||
| | `--SCAN k1
|
||||
| `--UNION ALL
|
||||
| |--SEARCH t02 USING INDEX t02x (w=? AND x=? AND y>? AND y<?)
|
||||
| `--LIST SUBQUERY xxxxxx
|
||||
| `--SCAN k1
|
||||
|--SEARCH t0
|
||||
`--LIST SUBQUERY xxxxxx
|
||||
`--SCAN k1
|
||||
}
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -227,21 +227,21 @@ ifcapable !allow_rowid_in_view {
|
||||
} else {
|
||||
# Note: The values returned by the RETURNING clauses of the following
|
||||
# two statements are the rowid columns of views. These values are not
|
||||
# well defined, so the INSERT returns -1, and the UPDATE returns 1, 2
|
||||
# and 3. These match the values used for new.rowid expressions, but
|
||||
# not much else.
|
||||
# well defined, so the INSERT returns -1, and the UPDATE returns NULL.
|
||||
# These match the values used for new.rowid expressions, but not much
|
||||
# else.
|
||||
do_catchsql_test 10.3a {
|
||||
INSERT INTO t1(a, b) VALUES(1234, 5678) RETURNING rowid;
|
||||
} {0 -1}
|
||||
|
||||
do_catchsql_test 10.3b {
|
||||
UPDATE t1 SET a='z' WHERE b='y' RETURNING rowid;
|
||||
} {0 {1 2 3}}
|
||||
} {0 {{} {} {}}}
|
||||
|
||||
do_execsql_test 10.4 {
|
||||
SELECT * FROM log;
|
||||
} {
|
||||
insert -1 1234 5678 update 1 z y update 2 z y update 3 z y
|
||||
insert -1 1234 5678 update {} z y update {} z y update {} z y
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+15
-2
@@ -270,7 +270,7 @@ set TRG(schema) {
|
||||
/* Fields updated as jobs run */
|
||||
starttime INTEGER,
|
||||
endtime INTEGER,
|
||||
state TEXT CHECK( state IN ('', 'ready', 'running', 'done', 'failed') ),
|
||||
state TEXT CHECK( state IN ('','ready','running','done','failed','omit') ),
|
||||
output TEXT
|
||||
);
|
||||
|
||||
@@ -447,6 +447,10 @@ if {[llength $argv]==1
|
||||
} job {
|
||||
display_job [array get job]
|
||||
}
|
||||
set nOmit [db one {SELECT count(*) FROM jobs WHERE state='omit'}]
|
||||
if {$nOmit} {
|
||||
puts "$nOmit jobs omitted due to failures"
|
||||
}
|
||||
}
|
||||
|
||||
mydb close
|
||||
@@ -975,11 +979,16 @@ proc make_new_testset {} {
|
||||
|
||||
proc mark_job_as_finished {jobid output state endtm} {
|
||||
r_write_db {
|
||||
if {$state=="failed"} {
|
||||
set childstate omit
|
||||
} else {
|
||||
set childstate ready
|
||||
}
|
||||
trdb eval {
|
||||
UPDATE jobs
|
||||
SET output=$output, state=$state, endtime=$endtm
|
||||
WHERE jobid=$jobid;
|
||||
UPDATE jobs SET state='ready' WHERE depid=$jobid;
|
||||
UPDATE jobs SET state=$childstate WHERE depid=$jobid;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1202,6 +1211,10 @@ proc run_testset {} {
|
||||
puts "FAILED: $displayname"
|
||||
}
|
||||
}
|
||||
set nOmit [trdb one {SELECT count(*) FROM jobs WHERE state='omit'}]
|
||||
if {$nOmit>0} {
|
||||
puts "$nOmit jobs skipped due to prior failures"
|
||||
}
|
||||
}
|
||||
|
||||
puts "\nTest database is $TRG(dbname)"
|
||||
|
||||
@@ -268,4 +268,28 @@ do_catchsql_test upsert1-1210 {
|
||||
INSERT INTO t1(a,b) VALUES(1,2) ON CONFLICT(b+?1) DO NOTHING;
|
||||
} {1 {ON CONFLICT clause does not match any PRIMARY KEY or UNIQUE constraint}}
|
||||
|
||||
# 2024-04-11 https://sqlite.org/forum/forumpost/284955a3cd454a15
|
||||
# Incorrect value passed into a trigger that fires as the result of
|
||||
# an upsert.
|
||||
#
|
||||
reset_db
|
||||
do_execsql_test upsert1-1300 {
|
||||
CREATE TABLE t1(x INT, y TEXT);
|
||||
INSERT INTO t1 VALUES
|
||||
(11, printf('%.9000c','a')),
|
||||
(11, printf('%.9000c','a')),
|
||||
(33, printf('%.9000c','b')),
|
||||
(33, printf('%.9000c','b'));
|
||||
CREATE TABLE t2(x INT UNIQUE, y TEXT);
|
||||
CREATE TRIGGER r1 BEFORE UPDATE ON t2 BEGIN
|
||||
SELECT raise(ABORT,'Incorrect old.y value passed to trigger!')
|
||||
WHERE old.y != new.y;
|
||||
/* ^^^ This trigger will fire and cause the ABORT if the problem has
|
||||
** not been fixed, or if there is a regression. */
|
||||
END;
|
||||
INSERT INTO t2(x, y) SELECT x, y FROM t1
|
||||
WHERE true
|
||||
ON CONFLICT (x) DO UPDATE SET y = excluded.y;
|
||||
} {}
|
||||
|
||||
finish_test
|
||||
|
||||
+34
-1
@@ -26,13 +26,36 @@ ifcapable {!vacuum} {
|
||||
|
||||
forcedelete out.db
|
||||
do_execsql_test vacuum-into-100 {
|
||||
CREATE TABLE t1(a INTEGER PRIMARY KEY, b);
|
||||
CREATE TABLE t1(
|
||||
a INTEGER PRIMARY KEY,
|
||||
b ANY,
|
||||
c INT AS (b+1), --- See "2024-04-09" block
|
||||
CHECK( typeof(b)!='integer' OR b>a-5 ) --- comment below
|
||||
);
|
||||
WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<100)
|
||||
INSERT INTO t1(a,b) SELECT x, randomblob(600) FROM c;
|
||||
CREATE INDEX t1b ON t1(b);
|
||||
DELETE FROM t1 WHERE a%2;
|
||||
SELECT count(*), sum(a), sum(length(b)) FROM t1;
|
||||
} {50 2550 30000}
|
||||
|
||||
# Update 2024-04-09 for forum post eec177d68fe7fa2c.
|
||||
#
|
||||
# VACUUM INTO is sensitive to tables holding both generated columns
|
||||
# and CHECK constraints.
|
||||
#
|
||||
# CHECK constraints are ignored for read-only databases in order to save
|
||||
# memory (see check-in 34ddf02d3d21151b on 2014-05-21). But the xfer
|
||||
# optimization normally only works if CHECK constraints match between the
|
||||
# source and destination tables. So the xfer optimization was not
|
||||
# working for VACUUM INTO when the source was a read-only database and the
|
||||
# table held CHECK constraints. But if the table has generated columns,
|
||||
# then the xfer optimization is required or else VACUUM will raise an
|
||||
# error.
|
||||
#
|
||||
# Fix this by ignoring CHECK constraints when determining whether or not
|
||||
# the xfer optimization can run while doing VACUUM.
|
||||
|
||||
do_execsql_test vacuum-into-110 {
|
||||
VACUUM main INTO 'out.db';
|
||||
} {}
|
||||
@@ -88,11 +111,21 @@ do_catchsql_test vacuum-into-420 {
|
||||
|
||||
# The ability to VACUUM INTO a read-only database
|
||||
db close
|
||||
if {$tcl_platform(platform)=="windows"} {
|
||||
file attributes test.db -readonly 1
|
||||
} else {
|
||||
file attributes test.db -permissions 292 ;# 292 == 0444
|
||||
}
|
||||
sqlite3 db test.db -readonly 1
|
||||
forcedelete test.db2
|
||||
do_execsql_test vacuum-into-500 {
|
||||
VACUUM INTO 'test.db2';
|
||||
}
|
||||
if {$tcl_platform(platform)=="windows"} {
|
||||
file attributes test.db -readonly 0
|
||||
} else {
|
||||
file attributes test.db -permissions 420 ;# 420 = 0644
|
||||
}
|
||||
sqlite3 db2 test.db2
|
||||
do_test vacuum-into-510 {
|
||||
db2 eval {SELECT name FROM sqlite_master ORDER BY 1}
|
||||
|
||||
Reference in New Issue
Block a user