Merge trunk into fiddle-opfs branch.
FossilOrigin-Name: 7f76eaec793720db87415a476ddf539bc4dea3e74c8e5406d6739206aebdacc2
This commit is contained in:
commit
ae1ed83831
43
manifest
43
manifest
@ -1,5 +1,5 @@
|
||||
C Minor\scleanups\sin\sOO\sAPI\s#1.\sAdd\sSudoku\sSQL\sto\sbatch-runner.js's\slist.
|
||||
D 2022-09-05T13:24:08.577
|
||||
C Merge\strunk\sinto\sfiddle-opfs\sbranch.
|
||||
D 2022-09-06T09:59:06.910
|
||||
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
||||
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
||||
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
|
||||
@ -543,7 +543,7 @@ F src/auth.c f4fa91b6a90bbc8e0d0f738aa284551739c9543a367071f55574681e0f24f8cf
|
||||
F src/backup.c a2891172438e385fdbe97c11c9745676bec54f518d4447090af97189fd8e52d7
|
||||
F src/bitvec.c 7c849aac407230278445cb069bebc5f89bf2ddd87c5ed9459b070a9175707b3d
|
||||
F src/btmutex.c 6ffb0a22c19e2f9110be0964d0731d2ef1c67b5f7fabfbaeb7b9dabc4b7740ca
|
||||
F src/btree.c 4a8d349b9ed4dc6d252c535227699d75319b633058a56432ebf43c9f56f9085e
|
||||
F src/btree.c 138804ba7c054533573e87facdfcf9f8aa003c7123152dda8d9281f837ab2622
|
||||
F src/btree.h 74d64b8f28cfa4a894d14d4ed64fa432cd697b98b61708d4351482ae15913e22
|
||||
F src/btreeInt.h 8ce1332edd89dfd2461d561ac10a0ab5601c8e06200cb5230596c3caaf54482e
|
||||
F src/build.c 898884afd67d953808cb687babc15b66a10213f99fe2ce7db98960e959881f98
|
||||
@ -587,28 +587,28 @@ F src/os.c 0eb831ba3575af5277e47f4edd14fdfc90025c67eb25ce5cda634518d308d4e9
|
||||
F src/os.h 1ff5ae51d339d0e30d8a9d814f4b8f8e448169304d83a7ed9db66a65732f3e63
|
||||
F src/os_common.h b2f4707a603e36811d9b1a13278bffd757857b85
|
||||
F src/os_setup.h 0dbaea40a7d36bf311613d31342e0b99e2536586
|
||||
F src/os_unix.c 81e24bcad127faf32da162a4bb06e7a4604bea76fe7b1ed5b01742e9eb320554
|
||||
F src/os_win.c a8ea80037e81127ca01959daa87387cc135f325c88dc745376c4f760de852a10
|
||||
F src/os_unix.c 102f7e5c5b59c18ea3dbc929dc3be8acb3afc0e0b6ad572e032335c9c27f44f1
|
||||
F src/os_win.c e9454cb141908e8eef2102180bad353a36480612d5b736e4c2bd5777d9b25a34
|
||||
F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a
|
||||
F src/pager.c c60031c483960660853dfecf14c8e830503baab1f638ac997f0144f1bd3e1781
|
||||
F src/pager.c 6176d9752eb580419e8fef4592dc417a6b00ddfd43ee22f818819bf8840ceee8
|
||||
F src/pager.h f82e9844166e1585f5786837ddc7709966138ced17f568c16af7ccf946c2baa3
|
||||
F src/parse.y 8e67d820030d2655b9942ffe61c1e7e6b96cea2f2f72183533299393907d0564
|
||||
F src/pcache.c 084e638432c610f95aea72b8509f0845d2791293f39d1b82f0c0a7e089c3bb6b
|
||||
F src/pcache.c 22a6ebe498d1d26c85fd1e3bcb246d97b882c060027c1e1688fbea905f5ac3cf
|
||||
F src/pcache.h 4f87acd914cef5016fae3030343540d75f5b85a1877eed1a2a19b9f284248586
|
||||
F src/pcache1.c 0b4245cd4964e635f2630908c2533cd8e9da7af3ca592e23ae8730aa25ae5eb9
|
||||
F src/pragma.c b57a859a366472131194a9ad35cd76d5920577226b04c884b1b9085605faa280
|
||||
F src/pcache1.c 849a26ea9dc1e6a176b75dc576672a598170b0b46aeef87a981dd25e0af0ccf9
|
||||
F src/pragma.c 9bf7d8a2a9ad3bc36df3ec0d61817a44c38a1da527d59c26c203047f906e334a
|
||||
F src/pragma.h e690a356c18e98414d2e870ea791c1be1545a714ba623719deb63f7f226d8bb7
|
||||
F src/prepare.c 971d5819a4bda88038c2283d71fc0a2974ffc3dd480f9bd941341017abacfd1b
|
||||
F src/printf.c e99ee9741e79ae3873458146f59644276657340385ade4e76a5f5d1c25793764
|
||||
F src/random.c 546d6feb15ec69c1aafe9bb351a277cbb498fd5410e646add673acb805714960
|
||||
F src/resolve.c efea4e5fbecfd6d0a9071b0be0d952620991673391b6ffaaf4c277b0bb674633
|
||||
F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92
|
||||
F src/select.c ccce37e7fbe71089cf6aec91e7134c9c0c1d4840cff9f02587bbc71240d914a5
|
||||
F src/select.c d69dfb5b082f9a25e6700e152ddb3d942359b847b1df504eb09f9b4531844f8d
|
||||
F src/shell.c.in e7e7c2c69ae86c5ee9e8ad66227203d46ff6dce8700a1b1dababff01c71d33df
|
||||
F src/sqlite.h.in b9b7fd73239d94db20332bb6e504688001e5564b655e1318a4427a1caef4b99e
|
||||
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
|
||||
F src/sqlite3ext.h a988810c9b21c0dc36dc7a62735012339dc76fc7ab448fb0792721d30eacb69d
|
||||
F src/sqliteInt.h ebf18764e404a2cef39ae5bfc8dd4a83bf0d70be1c444a4fbd8539eb35ef6ffd
|
||||
F src/sqliteInt.h 94e7fc2a5f0fa5d1f0af84513fd2d1c70a9f6e772556b9dfef16feee63291eae
|
||||
F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657
|
||||
F src/status.c 160c445d7d28c984a0eae38c144f6419311ed3eace59b44ac6dafc20db4af749
|
||||
F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1
|
||||
@ -673,13 +673,13 @@ F src/trigger.c 61bea163b1fa3039bc572ed8312461b978e5c527e5301f302b078f4c1ccdec6a
|
||||
F src/update.c c52a7991bece0453d22c77c08469512ee2f1391c12503fd347d1c939220c5877
|
||||
F src/upsert.c 8789047a8f0a601ea42fa0256d1ba3190c13746b6ba940fe2d25643a7e991937
|
||||
F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0
|
||||
F src/util.c 602fe229f32a96ceccae4f40824129669582096f7c355f53dbac156c9fecef23
|
||||
F src/util.c 0be191521ff6d2805995f4910f0b6231b42843678b2efdc1abecaf39929a673f
|
||||
F src/vacuum.c bb346170b0b54c6683bba4a5983aea40485597fdf605c87ec8bc2e199fe88cd8
|
||||
F src/vdbe.c d27ec9a57f752fc2acf6a64d43bbf6072d2415efc976184f6d8a146e65819d3b
|
||||
F src/vdbe.h 64619af62603dc3c4f5ff6ff6d2c8f389abd667a29ce6007ed44bd22b3211cd0
|
||||
F src/vdbeInt.h 17b7461ffcf9ee760d1341731715a419f6b8c763089a7ece25c2e8098d702b3f
|
||||
F src/vdbeapi.c fc3183daf72808b4311b228989120fdbc2dc44972fb0d77d5c453460cc0e5b2c
|
||||
F src/vdbeaux.c 1f33d20fc19f13ad781ee083276ffad2204a182617859895db9daa3412456457
|
||||
F src/vdbeaux.c c719cebaffa75e166f16a405b3dee96e7150d60fc563ab2dea716b60c6a51312
|
||||
F src/vdbeblob.c 5e61ce31aca17db8fb60395407457a8c1c7fb471dde405e0cd675974611dcfcd
|
||||
F src/vdbemem.c c3ce80af15e2ff5c2824a8db881681cbf511376f13613da020bac6d320c535b1
|
||||
F src/vdbesort.c 43756031ca7430f7aec3ef904824a7883c4ede783e51f280d99b9b65c0796e35
|
||||
@ -690,8 +690,8 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9
|
||||
F src/wal.c b9df133a705093da8977da5eb202eaadb844839f1c7297c08d33471f5491843d
|
||||
F src/wal.h c3aa7825bfa2fe0d85bef2db94655f99870a285778baa36307c0a16da32b226a
|
||||
F src/walker.c f890a3298418d7cba3b69b8803594fdc484ea241206a8dfa99db6dd36f8cbb3b
|
||||
F src/where.c 6d1ee6f6bc048406554176eb6146b27ac16ec96cca018848aa0b9836b2b71143
|
||||
F src/whereInt.h b48ca529ffe293c18cbfa8326af18a09e39910de66fb3e96ef788c7cbf8ef3a7
|
||||
F src/where.c 424c42590b71968a9b81cd890df2671902028613fee38a50ed4c2f7ca65315d3
|
||||
F src/whereInt.h 70cd30de9ed784aa33fa6bd1245f060617de7a00d992469b6d8e419eed915743
|
||||
F src/wherecode.c 6bb1cf9d0a4e3e04dab0bf0ea4a8d936a0dcc05a7e2207beeda6c61aea6dd341
|
||||
F src/whereexpr.c 55a39f42aaf982574fbf52906371a84cceed98a994422198dfd03db4fce4cc46
|
||||
F src/window.c 928e215840e2f2d9a2746e018c9643ef42c66c4ab6630ef0df7fa388fa145e86
|
||||
@ -1217,7 +1217,7 @@ F test/journal3.test 7c3cf23ffc77db06601c1fcfc9743de8441cb77db9d1aa931863d94f5ff
|
||||
F test/jrnlmode.test 9b5bc01dac22223cb60ec2d5f97acf568d73820794386de5634dcadbea9e1946
|
||||
F test/jrnlmode2.test 8759a1d4657c064637f8b079592651530db738419e1d649c6df7048cd724363d
|
||||
F test/jrnlmode3.test 556b447a05be0e0963f4311e95ab1632b11c9eaa
|
||||
F test/json101.test 9d46b8e254c4e23306da175dd226d5c4f164db6b294bcea98e5dcd891ba48c91
|
||||
F test/json101.test 9f6337e7423d2c1774d1d485c919fc4e11c8f7e423a2f8831f73471983432108
|
||||
F test/json102.test 327e77275f338c028faefa2da5164daf6b142a165e3015ff2a6e4251ddc6a0ac
|
||||
F test/json103.test 53df87f83a4e5fa0c0a56eb29ff6c94055c6eb919f33316d62161a8880112dbe
|
||||
F test/json104.test a502dc01853aada95d721b3b275afbe2dc18fffdac1fea6e96fb20c13586bbb5
|
||||
@ -1867,7 +1867,7 @@ F test/win32heap.test 10fd891266bd00af68671e702317726375e5407561d859be1aa04696f2
|
||||
F test/win32lock.test e0924eb8daac02bf80e9da88930747bd44dd9b230b7759fed927b1655b467c9c
|
||||
F test/win32longpath.test 4baffc3acb2e5188a5e3a895b2b543ed09e62f7c72d713c1feebf76222fe9976
|
||||
F test/win32nolock.test ac4f08811a562e45a5755e661f45ca85892bdbbc
|
||||
F test/window1.test ae87c4ea4e689725c7e1c826ab2b10704d5b6d31f9b9e5abadded996ba53a1d4
|
||||
F test/window1.test 08bac934238ff66987635ea3367c5aed5b4c088c414441beaba426e68a8257c1
|
||||
F test/window2.tcl 492c125fa550cda1dd3555768a2303b3effbeceee215293adf8871efc25f1476
|
||||
F test/window2.test e466a88bd626d66edc3d352d7d7e1d5531e0079b549ba44efb029d1fbff9fd3c
|
||||
F test/window3.tcl acea6e86a4324a210fd608d06741010ca83ded9fde438341cb978c49928faf03
|
||||
@ -1891,7 +1891,7 @@ F test/windowfault.test 15094c1529424e62f798bc679e3fe9dfab6e8ba2f7dfe8c923b6248c
|
||||
F test/windowpushd.test d8895d08870b7226f7693665bd292eb177e62ca06799184957b3ca7dc03067df
|
||||
F test/with1.test 9ad67fdeb2bbd808a5763c9060e214ea232f9b18d846ea3a59756dc38bdc3880
|
||||
F test/with2.test a1df41b987198383b9b70bf5e5fda390582e46398653858dbc6ceb24253b28df
|
||||
F test/with3.test ad32d13ad50661e6fa305f62a0717649c348792e7b658bf2644976227a9e0373
|
||||
F test/with3.test 1e2e8d5e7b1d955342d0d18c250aaaa6e6bcf36ef2a818477bd01cb74f9a5d66
|
||||
F test/with4.test 257be66c0c67fee1defbbac0f685c3465e2cad037f21ce65f23f86084f198205
|
||||
F test/with5.test 6248213c41fab36290b5b73aa3f937309dfba337004d9d8434c3fabc8c7d4be8
|
||||
F test/with6.test c18592592b5a1c5802fd4e933d506f7b34ebbe8fdd585229793e960ae58d433f
|
||||
@ -1957,6 +1957,7 @@ F tool/mksqlite3h.tcl 1f5e4a1dbbbc43c83cc6e74fe32c6c620502240b66c7c0f33a51378e78
|
||||
F tool/mksqlite3internalh.tcl eb994013e833359137eb53a55acdad0b5ae1049b
|
||||
F tool/mkvsix.tcl b9e0777a213c23156b6542842c238479e496ebf5
|
||||
F tool/offsets.c 8ed2b344d33f06e71366a9b93ccedaa38c096cc1dbd4c3c26ad08c6115285845
|
||||
F tool/omittest-msvc.tcl d6b8f501ac1d7798c4126065030f89812379012cad98a1735d6d7221492abc08
|
||||
F tool/omittest.tcl 3bc9609aceea871e1ca6ed6749df9ce79b89369d22b492f6ce6078f40647cc3f
|
||||
F tool/opcodesum.tcl 740ed206ba8c5040018988129abbf3089a0ccf4a
|
||||
F tool/pagesig.c ff0ca355fd3c2398e933da5e22439bbff89b803b
|
||||
@ -2014,8 +2015,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 36ceef94e1935f5e85f79e489cd0ed265a77820fb68329c190794df5e076bf84
|
||||
R 7441dbef21a285816a3b01822ba89eea
|
||||
P 4488cb5798f34cbba14eb8e2aa5da8420c14a85d37d278d357406aedd5c3a9e5 6b00ecb59fd303f7985902c35a46db9e729201d4beaedea46596b728d9e4b1c8
|
||||
R fe1e5247661b941e3cd5ee02be72aa3d
|
||||
U stephan
|
||||
Z 1c45c40df6428914f663fd75d3ed35bb
|
||||
Z 52c5dac4d2eba4046599a7e7052e5fe2
|
||||
# Remove this line to create a well-formed Fossil manifest.
|
||||
|
@ -1 +1 @@
|
||||
4488cb5798f34cbba14eb8e2aa5da8420c14a85d37d278d357406aedd5c3a9e5
|
||||
7f76eaec793720db87415a476ddf539bc4dea3e74c8e5406d6739206aebdacc2
|
57
src/btree.c
57
src/btree.c
@ -7893,8 +7893,6 @@ static int balance_nonroot(
|
||||
Pgno pgno; /* Temp var to store a page number in */
|
||||
u8 abDone[NB+2]; /* True after i'th new page is populated */
|
||||
Pgno aPgno[NB+2]; /* Page numbers of new pages before shuffling */
|
||||
Pgno aPgOrder[NB+2]; /* Copy of aPgno[] used for sorting pages */
|
||||
u16 aPgFlags[NB+2]; /* flags field of new pages before shuffling */
|
||||
CellArray b; /* Parsed information on cells being balanced */
|
||||
|
||||
memset(abDone, 0, sizeof(abDone));
|
||||
@ -8318,42 +8316,39 @@ static int balance_nonroot(
|
||||
** of the table is closer to a linear scan through the file. That in turn
|
||||
** helps the operating system to deliver pages from the disk more rapidly.
|
||||
**
|
||||
** An O(n^2) insertion sort algorithm is used, but since n is never more
|
||||
** than (NB+2) (a small constant), that should not be a problem.
|
||||
** An O(N*N) sort algorithm is used, but since N is never more than NB+2
|
||||
** (5), that is not a performance concern.
|
||||
**
|
||||
** When NB==3, this one optimization makes the database about 25% faster
|
||||
** for large insertions and deletions.
|
||||
*/
|
||||
for(i=0; i<nNew; i++){
|
||||
aPgOrder[i] = aPgno[i] = apNew[i]->pgno;
|
||||
aPgFlags[i] = apNew[i]->pDbPage->flags;
|
||||
for(j=0; j<i; j++){
|
||||
if( NEVER(aPgno[j]==aPgno[i]) ){
|
||||
/* This branch is taken if the set of sibling pages somehow contains
|
||||
** duplicate entries. This can happen if the database is corrupt.
|
||||
** It would be simpler to detect this as part of the loop below, but
|
||||
** we do the detection here in order to avoid populating the pager
|
||||
** cache with two separate objects associated with the same
|
||||
** page number. */
|
||||
assert( CORRUPT_DB );
|
||||
rc = SQLITE_CORRUPT_BKPT;
|
||||
goto balance_cleanup;
|
||||
}
|
||||
}
|
||||
aPgno[i] = apNew[i]->pgno;
|
||||
assert( apNew[i]->pDbPage->flags & PGHDR_WRITEABLE );
|
||||
assert( apNew[i]->pDbPage->flags & PGHDR_DIRTY );
|
||||
}
|
||||
for(i=0; i<nNew; i++){
|
||||
int iBest = 0; /* aPgno[] index of page number to use */
|
||||
for(j=1; j<nNew; j++){
|
||||
if( aPgOrder[j]<aPgOrder[iBest] ) iBest = j;
|
||||
for(i=0; i<nNew-1; i++){
|
||||
int iB = i;
|
||||
for(j=i+1; j<nNew; j++){
|
||||
if( apNew[j]->pgno < apNew[iB]->pgno ) iB = j;
|
||||
}
|
||||
pgno = aPgOrder[iBest];
|
||||
aPgOrder[iBest] = 0xffffffff;
|
||||
if( iBest!=i ){
|
||||
if( iBest>i ){
|
||||
sqlite3PagerRekey(apNew[iBest]->pDbPage, pBt->nPage+iBest+1, 0);
|
||||
}
|
||||
sqlite3PagerRekey(apNew[i]->pDbPage, pgno, aPgFlags[iBest]);
|
||||
apNew[i]->pgno = pgno;
|
||||
|
||||
/* If apNew[i] has a page number that is bigger than any of the
|
||||
** subsequence apNew[i] entries, then swap apNew[i] with the subsequent
|
||||
** entry that has the smallest page number (which we know to be
|
||||
** entry apNew[iB]).
|
||||
*/
|
||||
if( iB!=i ){
|
||||
Pgno pgnoA = apNew[i]->pgno;
|
||||
Pgno pgnoB = apNew[iB]->pgno;
|
||||
Pgno pgnoTemp = (PENDING_BYTE/pBt->pageSize)+1;
|
||||
u16 fgA = apNew[i]->pDbPage->flags;
|
||||
u16 fgB = apNew[iB]->pDbPage->flags;
|
||||
sqlite3PagerRekey(apNew[i]->pDbPage, pgnoTemp, fgB);
|
||||
sqlite3PagerRekey(apNew[iB]->pDbPage, pgnoA, fgA);
|
||||
sqlite3PagerRekey(apNew[i]->pDbPage, pgnoB, fgB);
|
||||
apNew[i]->pgno = pgnoB;
|
||||
apNew[iB]->pgno = pgnoA;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5855,6 +5855,7 @@ static const char *unixTempFileDir(void){
|
||||
static int unixGetTempname(int nBuf, char *zBuf){
|
||||
const char *zDir;
|
||||
int iLimit = 0;
|
||||
int rc = SQLITE_OK;
|
||||
|
||||
/* It's odd to simulate an io-error here, but really this is just
|
||||
** using the io-error infrastructure to test that SQLite handles this
|
||||
@ -5863,18 +5864,26 @@ static int unixGetTempname(int nBuf, char *zBuf){
|
||||
zBuf[0] = 0;
|
||||
SimulateIOError( return SQLITE_IOERR );
|
||||
|
||||
sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_TEMPDIR));
|
||||
zDir = unixTempFileDir();
|
||||
if( zDir==0 ) return SQLITE_IOERR_GETTEMPPATH;
|
||||
do{
|
||||
u64 r;
|
||||
sqlite3_randomness(sizeof(r), &r);
|
||||
assert( nBuf>2 );
|
||||
zBuf[nBuf-2] = 0;
|
||||
sqlite3_snprintf(nBuf, zBuf, "%s/"SQLITE_TEMP_FILE_PREFIX"%llx%c",
|
||||
zDir, r, 0);
|
||||
if( zBuf[nBuf-2]!=0 || (iLimit++)>10 ) return SQLITE_ERROR;
|
||||
}while( osAccess(zBuf,0)==0 );
|
||||
return SQLITE_OK;
|
||||
if( zDir==0 ){
|
||||
rc = SQLITE_IOERR_GETTEMPPATH;
|
||||
}else{
|
||||
do{
|
||||
u64 r;
|
||||
sqlite3_randomness(sizeof(r), &r);
|
||||
assert( nBuf>2 );
|
||||
zBuf[nBuf-2] = 0;
|
||||
sqlite3_snprintf(nBuf, zBuf, "%s/"SQLITE_TEMP_FILE_PREFIX"%llx%c",
|
||||
zDir, r, 0);
|
||||
if( zBuf[nBuf-2]!=0 || (iLimit++)>10 ){
|
||||
rc = SQLITE_ERROR;
|
||||
break;
|
||||
}
|
||||
}while( osAccess(zBuf,0)==0 );
|
||||
}
|
||||
sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_TEMPDIR));
|
||||
return rc;
|
||||
}
|
||||
|
||||
#if SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__)
|
||||
|
47
src/os_win.c
47
src/os_win.c
@ -1918,10 +1918,12 @@ int sqlite3_win32_set_directory8(
|
||||
const char *zValue /* New value for directory being set or reset */
|
||||
){
|
||||
char **ppDirectory = 0;
|
||||
int rc;
|
||||
#ifndef SQLITE_OMIT_AUTOINIT
|
||||
int rc = sqlite3_initialize();
|
||||
rc = sqlite3_initialize();
|
||||
if( rc ) return rc;
|
||||
#endif
|
||||
sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_TEMPDIR));
|
||||
if( type==SQLITE_WIN32_DATA_DIRECTORY_TYPE ){
|
||||
ppDirectory = &sqlite3_data_directory;
|
||||
}else if( type==SQLITE_WIN32_TEMP_DIRECTORY_TYPE ){
|
||||
@ -1936,14 +1938,19 @@ int sqlite3_win32_set_directory8(
|
||||
if( zValue && zValue[0] ){
|
||||
zCopy = sqlite3_mprintf("%s", zValue);
|
||||
if ( zCopy==0 ){
|
||||
return SQLITE_NOMEM_BKPT;
|
||||
rc = SQLITE_NOMEM_BKPT;
|
||||
goto set_directory8_done;
|
||||
}
|
||||
}
|
||||
sqlite3_free(*ppDirectory);
|
||||
*ppDirectory = zCopy;
|
||||
return SQLITE_OK;
|
||||
rc = SQLITE_OK;
|
||||
}else{
|
||||
rc = SQLITE_ERROR;
|
||||
}
|
||||
return SQLITE_ERROR;
|
||||
set_directory8_done:
|
||||
sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_TEMPDIR));
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -4717,6 +4724,18 @@ static int winMakeEndInDirSep(int nBuf, char *zBuf){
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
** If sqlite3_temp_directory is not, take the mutex and return true.
|
||||
**
|
||||
** If sqlite3_temp_directory is NULL, omit the mutex and return false.
|
||||
*/
|
||||
static int winTempDirDefined(void){
|
||||
sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_TEMPDIR));
|
||||
if( sqlite3_temp_directory!=0 ) return 1;
|
||||
sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_TEMPDIR));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
** Create a temporary file name and store the resulting pointer into pzBuf.
|
||||
** The pointer returned in pzBuf must be freed via sqlite3_free().
|
||||
@ -4753,20 +4772,23 @@ static int winGetTempname(sqlite3_vfs *pVfs, char **pzBuf){
|
||||
*/
|
||||
nDir = nMax - (nPre + 15);
|
||||
assert( nDir>0 );
|
||||
if( sqlite3_temp_directory ){
|
||||
if( winTempDirDefined() ){
|
||||
int nDirLen = sqlite3Strlen30(sqlite3_temp_directory);
|
||||
if( nDirLen>0 ){
|
||||
if( !winIsDirSep(sqlite3_temp_directory[nDirLen-1]) ){
|
||||
nDirLen++;
|
||||
}
|
||||
if( nDirLen>nDir ){
|
||||
sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_TEMPDIR));
|
||||
sqlite3_free(zBuf);
|
||||
OSTRACE(("TEMP-FILENAME rc=SQLITE_ERROR\n"));
|
||||
return winLogError(SQLITE_ERROR, 0, "winGetTempname1", 0);
|
||||
}
|
||||
sqlite3_snprintf(nMax, zBuf, "%s", sqlite3_temp_directory);
|
||||
}
|
||||
sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_TEMPDIR));
|
||||
}
|
||||
|
||||
#if defined(__CYGWIN__)
|
||||
else{
|
||||
static const char *azDirs[] = {
|
||||
@ -5555,7 +5577,7 @@ static BOOL winIsVerbatimPathname(
|
||||
** pathname into zOut[]. zOut[] will be at least pVfs->mxPathname
|
||||
** bytes in size.
|
||||
*/
|
||||
static int winFullPathname(
|
||||
static int winFullPathnameNoMutex(
|
||||
sqlite3_vfs *pVfs, /* Pointer to vfs object */
|
||||
const char *zRelative, /* Possibly relative input path */
|
||||
int nFull, /* Size of output buffer in bytes */
|
||||
@ -5734,6 +5756,19 @@ static int winFullPathname(
|
||||
}
|
||||
#endif
|
||||
}
|
||||
static int winFullPathname(
|
||||
sqlite3_vfs *pVfs, /* Pointer to vfs object */
|
||||
const char *zRelative, /* Possibly relative input path */
|
||||
int nFull, /* Size of output buffer in bytes */
|
||||
char *zFull /* Output buffer */
|
||||
){
|
||||
int rc;
|
||||
sqlite3_mutex *pMutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_TEMPDIR);
|
||||
sqlite3_mutex_enter(pMutex);
|
||||
rc = winFullPathnameNoMutex(pVfs, zRelative, nFull, zFull);
|
||||
sqlite3_mutex_leave(pMutex);
|
||||
return rc;
|
||||
}
|
||||
|
||||
#ifndef SQLITE_OMIT_LOAD_EXTENSION
|
||||
/*
|
||||
|
@ -5822,6 +5822,7 @@ static int pager_open_journal(Pager *pPager){
|
||||
if( rc!=SQLITE_OK ){
|
||||
sqlite3BitvecDestroy(pPager->pInJournal);
|
||||
pPager->pInJournal = 0;
|
||||
pPager->journalOff = 0;
|
||||
}else{
|
||||
assert( pPager->eState==PAGER_WRITER_LOCKED );
|
||||
pPager->eState = PAGER_WRITER_CACHEMOD;
|
||||
|
65
src/pcache.c
65
src/pcache.c
@ -66,12 +66,20 @@ struct PCache {
|
||||
int sqlite3PcacheTrace = 2; /* 0: off 1: simple 2: cache dumps */
|
||||
int sqlite3PcacheMxDump = 9999; /* Max cache entries for pcacheDump() */
|
||||
# define pcacheTrace(X) if(sqlite3PcacheTrace){sqlite3DebugPrintf X;}
|
||||
void pcacheDump(PCache *pCache){
|
||||
int N;
|
||||
int i, j;
|
||||
sqlite3_pcache_page *pLower;
|
||||
static void pcachePageTrace(int i, sqlite3_pcache_page *pLower){
|
||||
PgHdr *pPg;
|
||||
unsigned char *a;
|
||||
int j;
|
||||
pPg = (PgHdr*)pLower->pExtra;
|
||||
printf("%3d: nRef %2d flgs %02x data ", i, pPg->nRef, pPg->flags);
|
||||
a = (unsigned char *)pLower->pBuf;
|
||||
for(j=0; j<12; j++) printf("%02x", a[j]);
|
||||
printf(" ptr %p\n", pPg);
|
||||
}
|
||||
static void pcacheDump(PCache *pCache){
|
||||
int N;
|
||||
int i;
|
||||
sqlite3_pcache_page *pLower;
|
||||
|
||||
if( sqlite3PcacheTrace<2 ) return;
|
||||
if( pCache->pCache==0 ) return;
|
||||
@ -80,21 +88,32 @@ struct PCache {
|
||||
for(i=1; i<=N; i++){
|
||||
pLower = sqlite3GlobalConfig.pcache2.xFetch(pCache->pCache, i, 0);
|
||||
if( pLower==0 ) continue;
|
||||
pPg = (PgHdr*)pLower->pExtra;
|
||||
printf("%3d: nRef %2d flgs %02x data ", i, pPg->nRef, pPg->flags);
|
||||
a = (unsigned char *)pLower->pBuf;
|
||||
for(j=0; j<12; j++) printf("%02x", a[j]);
|
||||
printf("\n");
|
||||
if( pPg->pPage==0 ){
|
||||
pcachePageTrace(i, pLower);
|
||||
if( ((PgHdr*)pLower)->pPage==0 ){
|
||||
sqlite3GlobalConfig.pcache2.xUnpin(pCache->pCache, pLower, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
#else
|
||||
# define pcacheTrace(X)
|
||||
# define pcachePageTrace(PGNO, X)
|
||||
# define pcacheDump(X)
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Return 1 if pPg is on the dirty list for pCache. Return 0 if not.
|
||||
** This routine runs inside of assert() statements only.
|
||||
*/
|
||||
#ifdef SQLITE_DEBUG
|
||||
static int pageOnDirtyList(PCache *pCache, PgHdr *pPg){
|
||||
PgHdr *p;
|
||||
for(p=pCache->pDirty; p; p=p->pDirtyNext){
|
||||
if( p==pPg ) return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Check invariants on a PgHdr entry. Return true if everything is OK.
|
||||
** Return false if any invariant is violated.
|
||||
@ -113,8 +132,13 @@ int sqlite3PcachePageSanity(PgHdr *pPg){
|
||||
assert( pCache!=0 ); /* Every page has an associated PCache */
|
||||
if( pPg->flags & PGHDR_CLEAN ){
|
||||
assert( (pPg->flags & PGHDR_DIRTY)==0 );/* Cannot be both CLEAN and DIRTY */
|
||||
assert( pCache->pDirty!=pPg ); /* CLEAN pages not on dirty list */
|
||||
assert( pCache->pDirtyTail!=pPg );
|
||||
assert( !pageOnDirtyList(pCache, pPg) );/* CLEAN pages not on dirty list */
|
||||
}else{
|
||||
assert( (pPg->flags & PGHDR_DIRTY)!=0 );/* If not CLEAN must be DIRTY */
|
||||
assert( pPg->pDirtyNext==0 || pPg->pDirtyNext->pDirtyPrev==pPg );
|
||||
assert( pPg->pDirtyPrev==0 || pPg->pDirtyPrev->pDirtyNext==pPg );
|
||||
assert( pPg->pDirtyPrev!=0 || pCache->pDirty==pPg );
|
||||
assert( pageOnDirtyList(pCache, pPg) );
|
||||
}
|
||||
/* WRITEABLE pages must also be DIRTY */
|
||||
if( pPg->flags & PGHDR_WRITEABLE ){
|
||||
@ -388,8 +412,9 @@ sqlite3_pcache_page *sqlite3PcacheFetch(
|
||||
assert( createFlag==0 || pCache->eCreate==eCreate );
|
||||
assert( createFlag==0 || eCreate==1+(!pCache->bPurgeable||!pCache->pDirty) );
|
||||
pRes = sqlite3GlobalConfig.pcache2.xFetch(pCache->pCache, pgno, eCreate);
|
||||
pcacheTrace(("%p.FETCH %d%s (result: %p)\n",pCache,pgno,
|
||||
pcacheTrace(("%p.FETCH %d%s (result: %p) ",pCache,pgno,
|
||||
createFlag?" create":"",pRes));
|
||||
pcachePageTrace(pgno, pRes);
|
||||
return pRes;
|
||||
}
|
||||
|
||||
@ -517,6 +542,7 @@ void SQLITE_NOINLINE sqlite3PcacheRelease(PgHdr *p){
|
||||
pcacheUnpin(p);
|
||||
}else{
|
||||
pcacheManageDirtyList(p, PCACHE_DIRTYLIST_FRONT);
|
||||
assert( sqlite3PcachePageSanity(p) );
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -560,6 +586,7 @@ void sqlite3PcacheMakeDirty(PgHdr *p){
|
||||
pcacheTrace(("%p.DIRTY %d\n",p->pCache,p->pgno));
|
||||
assert( (p->flags & (PGHDR_DIRTY|PGHDR_CLEAN))==PGHDR_DIRTY );
|
||||
pcacheManageDirtyList(p, PCACHE_DIRTYLIST_ADD);
|
||||
assert( sqlite3PcachePageSanity(p) );
|
||||
}
|
||||
assert( sqlite3PcachePageSanity(p) );
|
||||
}
|
||||
@ -622,14 +649,24 @@ void sqlite3PcacheClearSyncFlags(PCache *pCache){
|
||||
*/
|
||||
void sqlite3PcacheMove(PgHdr *p, Pgno newPgno){
|
||||
PCache *pCache = p->pCache;
|
||||
sqlite3_pcache_page *pOther;
|
||||
assert( p->nRef>0 );
|
||||
assert( newPgno>0 );
|
||||
assert( sqlite3PcachePageSanity(p) );
|
||||
pcacheTrace(("%p.MOVE %d -> %d\n",pCache,p->pgno,newPgno));
|
||||
pOther = sqlite3GlobalConfig.pcache2.xFetch(pCache->pCache, newPgno, 0);
|
||||
sqlite3GlobalConfig.pcache2.xRekey(pCache->pCache, p->pPage, p->pgno,newPgno);
|
||||
if( pOther ){
|
||||
PgHdr *pPg = (PgHdr*)pOther->pExtra;
|
||||
pPg->pgno = p->pgno;
|
||||
if( pPg->pPage==0 ){
|
||||
sqlite3GlobalConfig.pcache2.xUnpin(pCache->pCache, pOther, 0);
|
||||
}
|
||||
}
|
||||
p->pgno = newPgno;
|
||||
if( (p->flags&PGHDR_DIRTY) && (p->flags&PGHDR_NEED_SYNC) ){
|
||||
pcacheManageDirtyList(p, PCACHE_DIRTYLIST_FRONT);
|
||||
assert( sqlite3PcachePageSanity(p) );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -106,19 +106,24 @@ typedef struct PGroup PGroup;
|
||||
** corrupt, code at the b-tree layer may overread the page buffer and
|
||||
** read part of this structure before the corruption is detected. This
|
||||
** can cause a valgrind error if the unitialized gap is accessed. Using u16
|
||||
** ensures there is no such gap, and therefore no bytes of unitialized memory
|
||||
** in the structure.
|
||||
** ensures there is no such gap, and therefore no bytes of uninitialized
|
||||
** memory in the structure.
|
||||
**
|
||||
** The pLruNext and pLruPrev pointers form a double-linked circular list
|
||||
** of all pages that are unpinned. The PGroup.lru element (which should be
|
||||
** the only element on the list with PgHdr1.isAnchor set to 1) forms the
|
||||
** beginning and the end of the list.
|
||||
*/
|
||||
struct PgHdr1 {
|
||||
sqlite3_pcache_page page; /* Base class. Must be first. pBuf & pExtra */
|
||||
unsigned int iKey; /* Key value (page number) */
|
||||
u16 isBulkLocal; /* This page from bulk local storage */
|
||||
u16 isAnchor; /* This is the PGroup.lru element */
|
||||
PgHdr1 *pNext; /* Next in hash table chain */
|
||||
PCache1 *pCache; /* Cache that currently owns this page */
|
||||
PgHdr1 *pLruNext; /* Next in LRU list of unpinned pages */
|
||||
PgHdr1 *pLruPrev; /* Previous in LRU list of unpinned pages */
|
||||
/* NB: pLruPrev is only valid if pLruNext!=0 */
|
||||
sqlite3_pcache_page page; /* Base class. Must be first. pBuf & pExtra */
|
||||
unsigned int iKey; /* Key value (page number) */
|
||||
u16 isBulkLocal; /* This page from bulk local storage */
|
||||
u16 isAnchor; /* This is the PGroup.lru element */
|
||||
PgHdr1 *pNext; /* Next in hash table chain */
|
||||
PCache1 *pCache; /* Cache that currently owns this page */
|
||||
PgHdr1 *pLruNext; /* Next in circular LRU list of unpinned pages */
|
||||
PgHdr1 *pLruPrev; /* Previous in LRU list of unpinned pages */
|
||||
/* NB: pLruPrev is only valid if pLruNext!=0 */
|
||||
};
|
||||
|
||||
/*
|
||||
@ -1114,23 +1119,41 @@ static void pcache1Rekey(
|
||||
PCache1 *pCache = (PCache1 *)p;
|
||||
PgHdr1 *pPage = (PgHdr1 *)pPg;
|
||||
PgHdr1 **pp;
|
||||
unsigned int h;
|
||||
unsigned int hOld, hNew;
|
||||
assert( pPage->iKey==iOld );
|
||||
assert( pPage->pCache==pCache );
|
||||
assert( iOld!=iNew ); /* The page number really is changing */
|
||||
|
||||
pcache1EnterMutex(pCache->pGroup);
|
||||
|
||||
h = iOld%pCache->nHash;
|
||||
pp = &pCache->apHash[h];
|
||||
|
||||
assert( pcache1FetchNoMutex(p, iOld, 0)==pPage ); /* pPg really is iOld */
|
||||
hOld = iOld%pCache->nHash;
|
||||
pp = &pCache->apHash[hOld];
|
||||
while( (*pp)!=pPage ){
|
||||
pp = &(*pp)->pNext;
|
||||
}
|
||||
*pp = pPage->pNext;
|
||||
|
||||
h = iNew%pCache->nHash;
|
||||
hNew = iNew%pCache->nHash;
|
||||
pp = &pCache->apHash[hNew];
|
||||
while( *pp ){
|
||||
if( (*pp)->iKey==iNew ){
|
||||
/* If there is already another pcache entry at iNew, change it to iOld,
|
||||
** thus swapping the positions of iNew and iOld */
|
||||
PgHdr1 *pOld = *pp;
|
||||
*pp = pOld->pNext;
|
||||
pOld->pNext = pCache->apHash[hOld];
|
||||
pCache->apHash[hOld] = pOld;
|
||||
pOld->iKey = iOld;
|
||||
break;
|
||||
}else{
|
||||
pp = &(*pp)->pNext;
|
||||
}
|
||||
}
|
||||
|
||||
pPage->iKey = iNew;
|
||||
pPage->pNext = pCache->apHash[h];
|
||||
pCache->apHash[h] = pPage;
|
||||
pPage->pNext = pCache->apHash[hNew];
|
||||
pCache->apHash[hNew] = pPage;
|
||||
if( iNew>pCache->iMaxKey ){
|
||||
pCache->iMaxKey = iNew;
|
||||
}
|
||||
|
@ -965,6 +965,7 @@ void sqlite3Pragma(
|
||||
**
|
||||
*/
|
||||
case PragTyp_TEMP_STORE_DIRECTORY: {
|
||||
sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_TEMPDIR));
|
||||
if( !zRight ){
|
||||
returnSingleText(v, sqlite3_temp_directory);
|
||||
}else{
|
||||
@ -974,6 +975,7 @@ void sqlite3Pragma(
|
||||
rc = sqlite3OsAccess(db->pVfs, zRight, SQLITE_ACCESS_READWRITE, &res);
|
||||
if( rc!=SQLITE_OK || res==0 ){
|
||||
sqlite3ErrorMsg(pParse, "not a writable directory");
|
||||
sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_TEMPDIR));
|
||||
goto pragma_out;
|
||||
}
|
||||
}
|
||||
@ -991,6 +993,7 @@ void sqlite3Pragma(
|
||||
}
|
||||
#endif /* SQLITE_OMIT_WSD */
|
||||
}
|
||||
sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_TEMPDIR));
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1009,6 +1012,7 @@ void sqlite3Pragma(
|
||||
**
|
||||
*/
|
||||
case PragTyp_DATA_STORE_DIRECTORY: {
|
||||
sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_TEMPDIR));
|
||||
if( !zRight ){
|
||||
returnSingleText(v, sqlite3_data_directory);
|
||||
}else{
|
||||
@ -1018,6 +1022,7 @@ void sqlite3Pragma(
|
||||
rc = sqlite3OsAccess(db->pVfs, zRight, SQLITE_ACCESS_READWRITE, &res);
|
||||
if( rc!=SQLITE_OK || res==0 ){
|
||||
sqlite3ErrorMsg(pParse, "not a writable directory");
|
||||
sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_TEMPDIR));
|
||||
goto pragma_out;
|
||||
}
|
||||
}
|
||||
@ -1029,6 +1034,7 @@ void sqlite3Pragma(
|
||||
}
|
||||
#endif /* SQLITE_OMIT_WSD */
|
||||
}
|
||||
sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_TEMPDIR));
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
@ -3690,10 +3690,11 @@ static int multiSelectOrderBy(
|
||||
*/
|
||||
sqlite3VdbeResolveLabel(v, labelEnd);
|
||||
|
||||
/* Reassembly the compound query so that it will be freed correctly
|
||||
/* Reassemble the compound query so that it will be freed correctly
|
||||
** by the calling function */
|
||||
if( pSplit->pPrior ){
|
||||
sqlite3SelectDelete(db, pSplit->pPrior);
|
||||
sqlite3ParserAddCleanup(pParse,
|
||||
(void(*)(sqlite3*,void*))sqlite3SelectDelete, pSplit->pPrior);
|
||||
}
|
||||
pSplit->pPrior = pPrior;
|
||||
pPrior->pNext = pSplit;
|
||||
|
@ -198,6 +198,11 @@
|
||||
*/
|
||||
#include "sqlite3.h"
|
||||
|
||||
/*
|
||||
** Reuse the STATIC_LRU for mutex access to sqlite3_temp_directory.
|
||||
*/
|
||||
#define SQLITE_MUTEX_STATIC_TEMPDIR SQLITE_MUTEX_STATIC_VFS1
|
||||
|
||||
/*
|
||||
** Include the configuration header output by 'configure' if we're using the
|
||||
** autoconf-based build
|
||||
|
@ -190,7 +190,7 @@ void sqlite3ErrorMsg(Parse *pParse, const char *zFormat, ...){
|
||||
va_list ap;
|
||||
sqlite3 *db = pParse->db;
|
||||
assert( db!=0 );
|
||||
assert( db->pParse==pParse );
|
||||
assert( db->pParse==pParse || db->pParse->pToplevel==pParse );
|
||||
db->errByteOffset = -2;
|
||||
va_start(ap, zFormat);
|
||||
zMsg = sqlite3VMPrintf(db, zFormat, ap);
|
||||
|
@ -388,6 +388,7 @@ int sqlite3VdbeAddFunctionCall(
|
||||
addr = sqlite3VdbeAddOp4(v, eCallCtx ? OP_PureFunc : OP_Function,
|
||||
p1, p2, p3, (char*)pCtx, P4_FUNCCTX);
|
||||
sqlite3VdbeChangeP5(v, eCallCtx & NC_SelfRef);
|
||||
sqlite3MayAbort(pParse);
|
||||
return addr;
|
||||
}
|
||||
|
||||
@ -723,6 +724,7 @@ int sqlite3VdbeAssertMayAbort(Vdbe *v, int mayAbort){
|
||||
|| opcode==OP_VDestroy
|
||||
|| opcode==OP_VCreate
|
||||
|| opcode==OP_ParseSchema
|
||||
|| opcode==OP_Function || opcode==OP_PureFunc
|
||||
|| ((opcode==OP_Halt || opcode==OP_HaltIfNull)
|
||||
&& ((pOp->p1)!=SQLITE_OK && pOp->p2==OE_Abort))
|
||||
){
|
||||
|
10
src/where.c
10
src/where.c
@ -3463,6 +3463,9 @@ static int whereLoopAddBtree(
|
||||
#else
|
||||
pNew->rRun = rSize + 16;
|
||||
#endif
|
||||
if( IsView(pTab) || (pTab->tabFlags & TF_Ephemeral)!=0 ){
|
||||
pNew->wsFlags |= WHERE_VIEWSCAN;
|
||||
}
|
||||
ApplyCostMultiplier(pNew->rRun, pTab->costMult);
|
||||
whereLoopOutputAdjust(pWC, pNew, rSize);
|
||||
rc = whereLoopInsert(pBuilder, pNew);
|
||||
@ -4843,6 +4846,13 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){
|
||||
rUnsorted -= 2; /* TUNING: Slight bias in favor of no-sort plans */
|
||||
}
|
||||
|
||||
/* TUNING: A full-scan of a VIEW or subquery in the outer loop
|
||||
** is not so bad. */
|
||||
if( iLoop==0 && (pWLoop->wsFlags & WHERE_VIEWSCAN)!=0 ){
|
||||
rCost += -10;
|
||||
nOut += -30;
|
||||
}
|
||||
|
||||
/* Check to see if pWLoop should be added to the set of
|
||||
** mxChoice best-so-far paths.
|
||||
**
|
||||
|
@ -648,5 +648,6 @@ void sqlite3WhereTabFuncArgs(Parse*, SrcItem*, WhereClause*);
|
||||
#define WHERE_BLOOMFILTER 0x00400000 /* Consider using a Bloom-filter */
|
||||
#define WHERE_SELFCULL 0x00800000 /* nOut reduced by extra WHERE terms */
|
||||
#define WHERE_OMIT_OFFSET 0x01000000 /* Set offset counter to zero */
|
||||
#define WHERE_VIEWSCAN 0x02000000 /* A full-scan of a VIEW or subquery */
|
||||
|
||||
#endif /* !defined(SQLITE_WHEREINT_H) */
|
||||
|
@ -867,4 +867,22 @@ do_catchsql_test json-18.5 {
|
||||
SELECT json_extract('{"":8}', '$.');
|
||||
} {1 {JSON path error near ''}}
|
||||
|
||||
# 2022-08-29 https://sqlite.org/forum/forumpost/9b9e4716c0d7bbd1
|
||||
# This is not a problem specifically with JSON functions. It is
|
||||
# a problem with transaction control. But the json() function makes
|
||||
# the problem more easily accessible, so it is tested here.
|
||||
#
|
||||
do_execsql_test json-19.1 {
|
||||
DROP TABLE IF EXISTS t1;
|
||||
CREATE TABLE t1(x);
|
||||
} {}
|
||||
do_catchsql_test json-19.2 {
|
||||
BEGIN;
|
||||
INSERT INTO t1 VALUES(0), (json('not-valid-json'));
|
||||
} {1 {malformed JSON}}
|
||||
do_execsql_test json-19.3 {
|
||||
COMMIT;
|
||||
SELECT * FROM t1;
|
||||
} {}
|
||||
|
||||
finish_test
|
||||
|
@ -212,10 +212,11 @@ do_execsql_test 6.1 {
|
||||
} {1 1 2 2 3 3 4 4 5 5 6 6 7 7}
|
||||
|
||||
do_execsql_test 6.2 {
|
||||
SELECT * FROM t2, (SELECT x, count(*) OVER (ORDER BY x) FROM t1);
|
||||
SELECT * FROM t2, (SELECT x, count(*) OVER (ORDER BY x) FROM t1)
|
||||
ORDER BY 1, 2;
|
||||
} {
|
||||
b 1 1 b 2 2 b 3 3 b 4 4 b 5 5 b 6 6 b 7 7
|
||||
a 1 1 a 2 2 a 3 3 a 4 4 a 5 5 a 6 6 a 7 7
|
||||
b 1 1 b 2 2 b 3 3 b 4 4 b 5 5 b 6 6 b 7 7
|
||||
}
|
||||
|
||||
do_catchsql_test 6.3 {
|
||||
|
@ -131,8 +131,8 @@ do_eqp_test 3.2.2 {
|
||||
| | `--SCALAR SUBQUERY xxxxxx
|
||||
| | `--SCAN w2
|
||||
| `--RECURSIVE STEP
|
||||
| |--SCAN w1
|
||||
| `--SCAN c
|
||||
| |--SCAN c
|
||||
| `--SCAN w1
|
||||
|--SCAN c
|
||||
|--SEARCH w2 USING INTEGER PRIMARY KEY (rowid=?)
|
||||
`--SEARCH w1 USING INTEGER PRIMARY KEY (rowid=?)
|
||||
|
99
tool/omittest-msvc.tcl
Normal file
99
tool/omittest-msvc.tcl
Normal file
@ -0,0 +1,99 @@
|
||||
# Run this TCL script in order to build using MSVC multiple times
|
||||
# with various compile-time options. Use this to verify that the various
|
||||
# compile-time options all work with MSVC.
|
||||
#
|
||||
set OPTIONS [list \
|
||||
SQLITE_ALLOW_ROWID_IN_VIEW \
|
||||
SQLITE_ENABLE_COLUMN_METADATA \
|
||||
SQLITE_ENABLE_EXPENSIVE_ASSERT \
|
||||
SQLITE_ENABLE_IOTRACE \
|
||||
SQLITE_ENABLE_MEMORY_MANAGEMENT \
|
||||
SQLITE_ENABLE_MEMSYS3 \
|
||||
SQLITE_ENABLE_MEMSYS5 \
|
||||
SQLITE_ENABLE_OVERSIZE_CELL_CHECK \
|
||||
SQLITE_ENABLE_UNLOCK_NOTIFY \
|
||||
SQLITE_ENABLE_UPDATE_DELETE_LIMIT \
|
||||
SQLITE_OMIT_ALTERTABLE-x \
|
||||
SQLITE_OMIT_ATTACH-x \
|
||||
SQLITE_OMIT_AUTHORIZATION \
|
||||
SQLITE_OMIT_AUTOINCREMENT \
|
||||
SQLITE_OMIT_AUTOINIT \
|
||||
SQLITE_OMIT_AUTOMATIC_INDEX \
|
||||
SQLITE_OMIT_AUTORESET \
|
||||
SQLITE_OMIT_AUTOVACUUM \
|
||||
SQLITE_OMIT_BETWEEN_OPTIMIZATION \
|
||||
SQLITE_OMIT_BLOB_LITERAL \
|
||||
SQLITE_OMIT_BTREECOUNT \
|
||||
SQLITE_OMIT_CASE_SENSITIVE_LIKE_PRAGMA \
|
||||
SQLITE_OMIT_CAST \
|
||||
SQLITE_OMIT_CHECK \
|
||||
SQLITE_OMIT_COMPILEOPTION_DIAGS \
|
||||
SQLITE_OMIT_COMPLETE \
|
||||
SQLITE_OMIT_COMPOUND_SELECT \
|
||||
SQLITE_OMIT_CONFLICT_CLAUSE \
|
||||
SQLITE_OMIT_CTE \
|
||||
SQLITE_OMIT_DATETIME_FUNCS \
|
||||
SQLITE_OMIT_DECLTYPE \
|
||||
SQLITE_OMIT_DEPRECATED \
|
||||
SQLITE_OMIT_DESERIALIZE \
|
||||
SQLITE_OMIT_DISKIO-x \
|
||||
SQLITE_OMIT_EXPLAIN-x \
|
||||
SQLITE_OMIT_FLAG_PRAGMAS \
|
||||
SQLITE_OMIT_FLOATING_POINT \
|
||||
SQLITE_OMIT_FOREIGN_KEY \
|
||||
SQLITE_OMIT_GENERATED_COLUMNS \
|
||||
SQLITE_OMIT_GET_TABLE \
|
||||
SQLITE_OMIT_HEX_INTEGER \
|
||||
SQLITE_OMIT_INCRBLOB-x \
|
||||
SQLITE_OMIT_INTEGRITY_CHECK \
|
||||
SQLITE_OMIT_INTROSPECTION_PRAGMAS \
|
||||
SQLITE_OMIT_JSON \
|
||||
SQLITE_OMIT_LIKE_OPTIMIZATION \
|
||||
SQLITE_OMIT_LOAD_EXTENSION \
|
||||
SQLITE_OMIT_LOCALTIME \
|
||||
SQLITE_OMIT_LOOKASIDE \
|
||||
SQLITE_OMIT_MEMORYDB \
|
||||
SQLITE_OMIT_OR_OPTIMIZATION \
|
||||
SQLITE_OMIT_PAGER_PRAGMAS-x \
|
||||
SQLITE_OMIT_PARSER_TRACE \
|
||||
SQLITE_OMIT_POPEN \
|
||||
SQLITE_OMIT_PRAGMA-x \
|
||||
SQLITE_OMIT_PROGRESS_CALLBACK \
|
||||
SQLITE_OMIT_QUICKBALANCE \
|
||||
SQLITE_OMIT_RANDOMNESS \
|
||||
SQLITE_OMIT_REINDEX-x \
|
||||
SQLITE_OMIT_SCHEMA_PRAGMAS \
|
||||
SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS \
|
||||
SQLITE_OMIT_SHARED_CACHE \
|
||||
SQLITE_OMIT_SHUTDOWN_DIRECTORIES \
|
||||
SQLITE_OMIT_SUBQUERY-x \
|
||||
SQLITE_OMIT_TCL_VARIABLE \
|
||||
SQLITE_OMIT_TEMPDB \
|
||||
SQLITE_OMIT_TEST_CONTROL \
|
||||
SQLITE_OMIT_TRACE \
|
||||
SQLITE_OMIT_TRIGGER \
|
||||
SQLITE_OMIT_TRUNCATE_OPTIMIZATION \
|
||||
SQLITE_OMIT_UPSERT \
|
||||
SQLITE_OMIT_UTF16 \
|
||||
SQLITE_OMIT_VACUUM-x \
|
||||
SQLITE_OMIT_VIEW-x \
|
||||
SQLITE_OMIT_VIRTUALTABLE-x \
|
||||
SQLITE_OMIT_WAL \
|
||||
SQLITE_OMIT_WINDOWFUNC-x \
|
||||
SQLITE_OMIT_WSD \
|
||||
SQLITE_OMIT_XFER_OPT \
|
||||
]
|
||||
set start [lindex $argv 0]
|
||||
foreach opt $OPTIONS {
|
||||
if {[regexp x $opt]} continue
|
||||
if {[string compare $opt $start]<0} continue
|
||||
exec fossil clean -x
|
||||
set cmd "nmake /f Makefile.msc USE_FULLWARN=0 OPTIMIZATIONS=0"
|
||||
append cmd " CCOPTS=-D$opt"
|
||||
puts $cmd
|
||||
set res [catch {eval exec $cmd} outtxt]
|
||||
if {[regexp {sqlite3.c.\d+.: error} $outtxt]} {
|
||||
puts "FAILED:\n$outtxt"
|
||||
exit
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user