From 5a500afd571a5f1219d6e840e8ab41ba772eb616 Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 11 Mar 2014 20:33:04 +0000 Subject: [PATCH 01/12] Enable the b-tree cursor objects overflow page-number cache, which is normally enabled only for incr-blob cursors, for all cursors. FossilOrigin-Name: da59198505990a4fe832be7932117c7e014955b7 --- manifest | 26 +++++++------- manifest.uuid | 2 +- src/btree.c | 98 +++++++++++++++++++++++--------------------------- src/btree.h | 2 +- src/btreeInt.h | 2 ++ src/vdbeblob.c | 4 +-- 6 files changed, 63 insertions(+), 71 deletions(-) diff --git a/manifest b/manifest index 219399a93b..17e141330e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Version\s3.8.4.1 -D 2014-03-11T15:27:36.923 +C Enable\sthe\sb-tree\scursor\sobjects\soverflow\spage-number\scache,\swhich\sis\snormally\senabled\sonly\sfor\sincr-blob\scursors,\sfor\sall\scursors. +D 2014-03-11T20:33:04.219 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -164,9 +164,9 @@ F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34 F src/backup.c a729e63cf5cd1829507cb7b8e89f99b95141bb53 F src/bitvec.c 19a4ba637bd85f8f63fc8c9bae5ade9fb05ec1cb F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7 -F src/btree.c 4d28fb15543f0e071b1780b2af8cd2ee489de32d -F src/btree.h 9e0f97c01b972f779eb7655cfb4f8727fd6dc26f -F src/btreeInt.h 0be66063468a520e4d66b80c7a1dc26d04ee6ea4 +F src/btree.c c748d8387789d01769e442b9da65e52ed61f408e +F src/btree.h 6b0c1a3f0937f9852ec727c820e71dbdd4bd0b27 +F src/btreeInt.h 22a8f07968ec821910ab93cc822d7f0c404c74d1 F src/build.c 0d50ef95aad63f4c4fc47f3fa2670d4557c45db0 F src/callback.c 174e3c8656bc29f91d710ab61550d16eea34be98 F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac @@ -283,7 +283,7 @@ F src/vdbe.h fb2c48c198300a7c632f09fc940011d2ad2fc2ae F src/vdbeInt.h e54fc4f289fce48e81b3371128446033d097733b F src/vdbeapi.c 0ed6053f947edd0b30f64ce5aeb811872a3450a4 F src/vdbeaux.c e45e3f9daf38c5be3fd39e9aacc1c9066af57a06 -F src/vdbeblob.c 15377abfb59251bccedd5a9c7d014a895f0c04aa +F src/vdbeblob.c 9205ce9d3b064d9600f8418a897fc88b5687d9ac F src/vdbemem.c 6fc77594c60f6155404f3f8d71bf36d1fdeb4447 F src/vdbesort.c 46801acb342e5e4c07ba1777fe58880c143abb59 F src/vdbetrace.c 6f52bc0c51e144b7efdcfb2a8f771167a8816767 @@ -1156,10 +1156,10 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 33f5694fa42d9a521ca081de4ddd1e9dc8952b16 -R 581994aed374f15c1c6bac5b0a9a5df5 -T +bgcolor * #d0c0ff -T +sym-release * -T +sym-version-3.8.4.1 * -U drh -Z c1ec45dc8a92b80bfa16f4c74ccfeec8 +P 018d317b1257ce68a92908b05c9c7cf1494050d0 +R 9660042129e37a760044c3b5edf13974 +T *branch * overflow-pgno-cache +T *sym-overflow-pgno-cache * +T -sym-trunk * +U dan +Z 262878375cf61ff20b91f83b47f52bc2 diff --git a/manifest.uuid b/manifest.uuid index 1f0b42178b..6b4cb8a17f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -018d317b1257ce68a92908b05c9c7cf1494050d0 \ No newline at end of file +da59198505990a4fe832be7932117c7e014955b7 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 29ead1c67a..5716a5199a 100644 --- a/src/btree.c +++ b/src/btree.c @@ -446,16 +446,11 @@ static int cursorHoldsMutex(BtCursor *p){ } #endif - -#ifndef SQLITE_OMIT_INCRBLOB /* -** Invalidate the overflow page-list cache for cursor pCur, if any. +** Invalidate the overflow cache of the cursor passed as the first argument. +** on the shared btree structure pBt. */ -static void invalidateOverflowCache(BtCursor *pCur){ - assert( cursorHoldsMutex(pCur) ); - sqlite3_free(pCur->aOverflow); - pCur->aOverflow = 0; -} +#define invalidateOverflowCache(pCur) (pCur->bOvflValid = 0) /* ** Invalidate the overflow page-list cache for all cursors opened @@ -469,6 +464,7 @@ static void invalidateAllOverflowCache(BtShared *pBt){ } } +#ifndef SQLITE_OMIT_INCRBLOB /* ** This function is called before modifying the contents of a table ** to invalidate any incrblob cursors that are open on the @@ -498,9 +494,7 @@ static void invalidateIncrblobCursors( } #else - /* Stub functions when INCRBLOB is omitted */ - #define invalidateOverflowCache(x) - #define invalidateAllOverflowCache(x) + /* Stub function when INCRBLOB is omitted */ #define invalidateIncrblobCursors(x,y,z) #endif /* SQLITE_OMIT_INCRBLOB */ @@ -3694,7 +3688,7 @@ int sqlite3BtreeCloseCursor(BtCursor *pCur){ releasePage(pCur->apPage[i]); } unlockBtreeIfUnused(pBt); - invalidateOverflowCache(pCur); + sqlite3DbFree(pBtree->db, pCur->aOverflow); /* sqlite3_free(pCur); */ sqlite3BtreeLeave(pBtree); } @@ -3915,10 +3909,12 @@ static int copyPayload( /* ** This function is used to read or overwrite payload information -** for the entry that the pCur cursor is pointing to. If the eOp -** parameter is 0, this is a read operation (data copied into -** buffer pBuf). If it is non-zero, a write (data copied from -** buffer pBuf). +** for the entry that the pCur cursor is pointing to. The eOp +** argument is interpreted as follows: +** +** 0: The operation is a read. Populate the overflow cache. +** 1: The operation is a write. Populate the overflow cache. +** 2: The operation is a read. Do not populate the overflow cache. ** ** A total of "amt" bytes are read or written beginning at "offset". ** Data is read to or from the buffer pBuf. @@ -3926,11 +3922,11 @@ static int copyPayload( ** The content being read or written might appear on the main page ** or be scattered out on multiple overflow pages. ** -** If the BtCursor.isIncrblobHandle flag is set, and the current -** cursor entry uses one or more overflow pages, this function -** allocates space for and lazily popluates the overflow page-list -** cache array (BtCursor.aOverflow). Subsequent calls use this -** cache to make seeking to the supplied offset more efficient. +** If the current cursor entry uses one or more overflow pages and the +** eOp argument is not 2, this function may allocate space for and lazily +** popluates the overflow page-list cache array (BtCursor.aOverflow). +** Subsequent calls use this cache to make seeking to the supplied offset +** more efficient. ** ** Once an overflow page-list cache has been allocated, it may be ** invalidated if some other cursor writes to the same table, or if @@ -3977,7 +3973,7 @@ static int accessPayload( if( a+offset>pCur->info.nLocal ){ a = pCur->info.nLocal - offset; } - rc = copyPayload(&aPayload[offset], pBuf, a, eOp, pPage->pDbPage); + rc = copyPayload(&aPayload[offset], pBuf, a, (eOp & 0x01), pPage->pDbPage); offset = 0; pBuf += a; amt -= a; @@ -3991,7 +3987,6 @@ static int accessPayload( nextPage = get4byte(&aPayload[pCur->info.nLocal]); -#ifndef SQLITE_OMIT_INCRBLOB /* If the isIncrblobHandle flag is set and the BtCursor.aOverflow[] ** has not been allocated, allocate it now. The array is sized at ** one entry for each overflow page in the overflow chain. The @@ -3999,13 +3994,22 @@ static int accessPayload( ** etc. A value of 0 in the aOverflow[] array means "not yet known" ** (the cache is lazily populated). */ - if( pCur->isIncrblobHandle && !pCur->aOverflow ){ + if( eOp!=2 && !pCur->bOvflValid ){ int nOvfl = (pCur->info.nPayload-pCur->info.nLocal+ovflSize-1)/ovflSize; - pCur->aOverflow = (Pgno *)sqlite3MallocZero(sizeof(Pgno)*nOvfl); - /* nOvfl is always positive. If it were zero, fetchPayload would have - ** been used instead of this routine. */ - if( ALWAYS(nOvfl) && !pCur->aOverflow ){ - rc = SQLITE_NOMEM; + if( nOvfl>pCur->nOvflAlloc ){ + Pgno *aNew = (Pgno*)sqlite3DbRealloc( + pCur->pBtree->db, pCur->aOverflow, nOvfl*2*sizeof(Pgno) + ); + if( aNew==0 ){ + rc = SQLITE_NOMEM; + }else{ + pCur->nOvflAlloc = nOvfl*2; + pCur->aOverflow = aNew; + } + } + if( rc==SQLITE_OK ){ + memset(pCur->aOverflow, 0, nOvfl*sizeof(Pgno)); + pCur->bOvflValid = 1; } } @@ -4013,22 +4017,19 @@ static int accessPayload( ** entry for the first required overflow page is valid, skip ** directly to it. */ - if( pCur->aOverflow && pCur->aOverflow[offset/ovflSize] ){ + if( pCur->bOvflValid && pCur->aOverflow[offset/ovflSize] ){ iIdx = (offset/ovflSize); nextPage = pCur->aOverflow[iIdx]; offset = (offset%ovflSize); } -#endif for( ; rc==SQLITE_OK && amt>0 && nextPage; iIdx++){ -#ifndef SQLITE_OMIT_INCRBLOB /* If required, populate the overflow page-list cache. */ - if( pCur->aOverflow ){ + if( pCur->bOvflValid ){ assert(!pCur->aOverflow[iIdx] || pCur->aOverflow[iIdx]==nextPage); pCur->aOverflow[iIdx] = nextPage; } -#endif if( offset>=ovflSize ){ /* The only reason to read this page is to obtain the page @@ -4037,11 +4038,9 @@ static int accessPayload( ** page-list cache, if any, then fall back to the getOverflowPage() ** function. */ -#ifndef SQLITE_OMIT_INCRBLOB - if( pCur->aOverflow && pCur->aOverflow[iIdx+1] ){ + if( pCur->bOvflValid && pCur->aOverflow[iIdx+1] ){ nextPage = pCur->aOverflow[iIdx+1]; } else -#endif rc = getOverflowPage(pBt, nextPage, 0, &nextPage); offset -= ovflSize; }else{ @@ -4069,7 +4068,7 @@ static int accessPayload( ** output buffer, bypassing the page-cache altogether. This speeds ** up loading large records that span many overflow pages. */ - if( eOp==0 /* (1) */ + if( (eOp&0x01)==0 /* (1) */ && offset==0 /* (2) */ && pBt->inTransaction==TRANS_READ /* (4) */ && (fd = sqlite3PagerFile(pBt->pPager))->pMethods /* (3) */ @@ -4087,12 +4086,12 @@ static int accessPayload( { DbPage *pDbPage; rc = sqlite3PagerAcquire(pBt->pPager, nextPage, &pDbPage, - (eOp==0 ? PAGER_GET_READONLY : 0) + ((eOp&0x01)==0 ? PAGER_GET_READONLY : 0) ); if( rc==SQLITE_OK ){ aPayload = sqlite3PagerGetData(pDbPage); nextPage = get4byte(aPayload); - rc = copyPayload(&aPayload[offset+4], pBuf, a, eOp, pDbPage); + rc = copyPayload(&aPayload[offset+4], pBuf, a, (eOp&0x01), pDbPage); sqlite3PagerUnref(pDbPage); offset = 0; } @@ -4337,6 +4336,7 @@ static int moveToRoot(BtCursor *pCur){ assert( CURSOR_INVALID < CURSOR_REQUIRESEEK ); assert( CURSOR_VALID < CURSOR_REQUIRESEEK ); assert( CURSOR_FAULT > CURSOR_REQUIRESEEK ); + invalidateOverflowCache(pCur); if( pCur->eState>=CURSOR_REQUIRESEEK ){ if( pCur->eState==CURSOR_FAULT ){ assert( pCur->skipNext!=SQLITE_OK ); @@ -4686,7 +4686,7 @@ int sqlite3BtreeMovetoUnpacked( goto moveto_finish; } pCur->aiIdx[pCur->iPage] = (u16)idx; - rc = accessPayload(pCur, 0, nCell, (unsigned char*)pCellKey, 0); + rc = accessPayload(pCur, 0, nCell, (unsigned char*)pCellKey, 2); if( rc ){ sqlite3_free(pCellKey); goto moveto_finish; @@ -4775,6 +4775,7 @@ int sqlite3BtreeNext(BtCursor *pCur, int *pRes){ assert( pRes!=0 ); assert( *pRes==0 || *pRes==1 ); assert( pCur->skipNext==0 || pCur->eState!=CURSOR_VALID ); + invalidateOverflowCache(pCur); if( pCur->eState!=CURSOR_VALID ){ rc = restoreCursorPosition(pCur); if( rc!=SQLITE_OK ){ @@ -4870,6 +4871,7 @@ int sqlite3BtreePrevious(BtCursor *pCur, int *pRes){ assert( pRes!=0 ); assert( *pRes==0 || *pRes==1 ); assert( pCur->skipNext==0 || pCur->eState!=CURSOR_VALID ); + invalidateOverflowCache(pCur); pCur->atLast = 0; if( pCur->eState!=CURSOR_VALID ){ if( ALWAYS(pCur->eState>=CURSOR_REQUIRESEEK) ){ @@ -8424,19 +8426,9 @@ int sqlite3BtreePutData(BtCursor *pCsr, u32 offset, u32 amt, void *z){ } /* -** Set a flag on this cursor to cache the locations of pages from the -** overflow list for the current row. This is used by cursors opened -** for incremental blob IO only. -** -** This function sets a flag only. The actual page location cache -** (stored in BtCursor.aOverflow[]) is allocated and used by function -** accessPayload() (the worker function for sqlite3BtreeData() and -** sqlite3BtreePutData()). +** Mark this cursor as an incremental blob cursor. */ -void sqlite3BtreeCacheOverflow(BtCursor *pCur){ - assert( cursorHoldsMutex(pCur) ); - assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) ); - invalidateOverflowCache(pCur); +void sqlite3BtreeIncrblobCursor(BtCursor *pCur){ pCur->isIncrblobHandle = 1; } #endif diff --git a/src/btree.h b/src/btree.h index eda7bef70a..bedbef692f 100644 --- a/src/btree.h +++ b/src/btree.h @@ -187,7 +187,7 @@ char *sqlite3BtreeIntegrityCheck(Btree*, int *aRoot, int nRoot, int, int*); struct Pager *sqlite3BtreePager(Btree*); int sqlite3BtreePutData(BtCursor*, u32 offset, u32 amt, void*); -void sqlite3BtreeCacheOverflow(BtCursor *); +void sqlite3BtreeIncrblobCursor(BtCursor *); void sqlite3BtreeClearCursor(BtCursor *); int sqlite3BtreeSetVersion(Btree *pBt, int iVersion); void sqlite3BtreeCursorHints(BtCursor *, unsigned int mask); diff --git a/src/btreeInt.h b/src/btreeInt.h index 87b4181f82..a41d8ebb55 100644 --- a/src/btreeInt.h +++ b/src/btreeInt.h @@ -497,6 +497,8 @@ struct BtCursor { BtCursor *pNext, *pPrev; /* Forms a linked list of all cursors */ struct KeyInfo *pKeyInfo; /* Argument passed to comparison function */ #ifndef SQLITE_OMIT_INCRBLOB + int nOvflAlloc; /* Allocated size of aOverflow[] array */ + u8 bOvflValid; /* True if size and contents of aOverflow[] valid */ Pgno *aOverflow; /* Cache of overflow page locations */ #endif Pgno pgnoRoot; /* The root page of this tree */ diff --git a/src/vdbeblob.c b/src/vdbeblob.c index cf7495e5b4..083f3f413c 100644 --- a/src/vdbeblob.c +++ b/src/vdbeblob.c @@ -77,9 +77,7 @@ static int blobSeekToRow(Incrblob *p, sqlite3_int64 iRow, char **pzErr){ p->iOffset = pC->aType[p->iCol + pC->nField]; p->nByte = sqlite3VdbeSerialTypeLen(type); p->pCsr = pC->pCursor; - sqlite3BtreeEnterCursor(p->pCsr); - sqlite3BtreeCacheOverflow(p->pCsr); - sqlite3BtreeLeaveCursor(p->pCsr); + sqlite3BtreeIncrblobCursor(p->pCsr); } } From 036dbec01c083e196725e7fff530e8f8de61914d Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 11 Mar 2014 23:40:44 +0000 Subject: [PATCH 02/12] Combine the various boolean fields of the BtCursor object into a single bit-vector. This allows setting or clearing more than one boolean at a time and makes the overflow-pgno-cache branch faster than trunk on speedtest1. FossilOrigin-Name: 968fec44d7fde3adbd3e9603e4282351f0d4bda1 --- manifest | 21 ++++++------ manifest.uuid | 2 +- src/btree.c | 84 +++++++++++++++++++++++++----------------------- src/btreeInt.h | 27 ++++++++-------- src/test_btree.c | 2 +- 5 files changed, 69 insertions(+), 67 deletions(-) diff --git a/manifest b/manifest index 17e141330e..24561347ec 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Enable\sthe\sb-tree\scursor\sobjects\soverflow\spage-number\scache,\swhich\sis\snormally\senabled\sonly\sfor\sincr-blob\scursors,\sfor\sall\scursors. -D 2014-03-11T20:33:04.219 +C Combine\sthe\svarious\sboolean\sfields\sof\sthe\sBtCursor\sobject\sinto\sa\ssingle\nbit-vector.\s\sThis\sallows\ssetting\sor\sclearing\smore\sthan\sone\sboolean\sat\sa\ntime\sand\smakes\sthe\soverflow-pgno-cache\sbranch\sfaster\sthan\strunk\son\s\nspeedtest1. +D 2014-03-11T23:40:44.961 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -164,9 +164,9 @@ F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34 F src/backup.c a729e63cf5cd1829507cb7b8e89f99b95141bb53 F src/bitvec.c 19a4ba637bd85f8f63fc8c9bae5ade9fb05ec1cb F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7 -F src/btree.c c748d8387789d01769e442b9da65e52ed61f408e +F src/btree.c 225a3f4d5511d4f5eab38a686f6c7e22290739f3 F src/btree.h 6b0c1a3f0937f9852ec727c820e71dbdd4bd0b27 -F src/btreeInt.h 22a8f07968ec821910ab93cc822d7f0c404c74d1 +F src/btreeInt.h d1784d1e17d08d29e890190dbb9836fa64573381 F src/build.c 0d50ef95aad63f4c4fc47f3fa2670d4557c45db0 F src/callback.c 174e3c8656bc29f91d710ab61550d16eea34be98 F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac @@ -239,7 +239,7 @@ F src/test9.c bea1e8cf52aa93695487badedd6e1886c321ea60 F src/test_async.c 21e11293a2f72080eda70e1124e9102044531cd8 F src/test_autoext.c dea8a01a7153b9adc97bd26161e4226329546e12 F src/test_backup.c 3875e899222b651e18b662f86e0e50daa946344e -F src/test_btree.c 5b89601dcb42a33ba8b820a6b763cc9cb48bac16 +F src/test_btree.c 2e9978eca99a9a4bfa8cae949efb00886860a64f F src/test_config.c 0336e0bdbe541b4af89d7e3dd0656e8e6b51e585 F src/test_demovfs.c 69b2085076654ebc18014cbc6386f04409c959a9 F src/test_devsym.c e7498904e72ba7491d142d5c83b476c4e76993bc @@ -1156,10 +1156,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 018d317b1257ce68a92908b05c9c7cf1494050d0 -R 9660042129e37a760044c3b5edf13974 -T *branch * overflow-pgno-cache -T *sym-overflow-pgno-cache * -T -sym-trunk * -U dan -Z 262878375cf61ff20b91f83b47f52bc2 +P da59198505990a4fe832be7932117c7e014955b7 +R a9a97bb8415d8a76adacb051af2ccc88 +U drh +Z 90b8a93448c14945f126312bc79eea6f diff --git a/manifest.uuid b/manifest.uuid index 6b4cb8a17f..6cfc27f694 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -da59198505990a4fe832be7932117c7e014955b7 \ No newline at end of file +968fec44d7fde3adbd3e9603e4282351f0d4bda1 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 5716a5199a..bd1a0e1c75 100644 --- a/src/btree.c +++ b/src/btree.c @@ -450,7 +450,7 @@ static int cursorHoldsMutex(BtCursor *p){ ** Invalidate the overflow cache of the cursor passed as the first argument. ** on the shared btree structure pBt. */ -#define invalidateOverflowCache(pCur) (pCur->bOvflValid = 0) +#define invalidateOverflowCache(pCur) (pCur->curFlags &= ~BTCF_ValidOvfl) /* ** Invalidate the overflow page-list cache for all cursors opened @@ -487,7 +487,7 @@ static void invalidateIncrblobCursors( BtShared *pBt = pBtree->pBt; assert( sqlite3BtreeHoldsMutex(pBtree) ); for(p=pBt->pCursor; p; p=p->pNext){ - if( p->isIncrblobHandle && (isClearTable || p->info.nKey==iRow) ){ + if( (p->curFlags & BTCF_Incrblob)!=0 && (isClearTable || p->info.nKey==iRow) ){ p->eState = CURSOR_INVALID; } } @@ -2543,7 +2543,8 @@ static int countValidCursors(BtShared *pBt, int wrOnly){ BtCursor *pCur; int r = 0; for(pCur=pBt->pCursor; pCur; pCur=pCur->pNext){ - if( (wrOnly==0 || pCur->wrFlag) && pCur->eState!=CURSOR_FAULT ) r++; + if( (wrOnly==0 || (pCur->curFlags & BTCF_WriteFlag)!=0) + && pCur->eState!=CURSOR_FAULT ) r++; } return r; } @@ -3618,7 +3619,7 @@ static int btreeCursor( pCur->pKeyInfo = pKeyInfo; pCur->pBtree = p; pCur->pBt = pBt; - pCur->wrFlag = (u8)wrFlag; + pCur->curFlags = wrFlag ? BTCF_WriteFlag : 0; pCur->pNext = pBt->pCursor; if( pCur->pNext ){ pCur->pNext->pPrev = pCur; @@ -3727,7 +3728,7 @@ int sqlite3BtreeCloseCursor(BtCursor *pCur){ if( pCur->info.nSize==0 ){ int iPage = pCur->iPage; btreeParseCell(pCur->apPage[iPage],pCur->aiIdx[iPage],&pCur->info); - pCur->validNKey = 1; + pCur->curFlags |= BTCF_ValidNKey; }else{ assertCellInfo(pCur); } @@ -3737,8 +3738,8 @@ int sqlite3BtreeCloseCursor(BtCursor *pCur){ #define getCellInfo(pCur) \ if( pCur->info.nSize==0 ){ \ int iPage = pCur->iPage; \ - btreeParseCell(pCur->apPage[iPage],pCur->aiIdx[iPage],&pCur->info); \ - pCur->validNKey = 1; \ + btreeParseCell(pCur->apPage[iPage],pCur->aiIdx[iPage],&pCur->info); \ + pCur->curFlags |= BTCF_ValidNKey; \ }else{ \ assertCellInfo(pCur); \ } @@ -3987,14 +3988,14 @@ static int accessPayload( nextPage = get4byte(&aPayload[pCur->info.nLocal]); - /* If the isIncrblobHandle flag is set and the BtCursor.aOverflow[] + /* If the BTCF_Incrblob flag is set and the BtCursor.aOverflow[] ** has not been allocated, allocate it now. The array is sized at ** one entry for each overflow page in the overflow chain. The ** page number of the first overflow page is stored in aOverflow[0], ** etc. A value of 0 in the aOverflow[] array means "not yet known" ** (the cache is lazily populated). */ - if( eOp!=2 && !pCur->bOvflValid ){ + if( eOp!=2 && (pCur->curFlags & BTCF_ValidOvfl)==0 ){ int nOvfl = (pCur->info.nPayload-pCur->info.nLocal+ovflSize-1)/ovflSize; if( nOvfl>pCur->nOvflAlloc ){ Pgno *aNew = (Pgno*)sqlite3DbRealloc( @@ -4009,7 +4010,7 @@ static int accessPayload( } if( rc==SQLITE_OK ){ memset(pCur->aOverflow, 0, nOvfl*sizeof(Pgno)); - pCur->bOvflValid = 1; + pCur->curFlags |= BTCF_ValidOvfl; } } @@ -4017,7 +4018,7 @@ static int accessPayload( ** entry for the first required overflow page is valid, skip ** directly to it. */ - if( pCur->bOvflValid && pCur->aOverflow[offset/ovflSize] ){ + if( (pCur->curFlags & BTCF_ValidOvfl)!=0 && pCur->aOverflow[offset/ovflSize] ){ iIdx = (offset/ovflSize); nextPage = pCur->aOverflow[iIdx]; offset = (offset%ovflSize); @@ -4026,7 +4027,7 @@ static int accessPayload( for( ; rc==SQLITE_OK && amt>0 && nextPage; iIdx++){ /* If required, populate the overflow page-list cache. */ - if( pCur->bOvflValid ){ + if( (pCur->curFlags & BTCF_ValidOvfl)!=0 ){ assert(!pCur->aOverflow[iIdx] || pCur->aOverflow[iIdx]==nextPage); pCur->aOverflow[iIdx] = nextPage; } @@ -4038,7 +4039,7 @@ static int accessPayload( ** page-list cache, if any, then fall back to the getOverflowPage() ** function. */ - if( pCur->bOvflValid && pCur->aOverflow[iIdx+1] ){ + if( (pCur->curFlags & BTCF_ValidOvfl)!=0 && pCur->aOverflow[iIdx+1] ){ nextPage = pCur->aOverflow[iIdx+1]; } else rc = getOverflowPage(pBt, nextPage, 0, &nextPage); @@ -4239,14 +4240,14 @@ static int moveToChild(BtCursor *pCur, u32 newPgno){ return SQLITE_CORRUPT_BKPT; } rc = getAndInitPage(pBt, newPgno, &pNewPage, - pCur->wrFlag==0 ? PAGER_GET_READONLY : 0); + (pCur->curFlags & BTCF_WriteFlag)==0 ? PAGER_GET_READONLY : 0); if( rc ) return rc; pCur->apPage[i+1] = pNewPage; pCur->aiIdx[i+1] = 0; pCur->iPage++; pCur->info.nSize = 0; - pCur->validNKey = 0; + pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl); if( pNewPage->nCell<1 || pNewPage->intKey!=pCur->apPage[i]->intKey ){ return SQLITE_CORRUPT_BKPT; } @@ -4304,7 +4305,7 @@ static void moveToParent(BtCursor *pCur){ releasePage(pCur->apPage[pCur->iPage]); pCur->iPage--; pCur->info.nSize = 0; - pCur->validNKey = 0; + pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl); } /* @@ -4336,7 +4337,7 @@ static int moveToRoot(BtCursor *pCur){ assert( CURSOR_INVALID < CURSOR_REQUIRESEEK ); assert( CURSOR_VALID < CURSOR_REQUIRESEEK ); assert( CURSOR_FAULT > CURSOR_REQUIRESEEK ); - invalidateOverflowCache(pCur); +// invalidateOverflowCache(pCur); if( pCur->eState>=CURSOR_REQUIRESEEK ){ if( pCur->eState==CURSOR_FAULT ){ assert( pCur->skipNext!=SQLITE_OK ); @@ -4352,7 +4353,7 @@ static int moveToRoot(BtCursor *pCur){ return SQLITE_OK; }else{ rc = getAndInitPage(pCur->pBtree->pBt, pCur->pgnoRoot, &pCur->apPage[0], - pCur->wrFlag==0 ? PAGER_GET_READONLY : 0); + (pCur->curFlags & BTCF_WriteFlag)==0 ? PAGER_GET_READONLY : 0); if( rc!=SQLITE_OK ){ pCur->eState = CURSOR_INVALID; return rc; @@ -4379,8 +4380,7 @@ static int moveToRoot(BtCursor *pCur){ pCur->aiIdx[0] = 0; pCur->info.nSize = 0; - pCur->atLast = 0; - pCur->validNKey = 0; + pCur->curFlags &= ~(BTCF_AtLast|BTCF_ValidNKey|BTCF_ValidOvfl); if( pRoot->nCell>0 ){ pCur->eState = CURSOR_VALID; @@ -4443,7 +4443,7 @@ static int moveToRightmost(BtCursor *pCur){ if( rc==SQLITE_OK ){ pCur->aiIdx[pCur->iPage] = pPage->nCell-1; pCur->info.nSize = 0; - pCur->validNKey = 0; + pCur->curFlags &= ~BTCF_ValidNKey; } return rc; } @@ -4482,7 +4482,7 @@ int sqlite3BtreeLast(BtCursor *pCur, int *pRes){ assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) ); /* If the cursor already points to the last entry, this is a no-op. */ - if( CURSOR_VALID==pCur->eState && pCur->atLast ){ + 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. */ @@ -4505,7 +4505,12 @@ int sqlite3BtreeLast(BtCursor *pCur, int *pRes){ assert( pCur->eState==CURSOR_VALID ); *pRes = 0; rc = moveToRightmost(pCur); - pCur->atLast = rc==SQLITE_OK ?1:0; + if( rc==SQLITE_OK ){ + pCur->curFlags |= BTCF_AtLast; + }else{ + pCur->curFlags &= ~BTCF_AtLast; + } + } } return rc; @@ -4556,14 +4561,14 @@ int sqlite3BtreeMovetoUnpacked( /* If the cursor is already positioned at the point we are trying ** to move to, then just return without doing any work */ - if( pCur->eState==CURSOR_VALID && pCur->validNKey + if( pCur->eState==CURSOR_VALID && (pCur->curFlags & BTCF_ValidNKey)!=0 && pCur->apPage[0]->intKey ){ if( pCur->info.nKey==intKey ){ *pRes = 0; return SQLITE_OK; } - if( pCur->atLast && pCur->info.nKeycurFlags & BTCF_AtLast)!=0 && pCur->info.nKeyupr ){ c = +1; break; } }else{ assert( nCellKey==intKey ); - pCur->validNKey = 1; + pCur->curFlags |= BTCF_ValidNKey; pCur->info.nKey = nCellKey; pCur->aiIdx[pCur->iPage] = (u16)idx; if( !pPage->leaf ){ @@ -4731,7 +4736,7 @@ moveto_next_layer: } moveto_finish: pCur->info.nSize = 0; - pCur->validNKey = 0; + pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl); return rc; } @@ -4775,8 +4780,8 @@ int sqlite3BtreeNext(BtCursor *pCur, int *pRes){ assert( pRes!=0 ); assert( *pRes==0 || *pRes==1 ); assert( pCur->skipNext==0 || pCur->eState!=CURSOR_VALID ); - invalidateOverflowCache(pCur); if( pCur->eState!=CURSOR_VALID ){ + invalidateOverflowCache(pCur); rc = restoreCursorPosition(pCur); if( rc!=SQLITE_OK ){ *pRes = 0; @@ -4810,7 +4815,7 @@ int sqlite3BtreeNext(BtCursor *pCur, int *pRes){ testcase( idx>pPage->nCell ); pCur->info.nSize = 0; - pCur->validNKey = 0; + pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl); if( idx>=pPage->nCell ){ if( !pPage->leaf ){ rc = moveToChild(pCur, get4byte(&pPage->aData[pPage->hdrOffset+8])); @@ -4871,8 +4876,7 @@ int sqlite3BtreePrevious(BtCursor *pCur, int *pRes){ assert( pRes!=0 ); assert( *pRes==0 || *pRes==1 ); assert( pCur->skipNext==0 || pCur->eState!=CURSOR_VALID ); - invalidateOverflowCache(pCur); - pCur->atLast = 0; + pCur->curFlags &= ~(BTCF_AtLast|BTCF_ValidOvfl); if( pCur->eState!=CURSOR_VALID ){ if( ALWAYS(pCur->eState>=CURSOR_REQUIRESEEK) ){ rc = btreeRestoreCursorPosition(pCur); @@ -4917,7 +4921,7 @@ int sqlite3BtreePrevious(BtCursor *pCur, int *pRes){ moveToParent(pCur); } pCur->info.nSize = 0; - pCur->validNKey = 0; + pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl); pCur->aiIdx[pCur->iPage]--; pPage = pCur->apPage[pCur->iPage]; @@ -6942,7 +6946,7 @@ int sqlite3BtreeInsert( } assert( cursorHoldsMutex(pCur) ); - assert( pCur->wrFlag && pBt->inTransaction==TRANS_WRITE + assert( (pCur->curFlags & BTCF_WriteFlag)!=0 && pBt->inTransaction==TRANS_WRITE && (pBt->btsFlags & BTS_READ_ONLY)==0 ); assert( hasSharedCacheTableLock(p, pCur->pgnoRoot, pCur->pKeyInfo!=0, 2) ); @@ -6975,7 +6979,7 @@ int sqlite3BtreeInsert( /* If the cursor is currently on the last row and we are appending a ** new row onto the end, set the "loc" to avoid an unnecessary btreeMoveto() ** call */ - if( pCur->validNKey && nKey>0 && pCur->info.nKey==nKey-1 ){ + if( (pCur->curFlags&BTCF_ValidNKey)!=0 && nKey>0 && pCur->info.nKey==nKey-1 ){ loc = -1; } } @@ -7028,7 +7032,7 @@ int sqlite3BtreeInsert( /* If no error has occurred and pPage has an overflow cell, call balance() ** to redistribute the cells within the tree. Since balance() may move - ** the cursor, zero the BtCursor.info.nSize and BtCursor.validNKey + ** the cursor, zero the BtCursor.info.nSize and BTCF_ValidNKey ** variables. ** ** Previous versions of SQLite called moveToRoot() to move the cursor @@ -7048,7 +7052,7 @@ int sqlite3BtreeInsert( */ pCur->info.nSize = 0; if( rc==SQLITE_OK && pPage->nOverflow ){ - pCur->validNKey = 0; + pCur->curFlags &= ~(BTCF_ValidNKey); rc = balance(pCur); /* Must make sure nOverflow is reset to zero even if the balance() @@ -7080,7 +7084,7 @@ int sqlite3BtreeDelete(BtCursor *pCur){ assert( cursorHoldsMutex(pCur) ); assert( pBt->inTransaction==TRANS_WRITE ); assert( (pBt->btsFlags & BTS_READ_ONLY)==0 ); - assert( pCur->wrFlag ); + assert( pCur->curFlags & BTCF_WriteFlag ); assert( hasSharedCacheTableLock(p, pCur->pgnoRoot, pCur->pKeyInfo!=0, 2) ); assert( !hasReadConflicts(p, pCur->pgnoRoot) ); @@ -8384,7 +8388,7 @@ int sqlite3BtreePutData(BtCursor *pCsr, u32 offset, u32 amt, void *z){ int rc; assert( cursorHoldsMutex(pCsr) ); assert( sqlite3_mutex_held(pCsr->pBtree->db->mutex) ); - assert( pCsr->isIncrblobHandle ); + assert( pCsr->curFlags & BTCF_Incrblob ); rc = restoreCursorPosition(pCsr); if( rc!=SQLITE_OK ){ @@ -8413,7 +8417,7 @@ int sqlite3BtreePutData(BtCursor *pCsr, u32 offset, u32 amt, void *z){ ** (d) there are no conflicting read-locks, and ** (e) the cursor points at a valid row of an intKey table. */ - if( !pCsr->wrFlag ){ + if( (pCsr->curFlags & BTCF_WriteFlag)==0 ){ return SQLITE_READONLY; } assert( (pCsr->pBt->btsFlags & BTS_READ_ONLY)==0 @@ -8429,7 +8433,7 @@ int sqlite3BtreePutData(BtCursor *pCsr, u32 offset, u32 amt, void *z){ ** Mark this cursor as an incremental blob cursor. */ void sqlite3BtreeIncrblobCursor(BtCursor *pCur){ - pCur->isIncrblobHandle = 1; + pCur->curFlags |= BTCF_Incrblob; } #endif diff --git a/src/btreeInt.h b/src/btreeInt.h index a41d8ebb55..dff07f145e 100644 --- a/src/btreeInt.h +++ b/src/btreeInt.h @@ -496,29 +496,30 @@ struct BtCursor { BtShared *pBt; /* The BtShared this cursor points to */ BtCursor *pNext, *pPrev; /* Forms a linked list of all cursors */ struct KeyInfo *pKeyInfo; /* Argument passed to comparison function */ -#ifndef SQLITE_OMIT_INCRBLOB - int nOvflAlloc; /* Allocated size of aOverflow[] array */ - u8 bOvflValid; /* True if size and contents of aOverflow[] valid */ Pgno *aOverflow; /* Cache of overflow page locations */ -#endif - Pgno pgnoRoot; /* The root page of this tree */ CellInfo info; /* A parse of the cell we are pointing at */ - i64 nKey; /* Size of pKey, or last integer key */ - void *pKey; /* Saved key that was cursor's last known position */ + i64 nKey; /* Size of pKey, or last integer key */ + void *pKey; /* Saved key that was cursor last known position */ + Pgno pgnoRoot; /* The root page of this tree */ + int nOvflAlloc; /* Allocated size of aOverflow[] array */ int skipNext; /* Prev() is noop if negative. Next() is noop if positive */ - u8 wrFlag; /* True if writable */ - u8 atLast; /* Cursor pointing to the last entry */ - u8 validNKey; /* True if info.nKey is valid */ + u8 curFlags; /* zero or more BTCF_* flags defined below */ u8 eState; /* One of the CURSOR_XXX constants (see below) */ -#ifndef SQLITE_OMIT_INCRBLOB - u8 isIncrblobHandle; /* True if this cursor is an incr. io handle */ -#endif u8 hints; /* As configured by CursorSetHints() */ i16 iPage; /* Index of current page in apPage */ u16 aiIdx[BTCURSOR_MAX_DEPTH]; /* Current index in apPage[i] */ MemPage *apPage[BTCURSOR_MAX_DEPTH]; /* Pages from root to current page */ }; +/* +** Legal values for BtCursor.curFlags +*/ +#define BTCF_ValidNKey 0x01 /* True if info.nKey is valid */ +#define BTCF_ValidOvfl 0x02 /* True if aOverflow is valid */ +#define BTCF_AtLast 0x04 /* Cursor is pointing ot the last entry */ +#define BTCF_WriteFlag 0x08 /* True if a write cursor */ +#define BTCF_Incrblob 0x10 /* True if an incremental I/O handle */ + /* ** Potential values for BtCursor.eState. ** diff --git a/src/test_btree.c b/src/test_btree.c index db72889b2a..dfe77051b6 100644 --- a/src/test_btree.c +++ b/src/test_btree.c @@ -51,7 +51,7 @@ void sqlite3BtreeCursorList(Btree *p){ BtShared *pBt = p->pBt; for(pCur=pBt->pCursor; pCur; pCur=pCur->pNext){ MemPage *pPage = pCur->apPage[pCur->iPage]; - char *zMode = pCur->wrFlag ? "rw" : "ro"; + char *zMode = (pCur->curFlags & BTCF_WriteFlag) ? "rw" : "ro"; sqlite3DebugPrintf("CURSOR %p rooted at %4d(%s) currently at %d.%d%s\n", pCur, pCur->pgnoRoot, zMode, pPage ? pPage->pgno : 0, pCur->aiIdx[pCur->iPage], From 926345e02761db4fc92b08568cc4c3a80c07953c Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 11 Mar 2014 23:44:10 +0000 Subject: [PATCH 03/12] Remove a stray C99-style comment. FossilOrigin-Name: f500e87d6ec6fa43c13f4e94edf32789f36e4233 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/btree.c | 1 - 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 24561347ec..ff09351dd2 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Combine\sthe\svarious\sboolean\sfields\sof\sthe\sBtCursor\sobject\sinto\sa\ssingle\nbit-vector.\s\sThis\sallows\ssetting\sor\sclearing\smore\sthan\sone\sboolean\sat\sa\ntime\sand\smakes\sthe\soverflow-pgno-cache\sbranch\sfaster\sthan\strunk\son\s\nspeedtest1. -D 2014-03-11T23:40:44.961 +C Remove\sa\sstray\sC99-style\scomment. +D 2014-03-11T23:44:10.719 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -164,7 +164,7 @@ F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34 F src/backup.c a729e63cf5cd1829507cb7b8e89f99b95141bb53 F src/bitvec.c 19a4ba637bd85f8f63fc8c9bae5ade9fb05ec1cb F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7 -F src/btree.c 225a3f4d5511d4f5eab38a686f6c7e22290739f3 +F src/btree.c 33b5ad54a14c2b62e8adbc7656dec2b7cd760cbf F src/btree.h 6b0c1a3f0937f9852ec727c820e71dbdd4bd0b27 F src/btreeInt.h d1784d1e17d08d29e890190dbb9836fa64573381 F src/build.c 0d50ef95aad63f4c4fc47f3fa2670d4557c45db0 @@ -1156,7 +1156,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P da59198505990a4fe832be7932117c7e014955b7 -R a9a97bb8415d8a76adacb051af2ccc88 +P 968fec44d7fde3adbd3e9603e4282351f0d4bda1 +R c766c2eb192c274bbd3dc0af3849118d U drh -Z 90b8a93448c14945f126312bc79eea6f +Z 264233dee2a1cd950306c0e6dc59ee29 diff --git a/manifest.uuid b/manifest.uuid index 6cfc27f694..4c7b90b821 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -968fec44d7fde3adbd3e9603e4282351f0d4bda1 \ No newline at end of file +f500e87d6ec6fa43c13f4e94edf32789f36e4233 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index bd1a0e1c75..045e8ba2fd 100644 --- a/src/btree.c +++ b/src/btree.c @@ -4337,7 +4337,6 @@ static int moveToRoot(BtCursor *pCur){ assert( CURSOR_INVALID < CURSOR_REQUIRESEEK ); assert( CURSOR_VALID < CURSOR_REQUIRESEEK ); assert( CURSOR_FAULT > CURSOR_REQUIRESEEK ); -// invalidateOverflowCache(pCur); if( pCur->eState>=CURSOR_REQUIRESEEK ){ if( pCur->eState==CURSOR_FAULT ){ assert( pCur->skipNext!=SQLITE_OK ); From 9bc21b535e9b5578fb4a8ef77f58d0f392a437af Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 20 Mar 2014 18:56:35 +0000 Subject: [PATCH 04/12] Only use the direct-overflow-read optimization if all data from the overflow page in question is being read. FossilOrigin-Name: d8e1f75ddf10f3c0b21acd5455f90fdcea54a948 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/btree.c | 4 ++++ test/func.test | 12 +++++++----- 4 files changed, 20 insertions(+), 14 deletions(-) diff --git a/manifest b/manifest index ff09351dd2..751024e857 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\sa\sstray\sC99-style\scomment. -D 2014-03-11T23:44:10.719 +C Only\suse\sthe\sdirect-overflow-read\soptimization\sif\sall\sdata\sfrom\sthe\soverflow\spage\sin\squestion\sis\sbeing\sread. +D 2014-03-20T18:56:35.309 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -164,7 +164,7 @@ F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34 F src/backup.c a729e63cf5cd1829507cb7b8e89f99b95141bb53 F src/bitvec.c 19a4ba637bd85f8f63fc8c9bae5ade9fb05ec1cb F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7 -F src/btree.c 33b5ad54a14c2b62e8adbc7656dec2b7cd760cbf +F src/btree.c 0384d399cfb12b3767edec355f00996658bb093e F src/btree.h 6b0c1a3f0937f9852ec727c820e71dbdd4bd0b27 F src/btreeInt.h d1784d1e17d08d29e890190dbb9836fa64573381 F src/build.c 0d50ef95aad63f4c4fc47f3fa2670d4557c45db0 @@ -574,7 +574,7 @@ F test/fts4merge4.test c19c85ca1faa7b6d536832b49c12e1867235f584 F test/fts4noti.test aed33ba44808852dcb24bf70fa132e7bf530f057 F test/fts4unicode.test 01ec3fe2a7c3cfff3b4c0581b83caa11b33efa36 F test/full.test 6b3c8fb43c6beab6b95438c1675374b95fab245d -F test/func.test a21814945d32137412b553d98ad2107f9b2173a9 +F test/func.test c2cbfc23d554c5bf8678d0fb271aa4f8ef94839c F test/func2.test 772d66227e4e6684b86053302e2d74a2500e1e0f F test/func3.test dbccee9133cfef1473c59ec07b5f0262b9d72f9a F test/func4.test 6beacdfcb0e18c358e6c2dcacf1b65d1fa80955f @@ -1156,7 +1156,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 968fec44d7fde3adbd3e9603e4282351f0d4bda1 -R c766c2eb192c274bbd3dc0af3849118d -U drh -Z 264233dee2a1cd950306c0e6dc59ee29 +P f500e87d6ec6fa43c13f4e94edf32789f36e4233 +R 97d65ef8b8853428f883a03b9234ff63 +U dan +Z c025d7be55b561d9bf0252bb6230f9e0 diff --git a/manifest.uuid b/manifest.uuid index 4c7b90b821..16aed852aa 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f500e87d6ec6fa43c13f4e94edf32789f36e4233 \ No newline at end of file +d8e1f75ddf10f3c0b21acd5455f90fdcea54a948 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 045e8ba2fd..cd2df05324 100644 --- a/src/btree.c +++ b/src/btree.c @@ -3951,6 +3951,7 @@ static int accessPayload( int iIdx = 0; MemPage *pPage = pCur->apPage[pCur->iPage]; /* Btree page of current entry */ BtShared *pBt = pCur->pBt; /* Btree this cursor belongs to */ + int bEnd; /* True if reading to end of data */ assert( pPage ); assert( pCur->eState==CURSOR_VALID ); @@ -3960,6 +3961,7 @@ static int accessPayload( getCellInfo(pCur); aPayload = pCur->info.pCell + pCur->info.nHeader; nKey = (pPage->intKey ? 0 : (int)pCur->info.nKey); + bEnd = (offset+amt==nKey+pCur->info.nData); if( NEVER(offset+amt > nKey+pCur->info.nData) || &aPayload[pCur->info.nLocal] > &pPage->aData[pBt->usableSize] @@ -4064,6 +4066,7 @@ static int accessPayload( ** 3) the database is file-backed, and ** 4) there is no open write-transaction, and ** 5) the database is not a WAL database, + ** 6) all data from the page is being read. ** ** then data can be read directly from the database file into the ** output buffer, bypassing the page-cache altogether. This speeds @@ -4071,6 +4074,7 @@ static int accessPayload( */ if( (eOp&0x01)==0 /* (1) */ && offset==0 /* (2) */ + && (bEnd || a==ovflSize) /* (6) */ && pBt->inTransaction==TRANS_READ /* (4) */ && (fd = sqlite3PagerFile(pBt->pPager))->pMethods /* (3) */ && pBt->pPage1->aData[19]==0x01 /* (5) */ diff --git a/test/func.test b/test/func.test index 0fafd1828d..e3cec32153 100644 --- a/test/func.test +++ b/test/func.test @@ -1301,11 +1301,13 @@ do_test func-29.3 { db eval {SELECT typeof(+x) FROM t29 ORDER BY id} } {integer null real blob text} if {[permutation] != "mmap"} { - do_test func-29.4 { - set x [lindex [sqlite3_db_status db CACHE_MISS 1] 1] - if {$x>100} {set x many} - set x - } {many} + ifcapable !direct_read { + do_test func-29.4 { + set x [lindex [sqlite3_db_status db CACHE_MISS 1] 1] + if {$x>100} {set x many} + set x + } {many} + } } do_test func-29.5 { db close From 4c417181c218c1e469f86bb754045b4134189ee7 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 31 Mar 2014 23:57:41 +0000 Subject: [PATCH 05/12] Fix a compiler warning when SQLITE_DIRECT_OVERFLOW_READ is defined. Minor performance enhancement and size reduction. FossilOrigin-Name: 96385dc460545807a5c8fcf6280a971700f84866 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/btree.c | 9 +++++++-- src/btreeInt.h | 8 ++++---- 4 files changed, 19 insertions(+), 14 deletions(-) diff --git a/manifest b/manifest index 1266012e4a..a1eded678c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\sin\sthe\slatest\schanges\sand\sfixes\sfrom\strunk. -D 2014-03-31T22:03:32.269 +C Fix\sa\scompiler\swarning\swhen\sSQLITE_DIRECT_OVERFLOW_READ\sis\sdefined.\nMinor\sperformance\senhancement\sand\ssize\sreduction. +D 2014-03-31T23:57:41.627 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -164,9 +164,9 @@ F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34 F src/backup.c a729e63cf5cd1829507cb7b8e89f99b95141bb53 F src/bitvec.c 19a4ba637bd85f8f63fc8c9bae5ade9fb05ec1cb F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7 -F src/btree.c 33338d61b912b5219fc5b466db8e0d7385c0b18b +F src/btree.c b1d6309d6623f4ea8d9466aebd1ec84adc40cb9b F src/btree.h d79306df4ed9181b48916737fe8871a4392c4594 -F src/btreeInt.h d1784d1e17d08d29e890190dbb9836fa64573381 +F src/btreeInt.h cf180d86b2e9e418f638d65baa425c4c69c0e0e3 F src/build.c 0d50ef95aad63f4c4fc47f3fa2670d4557c45db0 F src/callback.c 174e3c8656bc29f91d710ab61550d16eea34be98 F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac @@ -1159,7 +1159,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P d8e1f75ddf10f3c0b21acd5455f90fdcea54a948 b3296267fb67b9f59719a37093253062edde3746 -R 6014daa58aba2f75bf5f17a4d16cbf23 +P f6211540c9d66a08dc580dd733e4f4a98968ae30 +R a9646e8cad6830bc030ac01ef7720050 U drh -Z 6a8ee270f5925545ed8c5f82edf09850 +Z be4271c513a3efe06acb17f300ec9933 diff --git a/manifest.uuid b/manifest.uuid index 36c381c508..e03a98f749 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f6211540c9d66a08dc580dd733e4f4a98968ae30 \ No newline at end of file +96385dc460545807a5c8fcf6280a971700f84866 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 9b50ebae4f..cbb968ad8b 100644 --- a/src/btree.c +++ b/src/btree.c @@ -3633,7 +3633,8 @@ static int btreeCursor( pCur->pKeyInfo = pKeyInfo; pCur->pBtree = p; pCur->pBt = pBt; - pCur->curFlags = wrFlag ? BTCF_WriteFlag : 0; + assert( wrFlag==0 || wrFlag==BTCF_WriteFlag ); + pCur->curFlags = wrFlag; pCur->pNext = pBt->pCursor; if( pCur->pNext ){ pCur->pNext->pPrev = pCur; @@ -3965,7 +3966,9 @@ static int accessPayload( int iIdx = 0; MemPage *pPage = pCur->apPage[pCur->iPage]; /* Btree page of current entry */ BtShared *pBt = pCur->pBt; /* Btree this cursor belongs to */ - int bEnd; /* True if reading to end of data */ +#ifdef SQLITE_DIRECT_OVERFLOW_READ + int bEnd; /* True if reading to end of data */ +#endif assert( pPage ); assert( pCur->eState==CURSOR_VALID ); @@ -3975,7 +3978,9 @@ static int accessPayload( getCellInfo(pCur); aPayload = pCur->info.pCell + pCur->info.nHeader; nKey = (pPage->intKey ? 0 : (int)pCur->info.nKey); +#ifdef SQLITE_DIRECT_OVERFLOW_READ bEnd = (offset+amt==nKey+pCur->info.nData); +#endif if( NEVER(offset+amt > nKey+pCur->info.nData) || &aPayload[pCur->info.nLocal] > &pPage->aData[pBt->usableSize] diff --git a/src/btreeInt.h b/src/btreeInt.h index dff07f145e..d1cdd46983 100644 --- a/src/btreeInt.h +++ b/src/btreeInt.h @@ -514,10 +514,10 @@ struct BtCursor { /* ** Legal values for BtCursor.curFlags */ -#define BTCF_ValidNKey 0x01 /* True if info.nKey is valid */ -#define BTCF_ValidOvfl 0x02 /* True if aOverflow is valid */ -#define BTCF_AtLast 0x04 /* Cursor is pointing ot the last entry */ -#define BTCF_WriteFlag 0x08 /* True if a write cursor */ +#define BTCF_WriteFlag 0x01 /* True if a write cursor */ +#define BTCF_ValidNKey 0x02 /* True if info.nKey is valid */ +#define BTCF_ValidOvfl 0x04 /* True if aOverflow is valid */ +#define BTCF_AtLast 0x08 /* Cursor is pointing ot the last entry */ #define BTCF_Incrblob 0x10 /* True if an incremental I/O handle */ /* From a38c9516e847f90d914dce229b7c601698e94102 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 1 Apr 2014 01:24:34 +0000 Subject: [PATCH 06/12] Remove an unnecessary conditional, replacing it with an assert(). Improvements to comments. FossilOrigin-Name: 834bf1c367e1ccd498c7f9f843be2d2aa11ffb3c --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/btree.c | 24 ++++++++++++++++-------- 3 files changed, 23 insertions(+), 15 deletions(-) diff --git a/manifest b/manifest index a1eded678c..dbe10602d3 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\scompiler\swarning\swhen\sSQLITE_DIRECT_OVERFLOW_READ\sis\sdefined.\nMinor\sperformance\senhancement\sand\ssize\sreduction. -D 2014-03-31T23:57:41.627 +C Remove\san\sunnecessary\sconditional,\sreplacing\sit\swith\san\sassert().\nImprovements\sto\scomments. +D 2014-04-01T01:24:34.512 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -164,7 +164,7 @@ F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34 F src/backup.c a729e63cf5cd1829507cb7b8e89f99b95141bb53 F src/bitvec.c 19a4ba637bd85f8f63fc8c9bae5ade9fb05ec1cb F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7 -F src/btree.c b1d6309d6623f4ea8d9466aebd1ec84adc40cb9b +F src/btree.c 6c9b51abd404ce5b78b173b6f2248e8cb824758c F src/btree.h d79306df4ed9181b48916737fe8871a4392c4594 F src/btreeInt.h cf180d86b2e9e418f638d65baa425c4c69c0e0e3 F src/build.c 0d50ef95aad63f4c4fc47f3fa2670d4557c45db0 @@ -1159,7 +1159,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P f6211540c9d66a08dc580dd733e4f4a98968ae30 -R a9646e8cad6830bc030ac01ef7720050 +P 96385dc460545807a5c8fcf6280a971700f84866 +R 193f537069a669cf49d79f97b46daa7e U drh -Z be4271c513a3efe06acb17f300ec9933 +Z 9306db9f51cd1c998fccb67bf7fedc94 diff --git a/manifest.uuid b/manifest.uuid index e03a98f749..44d48365ac 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -96385dc460545807a5c8fcf6280a971700f84866 \ No newline at end of file +834bf1c367e1ccd498c7f9f843be2d2aa11ffb3c \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index cbb968ad8b..2bf026b840 100644 --- a/src/btree.c +++ b/src/btree.c @@ -3974,6 +3974,7 @@ static int accessPayload( assert( pCur->eState==CURSOR_VALID ); assert( pCur->aiIdx[pCur->iPage]nCell ); assert( cursorHoldsMutex(pCur) ); + assert( eOp!=2 || offset==0 ); /* Always start from beginning for eOp==2 */ getCellInfo(pCur); aPayload = pCur->info.pCell + pCur->info.nHeader; @@ -4009,12 +4010,13 @@ static int accessPayload( nextPage = get4byte(&aPayload[pCur->info.nLocal]); - /* If the BTCF_Incrblob flag is set and the BtCursor.aOverflow[] - ** has not been allocated, allocate it now. The array is sized at - ** one entry for each overflow page in the overflow chain. The - ** page number of the first overflow page is stored in aOverflow[0], - ** etc. A value of 0 in the aOverflow[] array means "not yet known" - ** (the cache is lazily populated). + /* If the BtCursor.aOverflow[] has not been allocated, allocate it now. + ** Except, do not allocate aOverflow[] for eOp==2. + ** + ** The aOverflow[] array is sized at one entry for each overflow page + ** in the overflow chain. The page number of the first overflow page is + ** stored in aOverflow[0], etc. A value of 0 in the aOverflow[] array + ** means "not yet known" (the cache is lazily populated). */ if( eOp!=2 && (pCur->curFlags & BTCF_ValidOvfl)==0 ){ int nOvfl = (pCur->info.nPayload-pCur->info.nLocal+ovflSize-1)/ovflSize; @@ -4059,11 +4061,17 @@ static int accessPayload( ** data is not required. So first try to lookup the overflow ** page-list cache, if any, then fall back to the getOverflowPage() ** function. + ** + ** Note that the aOverflow[] array must be allocated because eOp!=2 + ** here. If eOp==2, then offset==0 and this branch is never taken. */ - if( (pCur->curFlags & BTCF_ValidOvfl)!=0 && pCur->aOverflow[iIdx+1] ){ + assert( eOp!=2 ); + assert( pCur->curFlags & BTCF_ValidOvfl ); + if( pCur->aOverflow[iIdx+1] ){ nextPage = pCur->aOverflow[iIdx+1]; - } else + }else{ rc = getOverflowPage(pBt, nextPage, 0, &nextPage); + } offset -= ovflSize; }else{ /* Need to read this page properly. It contains some of the From d83cad235a5360fe670057d5a70da65b43aea793 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 10 Apr 2014 02:24:48 +0000 Subject: [PATCH 07/12] Modify the OR-clause handling so that it can safely deal with OR-clause with 17 or more terms. Fix for ticket [10fb063b1179be53ea0b53bb]. FossilOrigin-Name: a67b5312f63909737c052fe58ab5772d45530d49 --- manifest | 19 ++++++++--------- manifest.uuid | 2 +- src/rowset.c | 6 +++--- src/sqliteInt.h | 2 +- src/vdbe.c | 4 +--- test/whereD.test | 53 ++++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 68 insertions(+), 18 deletions(-) diff --git a/manifest b/manifest index 51582695c0..0b43c2f6e5 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Performance\simprovements\swhen\sreading\slarge\sblobs,\sespecially\sif\nSQLITE_DIRECT_OVERFLOW_READ\sis\sdefined. -D 2014-04-04T18:49:19.417 +C Modify\sthe\sOR-clause\shandling\sso\sthat\sit\scan\ssafely\sdeal\swith\sOR-clause\s\nwith\s17\sor\smore\sterms.\s\sFix\sfor\sticket\s[10fb063b1179be53ea0b53bb]. +D 2014-04-10T02:24:48.549 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -216,13 +216,13 @@ F src/prepare.c 677521ab7132615a8a26107a1d1c3132f44ae337 F src/printf.c e5a0005f8b3de21f85da6a709d2fbee76775bf4b F src/random.c d10c1f85b6709ca97278428fd5db5bbb9c74eece F src/resolve.c 273d5f47c4e2c05b2d3d2bffeda939551ab59e66 -F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 +F src/rowset.c a9c9aae3234b44a6d7c6f5a3cadf90dce1e627be F src/select.c 269c3e31a450fce642a10569221a49180348c88e F src/shell.c 5260f2ada8dd06e9f5ae0a448c8c01e7a75dd881 F src/sqlite.h.in a2ef671f92747a5a1c8a47bad5c585a8dd9eca80 F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc -F src/sqliteInt.h cc9582a91b2910404ccda7b7e198815ea0f75948 +F src/sqliteInt.h 9b1361478e821b1a68f7993047a922e3155ca87d F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e @@ -278,7 +278,7 @@ F src/update.c 5b3e74a03b3811e586b4f2b4cbd7c49f01c93115 F src/utf.c 6dc9ec9f1b3db43ae8ba0365377f11df1ee4c01c F src/util.c c46c90459ef9bdc0c6c73803cf4c55425b4771cf F src/vacuum.c 3728d74919d4fb1356f9e9a13e27773db60b7179 -F src/vdbe.c e811a0081149fb90db367026d154cd7efb3c7098 +F src/vdbe.c bf284edea1cee0508dc93c79a73498e0f317edb7 F src/vdbe.h 394464909ed682334aa3d5831aae0c2fe2abef94 F src/vdbeInt.h e6d83e5bfd62fc6685ba1ed6153f7099f82de9f7 F src/vdbeapi.c 0ed6053f947edd0b30f64ce5aeb811872a3450a4 @@ -1089,7 +1089,7 @@ F test/where9.test 4f3eab951353a3ae164befc521c777dfa903e46c F test/whereA.test 4d253178d135ec46d1671e440cd8f2b916aa6e6b F test/whereB.test 0def95db3bdec220a731c7e4bec5930327c1d8c5 F test/whereC.test d6f4ecd4fa2d9429681a5b22a25d2bda8e86ab8a -F test/whereD.test 6c2feb79ef1f68381b07f39017fe5f9b96da8d62 +F test/whereD.test fd9120e262f9da3c45940f52aefeef4d15b904e5 F test/whereE.test b3a055eef928c992b0a33198a7b8dc10eea5ad2f F test/whereF.test 5b2ba0dbe8074aa13e416b37c753991f0a2492d7 F test/whereG.test 2533b72ed4a31fd1687230a499b557b911525344 @@ -1160,8 +1160,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 683dd379a293b2f330e1e4cd746f190527fe48ee 834bf1c367e1ccd498c7f9f843be2d2aa11ffb3c -R 3de83004edd963c4959934c7f5a61b03 -T +closed 834bf1c367e1ccd498c7f9f843be2d2aa11ffb3c +P 2312eb6a9eb31051db4e0baf19e033ba39adc7b1 +R 2f4de3ec11a98155d746ed7623586007 U drh -Z f4df6ef034f1a63bb656a3ddc69e0011 +Z d44fb7b759451f899c9b9bdcaf2f6d96 diff --git a/manifest.uuid b/manifest.uuid index 0466f25ed2..41b50df795 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2312eb6a9eb31051db4e0baf19e033ba39adc7b1 \ No newline at end of file +a67b5312f63909737c052fe58ab5772d45530d49 \ No newline at end of file diff --git a/src/rowset.c b/src/rowset.c index 5761f98550..ba2e056bd4 100644 --- a/src/rowset.c +++ b/src/rowset.c @@ -112,8 +112,8 @@ struct RowSet { struct RowSetEntry *pFresh; /* Source of new entry objects */ struct RowSetEntry *pForest; /* List of binary trees of entries */ u16 nFresh; /* Number of objects on pFresh */ - u8 rsFlags; /* Various flags */ - u8 iBatch; /* Current insert batch */ + u16 rsFlags; /* Various flags */ + int iBatch; /* Current insert batch */ }; /* @@ -447,7 +447,7 @@ int sqlite3RowSetNext(RowSet *p, i64 *pRowid){ ** on pRowSet->pEntry, then sort those entires into the forest at ** pRowSet->pForest so that they can be tested. */ -int sqlite3RowSetTest(RowSet *pRowSet, u8 iBatch, sqlite3_int64 iRowid){ +int sqlite3RowSetTest(RowSet *pRowSet, int iBatch, sqlite3_int64 iRowid){ struct RowSetEntry *p, *pTree; /* This routine is never called after sqlite3RowSetNext() */ diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 0f67748fc8..57481b1084 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -3019,7 +3019,7 @@ int sqlite3BitvecBuiltinTest(int,int*); RowSet *sqlite3RowSetInit(sqlite3*, void*, unsigned int); void sqlite3RowSetClear(RowSet*); void sqlite3RowSetInsert(RowSet*, i64); -int sqlite3RowSetTest(RowSet*, u8 iBatch, i64); +int sqlite3RowSetTest(RowSet*, int iBatch, i64); int sqlite3RowSetNext(RowSet*, i64*); void sqlite3CreateView(Parse*,Token*,Token*,Token*,Select*,int,int); diff --git a/src/vdbe.c b/src/vdbe.c index 2d1d23e079..6102cf3c7e 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -5227,9 +5227,7 @@ case OP_RowSetTest: { /* jump, in1, in3 */ assert( pOp->p4type==P4_INT32 ); assert( iSet==-1 || iSet>=0 ); if( iSet ){ - exists = sqlite3RowSetTest(pIn1->u.pRowSet, - (u8)(iSet>=0 ? iSet & 0xf : 0xff), - pIn3->u.i); + exists = sqlite3RowSetTest(pIn1->u.pRowSet, iSet, pIn3->u.i); VdbeBranchTaken(exists!=0,2); if( exists ){ pc = pOp->p2 - 1; diff --git a/test/whereD.test b/test/whereD.test index eb0f864025..db993040b0 100644 --- a/test/whereD.test +++ b/test/whereD.test @@ -217,6 +217,59 @@ do_execsql_test 4.7 { ORDER BY a; } {3 4 3 4} +# Verify fix of a bug reported on the mailing list by Peter Reid +# +do_execsql_test 5.1 { + DROP TABLE IF EXISTS t; + CREATE TABLE t(c0,c1,c2,c3,c4,c5,c6,c7,c8,c9,c10,c11,c12,c13,c14,c15,c16,c17); + CREATE INDEX tc0 ON t(c0); + CREATE INDEX tc1 ON t(c1); + CREATE INDEX tc2 ON t(c2); + CREATE INDEX tc3 ON t(c3); + CREATE INDEX tc4 ON t(c4); + CREATE INDEX tc5 ON t(c5); + CREATE INDEX tc6 ON t(c6); + CREATE INDEX tc7 ON t(c7); + CREATE INDEX tc8 ON t(c8); + CREATE INDEX tc9 ON t(c9); + CREATE INDEX tc10 ON t(c10); + CREATE INDEX tc11 ON t(c11); + CREATE INDEX tc12 ON t(c12); + CREATE INDEX tc13 ON t(c13); + CREATE INDEX tc14 ON t(c14); + CREATE INDEX tc15 ON t(c15); + CREATE INDEX tc16 ON t(c16); + CREATE INDEX tc17 ON t(c17); + + INSERT INTO t(c0, c16) VALUES (1,1); + + SELECT * FROM t WHERE + c0=1 or c1=1 or c2=1 or c3=1 or + c4=1 or c5=1 or c6=1 or c7=1 or + c8=1 or c9=1 or c10=1 or c11=1 or + c12=1 or c13=1 or c14=1 or c15=1 or + c16=1 or c17=1; +} {1 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 1 {}} +do_execsql_test 5.2 { + DELETE FROM t; + INSERT INTO t(c0,c17) VALUES(1,1); + SELECT * FROM t WHERE + c0=1 or c1=1 or c2=1 or c3=1 or + c4=1 or c5=1 or c6=1 or c7=1 or + c8=1 or c9=1 or c10=1 or c11=1 or + c12=1 or c13=1 or c14=1 or c15=1 or + c16=1 or c17=1; +} {1 {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} 1} +do_execsql_test 5.3 { + DELETE FROM t; + INSERT INTO t(c0,c15) VALUES(1,1); + SELECT * FROM t WHERE + c0=1 or c1=1 or c2=1 or c3=1 or + c4=1 or c5=1 or c6=1 or c7=1 or + c8=1 or c9=1 or c10=1 or c11=1 or + c12=1 or c13=1 or c14=1 or c15=1 or + c16=1 or c17=1; +} {1 {} {} {} {} {} {} {} {} {} {} {} {} {} {} 1 {} {}} finish_test From 87744513e7374cae5f2df94d4ac1b014483683bc Mon Sep 17 00:00:00 2001 From: drh Date: Sun, 13 Apr 2014 19:15:49 +0000 Subject: [PATCH 08/12] Make sure column cache elements are cleared correctly when jumping over code for key generation in a partial index. Fix for ticket [2ea3e9fe6379fc3f6]. FossilOrigin-Name: 3122b8364082be783821da01d4af2af6a9586327 --- manifest | 20 ++++++++++---------- manifest.uuid | 2 +- src/build.c | 2 +- src/delete.c | 18 ++++++++++++++++-- src/pragma.c | 2 +- src/sqliteInt.h | 1 + test/index6.test | 19 +++++++++++++++++++ 7 files changed, 49 insertions(+), 15 deletions(-) diff --git a/manifest b/manifest index 0b43c2f6e5..80d510a4f9 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Modify\sthe\sOR-clause\shandling\sso\sthat\sit\scan\ssafely\sdeal\swith\sOR-clause\s\nwith\s17\sor\smore\sterms.\s\sFix\sfor\sticket\s[10fb063b1179be53ea0b53bb]. -D 2014-04-10T02:24:48.549 +C Make\ssure\scolumn\scache\selements\sare\scleared\scorrectly\swhen\sjumping\sover\ncode\sfor\skey\sgeneration\sin\sa\spartial\sindex.\s\nFix\sfor\sticket\s[2ea3e9fe6379fc3f6]. +D 2014-04-13T19:15:49.713 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -167,12 +167,12 @@ F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7 F src/btree.c 6c9b51abd404ce5b78b173b6f2248e8cb824758c F src/btree.h d79306df4ed9181b48916737fe8871a4392c4594 F src/btreeInt.h cf180d86b2e9e418f638d65baa425c4c69c0e0e3 -F src/build.c 0d50ef95aad63f4c4fc47f3fa2670d4557c45db0 +F src/build.c 5bfeea8f302ec2926c9eea321a61daea92a29fa4 F src/callback.c 174e3c8656bc29f91d710ab61550d16eea34be98 F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac F src/ctime.c 0231df905e2c4abba4483ee18ffc05adc321df2a F src/date.c 593c744b2623971e45affd0bde347631bdfa4625 -F src/delete.c cdd57149543bb28304d8f717c243f2a86b1fc280 +F src/delete.c d5e3a958519677049a752ed37657240b55ce5806 F src/expr.c da2b3cb41081af6b56e95e7c9e95949564ce2e21 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c 5269ef07b100763134f71b889327c333bd0989cf @@ -211,7 +211,7 @@ F src/parse.y 22d6a074e5f5a7258947a1dc55a9bf946b765dd0 F src/pcache.c d8eafac28290d4bb80332005435db44991d07fc2 F src/pcache.h a5e4f5d9f5d592051d91212c5949517971ae6222 F src/pcache1.c 102e6f5a2fbc646154463eb856d1fd716867b64c -F src/pragma.c 10f169b9650f0930a7a6df67e1387a4c2c449f38 +F src/pragma.c 21ece94d4f3e76e8e150deecafb9c7abd398ec67 F src/prepare.c 677521ab7132615a8a26107a1d1c3132f44ae337 F src/printf.c e5a0005f8b3de21f85da6a709d2fbee76775bf4b F src/random.c d10c1f85b6709ca97278428fd5db5bbb9c74eece @@ -222,7 +222,7 @@ F src/shell.c 5260f2ada8dd06e9f5ae0a448c8c01e7a75dd881 F src/sqlite.h.in a2ef671f92747a5a1c8a47bad5c585a8dd9eca80 F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc -F src/sqliteInt.h 9b1361478e821b1a68f7993047a922e3155ca87d +F src/sqliteInt.h 97df117e13dea9d2fe8a8e32376222e03fe4a4c9 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e @@ -610,7 +610,7 @@ F test/index2.test ee83c6b5e3173a3d7137140d945d9a5d4fdfb9d6 F test/index3.test 55a90cff99834305e8141df7afaef39674b57062 F test/index4.test ab92e736d5946840236cd61ac3191f91a7856bf6 F test/index5.test fc07c14193c0430814e7a08b5da46888ee795c33 -F test/index6.test 936979c3a1e87b81feaed2d00505665bf142d764 +F test/index6.test a0a2d286ffa6d35813f5003fdb7be124825b4422 F test/index7.test a3baf9a625bda7fd49471e99aeae04095fbfeecf F test/indexedby.test b2f22f3e693a53813aa3f50b812eb609ba6df1ec F test/indexfault.test 31d4ab9a7d2f6e9616933eb079722362a883eb1d @@ -1160,7 +1160,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 2312eb6a9eb31051db4e0baf19e033ba39adc7b1 -R 2f4de3ec11a98155d746ed7623586007 +P a67b5312f63909737c052fe58ab5772d45530d49 +R 47ced825f4356f6492f482f71c0fa4e8 U drh -Z d44fb7b759451f899c9b9bdcaf2f6d96 +Z d6e06c047caf6d5aab62e0b2ec59c712 diff --git a/manifest.uuid b/manifest.uuid index 41b50df795..6f61a4975d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a67b5312f63909737c052fe58ab5772d45530d49 \ No newline at end of file +3122b8364082be783821da01d4af2af6a9586327 \ No newline at end of file diff --git a/src/build.c b/src/build.c index 10077e5018..4d4155ba90 100644 --- a/src/build.c +++ b/src/build.c @@ -2680,7 +2680,7 @@ static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){ sqlite3GenerateIndexKey(pParse,pIndex,iTab,regRecord,0,&iPartIdxLabel,0,0); sqlite3VdbeAddOp2(v, OP_SorterInsert, iSorter, regRecord); - sqlite3VdbeResolveLabel(v, iPartIdxLabel); + sqlite3ResolvePartIdxLabel(pParse, iPartIdxLabel); sqlite3VdbeAddOp2(v, OP_Next, iTab, addr1+1); VdbeCoverage(v); sqlite3VdbeJumpHere(v, addr1); if( memRootPage<0 ) sqlite3VdbeAddOp2(v, OP_Clear, tnum, iDb); diff --git a/src/delete.c b/src/delete.c index 79e83cae52..c6e1762215 100644 --- a/src/delete.c +++ b/src/delete.c @@ -739,7 +739,7 @@ void sqlite3GenerateRowIndexDelete( &iPartIdxLabel, pPrior, r1); sqlite3VdbeAddOp3(v, OP_IdxDelete, iIdxCur+i, r1, pIdx->uniqNotNull ? pIdx->nKeyCol : pIdx->nColumn); - sqlite3VdbeResolveLabel(v, iPartIdxLabel); + sqlite3ResolvePartIdxLabel(pParse, iPartIdxLabel); pPrior = pIdx; } } @@ -758,10 +758,11 @@ void sqlite3GenerateRowIndexDelete( ** ** If *piPartIdxLabel is not NULL, fill it in with a label and jump ** to that label if pIdx is a partial index that should be skipped. +** The label should be resolved using sqlite3ResolvePartIdxLabel(). ** A partial index should be skipped if its WHERE clause evaluates ** to false or null. If pIdx is not a partial index, *piPartIdxLabel ** will be set to zero which is an empty label that is ignored by -** sqlite3VdbeResolveLabel(). +** sqlite3ResolvePartIdxLabel(). ** ** The pPrior and regPrior parameters are used to implement a cache to ** avoid unnecessary register loads. If pPrior is not NULL, then it is @@ -794,6 +795,7 @@ int sqlite3GenerateIndexKey( if( pIdx->pPartIdxWhere ){ *piPartIdxLabel = sqlite3VdbeMakeLabel(v); pParse->iPartIdxTab = iDataCur; + sqlite3ExprCachePush(pParse); sqlite3ExprIfFalse(pParse, pIdx->pPartIdxWhere, *piPartIdxLabel, SQLITE_JUMPIFNULL); }else{ @@ -821,3 +823,15 @@ int sqlite3GenerateIndexKey( sqlite3ReleaseTempRange(pParse, regBase, nCol); return regBase; } + +/* +** If a prior call to sqlite3GenerateIndexKey() generated a jump-over label +** because it was a partial index, then this routine should be called to +** resolve that label. +*/ +void sqlite3ResolvePartIdxLabel(Parse *pParse, int iLabel){ + if( iLabel ){ + sqlite3VdbeResolveLabel(pParse->pVdbe, iLabel); + sqlite3ExprCachePop(pParse, 1); + } +} diff --git a/src/pragma.c b/src/pragma.c index 20da9a6892..66d0c3328e 100644 --- a/src/pragma.c +++ b/src/pragma.c @@ -1928,7 +1928,7 @@ void sqlite3Pragma( sqlite3VdbeAddOp0(v, OP_Halt); sqlite3VdbeJumpHere(v, jmp4); sqlite3VdbeJumpHere(v, jmp2); - sqlite3VdbeResolveLabel(v, jmp3); + sqlite3ResolvePartIdxLabel(pParse, jmp3); } sqlite3VdbeAddOp2(v, OP_Next, iDataCur, loopTop); VdbeCoverage(v); sqlite3VdbeJumpHere(v, loopTop-1); diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 57481b1084..7d3302eeb7 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -3135,6 +3135,7 @@ int sqlite3IsRowid(const char*); void sqlite3GenerateRowDelete(Parse*,Table*,Trigger*,int,int,int,i16,u8,u8,u8); void sqlite3GenerateRowIndexDelete(Parse*, Table*, int, int, int*); int sqlite3GenerateIndexKey(Parse*, Index*, int, int, int, int*,Index*,int); +void sqlite3ResolvePartIdxLabel(Parse*,int); void sqlite3GenerateConstraintChecks(Parse*,Table*,int*,int,int,int,int, u8,u8,int,int*); void sqlite3CompleteInsertion(Parse*,Table*,int,int,int,int*,int,int,int); diff --git a/test/index6.test b/test/index6.test index 48706be3cc..3451e5c1df 100644 --- a/test/index6.test +++ b/test/index6.test @@ -248,4 +248,23 @@ do_execsql_test index6-5.0 { SELECT stat+0 FROM sqlite_stat1 WHERE idx='t3b'; } {6 6} +# Test case for ticket [2ea3e9fe6379fc3f6ce7e090ce483c1a3a80d6c9] from +# 2014-04-13: Partial index causes assertion fault on UPDATE OR REPLACE. +# +do_execsql_test index6-6.0 { + CREATE TABLE t6(a,b); + CREATE UNIQUE INDEX t6ab ON t1(a,b); + CREATE INDEX t6b ON t6(b) WHERE b=1; + INSERT INTO t6(a,b) VALUES(123,456); + SELECT * FROM t6; +} {123 456} +do_execsql_test index6-6.1 { + UPDATE OR REPLACE t6 SET b=789; + SELECT * FROM t6; +} {123 789} +do_execsql_test index6-6.2 { + PRAGMA integrity_check; +} {ok} + + finish_test From d2490904507b0f9abeb077a40c2d91ad3a222f7f Mon Sep 17 00:00:00 2001 From: drh Date: Sun, 13 Apr 2014 19:28:15 +0000 Subject: [PATCH 09/12] Remove the unused second argument from sqlite3ExprCachePop(). Add an ALWAYS() on an always-true conditional in sqlite3VdbeResolveLabel(). FossilOrigin-Name: ab23abf392175d3e256ff619b13abbbe732a49ed --- manifest | 20 ++++++++++---------- manifest.uuid | 2 +- src/delete.c | 2 +- src/expr.c | 31 +++++++++++++++---------------- src/sqliteInt.h | 2 +- src/vdbeaux.c | 2 +- src/where.c | 2 +- 7 files changed, 30 insertions(+), 31 deletions(-) diff --git a/manifest b/manifest index 80d510a4f9..3301b08ca6 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Make\ssure\scolumn\scache\selements\sare\scleared\scorrectly\swhen\sjumping\sover\ncode\sfor\skey\sgeneration\sin\sa\spartial\sindex.\s\nFix\sfor\sticket\s[2ea3e9fe6379fc3f6]. -D 2014-04-13T19:15:49.713 +C Remove\sthe\sunused\ssecond\sargument\sfrom\ssqlite3ExprCachePop().\s\sAdd\san\nALWAYS()\son\san\salways-true\sconditional\sin\ssqlite3VdbeResolveLabel(). +D 2014-04-13T19:28:15.499 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -172,8 +172,8 @@ F src/callback.c 174e3c8656bc29f91d710ab61550d16eea34be98 F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac F src/ctime.c 0231df905e2c4abba4483ee18ffc05adc321df2a F src/date.c 593c744b2623971e45affd0bde347631bdfa4625 -F src/delete.c d5e3a958519677049a752ed37657240b55ce5806 -F src/expr.c da2b3cb41081af6b56e95e7c9e95949564ce2e21 +F src/delete.c bcf8f72126cea80fc3d5bc5494cf19b3f8935aaf +F src/expr.c 4f9e497c66e2f25a4d139357a778c84d5713207c F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c 5269ef07b100763134f71b889327c333bd0989cf F src/func.c 2945bb2c4cdc0ac43733046285a4434310be1811 @@ -222,7 +222,7 @@ F src/shell.c 5260f2ada8dd06e9f5ae0a448c8c01e7a75dd881 F src/sqlite.h.in a2ef671f92747a5a1c8a47bad5c585a8dd9eca80 F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc -F src/sqliteInt.h 97df117e13dea9d2fe8a8e32376222e03fe4a4c9 +F src/sqliteInt.h dadd17dbd05fd17cad157a7d96339bf4a0b41172 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e @@ -282,7 +282,7 @@ F src/vdbe.c bf284edea1cee0508dc93c79a73498e0f317edb7 F src/vdbe.h 394464909ed682334aa3d5831aae0c2fe2abef94 F src/vdbeInt.h e6d83e5bfd62fc6685ba1ed6153f7099f82de9f7 F src/vdbeapi.c 0ed6053f947edd0b30f64ce5aeb811872a3450a4 -F src/vdbeaux.c 1153175fb57a8454e1c8cf79b59b7bf92b26779d +F src/vdbeaux.c e493f38758c4b8f4ca2007cf6a700bd405d192f3 F src/vdbeblob.c 9205ce9d3b064d9600f8418a897fc88b5687d9ac F src/vdbemem.c 6fc77594c60f6155404f3f8d71bf36d1fdeb4447 F src/vdbesort.c 4abb7c0f8f19b7d7d82f4558d5da1a30fdf9ea38 @@ -291,7 +291,7 @@ F src/vtab.c 21b932841e51ebd7d075e2d0ad1415dce8d2d5fd F src/wal.c 76e7fc6de229bea8b30bb2539110f03a494dc3a8 F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 F src/walker.c 11edb74d587bc87b33ca96a5173e3ec1b8389e45 -F src/where.c 70eb10da08cebbd6a576ced18edb7c8f79d41597 +F src/where.c 7614c4383d8b6143558dc349da286d0325704d35 F src/whereInt.h 2564055b440e44ebec8b47f237bbccae6719b7af F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 @@ -1160,7 +1160,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P a67b5312f63909737c052fe58ab5772d45530d49 -R 47ced825f4356f6492f482f71c0fa4e8 +P 3122b8364082be783821da01d4af2af6a9586327 +R e1df7805a07beb887bab893b56a4a7f9 U drh -Z d6e06c047caf6d5aab62e0b2ec59c712 +Z 77065e6cb595843b2b0b90941a9d16f6 diff --git a/manifest.uuid b/manifest.uuid index 6f61a4975d..39f1fc5832 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3122b8364082be783821da01d4af2af6a9586327 \ No newline at end of file +ab23abf392175d3e256ff619b13abbbe732a49ed \ No newline at end of file diff --git a/src/delete.c b/src/delete.c index c6e1762215..c74d8eab7d 100644 --- a/src/delete.c +++ b/src/delete.c @@ -832,6 +832,6 @@ int sqlite3GenerateIndexKey( void sqlite3ResolvePartIdxLabel(Parse *pParse, int iLabel){ if( iLabel ){ sqlite3VdbeResolveLabel(pParse->pVdbe, iLabel); - sqlite3ExprCachePop(pParse, 1); + sqlite3ExprCachePop(pParse); } } diff --git a/src/expr.c b/src/expr.c index b070621ebd..08c121e386 100644 --- a/src/expr.c +++ b/src/expr.c @@ -1883,7 +1883,7 @@ int sqlite3CodeSubselect( if( testAddr>=0 ){ sqlite3VdbeJumpHere(v, testAddr); } - sqlite3ExprCachePop(pParse, 1); + sqlite3ExprCachePop(pParse); return rReg; } @@ -2018,7 +2018,7 @@ static void sqlite3ExprCodeIN( } } sqlite3ReleaseTempReg(pParse, r1); - sqlite3ExprCachePop(pParse, 1); + sqlite3ExprCachePop(pParse); VdbeComment((v, "end IN expr")); } #endif /* SQLITE_OMIT_SUBQUERY */ @@ -2201,15 +2201,14 @@ void sqlite3ExprCachePush(Parse *pParse){ /* ** Remove from the column cache any entries that were added since the -** the previous N Push operations. In other words, restore the cache -** to the state it was in N Pushes ago. +** the previous sqlite3ExprCachePush operation. In other words, restore +** the cache to the state it was in prior the most recent Push. */ -void sqlite3ExprCachePop(Parse *pParse, int N){ +void sqlite3ExprCachePop(Parse *pParse){ int i; struct yColCache *p; - assert( N>0 ); - assert( pParse->iCacheLevel>=N ); - pParse->iCacheLevel -= N; + assert( pParse->iCacheLevel>=1 ); + pParse->iCacheLevel--; #ifdef SQLITE_DEBUG if( pParse->db->flags & SQLITE_VdbeAddopTrace ){ printf("POP to %d\n", pParse->iCacheLevel); @@ -2687,7 +2686,7 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){ sqlite3ExprCacheRemove(pParse, target, 1); sqlite3ExprCachePush(pParse); sqlite3ExprCode(pParse, pFarg->a[i].pExpr, target); - sqlite3ExprCachePop(pParse, 1); + sqlite3ExprCachePop(pParse); } sqlite3VdbeResolveLabel(v, endCoalesce); break; @@ -2741,7 +2740,7 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){ sqlite3ExprCachePush(pParse); /* Ticket 2ea2425d34be */ sqlite3ExprCodeExprList(pParse, pFarg, r1, SQLITE_ECEL_DUP|SQLITE_ECEL_FACTOR); - sqlite3ExprCachePop(pParse, 1); /* Ticket 2ea2425d34be */ + sqlite3ExprCachePop(pParse); /* Ticket 2ea2425d34be */ }else{ r1 = 0; } @@ -2961,13 +2960,13 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){ testcase( aListelem[i+1].pExpr->op==TK_COLUMN ); sqlite3ExprCode(pParse, aListelem[i+1].pExpr, target); sqlite3VdbeAddOp2(v, OP_Goto, 0, endLabel); - sqlite3ExprCachePop(pParse, 1); + sqlite3ExprCachePop(pParse); sqlite3VdbeResolveLabel(v, nextCase); } if( (nExpr&1)!=0 ){ sqlite3ExprCachePush(pParse); sqlite3ExprCode(pParse, pEList->a[nExpr-1].pExpr, target); - sqlite3ExprCachePop(pParse, 1); + sqlite3ExprCachePop(pParse); }else{ sqlite3VdbeAddOp2(v, OP_Null, 0, target); } @@ -3546,7 +3545,7 @@ void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){ sqlite3ExprCachePush(pParse); sqlite3ExprIfTrue(pParse, pExpr->pRight, dest, jumpIfNull); sqlite3VdbeResolveLabel(v, d2); - sqlite3ExprCachePop(pParse, 1); + sqlite3ExprCachePop(pParse); break; } case TK_OR: { @@ -3554,7 +3553,7 @@ void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){ sqlite3ExprIfTrue(pParse, pExpr->pLeft, dest, jumpIfNull); sqlite3ExprCachePush(pParse); sqlite3ExprIfTrue(pParse, pExpr->pRight, dest, jumpIfNull); - sqlite3ExprCachePop(pParse, 1); + sqlite3ExprCachePop(pParse); break; } case TK_NOT: { @@ -3700,7 +3699,7 @@ void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){ sqlite3ExprIfFalse(pParse, pExpr->pLeft, dest, jumpIfNull); sqlite3ExprCachePush(pParse); sqlite3ExprIfFalse(pParse, pExpr->pRight, dest, jumpIfNull); - sqlite3ExprCachePop(pParse, 1); + sqlite3ExprCachePop(pParse); break; } case TK_OR: { @@ -3710,7 +3709,7 @@ void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){ sqlite3ExprCachePush(pParse); sqlite3ExprIfFalse(pParse, pExpr->pRight, dest, jumpIfNull); sqlite3VdbeResolveLabel(v, d2); - sqlite3ExprCachePop(pParse, 1); + sqlite3ExprCachePop(pParse); break; } case TK_NOT: { diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 7d3302eeb7..da46676adf 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -3083,7 +3083,7 @@ void sqlite3ExprCodeGetColumnOfTable(Vdbe*, Table*, int, int, int); void sqlite3ExprCodeMove(Parse*, int, int, int); void sqlite3ExprCacheStore(Parse*, int, int, int); void sqlite3ExprCachePush(Parse*); -void sqlite3ExprCachePop(Parse*, int); +void sqlite3ExprCachePop(Parse*); void sqlite3ExprCacheRemove(Parse*, int, int); void sqlite3ExprCacheClear(Parse*); void sqlite3ExprCacheAffinityChange(Parse*, int, int); diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 0ce21378d5..0a6b536720 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -276,7 +276,7 @@ void sqlite3VdbeResolveLabel(Vdbe *v, int x){ int j = -1-x; assert( v->magic==VDBE_MAGIC_INIT ); assert( jnLabel ); - if( j>=0 && p->aLabel ){ + if( ALWAYS(j>=0) && p->aLabel ){ p->aLabel[j] = v->nOp; } p->iFixedOp = v->nOp - 1; diff --git a/src/where.c b/src/where.c index 16db3e7f29..e51eee5350 100644 --- a/src/where.c +++ b/src/where.c @@ -2841,7 +2841,7 @@ static Bitmask codeOneLoopStart( pLevel->p1 = iCur; pLevel->p2 = sqlite3VdbeCurrentAddr(v); sqlite3ReleaseTempRange(pParse, iReg, nConstraint+2); - sqlite3ExprCachePop(pParse, 1); + sqlite3ExprCachePop(pParse); }else #endif /* SQLITE_OMIT_VIRTUALTABLE */ From 65b9ac522430cdc55855b24de406c54d12199346 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 14 Apr 2014 19:48:25 +0000 Subject: [PATCH 10/12] Make sure the undocumented sqlite_rename_parent() function does not crash even if it is invoked with NULL arguments. Ticket [264b970c4379fd4b94] FossilOrigin-Name: c6fa8d0d82805be230f672eabccdfa5680d4ddfd --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/alter.c | 1 + test/alter.test | 38 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 47 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 3301b08ca6..5ba411e0a6 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\sthe\sunused\ssecond\sargument\sfrom\ssqlite3ExprCachePop().\s\sAdd\san\nALWAYS()\son\san\salways-true\sconditional\sin\ssqlite3VdbeResolveLabel(). -D 2014-04-13T19:28:15.499 +C Make\ssure\sthe\sundocumented\ssqlite_rename_parent()\sfunction\sdoes\snot\ncrash\seven\sif\sit\sis\sinvoked\swith\sNULL\sarguments.\nTicket\s[264b970c4379fd4b94] +D 2014-04-14T19:48:25.984 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -157,7 +157,7 @@ F spec.template 86a4a43b99ebb3e75e6b9a735d5fd293a24e90ca F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite3.1 3d8b83c91651f53472ca17599dae3457b8b89494 F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a -F src/alter.c 5d99edbac5bc416032772b723ee30182ee6e5de0 +F src/alter.c b00900877f766f116f9e16116f1ccacdc21d82f1 F src/analyze.c 663e0b291d27eb03c9fd6b421e2d61ba348a2389 F src/attach.c 3801129015ef59d76bf23c95ef9b0069d18a0c52 F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34 @@ -298,7 +298,7 @@ F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 F test/aggnested.test 45c0201e28045ad38a530b5a144b73cd4aa2cfd6 F test/alias.test 4529fbc152f190268a15f9384a5651bbbabc9d87 F test/all.test 6ff7b43c2b4b905c74dc4a813d201d0fa64c5783 -F test/alter.test e88dfa77e020c2b48e52a8020c70171ab828e079 +F test/alter.test 547dc2d292644301ac9a7dda22b319b74f9c08d2 F test/alter2.test 7ea05c7d92ac99349a802ef7ada17294dd647060 F test/alter3.test 49c9d9fba2b8fcdce2dedeca97bbf1f369cc548d F test/alter4.test d6c011fa0d6227abba762498cafbb607c9609e93 @@ -1160,7 +1160,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 3122b8364082be783821da01d4af2af6a9586327 -R e1df7805a07beb887bab893b56a4a7f9 +P ab23abf392175d3e256ff619b13abbbe732a49ed +R 410ec05c8f2a9918dc68eaaf465de80d U drh -Z 77065e6cb595843b2b0b90941a9d16f6 +Z 8590c3c7b25dad5b568a22b07ca7e219 diff --git a/manifest.uuid b/manifest.uuid index 39f1fc5832..1f38f99a6e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ab23abf392175d3e256ff619b13abbbe732a49ed \ No newline at end of file +c6fa8d0d82805be230f672eabccdfa5680d4ddfd \ No newline at end of file diff --git a/src/alter.c b/src/alter.c index 1a83e570db..64204b7b24 100644 --- a/src/alter.c +++ b/src/alter.c @@ -116,6 +116,7 @@ static void renameParentFunc( int token; /* Type of token */ UNUSED_PARAMETER(NotUsed); + if( zInput==0 || zOld==0 ) return; for(z=zInput; *z; z=z+n){ n = sqlite3GetToken(z, &token); if( token==TK_REFERENCES ){ diff --git a/test/alter.test b/test/alter.test index 557162f837..ddf1698824 100644 --- a/test/alter.test +++ b/test/alter.test @@ -875,4 +875,42 @@ do_execsql_test alter-16.2 { SELECT * FROM t16a_rn ORDER BY a; } {abc 1.25 99 xyzzy cba 5.5 98 fizzle} +#------------------------------------------------------------------------- +# Verify that NULL values into the internal-use-only sqlite_rename_*() +# functions do not cause problems. +# +do_execsql_test alter-17.1 { + SELECT sqlite_rename_table('CREATE TABLE xyz(a,b,c)','abc'); +} {{CREATE TABLE "abc"(a,b,c)}} +do_execsql_test alter-17.2 { + SELECT sqlite_rename_table('CREATE TABLE xyz(a,b,c)',NULL); +} {{CREATE TABLE "(NULL)"(a,b,c)}} +do_execsql_test alter-17.3 { + SELECT sqlite_rename_table(NULL,'abc'); +} {{}} +do_execsql_test alter-17.4 { + SELECT sqlite_rename_trigger('CREATE TRIGGER r1 ON xyz WHEN','abc'); +} {{CREATE TRIGGER r1 ON "abc" WHEN}} +do_execsql_test alter-17.5 { + SELECT sqlite_rename_trigger('CREATE TRIGGER r1 ON xyz WHEN',NULL); +} {{CREATE TRIGGER r1 ON "(NULL)" WHEN}} +do_execsql_test alter-17.6 { + SELECT sqlite_rename_trigger(NULL,'abc'); +} {{}} +do_execsql_test alter-17.7 { + SELECT sqlite_rename_parent('CREATE TABLE t1(a REFERENCES "xyzzy")', + 'xyzzy','lmnop'); +} {{CREATE TABLE t1(a REFERENCES "lmnop")}} +do_execsql_test alter-17.8 { + SELECT sqlite_rename_parent('CREATE TABLE t1(a REFERENCES "xyzzy")', + 'xyzzy',NULL); +} {{CREATE TABLE t1(a REFERENCES "(NULL)")}} +do_execsql_test alter-17.9 { + SELECT sqlite_rename_parent('CREATE TABLE t1(a REFERENCES "xyzzy")', + NULL, 'lmnop'); +} {{}} +do_execsql_test alter-17.10 { + SELECT sqlite_rename_parent(NULL,'abc','xyz'); +} {{}} + finish_test From 2cf4acbd9f774e1c7bbaa232edbbdf93cff553ee Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 18 Apr 2014 00:06:02 +0000 Subject: [PATCH 11/12] Add the SQLITE_TESTCTRL_BYTEORDER test control to interrogate SQLite's notion of the processor byte order and whether the byte order is known at compile-time or determined at run-time. FossilOrigin-Name: 9c6961967ae00e563ebe2859eaf2639a79f2cb01 --- manifest | 18 +++++++++--------- manifest.uuid | 2 +- src/main.c | 16 ++++++++++++++++ src/shell.c | 6 ++++-- src/sqlite.h.in | 3 ++- src/sqliteInt.h | 9 ++++++--- 6 files changed, 38 insertions(+), 16 deletions(-) diff --git a/manifest b/manifest index 5ba411e0a6..a1452995b3 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Make\ssure\sthe\sundocumented\ssqlite_rename_parent()\sfunction\sdoes\snot\ncrash\seven\sif\sit\sis\sinvoked\swith\sNULL\sarguments.\nTicket\s[264b970c4379fd4b94] -D 2014-04-14T19:48:25.984 +C Add\sthe\sSQLITE_TESTCTRL_BYTEORDER\stest\scontrol\sto\sinterrogate\sSQLite's\snotion\nof\sthe\sprocessor\sbyte\sorder\sand\swhether\sthe\sbyte\sorder\sis\sknown\sat\scompile-time\nor\sdetermined\sat\srun-time. +D 2014-04-18T00:06:02.110 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -186,7 +186,7 @@ F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d F src/legacy.c 0df0b1550b9cc1f58229644735e317ac89131f12 F src/lempar.c cdf0a000315332fc9b50b62f3b5e22e080a0952b F src/loadext.c 867c7b330b740c6c917af9956b13b81d0a048303 -F src/main.c 691b25754bef596108fe60ff1bcbe8445369c9db +F src/main.c 0a8cfb6b2899649880e5874ac9bfd1c6f7c6a4a3 F src/malloc.c 0203ebce9152c6a0e5de520140b8ba65187350be F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c c0c990fcaddff810ea277b4fb5d9138603dd5d4b @@ -218,11 +218,11 @@ F src/random.c d10c1f85b6709ca97278428fd5db5bbb9c74eece F src/resolve.c 273d5f47c4e2c05b2d3d2bffeda939551ab59e66 F src/rowset.c a9c9aae3234b44a6d7c6f5a3cadf90dce1e627be F src/select.c 269c3e31a450fce642a10569221a49180348c88e -F src/shell.c 5260f2ada8dd06e9f5ae0a448c8c01e7a75dd881 -F src/sqlite.h.in a2ef671f92747a5a1c8a47bad5c585a8dd9eca80 +F src/shell.c 2afe7a7154e97be0c74c5feacf09626bda8493be +F src/sqlite.h.in bde98816e1ba0c9ffef50afe7b32f4e5a8f54fe0 F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc -F src/sqliteInt.h dadd17dbd05fd17cad157a7d96339bf4a0b41172 +F src/sqliteInt.h 35a265ef6e137e9af289d6e3b55745323148ad66 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e @@ -1160,7 +1160,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P ab23abf392175d3e256ff619b13abbbe732a49ed -R 410ec05c8f2a9918dc68eaaf465de80d +P c6fa8d0d82805be230f672eabccdfa5680d4ddfd +R f2d9932522491a86ed313bf5e3a1693d U drh -Z 8590c3c7b25dad5b568a22b07ca7e219 +Z 4f6d25a564bc084e4d5fbc71ec75b6b1 diff --git a/manifest.uuid b/manifest.uuid index 1f38f99a6e..c03388d6de 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c6fa8d0d82805be230f672eabccdfa5680d4ddfd \ No newline at end of file +9c6961967ae00e563ebe2859eaf2639a79f2cb01 \ No newline at end of file diff --git a/src/main.c b/src/main.c index 9e83d4963a..65521f4466 100644 --- a/src/main.c +++ b/src/main.c @@ -3205,6 +3205,22 @@ int sqlite3_test_control(int op, ...){ break; } + /* + ** sqlite3_test_control(SQLITE_TESTCTRL_BYTEORDER); + ** + ** The integer returned reveals the byte-order of the computer on which + ** SQLite is running: + ** + ** 1 big-endian, determined at run-time + ** 10 little-endian, determined at run-time + ** 432101 big-endian, determined at compile-time + ** 123410 little-endian, determined at compile-time + */ + case SQLITE_TESTCTRL_BYTEORDER: { + rc = SQLITE_BYTEORDER*100 + SQLITE_LITTLEENDIAN*10 + SQLITE_BIGENDIAN; + break; + } + /* sqlite3_test_control(SQLITE_TESTCTRL_RESERVE, sqlite3 *db, int N) ** ** Set the nReserve size to N for the main database on the database diff --git a/src/shell.c b/src/shell.c index f380962a86..61965d2d39 100644 --- a/src/shell.c +++ b/src/shell.c @@ -3027,6 +3027,7 @@ static int do_meta_command(char *zLine, struct callback_data *p){ { "optimizations", SQLITE_TESTCTRL_OPTIMIZATIONS }, { "iskeyword", SQLITE_TESTCTRL_ISKEYWORD }, { "scratchmalloc", SQLITE_TESTCTRL_SCRATCHMALLOC }, + { "byteorder", SQLITE_TESTCTRL_BYTEORDER }, }; int testctrl = -1; int rc = 0; @@ -3067,9 +3068,10 @@ static int do_meta_command(char *zLine, struct callback_data *p){ break; /* sqlite3_test_control(int) */ - case SQLITE_TESTCTRL_PRNG_SAVE: - case SQLITE_TESTCTRL_PRNG_RESTORE: + case SQLITE_TESTCTRL_PRNG_SAVE: + case SQLITE_TESTCTRL_PRNG_RESTORE: case SQLITE_TESTCTRL_PRNG_RESET: + case SQLITE_TESTCTRL_BYTEORDER: if( nArg==2 ){ rc = sqlite3_test_control(testctrl); fprintf(p->out, "%d (0x%08x)\n", rc, rc); diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 5d2c87552c..e8dddc468c 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -6118,7 +6118,8 @@ int sqlite3_test_control(int op, ...); #define SQLITE_TESTCTRL_EXPLAIN_STMT 19 #define SQLITE_TESTCTRL_NEVER_CORRUPT 20 #define SQLITE_TESTCTRL_VDBE_COVERAGE 21 -#define SQLITE_TESTCTRL_LAST 21 +#define SQLITE_TESTCTRL_BYTEORDER 22 +#define SQLITE_TESTCTRL_LAST 22 /* ** CAPI3REF: SQLite Runtime Status diff --git a/src/sqliteInt.h b/src/sqliteInt.h index da46676adf..2a12466a4e 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -553,15 +553,18 @@ const int sqlite3one = 1; #else extern const int sqlite3one; #endif -#if defined(i386) || defined(__i386__) || defined(_M_IX86)\ - || defined(__x86_64) || defined(__x86_64__) +#if defined(i386) || defined(__i386__) || defined(_M_IX86) \ + || defined(__x86_64) || defined(__x86_64__) || defined(_M_X64) \ + || defined(_M_AMD64) || defined(_M_ARM) || defined(__x86) +# define SQLITE_BYTEORDER 1234 # define SQLITE_BIGENDIAN 0 # define SQLITE_LITTLEENDIAN 1 # define SQLITE_UTF16NATIVE SQLITE_UTF16LE #else +# define SQLITE_BYTEORDER 0 /* 0 means "unknown at compile-time" */ # define SQLITE_BIGENDIAN (*(char *)(&sqlite3one)==0) # define SQLITE_LITTLEENDIAN (*(char *)(&sqlite3one)==1) -# define SQLITE_UTF16NATIVE (SQLITE_BIGENDIAN?SQLITE_UTF16BE:SQLITE_UTF16LE) +# define SQLITE_UTF16NATIVE (SQLITE_BIGENDIAN?SQLITE_UTF16BE:SQLITE_UTF16LE) #endif /* From 71794dbaeb73f594ef704fa265715b207f98edc7 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 18 Apr 2014 00:49:29 +0000 Subject: [PATCH 12/12] Add the SQLITE_RUNTIME_BYTEORDER compile-time option to force SQLite to check the processor byte-order at run-time. Add additional compile-time byte order checks for ARM, PPC, and SPARC. FossilOrigin-Name: 2c5363873a6f990a0abaacac6303acd46b48befc --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/sqliteInt.h | 24 +++++++++++++++++++----- 3 files changed, 26 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index a1452995b3..97b4f2b46f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\sSQLITE_TESTCTRL_BYTEORDER\stest\scontrol\sto\sinterrogate\sSQLite's\snotion\nof\sthe\sprocessor\sbyte\sorder\sand\swhether\sthe\sbyte\sorder\sis\sknown\sat\scompile-time\nor\sdetermined\sat\srun-time. -D 2014-04-18T00:06:02.110 +C Add\sthe\sSQLITE_RUNTIME_BYTEORDER\scompile-time\soption\sto\sforce\sSQLite\sto\scheck\nthe\sprocessor\sbyte-order\sat\srun-time.\s\sAdd\sadditional\scompile-time\sbyte\sorder\nchecks\sfor\sARM,\sPPC,\sand\sSPARC. +D 2014-04-18T00:49:29.419 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -222,7 +222,7 @@ F src/shell.c 2afe7a7154e97be0c74c5feacf09626bda8493be F src/sqlite.h.in bde98816e1ba0c9ffef50afe7b32f4e5a8f54fe0 F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc -F src/sqliteInt.h 35a265ef6e137e9af289d6e3b55745323148ad66 +F src/sqliteInt.h d3ca0bdd6743c9af2f333cb372b4bf95b19cd1fd F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e @@ -1160,7 +1160,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P c6fa8d0d82805be230f672eabccdfa5680d4ddfd -R f2d9932522491a86ed313bf5e3a1693d +P 9c6961967ae00e563ebe2859eaf2639a79f2cb01 +R 1b4cbcab83595d3a8147d0a70e1ae961 U drh -Z 4f6d25a564bc084e4d5fbc71ec75b6b1 +Z a694f54c65c4a003c92caa29b70309b3 diff --git a/manifest.uuid b/manifest.uuid index c03388d6de..05a8b60e7e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9c6961967ae00e563ebe2859eaf2639a79f2cb01 \ No newline at end of file +2c5363873a6f990a0abaacac6303acd46b48befc \ No newline at end of file diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 2a12466a4e..8197a61eb5 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -546,21 +546,35 @@ typedef INT16_TYPE LogEst; /* ** Macros to determine whether the machine is big or little endian, -** evaluated at runtime. +** and whether or not that determination is run-time or compile-time. +** +** For best performance, an attempt is made to guess at the byte-order +** using C-preprocessor macros. If that is unsuccessful, or if +** -DSQLITE_RUNTIME_BYTEORDER=1 is set, then byte-order is determined +** at run-time. */ #ifdef SQLITE_AMALGAMATION const int sqlite3one = 1; #else extern const int sqlite3one; #endif -#if defined(i386) || defined(__i386__) || defined(_M_IX86) \ - || defined(__x86_64) || defined(__x86_64__) || defined(_M_X64) \ - || defined(_M_AMD64) || defined(_M_ARM) || defined(__x86) +#if (defined(i386) || defined(__i386__) || defined(_M_IX86) || \ + defined(__x86_64) || defined(__x86_64__) || defined(_M_X64) || \ + defined(_M_AMD64) || defined(_M_ARM) || defined(__x86) || \ + defined(__arm__)) && !defined(SQLITE_RUNTIME_BYTEORDER) # define SQLITE_BYTEORDER 1234 # define SQLITE_BIGENDIAN 0 # define SQLITE_LITTLEENDIAN 1 # define SQLITE_UTF16NATIVE SQLITE_UTF16LE -#else +#endif +#if (defined(sparc) || defined(__ppc__)) \ + && !defined(SQLITE_RUNTIME_BYTEORDER) +# define SQLITE_BYTEORDER 4321 +# define SQLITE_BIGENDIAN 1 +# define SQLITE_LITTLEENDIAN 0 +# define SQLITE_UTF16NATIVE SQLITE_UTF16BE +#endif +#if !defined(SQLITE_BYTEORDER) # define SQLITE_BYTEORDER 0 /* 0 means "unknown at compile-time" */ # define SQLITE_BIGENDIAN (*(char *)(&sqlite3one)==0) # define SQLITE_LITTLEENDIAN (*(char *)(&sqlite3one)==1)