From 75e96b31005447d799619926b22bcaf5b8ac68c8 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 1 Apr 2017 00:20:06 +0000 Subject: [PATCH 01/28] Save a 78 bytes of code space and a million CPU cycles in speedtest1 by storing the cell index for the leaf page in the BtCursor object in its own field (BtCursor.ix), rather than as an entry in the BtCursor.aiIdx array. FossilOrigin-Name: 2452f0617d1085689264b5f66681788cfe9e3b1a7b318307c93942b702a443df --- manifest | 14 ++++----- manifest.uuid | 2 +- src/btree.c | 77 +++++++++++++++++++++++++------------------------- src/btreeInt.h | 1 + 4 files changed, 48 insertions(+), 46 deletions(-) diff --git a/manifest b/manifest index eee647a65b..8cff8164b6 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Declare\sthe\sLemon-generated\sparser\sobject\sas\sitself.\s\s(Duh) -D 2017-03-30T17:13:37.978 +C Save\sa\s78\sbytes\sof\scode\sspace\sand\sa\smillion\sCPU\scycles\sin\sspeedtest1\sby\nstoring\sthe\scell\sindex\sfor\sthe\sleaf\spage\sin\sthe\sBtCursor\sobject\sin\sits\sown\nfield\s(BtCursor.ix),\srather\sthan\sas\san\sentry\sin\sthe\sBtCursor.aiIdx\sarray. +D 2017-04-01T00:20:06.305 F Makefile.in 1cc758ce3374a32425e4d130c2fe7b026b20de5b8843243de75f087c0a2661fb F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc a4c0613a18663bda56d8cf76079ab6590a7c3602e54befb4bbdef76bcaa38b6a @@ -344,9 +344,9 @@ F src/auth.c 930b376a9c56998557367e6f7f8aaeac82a2a792 F src/backup.c faf17e60b43233c214aae6a8179d24503a61e83b F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33 F src/btmutex.c 0e9ce2d56159b89b9bc8e197e023ee11e39ff8ca -F src/btree.c 64ff65a01851a34c8145e5bc767df9e57d2f3c1acdc6aba334794b7c40c684e6 +F src/btree.c 24ae5472bd0b53b4130ecdda389deb621af721d1fcb50890b878102b00bd10fa F src/btree.h bf64dfeeddeebdb775a5eba0098bbc00d073290d -F src/btreeInt.h cd55d39d9916270837a88c12e701047cba0729b0 +F src/btreeInt.h 874e49bdfab514285dda1cb01880e4c82b7a428a0de7d9b2978d8d8849fbb210 F src/build.c 43f903c9082040ced2b421543cb0300c2973647d F src/callback.c 2e76147783386374bf01b227f752c81ec872d730 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e @@ -1569,7 +1569,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 9e550ccc29f317422dae3a4bb89a78b839330825fecd40a01d1a2acc719cef79 -R 288166ae6bc74f6b9a15fa169ea78182 +P c8000e94cca59dabf83d6cb75b40441aaf793d29880582dc4baa17246449b5fe +R a50a3e5b98174af9f9e2e47aca996e63 U drh -Z 81f3770fca5082b63e34ff795f3d141f +Z 14f3c01fb36e600191848f3a558eb584 diff --git a/manifest.uuid b/manifest.uuid index 5037f50129..c9a1f2708c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c8000e94cca59dabf83d6cb75b40441aaf793d29880582dc4baa17246449b5fe \ No newline at end of file +2452f0617d1085689264b5f66681788cfe9e3b1a7b318307c93942b702a443df \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index aecf06e63f..48cfae5c72 100644 --- a/src/btree.c +++ b/src/btree.c @@ -4317,7 +4317,7 @@ int sqlite3BtreeCloseCursor(BtCursor *pCur){ CellInfo info; int iPage = pCur->iPage; memset(&info, 0, sizeof(info)); - btreeParseCell(pCur->apPage[iPage], pCur->aiIdx[iPage], &info); + btreeParseCell(pCur->apPage[iPage], pCur->ix, &info); assert( CORRUPT_DB || memcmp(&info, &pCur->info, sizeof(info))==0 ); } #else @@ -4327,7 +4327,7 @@ static SQLITE_NOINLINE void getCellInfo(BtCursor *pCur){ if( pCur->info.nSize==0 ){ int iPage = pCur->iPage; pCur->curFlags |= BTCF_ValidNKey; - btreeParseCell(pCur->apPage[iPage],pCur->aiIdx[iPage],&pCur->info); + btreeParseCell(pCur->apPage[iPage],pCur->ix,&pCur->info); }else{ assertCellInfo(pCur); } @@ -4534,7 +4534,7 @@ static int accessPayload( assert( pPage ); assert( eOp==0 || eOp==1 ); assert( pCur->eState==CURSOR_VALID ); - assert( pCur->aiIdx[pCur->iPage]nCell ); + assert( pCur->ixnCell ); assert( cursorHoldsMutex(pCur) ); getCellInfo(pCur); @@ -4721,7 +4721,7 @@ int sqlite3BtreePayload(BtCursor *pCur, u32 offset, u32 amt, void *pBuf){ assert( cursorHoldsMutex(pCur) ); assert( pCur->eState==CURSOR_VALID ); assert( pCur->iPage>=0 && pCur->apPage[pCur->iPage] ); - assert( pCur->aiIdx[pCur->iPage]apPage[pCur->iPage]->nCell ); + assert( pCur->ixapPage[pCur->iPage]->nCell ); return accessPayload(pCur, offset, amt, (unsigned char*)pBuf, 0); } @@ -4783,7 +4783,7 @@ static const void *fetchPayload( assert( pCur->eState==CURSOR_VALID ); assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) ); assert( cursorOwnsBtShared(pCur) ); - assert( pCur->aiIdx[pCur->iPage]apPage[pCur->iPage]->nCell ); + assert( pCur->ixapPage[pCur->iPage]->nCell ); assert( pCur->info.nSize>0 ); assert( pCur->info.pPayload>pCur->apPage[pCur->iPage]->aData || CORRUPT_DB ); assert( pCur->info.pPayloadapPage[pCur->iPage]->aDataEnd ||CORRUPT_DB); @@ -4834,8 +4834,8 @@ static int moveToChild(BtCursor *pCur, u32 newPgno){ } pCur->info.nSize = 0; pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl); - pCur->iPage++; - pCur->aiIdx[pCur->iPage] = 0; + pCur->aiIdx[pCur->iPage++] = pCur->ix; + pCur->ix = 0; return getAndInitPage(pBt, newPgno, &pCur->apPage[pCur->iPage], pCur, pCur->curPagerFlags); } @@ -4883,6 +4883,7 @@ static void moveToParent(BtCursor *pCur){ testcase( pCur->aiIdx[pCur->iPage-1] > pCur->apPage[pCur->iPage-1]->nCell ); pCur->info.nSize = 0; pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl); + pCur->ix = pCur->aiIdx[pCur->iPage-1]; releasePageNotNull(pCur->apPage[pCur->iPage--]); } @@ -4964,7 +4965,7 @@ static int moveToRoot(BtCursor *pCur){ } skip_init: - pCur->aiIdx[0] = 0; + pCur->ix = 0; pCur->info.nSize = 0; pCur->curFlags &= ~(BTCF_AtLast|BTCF_ValidNKey|BTCF_ValidOvfl); @@ -4998,8 +4999,8 @@ static int moveToLeftmost(BtCursor *pCur){ assert( cursorOwnsBtShared(pCur) ); assert( pCur->eState==CURSOR_VALID ); while( rc==SQLITE_OK && !(pPage = pCur->apPage[pCur->iPage])->leaf ){ - assert( pCur->aiIdx[pCur->iPage]nCell ); - pgno = get4byte(findCell(pPage, pCur->aiIdx[pCur->iPage])); + assert( pCur->ixnCell ); + pgno = get4byte(findCell(pPage, pCur->ix)); rc = moveToChild(pCur, pgno); } return rc; @@ -5024,11 +5025,11 @@ static int moveToRightmost(BtCursor *pCur){ assert( pCur->eState==CURSOR_VALID ); while( !(pPage = pCur->apPage[pCur->iPage])->leaf ){ pgno = get4byte(&pPage->aData[pPage->hdrOffset+8]); - pCur->aiIdx[pCur->iPage] = pPage->nCell; + pCur->ix = pPage->nCell; rc = moveToChild(pCur, pgno); if( rc ) return rc; } - pCur->aiIdx[pCur->iPage] = pPage->nCell-1; + pCur->ix = pPage->nCell-1; assert( pCur->info.nSize==0 ); assert( (pCur->curFlags & BTCF_ValidNKey)==0 ); return SQLITE_OK; @@ -5076,7 +5077,7 @@ int sqlite3BtreeLast(BtCursor *pCur, int *pRes){ for(ii=0; iiiPage; ii++){ assert( pCur->aiIdx[ii]==pCur->apPage[ii]->nCell ); } - assert( pCur->aiIdx[pCur->iPage]==pCur->apPage[pCur->iPage]->nCell-1 ); + assert( pCur->ix==pCur->apPage[pCur->iPage]->nCell-1 ); assert( pCur->apPage[pCur->iPage]->leaf ); #endif return SQLITE_OK; @@ -5223,7 +5224,7 @@ int sqlite3BtreeMovetoUnpacked( upr = pPage->nCell-1; assert( biasRight==0 || biasRight==1 ); idx = upr>>(1-biasRight); /* idx = biasRight ? upr : (lwr+upr)/2; */ - pCur->aiIdx[pCur->iPage] = (u16)idx; + pCur->ix = (u16)idx; if( xRecordCompare==0 ){ for(;;){ i64 nCellKey; @@ -5242,7 +5243,7 @@ int sqlite3BtreeMovetoUnpacked( if( lwr>upr ){ c = +1; break; } }else{ assert( nCellKey==intKey ); - pCur->aiIdx[pCur->iPage] = (u16)idx; + pCur->ix = (u16)idx; if( !pPage->leaf ){ lwr = idx; goto moveto_next_layer; @@ -5311,7 +5312,7 @@ int sqlite3BtreeMovetoUnpacked( rc = SQLITE_NOMEM_BKPT; goto moveto_finish; } - pCur->aiIdx[pCur->iPage] = (u16)idx; + pCur->ix = (u16)idx; rc = accessPayload(pCur, 0, nCell, (unsigned char*)pCellKey, 0); pCur->curFlags &= ~BTCF_ValidOvfl; if( rc ){ @@ -5333,7 +5334,7 @@ int sqlite3BtreeMovetoUnpacked( assert( c==0 ); *pRes = 0; rc = SQLITE_OK; - pCur->aiIdx[pCur->iPage] = (u16)idx; + pCur->ix = (u16)idx; if( pIdxKey->errCode ) rc = SQLITE_CORRUPT; goto moveto_finish; } @@ -5345,8 +5346,8 @@ int sqlite3BtreeMovetoUnpacked( assert( lwr==upr+1 || (pPage->intKey && !pPage->leaf) ); assert( pPage->isInit ); if( pPage->leaf ){ - assert( pCur->aiIdx[pCur->iPage]apPage[pCur->iPage]->nCell ); - pCur->aiIdx[pCur->iPage] = (u16)idx; + assert( pCur->ixapPage[pCur->iPage]->nCell ); + pCur->ix = (u16)idx; *pRes = c; rc = SQLITE_OK; goto moveto_finish; @@ -5357,7 +5358,7 @@ moveto_next_layer: }else{ chldPg = get4byte(findCell(pPage, lwr)); } - pCur->aiIdx[pCur->iPage] = (u16)lwr; + pCur->ix = (u16)lwr; rc = moveToChild(pCur, chldPg); if( rc ) break; } @@ -5458,7 +5459,7 @@ static SQLITE_NOINLINE int btreeNext(BtCursor *pCur, int *pRes){ } pPage = pCur->apPage[pCur->iPage]; - idx = ++pCur->aiIdx[pCur->iPage]; + idx = ++pCur->ix; assert( pPage->isInit ); /* If the database file is corrupt, it is possible for the value of idx @@ -5482,7 +5483,7 @@ static SQLITE_NOINLINE int btreeNext(BtCursor *pCur, int *pRes){ } moveToParent(pCur); pPage = pCur->apPage[pCur->iPage]; - }while( pCur->aiIdx[pCur->iPage]>=pPage->nCell ); + }while( pCur->ix>=pPage->nCell ); if( pPage->intKey ){ return sqlite3BtreeNext(pCur, pRes); }else{ @@ -5506,8 +5507,8 @@ int sqlite3BtreeNext(BtCursor *pCur, int *pRes){ *pRes = 0; if( pCur->eState!=CURSOR_VALID ) return btreeNext(pCur, pRes); pPage = pCur->apPage[pCur->iPage]; - if( (++pCur->aiIdx[pCur->iPage])>=pPage->nCell ){ - pCur->aiIdx[pCur->iPage]--; + if( (++pCur->ix)>=pPage->nCell ){ + pCur->ix--; return btreeNext(pCur, pRes); } if( pPage->leaf ){ @@ -5571,12 +5572,12 @@ static SQLITE_NOINLINE int btreePrevious(BtCursor *pCur, int *pRes){ pPage = pCur->apPage[pCur->iPage]; assert( pPage->isInit ); if( !pPage->leaf ){ - int idx = pCur->aiIdx[pCur->iPage]; + int idx = pCur->ix; rc = moveToChild(pCur, get4byte(findCell(pPage, idx))); if( rc ) return rc; rc = moveToRightmost(pCur); }else{ - while( pCur->aiIdx[pCur->iPage]==0 ){ + while( pCur->ix==0 ){ if( pCur->iPage==0 ){ pCur->eState = CURSOR_INVALID; *pRes = 1; @@ -5587,7 +5588,7 @@ static SQLITE_NOINLINE int btreePrevious(BtCursor *pCur, int *pRes){ assert( pCur->info.nSize==0 ); assert( (pCur->curFlags & (BTCF_ValidOvfl))==0 ); - pCur->aiIdx[pCur->iPage]--; + pCur->ix--; pPage = pCur->apPage[pCur->iPage]; if( pPage->intKey && !pPage->leaf ){ rc = sqlite3BtreePrevious(pCur, pRes); @@ -5606,12 +5607,12 @@ int sqlite3BtreePrevious(BtCursor *pCur, int *pRes){ pCur->curFlags &= ~(BTCF_AtLast|BTCF_ValidOvfl|BTCF_ValidNKey); pCur->info.nSize = 0; if( pCur->eState!=CURSOR_VALID - || pCur->aiIdx[pCur->iPage]==0 + || pCur->ix==0 || pCur->apPage[pCur->iPage]->leaf==0 ){ return btreePrevious(pCur, pRes); } - pCur->aiIdx[pCur->iPage]--; + pCur->ix--; return SQLITE_OK; } @@ -7933,8 +7934,8 @@ static int balance(BtCursor *pCur){ rc = balance_deeper(pPage, &pCur->apPage[1]); if( rc==SQLITE_OK ){ pCur->iPage = 1; + pCur->ix = 0; pCur->aiIdx[0] = 0; - pCur->aiIdx[1] = 0; assert( pCur->apPage[1]->nOverflow ); } }else{ @@ -8163,7 +8164,7 @@ int sqlite3BtreeInsert( if( rc ) goto end_insert; assert( szNew==pPage->xCellSize(pPage, newCell) ); assert( szNew <= MX_CELL_SIZE(pBt) ); - idx = pCur->aiIdx[pCur->iPage]; + idx = pCur->ix; if( loc==0 ){ CellInfo info; assert( idxnCell ); @@ -8191,7 +8192,7 @@ int sqlite3BtreeInsert( if( rc ) goto end_insert; }else if( loc<0 && pPage->nCell>0 ){ assert( pPage->leaf ); - idx = ++pCur->aiIdx[pCur->iPage]; + idx = ++pCur->ix; }else{ assert( pPage->leaf ); } @@ -8287,12 +8288,12 @@ int sqlite3BtreeDelete(BtCursor *pCur, u8 flags){ assert( pCur->curFlags & BTCF_WriteFlag ); assert( hasSharedCacheTableLock(p, pCur->pgnoRoot, pCur->pKeyInfo!=0, 2) ); assert( !hasReadConflicts(p, pCur->pgnoRoot) ); - assert( pCur->aiIdx[pCur->iPage]apPage[pCur->iPage]->nCell ); + assert( pCur->ixapPage[pCur->iPage]->nCell ); assert( pCur->eState==CURSOR_VALID ); assert( (flags & ~(BTREE_SAVEPOSITION | BTREE_AUXDELETE))==0 ); iCellDepth = pCur->iPage; - iCellIdx = pCur->aiIdx[iCellDepth]; + iCellIdx = pCur->ix; pPage = pCur->apPage[iCellDepth]; pCell = findCell(pPage, iCellIdx); @@ -8409,7 +8410,7 @@ int sqlite3BtreeDelete(BtCursor *pCur, u8 flags){ pCur->eState = CURSOR_SKIPNEXT; if( iCellIdx>=pPage->nCell ){ pCur->skipNext = -1; - pCur->aiIdx[iCellDepth] = pPage->nCell-1; + pCur->ix = pPage->nCell-1; }else{ pCur->skipNext = 1; } @@ -8922,16 +8923,16 @@ int sqlite3BtreeCount(BtCursor *pCur, i64 *pnEntry){ return moveToRoot(pCur); } moveToParent(pCur); - }while ( pCur->aiIdx[pCur->iPage]>=pCur->apPage[pCur->iPage]->nCell ); + }while ( pCur->ix>=pCur->apPage[pCur->iPage]->nCell ); - pCur->aiIdx[pCur->iPage]++; + pCur->ix++; pPage = pCur->apPage[pCur->iPage]; } /* Descend to the child node of the cell that the cursor currently ** points at. This is the right-child if (iIdx==pPage->nCell). */ - iIdx = pCur->aiIdx[pCur->iPage]; + iIdx = pCur->ix; if( iIdx==pPage->nCell ){ rc = moveToChild(pCur, get4byte(&pPage->aData[pPage->hdrOffset+8])); }else{ diff --git a/src/btreeInt.h b/src/btreeInt.h index b01163c33f..a676010ace 100644 --- a/src/btreeInt.h +++ b/src/btreeInt.h @@ -517,6 +517,7 @@ struct BtCursor { ** initialized. */ i8 iPage; /* Index of current page in apPage */ u8 curIntKey; /* Value of apPage[0]->intKey */ + u16 ix; /* Current index for apPage[iPage] */ struct KeyInfo *pKeyInfo; /* Argument passed to comparison function */ void *padding1; /* Make object size a multiple of 16 */ u16 aiIdx[BTCURSOR_MAX_DEPTH]; /* Current index in apPage[i] */ From b6017a44c5beca2c8d47cc1e16795f5a464db9d2 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 1 Apr 2017 11:40:05 +0000 Subject: [PATCH 02/28] Remove unused fields from the BtCursor object. FossilOrigin-Name: 1c0d82e0786ed22d07d774b8b166340fad97bcaab6016e395c469bcfcb7c77a3 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/btreeInt.h | 7 +++---- 3 files changed, 10 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index 8cff8164b6..1e16c25a50 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Save\sa\s78\sbytes\sof\scode\sspace\sand\sa\smillion\sCPU\scycles\sin\sspeedtest1\sby\nstoring\sthe\scell\sindex\sfor\sthe\sleaf\spage\sin\sthe\sBtCursor\sobject\sin\sits\sown\nfield\s(BtCursor.ix),\srather\sthan\sas\san\sentry\sin\sthe\sBtCursor.aiIdx\sarray. -D 2017-04-01T00:20:06.305 +C Remove\sunused\sfields\sfrom\sthe\sBtCursor\sobject. +D 2017-04-01T11:40:05.090 F Makefile.in 1cc758ce3374a32425e4d130c2fe7b026b20de5b8843243de75f087c0a2661fb F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc a4c0613a18663bda56d8cf76079ab6590a7c3602e54befb4bbdef76bcaa38b6a @@ -346,7 +346,7 @@ F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33 F src/btmutex.c 0e9ce2d56159b89b9bc8e197e023ee11e39ff8ca F src/btree.c 24ae5472bd0b53b4130ecdda389deb621af721d1fcb50890b878102b00bd10fa F src/btree.h bf64dfeeddeebdb775a5eba0098bbc00d073290d -F src/btreeInt.h 874e49bdfab514285dda1cb01880e4c82b7a428a0de7d9b2978d8d8849fbb210 +F src/btreeInt.h a392d353104b4add58b4a59cb185f5d5693dde832c565b77d8d4c343ed98f610 F src/build.c 43f903c9082040ced2b421543cb0300c2973647d F src/callback.c 2e76147783386374bf01b227f752c81ec872d730 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e @@ -1569,7 +1569,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P c8000e94cca59dabf83d6cb75b40441aaf793d29880582dc4baa17246449b5fe -R a50a3e5b98174af9f9e2e47aca996e63 +P 2452f0617d1085689264b5f66681788cfe9e3b1a7b318307c93942b702a443df +R a9b36ce777e90549c853b64c225197a6 U drh -Z 14f3c01fb36e600191848f3a558eb584 +Z 4b939d3dd6a7f0c2f29593c397a2c2a8 diff --git a/manifest.uuid b/manifest.uuid index c9a1f2708c..773ed91459 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2452f0617d1085689264b5f66681788cfe9e3b1a7b318307c93942b702a443df \ No newline at end of file +1c0d82e0786ed22d07d774b8b166340fad97bcaab6016e395c469bcfcb7c77a3 \ No newline at end of file diff --git a/src/btreeInt.h b/src/btreeInt.h index a676010ace..47de58f509 100644 --- a/src/btreeInt.h +++ b/src/btreeInt.h @@ -518,10 +518,9 @@ struct BtCursor { i8 iPage; /* Index of current page in apPage */ u8 curIntKey; /* Value of apPage[0]->intKey */ u16 ix; /* Current index for apPage[iPage] */ - struct KeyInfo *pKeyInfo; /* Argument passed to comparison function */ - void *padding1; /* Make object size a multiple of 16 */ - u16 aiIdx[BTCURSOR_MAX_DEPTH]; /* Current index in apPage[i] */ - MemPage *apPage[BTCURSOR_MAX_DEPTH]; /* Pages from root to current page */ + u16 aiIdx[BTCURSOR_MAX_DEPTH-1]; /* Current index in apPage[i] */ + struct KeyInfo *pKeyInfo; /* Arg passed to comparison function */ + MemPage *apPage[BTCURSOR_MAX_DEPTH]; /* Pages from root to current page */ }; /* From b808d7777118c846907da5143940a9d549232fce Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 1 Apr 2017 11:59:36 +0000 Subject: [PATCH 03/28] Faster implementation for sqlite3VdbeIntValue() and sqlite3VdbeRealValue(). FossilOrigin-Name: 8698df60c23d4dcc80b58352c14ae80ec238cac496f8a87bd72a96fef61cc63f --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbemem.c | 22 ++++++++++++++-------- 3 files changed, 21 insertions(+), 15 deletions(-) diff --git a/manifest b/manifest index 1e16c25a50..216e566be6 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\sunused\sfields\sfrom\sthe\sBtCursor\sobject. -D 2017-04-01T11:40:05.090 +C Faster\simplementation\sfor\ssqlite3VdbeIntValue()\sand\ssqlite3VdbeRealValue(). +D 2017-04-01T11:59:36.584 F Makefile.in 1cc758ce3374a32425e4d130c2fe7b026b20de5b8843243de75f087c0a2661fb F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc a4c0613a18663bda56d8cf76079ab6590a7c3602e54befb4bbdef76bcaa38b6a @@ -474,7 +474,7 @@ F src/vdbeInt.h 5db089ce18c4feff8820ec6e4cac2d2c82e03d4b1d96f10a6e43832147b8dffe F src/vdbeapi.c 5b08d82592bcff4470601fe78aaabebd50837860 F src/vdbeaux.c ecd0468611925d218e1eb4b3f538907904b136f0e15e333291a232b521bfcef1 F src/vdbeblob.c 359891617358deefc85bef7bcf787fa6b77facb9 -F src/vdbemem.c 3b5a9a5b375458d3e12a50ae1aaa41eeec2175fd +F src/vdbemem.c bbd8f5fdb7f11e02d9a6201f18a52325f1d2361a2850ff03a38f8efa5188f2dc F src/vdbesort.c eda25cb2d1727efca6f7862fea32b8aa33c0face F src/vdbetrace.c 41963d5376f0349842b5fc4aaaaacd7d9cdc0834 F src/vtab.c 007513c2ef52472fcdea6a741683d50662e82790 @@ -1569,7 +1569,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 2452f0617d1085689264b5f66681788cfe9e3b1a7b318307c93942b702a443df -R a9b36ce777e90549c853b64c225197a6 +P 1c0d82e0786ed22d07d774b8b166340fad97bcaab6016e395c469bcfcb7c77a3 +R e7e1f4a4fa7fe0c6a0bd77f428c6873c U drh -Z 4b939d3dd6a7f0c2f29593c397a2c2a8 +Z b92e301c12dc9a925621c9624fd5cc90 diff --git a/manifest.uuid b/manifest.uuid index 773ed91459..b022468409 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1c0d82e0786ed22d07d774b8b166340fad97bcaab6016e395c469bcfcb7c77a3 \ No newline at end of file +8698df60c23d4dcc80b58352c14ae80ec238cac496f8a87bd72a96fef61cc63f \ No newline at end of file diff --git a/src/vdbemem.c b/src/vdbemem.c index 656e19bfa8..9b1f43a94a 100644 --- a/src/vdbemem.c +++ b/src/vdbemem.c @@ -420,7 +420,7 @@ void sqlite3VdbeMemRelease(Mem *p){ ** If the double is out of range of a 64-bit signed integer then ** return the closest available 64-bit signed integer. */ -static i64 doubleToInt64(double r){ +static SQLITE_NOINLINE i64 doubleToInt64(double r){ #ifdef SQLITE_OMIT_FLOATING_POINT /* When floating-point is omitted, double and int64 are the same thing */ return r; @@ -456,6 +456,11 @@ static i64 doubleToInt64(double r){ ** ** If pMem represents a string value, its encoding might be changed. */ +static SQLITE_NOINLINE i64 memIntValue(Mem *pMem){ + i64 value = 0; + sqlite3Atoi64(pMem->z, &value, pMem->n, pMem->enc); + return value; +} i64 sqlite3VdbeIntValue(Mem *pMem){ int flags; assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); @@ -466,10 +471,8 @@ i64 sqlite3VdbeIntValue(Mem *pMem){ }else if( flags & MEM_Real ){ return doubleToInt64(pMem->u.r); }else if( flags & (MEM_Str|MEM_Blob) ){ - i64 value = 0; assert( pMem->z || pMem->n==0 ); - sqlite3Atoi64(pMem->z, &value, pMem->n, pMem->enc); - return value; + return memIntValue(pMem); }else{ return 0; } @@ -481,6 +484,12 @@ i64 sqlite3VdbeIntValue(Mem *pMem){ ** value. If it is a string or blob, try to convert it to a double. ** If it is a NULL, return 0.0. */ +static SQLITE_NOINLINE double memRealValue(Mem *pMem){ + /* (double)0 In case of SQLITE_OMIT_FLOATING_POINT... */ + double val = (double)0; + sqlite3AtoF(pMem->z, &val, pMem->n, pMem->enc); + return val; +} double sqlite3VdbeRealValue(Mem *pMem){ assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); assert( EIGHT_BYTE_ALIGNMENT(pMem) ); @@ -489,10 +498,7 @@ double sqlite3VdbeRealValue(Mem *pMem){ }else if( pMem->flags & MEM_Int ){ return (double)pMem->u.i; }else if( pMem->flags & (MEM_Str|MEM_Blob) ){ - /* (double)0 In case of SQLITE_OMIT_FLOATING_POINT... */ - double val = (double)0; - sqlite3AtoF(pMem->z, &val, pMem->n, pMem->enc); - return val; + return memRealValue(pMem); }else{ /* (double)0 In case of SQLITE_OMIT_FLOATING_POINT... */ return (double)0; From 96a7e28df69b205428340259eee546941e7cbec6 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 1 Apr 2017 19:45:20 +0000 Subject: [PATCH 04/28] Remove an unnecessary clearing of the Vdbe.iCurrentTime value. FossilOrigin-Name: fcd2acdd6075aa9a7a66ce254eba77485f7b2804127e109c0309173488cd4b87 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbeaux.c | 1 - 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 216e566be6..2f2efc5396 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Faster\simplementation\sfor\ssqlite3VdbeIntValue()\sand\ssqlite3VdbeRealValue(). -D 2017-04-01T11:59:36.584 +C Remove\san\sunnecessary\sclearing\sof\sthe\sVdbe.iCurrentTime\svalue. +D 2017-04-01T19:45:20.706 F Makefile.in 1cc758ce3374a32425e4d130c2fe7b026b20de5b8843243de75f087c0a2661fb F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc a4c0613a18663bda56d8cf76079ab6590a7c3602e54befb4bbdef76bcaa38b6a @@ -472,7 +472,7 @@ F src/vdbe.c f1acf5744cef62cbfd0b503d84289f840b6cdc980ac47b0d9632dfdb89cc79eb F src/vdbe.h caa5346d52bae2a3c8c1dcfa60a7a4dc878a9e3865cb8239da55808b316c8158 F src/vdbeInt.h 5db089ce18c4feff8820ec6e4cac2d2c82e03d4b1d96f10a6e43832147b8dffe F src/vdbeapi.c 5b08d82592bcff4470601fe78aaabebd50837860 -F src/vdbeaux.c ecd0468611925d218e1eb4b3f538907904b136f0e15e333291a232b521bfcef1 +F src/vdbeaux.c 514eb1749346b1e587fbeb775198ed9385476d5639bc81aef42914e2fe70962d F src/vdbeblob.c 359891617358deefc85bef7bcf787fa6b77facb9 F src/vdbemem.c bbd8f5fdb7f11e02d9a6201f18a52325f1d2361a2850ff03a38f8efa5188f2dc F src/vdbesort.c eda25cb2d1727efca6f7862fea32b8aa33c0face @@ -1569,7 +1569,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 1c0d82e0786ed22d07d774b8b166340fad97bcaab6016e395c469bcfcb7c77a3 -R e7e1f4a4fa7fe0c6a0bd77f428c6873c +P 8698df60c23d4dcc80b58352c14ae80ec238cac496f8a87bd72a96fef61cc63f +R 07505fb3d31361478cf20d311fece580 U drh -Z b92e301c12dc9a925621c9624fd5cc90 +Z 308793a249443429e619af47ce6ccfc8 diff --git a/manifest.uuid b/manifest.uuid index b022468409..a49b480463 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8698df60c23d4dcc80b58352c14ae80ec238cac496f8a87bd72a96fef61cc63f \ No newline at end of file +fcd2acdd6075aa9a7a66ce254eba77485f7b2804127e109c0309173488cd4b87 \ No newline at end of file diff --git a/src/vdbeaux.c b/src/vdbeaux.c index a8f215420a..cd765a1773 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -2930,7 +2930,6 @@ int sqlite3VdbeReset(Vdbe *p){ } } #endif - p->iCurrentTime = 0; p->magic = VDBE_MAGIC_RESET; return p->rc & db->errMask; } From 662c50e067e64618019f7798df027e4f04c49a93 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 1 Apr 2017 20:14:01 +0000 Subject: [PATCH 05/28] Minor performance enhancements to the OP_Affinity opcode. FossilOrigin-Name: c45cd3b947c0f03a688f827fddb4629a986788f0dd98d5ef899f11e68ff1c202 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbe.c | 8 ++++---- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index 2f2efc5396..e8f78f99ed 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\san\sunnecessary\sclearing\sof\sthe\sVdbe.iCurrentTime\svalue. -D 2017-04-01T19:45:20.706 +C Minor\sperformance\senhancements\sto\sthe\sOP_Affinity\sopcode. +D 2017-04-01T20:14:01.312 F Makefile.in 1cc758ce3374a32425e4d130c2fe7b026b20de5b8843243de75f087c0a2661fb F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc a4c0613a18663bda56d8cf76079ab6590a7c3602e54befb4bbdef76bcaa38b6a @@ -468,7 +468,7 @@ F src/update.c 456d4a4656f8a03c2abc88a51b19172197400e58 F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c F src/util.c ca8440ede81e155d15cff7c101654f60b55a9ae6 F src/vacuum.c 1fe4555cd8c9b263afb85b5b4ee3a4a4181ad569 -F src/vdbe.c f1acf5744cef62cbfd0b503d84289f840b6cdc980ac47b0d9632dfdb89cc79eb +F src/vdbe.c 73ddbad81e181cd97db84a654d9f4e0e2a1cffe5ada55d2d415730bb92ba9154 F src/vdbe.h caa5346d52bae2a3c8c1dcfa60a7a4dc878a9e3865cb8239da55808b316c8158 F src/vdbeInt.h 5db089ce18c4feff8820ec6e4cac2d2c82e03d4b1d96f10a6e43832147b8dffe F src/vdbeapi.c 5b08d82592bcff4470601fe78aaabebd50837860 @@ -1569,7 +1569,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 8698df60c23d4dcc80b58352c14ae80ec238cac496f8a87bd72a96fef61cc63f -R 07505fb3d31361478cf20d311fece580 +P fcd2acdd6075aa9a7a66ce254eba77485f7b2804127e109c0309173488cd4b87 +R b2865bd21e6736872cabd9a653d63ed6 U drh -Z 308793a249443429e619af47ce6ccfc8 +Z b3718432a24e2278ab854298acb77351 diff --git a/manifest.uuid b/manifest.uuid index a49b480463..7d8d3f0fe3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -fcd2acdd6075aa9a7a66ce254eba77485f7b2804127e109c0309173488cd4b87 \ No newline at end of file +c45cd3b947c0f03a688f827fddb4629a986788f0dd98d5ef899f11e68ff1c202 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index 406394c5be..feccb424ec 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -2710,18 +2710,18 @@ op_column_out: */ case OP_Affinity: { const char *zAffinity; /* The affinity to be applied */ - char cAff; /* A single character of affinity */ zAffinity = pOp->p4.z; assert( zAffinity!=0 ); + assert( pOp->p2>0 ); assert( zAffinity[pOp->p2]==0 ); pIn1 = &aMem[pOp->p1]; - while( (cAff = *(zAffinity++))!=0 ){ + do{ assert( pIn1 <= &p->aMem[(p->nMem+1 - p->nCursor)] ); assert( memIsValid(pIn1) ); - applyAffinity(pIn1, cAff, encoding); + applyAffinity(pIn1, *(zAffinity++), encoding); pIn1++; - } + }while( zAffinity[0] ); break; } From 8e633b3ba9d0efbb3637312420ee4ffdd3e44e08 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 1 Apr 2017 20:44:26 +0000 Subject: [PATCH 06/28] Remove an unnecessary setting of the Mem.enc field for the output of the OP_Record opcode, for a performance improvement and size reduction. FossilOrigin-Name: e6e36b288fdf21b7ff7f0bf85d2225b6505f54367b183c302c93c34a4a40b8b5 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbe.c | 1 - 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index e8f78f99ed..78dd3266f7 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Minor\sperformance\senhancements\sto\sthe\sOP_Affinity\sopcode. -D 2017-04-01T20:14:01.312 +C Remove\san\sunnecessary\ssetting\sof\sthe\sMem.enc\sfield\sfor\sthe\soutput\sof\sthe\nOP_Record\sopcode,\sfor\sa\sperformance\simprovement\sand\ssize\sreduction. +D 2017-04-01T20:44:26.383 F Makefile.in 1cc758ce3374a32425e4d130c2fe7b026b20de5b8843243de75f087c0a2661fb F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc a4c0613a18663bda56d8cf76079ab6590a7c3602e54befb4bbdef76bcaa38b6a @@ -468,7 +468,7 @@ F src/update.c 456d4a4656f8a03c2abc88a51b19172197400e58 F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c F src/util.c ca8440ede81e155d15cff7c101654f60b55a9ae6 F src/vacuum.c 1fe4555cd8c9b263afb85b5b4ee3a4a4181ad569 -F src/vdbe.c 73ddbad81e181cd97db84a654d9f4e0e2a1cffe5ada55d2d415730bb92ba9154 +F src/vdbe.c d275c79e5e23f5208da106bd8e04206dff373a9797f07ab01d64af139a0301fd F src/vdbe.h caa5346d52bae2a3c8c1dcfa60a7a4dc878a9e3865cb8239da55808b316c8158 F src/vdbeInt.h 5db089ce18c4feff8820ec6e4cac2d2c82e03d4b1d96f10a6e43832147b8dffe F src/vdbeapi.c 5b08d82592bcff4470601fe78aaabebd50837860 @@ -1569,7 +1569,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P fcd2acdd6075aa9a7a66ce254eba77485f7b2804127e109c0309173488cd4b87 -R b2865bd21e6736872cabd9a653d63ed6 +P c45cd3b947c0f03a688f827fddb4629a986788f0dd98d5ef899f11e68ff1c202 +R 9110f45f53ee5a3c301af47a0be3a540 U drh -Z b3718432a24e2278ab854298acb77351 +Z db07b81eed986b15417f2526357a7c90 diff --git a/manifest.uuid b/manifest.uuid index 7d8d3f0fe3..af50b4417d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c45cd3b947c0f03a688f827fddb4629a986788f0dd98d5ef899f11e68ff1c202 \ No newline at end of file +e6e36b288fdf21b7ff7f0bf85d2225b6505f54367b183c302c93c34a4a40b8b5 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index feccb424ec..7056d20aaa 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -2892,7 +2892,6 @@ case OP_MakeRecord: { pOut->u.nZero = nZero; pOut->flags |= MEM_Zero; } - pOut->enc = SQLITE_UTF8; /* In case the blob is ever converted to text */ REGISTER_TRACE(pOp->p3, pOut); UPDATE_MAX_BLOBSIZE(pOut); break; From caab5f42dbc4f37bcac76057068bd5b2532edf62 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 3 Apr 2017 12:04:39 +0000 Subject: [PATCH 07/28] Slightly smaller and faster implementation for vdbeSorterCompareInt(). FossilOrigin-Name: 84fa069c5bdfe41d03d03875c9157cc6785150b677c04e40b8916ba5af073dc8 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbesort.c | 53 +++++++++++++++++++++++++------------------------- 3 files changed, 33 insertions(+), 34 deletions(-) diff --git a/manifest b/manifest index 78dd3266f7..aa94d46525 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\san\sunnecessary\ssetting\sof\sthe\sMem.enc\sfield\sfor\sthe\soutput\sof\sthe\nOP_Record\sopcode,\sfor\sa\sperformance\simprovement\sand\ssize\sreduction. -D 2017-04-01T20:44:26.383 +C Slightly\ssmaller\sand\sfaster\simplementation\sfor\svdbeSorterCompareInt(). +D 2017-04-03T12:04:39.935 F Makefile.in 1cc758ce3374a32425e4d130c2fe7b026b20de5b8843243de75f087c0a2661fb F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc a4c0613a18663bda56d8cf76079ab6590a7c3602e54befb4bbdef76bcaa38b6a @@ -475,7 +475,7 @@ F src/vdbeapi.c 5b08d82592bcff4470601fe78aaabebd50837860 F src/vdbeaux.c 514eb1749346b1e587fbeb775198ed9385476d5639bc81aef42914e2fe70962d F src/vdbeblob.c 359891617358deefc85bef7bcf787fa6b77facb9 F src/vdbemem.c bbd8f5fdb7f11e02d9a6201f18a52325f1d2361a2850ff03a38f8efa5188f2dc -F src/vdbesort.c eda25cb2d1727efca6f7862fea32b8aa33c0face +F src/vdbesort.c e72fe02a2121386ba767ede8942e9450878b8fc873abf3d1b6824485f092570c F src/vdbetrace.c 41963d5376f0349842b5fc4aaaaacd7d9cdc0834 F src/vtab.c 007513c2ef52472fcdea6a741683d50662e82790 F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 @@ -1569,7 +1569,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P c45cd3b947c0f03a688f827fddb4629a986788f0dd98d5ef899f11e68ff1c202 -R 9110f45f53ee5a3c301af47a0be3a540 +P e6e36b288fdf21b7ff7f0bf85d2225b6505f54367b183c302c93c34a4a40b8b5 +R d96ebce90865dec08afc476da7f545eb U drh -Z db07b81eed986b15417f2526357a7c90 +Z ac1b2d769355137cbadf1703484266cb diff --git a/manifest.uuid b/manifest.uuid index af50b4417d..35356ca02e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e6e36b288fdf21b7ff7f0bf85d2225b6505f54367b183c302c93c34a4a40b8b5 \ No newline at end of file +84fa069c5bdfe41d03d03875c9157cc6785150b677c04e40b8916ba5af073dc8 \ No newline at end of file diff --git a/src/vdbesort.c b/src/vdbesort.c index 631fb19616..7dbb1b063f 100644 --- a/src/vdbesort.c +++ b/src/vdbesort.c @@ -858,37 +858,36 @@ static int vdbeSorterCompareInt( assert( (s1>0 && s1<7) || s1==8 || s1==9 ); assert( (s2>0 && s2<7) || s2==8 || s2==9 ); - if( s1>7 && s2>7 ){ + if( s1==s2 ){ + /* The two values have the same sign. Compare using memcmp(). */ + static const u8 aLen[] = {0, 1, 2, 3, 4, 6, 8, 0, 0, 0 }; + const u8 n = aLen[s1]; + int i; + res = 0; + for(i=0; i7 && s2>7 ){ res = s1 - s2; }else{ - if( s1==s2 ){ - if( (*v1 ^ *v2) & 0x80 ){ - /* The two values have different signs */ - res = (*v1 & 0x80) ? -1 : +1; - }else{ - /* The two values have the same sign. Compare using memcmp(). */ - static const u8 aLen[] = {0, 1, 2, 3, 4, 6, 8 }; - int i; - res = 0; - for(i=0; i7 ){ + res = +1; + }else if( s1>7 ){ + res = -1; }else{ - if( s2>7 ){ - res = +1; - }else if( s1>7 ){ - res = -1; - }else{ - res = s1 - s2; - } - assert( res!=0 ); + res = s1 - s2; + } + assert( res!=0 ); - if( res>0 ){ - if( *v1 & 0x80 ) res = -1; - }else{ - if( *v2 & 0x80 ) res = +1; - } + if( res>0 ){ + if( *v1 & 0x80 ) res = -1; + }else{ + if( *v2 & 0x80 ) res = +1; } } From 1cc3a36d90488d00c723d780c9f9c0766555532d Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 3 Apr 2017 13:17:31 +0000 Subject: [PATCH 08/28] Fix typos in the documentation for OP_Column. FossilOrigin-Name: 777b43e64ffb2fb80ba7b705c129c133bf9787993a66cde1759dc070b324b4b4 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbe.c | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index aa94d46525..e817e1e57f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Slightly\ssmaller\sand\sfaster\simplementation\sfor\svdbeSorterCompareInt(). -D 2017-04-03T12:04:39.935 +C Fix\stypos\sin\sthe\sdocumentation\sfor\sOP_Column. +D 2017-04-03T13:17:31.089 F Makefile.in 1cc758ce3374a32425e4d130c2fe7b026b20de5b8843243de75f087c0a2661fb F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc a4c0613a18663bda56d8cf76079ab6590a7c3602e54befb4bbdef76bcaa38b6a @@ -468,7 +468,7 @@ F src/update.c 456d4a4656f8a03c2abc88a51b19172197400e58 F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c F src/util.c ca8440ede81e155d15cff7c101654f60b55a9ae6 F src/vacuum.c 1fe4555cd8c9b263afb85b5b4ee3a4a4181ad569 -F src/vdbe.c d275c79e5e23f5208da106bd8e04206dff373a9797f07ab01d64af139a0301fd +F src/vdbe.c 1be564c66097e8982229bbc4d3de3042427dfdff0e5e7b7287bf7531faf474bf F src/vdbe.h caa5346d52bae2a3c8c1dcfa60a7a4dc878a9e3865cb8239da55808b316c8158 F src/vdbeInt.h 5db089ce18c4feff8820ec6e4cac2d2c82e03d4b1d96f10a6e43832147b8dffe F src/vdbeapi.c 5b08d82592bcff4470601fe78aaabebd50837860 @@ -1569,7 +1569,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P e6e36b288fdf21b7ff7f0bf85d2225b6505f54367b183c302c93c34a4a40b8b5 -R d96ebce90865dec08afc476da7f545eb +P 84fa069c5bdfe41d03d03875c9157cc6785150b677c04e40b8916ba5af073dc8 +R 712574d4524a4e566586181081140bf0 U drh -Z ac1b2d769355137cbadf1703484266cb +Z 0dbc639fc4406be2788a574780c7997d diff --git a/manifest.uuid b/manifest.uuid index 35356ca02e..7e8c18ad23 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -84fa069c5bdfe41d03d03875c9157cc6785150b677c04e40b8916ba5af073dc8 \ No newline at end of file +777b43e64ffb2fb80ba7b705c129c133bf9787993a66cde1759dc070b324b4b4 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index 7056d20aaa..fd4705abcd 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -2440,7 +2440,7 @@ case OP_NotNull: { /* same as TK_NOTNULL, jump, in1 */ ** ** The value extracted is stored in register P3. ** -** If the column contains fewer than P2 fields, then extract a NULL. Or, +** If the record contains fewer than P2 fields, then extract a NULL. Or, ** if the P4 argument is a P4_MEM use the value of the P4 argument as ** the result. ** @@ -2449,7 +2449,7 @@ case OP_NotNull: { /* same as TK_NOTNULL, jump, in1 */ ** The first OP_Column against a pseudo-table after the value of the content ** register has changed should have this bit set. ** -** If the OPFLAG_LENGTHARG and OPFLAG_TYPEOFARG bits are set on P5 when +** If the OPFLAG_LENGTHARG and OPFLAG_TYPEOFARG bits are set on P5 then ** the result is guaranteed to only be used as the argument of a length() ** or typeof() function, respectively. The loading of large blobs can be ** skipped for length() and all content loading can be skipped for typeof(). From 761f691d0ecf5dba25698aefc1012531bc368bc2 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 3 Apr 2017 13:33:51 +0000 Subject: [PATCH 09/28] Force a schema load prior to "PRAGMA optimize". FossilOrigin-Name: 86897c24c0b35ffea8df72d86a099addf67de210c6568aaba22ef92f1a60c3cf --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/pragma.h | 2 +- tool/mkpragmatab.tcl | 2 +- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index e817e1e57f..0fff1f86cd 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\stypos\sin\sthe\sdocumentation\sfor\sOP_Column. -D 2017-04-03T13:17:31.089 +C Force\sa\sschema\sload\sprior\sto\s"PRAGMA\soptimize". +D 2017-04-03T13:33:51.502 F Makefile.in 1cc758ce3374a32425e4d130c2fe7b026b20de5b8843243de75f087c0a2661fb F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc a4c0613a18663bda56d8cf76079ab6590a7c3602e54befb4bbdef76bcaa38b6a @@ -395,7 +395,7 @@ F src/pcache.c 62835bed959e2914edd26afadfecce29ece0e870 F src/pcache.h 2cedcd8407eb23017d92790b112186886e179490 F src/pcache1.c 1195a21fe28e223e024f900b2011e80df53793f0356a24caace4188b098540dc F src/pragma.c 2b244434e76c7075edbcfd9e4d634899af0944ff01183b126d4671f7407c2368 -F src/pragma.h c9c763958fec92b04125571472c9500b351c5f7f +F src/pragma.h 37a1311d0388db480388d7ec09054f7103045eff20d4971f8a433b77f40b9921 F src/prepare.c b1140c3d0cf59bc85ace00ce363153041b424b7a F src/printf.c 8757834f1b54dae512fb25eb1acc8e94a0d15dd2290b58f2563f65973265adb2 F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 @@ -1507,7 +1507,7 @@ F tool/mkmsvcmin.tcl 95b37e202cbed873aa8ffdbb493b9db45927be2b F tool/mkopcodec.tcl d1b6362bd3aa80d5520d4d6f3765badf01f6c43c F tool/mkopcodeh.tcl a01d2c1d8a6205b03fc635adf3735b4c523befd3 F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e -F tool/mkpragmatab.tcl 2ffe6d5fdc2d3381621d6c77978ba054466e757f +F tool/mkpragmatab.tcl 32bb40741df11bddc8451de9ea4d130e7b4476d8064794b1cf402ac110840fba F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97 F tool/mksqlite3c-noext.tcl fef88397668ae83166735c41af99d79f56afaabb F tool/mksqlite3c.tcl 06b2e6a0f21cc0a5d70fbbd136b3e0a96470645e @@ -1569,7 +1569,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 84fa069c5bdfe41d03d03875c9157cc6785150b677c04e40b8916ba5af073dc8 -R 712574d4524a4e566586181081140bf0 +P 777b43e64ffb2fb80ba7b705c129c133bf9787993a66cde1759dc070b324b4b4 +R 9a743d9771b82de1d9bbf28369abee2c U drh -Z 0dbc639fc4406be2788a574780c7997d +Z 64ccfe96d48e9643ce5426be1683d306 diff --git a/manifest.uuid b/manifest.uuid index 7e8c18ad23..37505706dc 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -777b43e64ffb2fb80ba7b705c129c133bf9787993a66cde1759dc070b324b4b4 \ No newline at end of file +86897c24c0b35ffea8df72d86a099addf67de210c6568aaba22ef92f1a60c3cf \ No newline at end of file diff --git a/src/pragma.h b/src/pragma.h index 9b1c723b3e..d05657c799 100644 --- a/src/pragma.h +++ b/src/pragma.h @@ -417,7 +417,7 @@ static const PragmaName aPragmaName[] = { #endif {/* zName: */ "optimize", /* ePragTyp: */ PragTyp_OPTIMIZE, - /* ePragFlg: */ PragFlg_Result1, + /* ePragFlg: */ PragFlg_Result1|PragFlg_NeedSchema, /* ColNames: */ 0, 0, /* iArg: */ 0 }, #if !defined(SQLITE_OMIT_PAGER_PRAGMAS) diff --git a/tool/mkpragmatab.tcl b/tool/mkpragmatab.tcl index 59b245cc76..080e3da003 100644 --- a/tool/mkpragmatab.tcl +++ b/tool/mkpragmatab.tcl @@ -363,7 +363,7 @@ set pragma_def { FLAG: Result0 NAME: optimize - FLAG: Result1 + FLAG: Result1 NeedSchema } # Open the output file From cfb3235752fba0c4526f8b8cd70a986995a5f00d Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 3 Apr 2017 13:59:22 +0000 Subject: [PATCH 10/28] Do not attempt to run sync2.test with SQLITE_DISABLE_DIRSYNC builds. FossilOrigin-Name: 658f08ce84b45f057843263961f6c47a322f841764134ec38f35719f0f2042d7 --- manifest | 14 +++++++------- manifest.uuid | 2 +- test/sync2.test | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 0fff1f86cd..2ed7a46f83 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Force\sa\sschema\sload\sprior\sto\s"PRAGMA\soptimize". -D 2017-04-03T13:33:51.502 +C Do\snot\sattempt\sto\srun\ssync2.test\swith\sSQLITE_DISABLE_DIRSYNC\sbuilds. +D 2017-04-03T13:59:22.968 F Makefile.in 1cc758ce3374a32425e4d130c2fe7b026b20de5b8843243de75f087c0a2661fb F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc a4c0613a18663bda56d8cf76079ab6590a7c3602e54befb4bbdef76bcaa38b6a @@ -1167,7 +1167,7 @@ F test/subtype1.test 7fe09496352f97053af1437150751be2d0a0cae8 F test/superlock.test ec94f0556b6488d97f71c79f9061ae08d9ab8f12 F test/symlink.test c9ebe7330d228249e447038276bfc8a7b22f4849 F test/sync.test 2f84bdbc2b2df1fcb0220575b4b9f8cea94b7529 -F test/sync2.test 29af00fe9e468a1e20315d1edced8f8a32ac156df983ae9b53802e7d472675d5 +F test/sync2.test 6be8ed007fa063b147773c1982b5bdba97a32badc536bdc6077eff5cf8710ece F test/syscall.test f59ba4e25f7ba4a4c031026cc2ef8b6e4b4c639c F test/sysfault.test c9f2b0d8d677558f74de750c75e12a5454719d04 F test/tabfunc01.test 699251cb99651415218a891384510a685c7ab012 @@ -1569,7 +1569,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 777b43e64ffb2fb80ba7b705c129c133bf9787993a66cde1759dc070b324b4b4 -R 9a743d9771b82de1d9bbf28369abee2c -U drh -Z 64ccfe96d48e9643ce5426be1683d306 +P 86897c24c0b35ffea8df72d86a099addf67de210c6568aaba22ef92f1a60c3cf +R ec6f0280f0b5bac989fcec1c5dd2103a +U dan +Z d34161eab469d9f5620a10a3616b7e4e diff --git a/manifest.uuid b/manifest.uuid index 37505706dc..62b9cbadab 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -86897c24c0b35ffea8df72d86a099addf67de210c6568aaba22ef92f1a60c3cf \ No newline at end of file +658f08ce84b45f057843263961f6c47a322f841764134ec38f35719f0f2042d7 \ No newline at end of file diff --git a/test/sync2.test b/test/sync2.test index 4f6ed7754c..46e8bc72fb 100644 --- a/test/sync2.test +++ b/test/sync2.test @@ -22,7 +22,7 @@ set testprefix sync2 # enabled. Also, since every test uses an ATTACHed database, they # are only run when ATTACH is enabled. # -ifcapable !pager_pragmas||!attach { +ifcapable !pager_pragmas||!attach||!dirsync { finish_test return } From 628dfe163f6a77c757759253c2714562079df16e Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 3 Apr 2017 14:07:08 +0000 Subject: [PATCH 11/28] Avoid an unnecessary call to sqlite3WhereGetMask() inside of whereShortCut(). FossilOrigin-Name: 5c11f4303f6a33d6358f451244551be63baf9afe5630332e60b349215e20a3af --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/where.c | 3 ++- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 2ed7a46f83..9045344b56 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Do\snot\sattempt\sto\srun\ssync2.test\swith\sSQLITE_DISABLE_DIRSYNC\sbuilds. -D 2017-04-03T13:59:22.968 +C Avoid\san\sunnecessary\scall\sto\ssqlite3WhereGetMask()\sinside\sof\swhereShortCut(). +D 2017-04-03T14:07:08.340 F Makefile.in 1cc758ce3374a32425e4d130c2fe7b026b20de5b8843243de75f087c0a2661fb F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc a4c0613a18663bda56d8cf76079ab6590a7c3602e54befb4bbdef76bcaa38b6a @@ -482,7 +482,7 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 40c543f0a2195d1b0dc88ef12142bea690009344 F src/wal.h 06b2a0b599cc0f53ea97f497cf8c6b758c999f71 F src/walker.c b71a992b413b3a022572eccf29ef4b4890223791 -F src/where.c e815093e5ee039b6b4eb19b646d22deb1a3a523f +F src/where.c aed99e51153930ce30a6b25968fa61fabdc0160f6198e01ed3d108e9dbb49a15 F src/whereInt.h 2d50c2b74a33be44cb68fdecee30b4d93552f1f4 F src/wherecode.c 677e95413c472c0b413023b6b69a47f40fce1b04 F src/whereexpr.c 130cdd1a43af71b19755270fb1224874cf55158c @@ -1569,7 +1569,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 86897c24c0b35ffea8df72d86a099addf67de210c6568aaba22ef92f1a60c3cf -R ec6f0280f0b5bac989fcec1c5dd2103a -U dan -Z d34161eab469d9f5620a10a3616b7e4e +P 658f08ce84b45f057843263961f6c47a322f841764134ec38f35719f0f2042d7 +R e39c693ad3e0951889c32471c5e8f7c7 +U drh +Z c6c3b56859c36a08dcbd07df15c30b8c diff --git a/manifest.uuid b/manifest.uuid index 62b9cbadab..da4717fdfe 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -658f08ce84b45f057843263961f6c47a322f841764134ec38f35719f0f2042d7 \ No newline at end of file +5c11f4303f6a33d6358f451244551be63baf9afe5630332e60b349215e20a3af \ No newline at end of file diff --git a/src/where.c b/src/where.c index 4f65695a3f..d9c8b55d01 100644 --- a/src/where.c +++ b/src/where.c @@ -4262,7 +4262,8 @@ static int whereShortCut(WhereLoopBuilder *pBuilder){ if( pLoop->wsFlags ){ pLoop->nOut = (LogEst)1; pWInfo->a[0].pWLoop = pLoop; - pLoop->maskSelf = sqlite3WhereGetMask(&pWInfo->sMaskSet, iCur); + assert( pWInfo->sMaskSet.n==1 && iCur==pWInfo->sMaskSet.ix[0] ); + pLoop->maskSelf = 1; /* sqlite3WhereGetMask(&pWInfo->sMaskSet, iCur); */ pWInfo->a[0].iTabCur = iCur; pWInfo->nRowOut = 1; if( pWInfo->pOrderBy ) pWInfo->nOBSat = pWInfo->pOrderBy->nExpr; From 75f9558808e3c0e10b696f16ea368dc64a13cdec Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 4 Apr 2017 19:58:54 +0000 Subject: [PATCH 12/28] Fix a problem causing "PRAGMA integrity_check" to disable the xfer optimization for subsequent VACUUM operations on tables with one or more CHECK constraints. This could result in VACUUM producing slightly larger database files. FossilOrigin-Name: e5bb7db51cdfd8124c60329782798cea398733545594dab55cb892b2a08c4d29 --- manifest | 17 +++++++++-------- manifest.uuid | 2 +- src/pragma.c | 39 +++++++++++++++++++++------------------ test/insert4.test | 33 +++++++++++++++++++++++++++++++++ test/pragmafault.test | 39 +++++++++++++++++++++++++++++++++++++++ 5 files changed, 103 insertions(+), 27 deletions(-) create mode 100644 test/pragmafault.test diff --git a/manifest b/manifest index 9045344b56..ddb970509e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Avoid\san\sunnecessary\scall\sto\ssqlite3WhereGetMask()\sinside\sof\swhereShortCut(). -D 2017-04-03T14:07:08.340 +C Fix\sa\sproblem\scausing\s"PRAGMA\sintegrity_check"\sto\sdisable\sthe\sxfer\noptimization\sfor\ssubsequent\sVACUUM\soperations\son\stables\swith\sone\sor\smore\sCHECK\nconstraints.\sThis\scould\sresult\sin\sVACUUM\sproducing\sslightly\slarger\sdatabase\nfiles. +D 2017-04-04T19:58:54.565 F Makefile.in 1cc758ce3374a32425e4d130c2fe7b026b20de5b8843243de75f087c0a2661fb F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc a4c0613a18663bda56d8cf76079ab6590a7c3602e54befb4bbdef76bcaa38b6a @@ -394,7 +394,7 @@ F src/parse.y 48b03113704ee8bd78ee6996d81de7fbee22e105 F src/pcache.c 62835bed959e2914edd26afadfecce29ece0e870 F src/pcache.h 2cedcd8407eb23017d92790b112186886e179490 F src/pcache1.c 1195a21fe28e223e024f900b2011e80df53793f0356a24caace4188b098540dc -F src/pragma.c 2b244434e76c7075edbcfd9e4d634899af0944ff01183b126d4671f7407c2368 +F src/pragma.c 220474f113cade6a6b5bacd3e3a65eca339acbee804128bc5db13a9cad55fba5 F src/pragma.h 37a1311d0388db480388d7ec09054f7103045eff20d4971f8a433b77f40b9921 F src/prepare.c b1140c3d0cf59bc85ace00ce363153041b424b7a F src/printf.c 8757834f1b54dae512fb25eb1acc8e94a0d15dd2290b58f2563f65973265adb2 @@ -883,7 +883,7 @@ F test/init.test 15c823093fdabbf7b531fe22cf037134d09587a7 F test/insert.test 38742b5e9601c8f8d76e9b7555f7270288c2d371 F test/insert2.test 4d14b8f1b810a41995f6286b64a6943215d52208 F test/insert3.test 1b7db95a03ad9c5013fdf7d6722b6cd66ee55e30 -F test/insert4.test a20432f1c0fbbcff8f11d0e6ab4acb8c9db58023 +F test/insert4.test 46bead5f39e181850ee56adcf49d3a3157c460c52249211714612ac89fe34835 F test/insert5.test 394f96728d1258f406fe5f5aeb0aaf29487c39a6 F test/instr.test 9a8802f28437d8ade53fedfc47b2ca599b4e48ba F test/instrfault.test 0f870b218ea17cd477bb19ed330eecdb460dd53a @@ -1032,6 +1032,7 @@ F test/pragma.test 1e94755164a3a3264cd39836de4bebcb7809e5f8 F test/pragma2.test e5d5c176360c321344249354c0c16aec46214c9f F test/pragma3.test 14c12bc5352b1e100e0b6b44f371053a81ccf8ed F test/pragma4.test 6e85b6eab8e61ffc9c7db59d842276674e8e3264 +F test/pragmafault.test 275edaf3161771d37de60e5c2b412627ac94cef11739236bec12ed1258b240f8 F test/printf.test b3ff34e73d59124140eaf89f7672e21bc2ca5fcc F test/printf2.test 9e6db85f81c63f2367c34a9d7db384088bd374ad F test/progress.test ebab27f670bd0d4eb9d20d49cef96e68141d92fb @@ -1569,7 +1570,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 658f08ce84b45f057843263961f6c47a322f841764134ec38f35719f0f2042d7 -R e39c693ad3e0951889c32471c5e8f7c7 -U drh -Z c6c3b56859c36a08dcbd07df15c30b8c +P 5c11f4303f6a33d6358f451244551be63baf9afe5630332e60b349215e20a3af +R 160204ba2e30552a39ad215784116585 +U dan +Z c1b366616d6f296d38ff56ec0865eee0 diff --git a/manifest.uuid b/manifest.uuid index da4717fdfe..49b3a8a4f7 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5c11f4303f6a33d6358f451244551be63baf9afe5630332e60b349215e20a3af \ No newline at end of file +e5bb7db51cdfd8124c60329782798cea398733545594dab55cb892b2a08c4d29 \ No newline at end of file diff --git a/src/pragma.c b/src/pragma.c index 6c27fdc5c9..7f0b683f13 100644 --- a/src/pragma.c +++ b/src/pragma.c @@ -1541,25 +1541,28 @@ void sqlite3Pragma( } /* Verify CHECK constraints */ if( pTab->pCheck && (db->flags & SQLITE_IgnoreChecks)==0 ){ - int addrCkFault = sqlite3VdbeMakeLabel(v); - int addrCkOk = sqlite3VdbeMakeLabel(v); - ExprList *pCheck = pTab->pCheck; - char *zErr; - int k; - pParse->iSelfTab = iDataCur; - sqlite3ExprCachePush(pParse); - for(k=pCheck->nExpr-1; k>0; k--){ - sqlite3ExprIfFalse(pParse, pCheck->a[k].pExpr, addrCkFault, 0); + ExprList *pCheck = sqlite3ExprListDup(db, pTab->pCheck, 0); + if( db->mallocFailed==0 ){ + int addrCkFault = sqlite3VdbeMakeLabel(v); + int addrCkOk = sqlite3VdbeMakeLabel(v); + char *zErr; + int k; + pParse->iSelfTab = iDataCur; + sqlite3ExprCachePush(pParse); + for(k=pCheck->nExpr-1; k>0; k--){ + sqlite3ExprIfFalse(pParse, pCheck->a[k].pExpr, addrCkFault, 0); + } + sqlite3ExprIfTrue(pParse, pCheck->a[0].pExpr, addrCkOk, + SQLITE_JUMPIFNULL); + sqlite3VdbeResolveLabel(v, addrCkFault); + zErr = sqlite3MPrintf(db, "CHECK constraint failed in %s", + pTab->zName); + sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, zErr, P4_DYNAMIC); + integrityCheckResultRow(v, 3); + sqlite3VdbeResolveLabel(v, addrCkOk); + sqlite3ExprCachePop(pParse); } - sqlite3ExprIfTrue(pParse, pCheck->a[0].pExpr, addrCkOk, - SQLITE_JUMPIFNULL); - sqlite3VdbeResolveLabel(v, addrCkFault); - zErr = sqlite3MPrintf(db, "CHECK constraint failed in %s", - pTab->zName); - sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, zErr, P4_DYNAMIC); - integrityCheckResultRow(v, 3); - sqlite3VdbeResolveLabel(v, addrCkOk); - sqlite3ExprCachePop(pParse); + sqlite3ExprListDelete(db, pCheck); } /* Validate index entries for the current row */ for(j=0, pIdx=pTab->pIndex; pIdx && !isQuick; pIdx=pIdx->pNext, j++){ diff --git a/test/insert4.test b/test/insert4.test index 3eece87e5f..85cbf82a56 100644 --- a/test/insert4.test +++ b/test/insert4.test @@ -15,6 +15,7 @@ set testdir [file dirname $argv0] source $testdir/tester.tcl +set testprefix insert4 ifcapable !view||!subquery { finish_test @@ -566,4 +567,36 @@ do_catchsql_test insert4-9.1 { INSERT INTO t1(x) VALUES(5 COLLATE xyzzy) UNION SELECT 0; } {1 {no such collation sequence: xyzzy}} +#------------------------------------------------------------------------- +# Check that running an integrity-check does not disable the xfer +# optimization for tables with CHECK constraints. +# +do_execsql_test 10.1 { + CREATE TABLE t8( + rid INTEGER, + pid INTEGER, + mid INTEGER, + px INTEGER DEFAULT(0) CHECK(px IN(0, 1)) + ); + CREATE TEMP TABLE x( + rid INTEGER, + pid INTEGER, + mid INTEGER, + px INTEGER DEFAULT(0) CHECK(px IN(0, 1)) + ); +} +do_test 10.2 { + set sqlite3_xferopt_count 0 + execsql { INSERT INTO x SELECT * FROM t8 } + set sqlite3_xferopt_count +} {1} + +do_test 10.3 { + execsql { PRAGMA integrity_check } + set sqlite3_xferopt_count 0 + execsql { INSERT INTO x SELECT * FROM t8 } + set sqlite3_xferopt_count +} {1} + + finish_test diff --git a/test/pragmafault.test b/test/pragmafault.test new file mode 100644 index 0000000000..34718aeca1 --- /dev/null +++ b/test/pragmafault.test @@ -0,0 +1,39 @@ +# 2010 June 15 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +source $testdir/lock_common.tcl +source $testdir/malloc_common.tcl +set testprefix pragmafault + +db close +sqlite3 db test.db +sqlite3_db_config_lookaside db 0 0 0 +do_execsql_test 1.0 { + CREATE TABLE t1(a, b, CHECK(a!=b)); + INSERT INTO t1 VALUES(1, 2); + INSERT INTO t1 VALUES(3, 4); +} +faultsim_save_and_close + +do_faultsim_test 1 -prep { + faultsim_restore_and_reopen +} -body { + catchsql { PRAGMA integrity_check } + set {} 0 +} -test { + faultsim_test_result {0 0} +} + + +finish_test From 32d0eba4c2250059f0dcef0612f0a6b3ab5679f6 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 5 Apr 2017 10:54:14 +0000 Subject: [PATCH 13/28] Attempt to remove bash-isms from configure.ac. Use -O0 with --enable-debug. FossilOrigin-Name: 71ed35ccf7c0f6c49118a44cf6621f46b9ea883e4a74d51b8b1ade6d9a95413a --- configure | 20 ++++++++++---------- configure.ac | 20 ++++++++++---------- manifest | 16 ++++++++-------- manifest.uuid | 2 +- 4 files changed, 29 insertions(+), 29 deletions(-) diff --git a/configure b/configure index 84422d3343..8805614438 100755 --- a/configure +++ b/configure @@ -11252,7 +11252,7 @@ else fi if test "${use_debug}" = "yes" ; then - TARGET_DEBUG="-DSQLITE_DEBUG=1 -DSQLITE_ENABLE_SELECTTRACE -DSQLITE_ENABLE_WHERETRACE" + TARGET_DEBUG="-DSQLITE_DEBUG=1 -DSQLITE_ENABLE_SELECTTRACE -DSQLITE_ENABLE_WHERETRACE -O0" else TARGET_DEBUG="-DNDEBUG" fi @@ -11356,7 +11356,7 @@ fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to support MEMSYS5" >&5 $as_echo_n "checking whether to support MEMSYS5... " >&6; } if test "${enable_memsys5}" = "yes"; then - OPT_FEATURE_FLAGS+=" -DSQLITE_ENABLE_MEMSYS5" + OPT_FEATURE_FLAGS="$(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_MEMSYS5" { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else @@ -11373,7 +11373,7 @@ fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to support MEMSYS3" >&5 $as_echo_n "checking whether to support MEMSYS3... " >&6; } if test "${enable_memsys3}" = "yes" -a "${enable_memsys5}" = "no"; then - OPT_FEATURE_FLAGS+=" -DSQLITE_ENABLE_MEMSYS3" + OPT_FEATURE_FLAGS="$(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_MEMSYS3" { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else @@ -11391,7 +11391,7 @@ else fi if test "${enable_fts3}" = "yes" ; then - OPT_FEATURE_FLAGS+=" -DSQLITE_ENABLE_FTS3" + OPT_FEATURE_FLAGS="$(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_FTS3" fi # Check whether --enable-fts4 was given. if test "${enable_fts4+set}" = set; then : @@ -11401,7 +11401,7 @@ else fi if test "${enable_fts4}" = "yes" ; then - OPT_FEATURE_FLAGS+=" -DSQLITE_ENABLE_FTS4" + OPT_FEATURE_FLAGS="$(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_FTS4" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing log" >&5 $as_echo_n "checking for library containing log... " >&6; } if ${ac_cv_search_log+:} false; then : @@ -11467,7 +11467,7 @@ else fi if test "${enable_fts5}" = "yes" ; then - OPT_FEATURE_FLAGS+=" -DSQLITE_ENABLE_FTS5" + OPT_FEATURE_FLAGS="$(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_FTS5" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing log" >&5 $as_echo_n "checking for library containing log... " >&6; } if ${ac_cv_search_log+:} false; then : @@ -11536,7 +11536,7 @@ else fi if test "${enable_json1}" = "yes" ; then - OPT_FEATURE_FLAGS+=" -DSQLITE_ENABLE_JSON1" + OPT_FEATURE_FLAGS="$(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_JSON1" fi ######### @@ -11549,7 +11549,7 @@ else fi if test "${enable_rtree}" = "yes" ; then - OPT_FEATURE_FLAGS+=" -DSQLITE_ENABLE_RTREE" + OPT_FEATURE_FLAGS="$(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_RTREE" fi ######### @@ -11562,8 +11562,8 @@ else fi if test "${enable_session}" = "yes" ; then - OPT_FEATURE_FLAGS+=" -DSQLITE_ENABLE_SESSION" - OPT_FEATURE_FLAGS+=" -DSQLITE_ENABLE_PREUPDATE_HOOK" + OPT_FEATURE_FLAGS="$(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_SESSION" + OPT_FEATURE_FLAGS="$(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_PREUPDATE_HOOK" fi ######### diff --git a/configure.ac b/configure.ac index 095db6bf81..a0aeb94f72 100644 --- a/configure.ac +++ b/configure.ac @@ -560,7 +560,7 @@ AC_SEARCH_LIBS(fdatasync, [rt]) AC_ARG_ENABLE(debug, AC_HELP_STRING([--enable-debug],[enable debugging & verbose explain]), [use_debug=$enableval],[use_debug=no]) if test "${use_debug}" = "yes" ; then - TARGET_DEBUG="-DSQLITE_DEBUG=1 -DSQLITE_ENABLE_SELECTTRACE -DSQLITE_ENABLE_WHERETRACE" + TARGET_DEBUG="-DSQLITE_DEBUG=1 -DSQLITE_ENABLE_SELECTTRACE -DSQLITE_ENABLE_WHERETRACE -O0" else TARGET_DEBUG="-DNDEBUG" fi @@ -596,7 +596,7 @@ AC_ARG_ENABLE(memsys5, [enable_memsys5=yes],[enable_memsys5=no]) AC_MSG_CHECKING([whether to support MEMSYS5]) if test "${enable_memsys5}" = "yes"; then - OPT_FEATURE_FLAGS+=" -DSQLITE_ENABLE_MEMSYS5" + OPT_FEATURE_FLAGS="$(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_MEMSYS5" AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) @@ -606,7 +606,7 @@ AC_ARG_ENABLE(memsys3, [enable_memsys3=yes],[enable_memsys3=no]) AC_MSG_CHECKING([whether to support MEMSYS3]) if test "${enable_memsys3}" = "yes" -a "${enable_memsys5}" = "no"; then - OPT_FEATURE_FLAGS+=" -DSQLITE_ENABLE_MEMSYS3" + OPT_FEATURE_FLAGS="$(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_MEMSYS3" AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) @@ -618,20 +618,20 @@ AC_ARG_ENABLE(fts3, AC_HELP_STRING([--enable-fts3], [Enable the FTS3 extension]), [enable_fts3=yes],[enable_fts3=no]) if test "${enable_fts3}" = "yes" ; then - OPT_FEATURE_FLAGS+=" -DSQLITE_ENABLE_FTS3" + OPT_FEATURE_FLAGS="$(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_FTS3" fi AC_ARG_ENABLE(fts4, AC_HELP_STRING([--enable-fts4], [Enable the FTS4 extension]), [enable_fts4=yes],[enable_fts4=no]) if test "${enable_fts4}" = "yes" ; then - OPT_FEATURE_FLAGS+=" -DSQLITE_ENABLE_FTS4" + OPT_FEATURE_FLAGS="$(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_FTS4" AC_SEARCH_LIBS([log],[m]) fi AC_ARG_ENABLE(fts5, AC_HELP_STRING([--enable-fts5], [Enable the FTS5 extension]), [enable_fts5=yes],[enable_fts5=no]) if test "${enable_fts5}" = "yes" ; then - OPT_FEATURE_FLAGS+=" -DSQLITE_ENABLE_FTS5" + OPT_FEATURE_FLAGS="$(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_FTS5" AC_SEARCH_LIBS([log],[m]) fi @@ -641,7 +641,7 @@ AC_ARG_ENABLE(json1, AC_HELP_STRING([--enable-json1], [Enable the JSON1 extension]), [enable_json1=yes],[enable_json1=no]) if test "${enable_json1}" = "yes" ; then - OPT_FEATURE_FLAGS+=" -DSQLITE_ENABLE_JSON1" + OPT_FEATURE_FLAGS="$(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_JSON1" fi ######### @@ -650,7 +650,7 @@ AC_ARG_ENABLE(rtree, AC_HELP_STRING([--enable-rtree], [Enable the RTREE extension]), [enable_rtree=yes],[enable_rtree=no]) if test "${enable_rtree}" = "yes" ; then - OPT_FEATURE_FLAGS+=" -DSQLITE_ENABLE_RTREE" + OPT_FEATURE_FLAGS="$(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_RTREE" fi ######### @@ -659,8 +659,8 @@ AC_ARG_ENABLE(session, AC_HELP_STRING([--enable-session], [Enable the SESSION extension]), [enable_session=yes],[enable_session=no]) if test "${enable_session}" = "yes" ; then - OPT_FEATURE_FLAGS+=" -DSQLITE_ENABLE_SESSION" - OPT_FEATURE_FLAGS+=" -DSQLITE_ENABLE_PREUPDATE_HOOK" + OPT_FEATURE_FLAGS="$(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_SESSION" + OPT_FEATURE_FLAGS="$(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_PREUPDATE_HOOK" fi ######### diff --git a/manifest b/manifest index ddb970509e..5a37bcc9d0 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sproblem\scausing\s"PRAGMA\sintegrity_check"\sto\sdisable\sthe\sxfer\noptimization\sfor\ssubsequent\sVACUUM\soperations\son\stables\swith\sone\sor\smore\sCHECK\nconstraints.\sThis\scould\sresult\sin\sVACUUM\sproducing\sslightly\slarger\sdatabase\nfiles. -D 2017-04-04T19:58:54.565 +C Attempt\sto\sremove\sbash-isms\sfrom\sconfigure.ac.\s\sUse\s-O0\swith\s--enable-debug. +D 2017-04-05T10:54:14.647 F Makefile.in 1cc758ce3374a32425e4d130c2fe7b026b20de5b8843243de75f087c0a2661fb F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc a4c0613a18663bda56d8cf76079ab6590a7c3602e54befb4bbdef76bcaa38b6a @@ -30,8 +30,8 @@ F autoconf/tea/win/rules.vc c511f222b80064096b705dbeb97060ee1d6b6d63 F config.guess 226d9a188c6196f3033ffc651cbc9dcee1a42977 F config.h.in 6376abec766e9a0785178b1823b5a587e9f1ccbc F config.sub 9ebe4c3b3dab6431ece34f16828b594fb420da55 -F configure cea63449647267beb335e899fd8a79778912ffa55d6b179730267b8ef84aa1aa x -F configure.ac 605173e829ab64514ed89f9b53d0da1739d7b0a0 +F configure bddf7d1d945894b724e2b16a1266359a40abec2c798c95b4409a7ebf771c38ef x +F configure.ac 901e8db2c211e8b655e51ee24f2b8faa33407acde87effc47f70380f3b04e452 F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad F doc/lemon.html b5a3c07d33ecb8e019ce8f7660fe2dbbad9d7977 F doc/pager-invariants.txt 27fed9a70ddad2088750c4a2b493b63853da2710 @@ -1570,7 +1570,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 5c11f4303f6a33d6358f451244551be63baf9afe5630332e60b349215e20a3af -R 160204ba2e30552a39ad215784116585 -U dan -Z c1b366616d6f296d38ff56ec0865eee0 +P e5bb7db51cdfd8124c60329782798cea398733545594dab55cb892b2a08c4d29 +R 19ba25e72f57d434a638f0fb43aed7b5 +U drh +Z 3d232979ad76612c4a27973fcd4ac955 diff --git a/manifest.uuid b/manifest.uuid index 49b3a8a4f7..6480f764fb 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e5bb7db51cdfd8124c60329782798cea398733545594dab55cb892b2a08c4d29 \ No newline at end of file +71ed35ccf7c0f6c49118a44cf6621f46b9ea883e4a74d51b8b1ade6d9a95413a \ No newline at end of file From 43606175e2e8fae94fa98f18353a3c335c708eb1 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 5 Apr 2017 11:32:13 +0000 Subject: [PATCH 14/28] Combine the ExprList_item objects and the ExprList wrapper into a single memory allocation, for improved performance and reduced footprint. FossilOrigin-Name: 2b6560ad88b92820c383bcdc1e30c06f8b081ef7c6d9b1af71d2bb76c83e35cd --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/expr.c | 40 ++++++++++++++++------------------------ src/select.c | 2 +- src/sqliteInt.h | 3 ++- 5 files changed, 28 insertions(+), 35 deletions(-) diff --git a/manifest b/manifest index 5a37bcc9d0..3ba9e765b9 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Attempt\sto\sremove\sbash-isms\sfrom\sconfigure.ac.\s\sUse\s-O0\swith\s--enable-debug. -D 2017-04-05T10:54:14.647 +C Combine\sthe\sExprList_item\sobjects\sand\sthe\sExprList\swrapper\sinto\sa\ssingle\nmemory\sallocation,\sfor\simproved\sperformance\sand\sreduced\sfootprint. +D 2017-04-05T11:32:13.794 F Makefile.in 1cc758ce3374a32425e4d130c2fe7b026b20de5b8843243de75f087c0a2661fb F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc a4c0613a18663bda56d8cf76079ab6590a7c3602e54befb4bbdef76bcaa38b6a @@ -354,7 +354,7 @@ F src/ctime.c 47d91a25ad8f199a71a5b1b7b169d6dd0d6e98c5719eca801568798743d1161c F src/date.c ee676e7694dfadbdd2fde1a258a71be8360ba5ae F src/dbstat.c 19ee7a4e89979d4df8e44cfac7a8f905ec89b77d F src/delete.c 0d9d5549d42e79ce4d82ff1db1e6c81e36d2f67c -F src/expr.c f12a581f342a6fd85d14c31e4fb84f16b3dd107f54d7728dddb62cebc79d7ce1 +F src/expr.c 6b186566a120d7d0aa4d0a846d9500704a22530f8f1c216185629dd8aee17743 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 2e9aabe1aee76273aff8a84ee92c464e095400ae F src/func.c 9d52522cc8ae7f5cdadfe14594262f1618bc1f86083c4cd6da861b4cf5af6174 @@ -401,12 +401,12 @@ F src/printf.c 8757834f1b54dae512fb25eb1acc8e94a0d15dd2290b58f2563f65973265adb2 F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c 3e518b962d932a997fae373366880fc028c75706 F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac -F src/select.c 2496d0cc6368dabe7ad2e4c7f5ed3ad9aa3b4d11cd90f33fa1d1ef72493f43aa +F src/select.c bbcfd919d795ba4796859aeaf2a202d9e0138fbfb5aa6c35fee816343cd82995 F src/shell.c ceb2b2f1f958ea2c47a7f37972d0f715fbf9dcf6a34a5e98c886b85e3ce6a238 F src/sqlite.h.in 723107d97f2345a7c103632169dc61366121c4ab65d75a7d83c6dc0e5bbe5ca4 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 58fd0676d3111d02e62e5a35992a7d3da5d3f88753acc174f2d37b774fbbdd28 -F src/sqliteInt.h a530e5baf5e559154d5c2e5cc57471bc780a7af4cd0a5d72750b1d850fef1e22 +F src/sqliteInt.h c5e83040837328293dfec3b89923300591ed1de6ac3d073818d414b55c0e21a0 F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b F src/status.c a9e66593dfb28a9e746cba7153f84d49c1ddc4b1 F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34 @@ -1570,7 +1570,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P e5bb7db51cdfd8124c60329782798cea398733545594dab55cb892b2a08c4d29 -R 19ba25e72f57d434a638f0fb43aed7b5 +P 71ed35ccf7c0f6c49118a44cf6621f46b9ea883e4a74d51b8b1ade6d9a95413a +R 35ab32fb0c98cf97e1b56263304a8725 U drh -Z 3d232979ad76612c4a27973fcd4ac955 +Z 9400dede22aec4be5e7e28c14dab8209 diff --git a/manifest.uuid b/manifest.uuid index 6480f764fb..7d4e9ca826 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -71ed35ccf7c0f6c49118a44cf6621f46b9ea883e4a74d51b8b1ade6d9a95413a \ No newline at end of file +2b6560ad88b92820c383bcdc1e30c06f8b081ef7c6d9b1af71d2bb76c83e35cd \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index ce948be69e..8d935764ac 100644 --- a/src/expr.c +++ b/src/expr.c @@ -1305,15 +1305,11 @@ ExprList *sqlite3ExprListDup(sqlite3 *db, ExprList *p, int flags){ Expr *pPriorSelectCol = 0; assert( db!=0 ); if( p==0 ) return 0; - pNew = sqlite3DbMallocRawNN(db, sizeof(*pNew) ); + pNew = sqlite3DbMallocRawNN(db, + sizeof(*pNew)+sizeof(pNew->a[0])*(p->nExpr-1) ); if( pNew==0 ) return 0; - pNew->nExpr = i = p->nExpr; - if( (flags & EXPRDUP_REDUCE)==0 ) for(i=1; inExpr; i+=i){} - pNew->a = pItem = sqlite3DbMallocRawNN(db, i*sizeof(p->a[0]) ); - if( pItem==0 ){ - sqlite3DbFree(db, pNew); - return 0; - } + pNew->nAlloc = pNew->nExpr = p->nExpr; + pItem = pNew->a; pOldItem = p->a; for(i=0; inExpr; i++, pItem++, pOldItem++){ Expr *pOldExpr = pOldItem->pExpr; @@ -1475,6 +1471,7 @@ ExprList *sqlite3ExprListAppend( ExprList *pList, /* List to which to append. Might be NULL */ Expr *pExpr /* Expression to be appended. Might be NULL */ ){ + struct ExprList_item *pItem; sqlite3 *db = pParse->db; assert( db!=0 ); if( pList==0 ){ @@ -1483,23 +1480,20 @@ ExprList *sqlite3ExprListAppend( goto no_mem; } pList->nExpr = 0; - pList->a = sqlite3DbMallocRawNN(db, sizeof(pList->a[0])); - if( pList->a==0 ) goto no_mem; - }else if( (pList->nExpr & (pList->nExpr-1))==0 ){ - struct ExprList_item *a; - assert( pList->nExpr>0 ); - a = sqlite3DbRealloc(db, pList->a, pList->nExpr*2*sizeof(pList->a[0])); - if( a==0 ){ + pList->nAlloc = 1; + }else if( pList->nExpr==pList->nAlloc ){ + ExprList *pNew; + pNew = sqlite3DbRealloc(db, pList, + sizeof(*pList)+(2*pList->nAlloc - 1)*sizeof(pList->a[0])); + if( pNew==0 ){ goto no_mem; } - pList->a = a; - } - assert( pList->a!=0 ); - if( 1 ){ - struct ExprList_item *pItem = &pList->a[pList->nExpr++]; - memset(pItem, 0, sizeof(*pItem)); - pItem->pExpr = pExpr; + pList = pNew; + pList->nAlloc *= 2; } + pItem = &pList->a[pList->nExpr++]; + memset(pItem, 0, sizeof(*pItem)); + pItem->pExpr = pExpr; return pList; no_mem: @@ -1665,13 +1659,11 @@ void sqlite3ExprListCheckLength( static SQLITE_NOINLINE void exprListDeleteNN(sqlite3 *db, ExprList *pList){ int i; struct ExprList_item *pItem; - assert( pList->a!=0 || pList->nExpr==0 ); for(pItem=pList->a, i=0; inExpr; i++, pItem++){ sqlite3ExprDelete(db, pItem->pExpr); sqlite3DbFree(db, pItem->zName); sqlite3DbFree(db, pItem->zSpan); } - sqlite3DbFree(db, pList->a); sqlite3DbFree(db, pList); } void sqlite3ExprListDelete(sqlite3 *db, ExprList *pList){ diff --git a/src/select.c b/src/select.c index bb055c7894..297b4d719b 100644 --- a/src/select.c +++ b/src/select.c @@ -2900,7 +2900,7 @@ static int multiSelectOrderBy( if( pNew==0 ) return SQLITE_NOMEM_BKPT; pNew->flags |= EP_IntValue; pNew->u.iValue = i; - pOrderBy = sqlite3ExprListAppend(pParse, pOrderBy, pNew); + p->pOrderBy = pOrderBy = sqlite3ExprListAppend(pParse, pOrderBy, pNew); if( pOrderBy ) pOrderBy->a[nOrderBy++].u.x.iOrderByCol = (u16)i; } } diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 271ea9a3ef..a0acec471d 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -2443,6 +2443,7 @@ struct Expr { */ struct ExprList { int nExpr; /* Number of expressions on the list */ + int nAlloc; /* Number of a[] slots allocated */ struct ExprList_item { /* For each expression in the list */ Expr *pExpr; /* The parse tree for this expression */ char *zName; /* Token associated with this expression */ @@ -2458,7 +2459,7 @@ struct ExprList { } x; int iConstExprReg; /* Register in which Expr value is cached */ } u; - } *a; /* Alloc a power of two greater or equal to nExpr */ + } a[1]; /* One slot for each expression in the list */ }; /* From f4dd26c5a00407d0c5f5d3874b684a40cb9ab5ef Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 5 Apr 2017 11:49:06 +0000 Subject: [PATCH 15/28] Remove a conditional made unreachable by the previous ExprList enhancement. FossilOrigin-Name: a1cf44763277b6c745b5b5509ca9129b6c3231608b4d1c8aec2815b64b5a2a07 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/expr.c | 23 +++++++++++------------ 3 files changed, 18 insertions(+), 19 deletions(-) diff --git a/manifest b/manifest index 3ba9e765b9..4619075773 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Combine\sthe\sExprList_item\sobjects\sand\sthe\sExprList\swrapper\sinto\sa\ssingle\nmemory\sallocation,\sfor\simproved\sperformance\sand\sreduced\sfootprint. -D 2017-04-05T11:32:13.794 +C Remove\sa\sconditional\smade\sunreachable\sby\sthe\sprevious\sExprList\senhancement. +D 2017-04-05T11:49:06.526 F Makefile.in 1cc758ce3374a32425e4d130c2fe7b026b20de5b8843243de75f087c0a2661fb F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc a4c0613a18663bda56d8cf76079ab6590a7c3602e54befb4bbdef76bcaa38b6a @@ -354,7 +354,7 @@ F src/ctime.c 47d91a25ad8f199a71a5b1b7b169d6dd0d6e98c5719eca801568798743d1161c F src/date.c ee676e7694dfadbdd2fde1a258a71be8360ba5ae F src/dbstat.c 19ee7a4e89979d4df8e44cfac7a8f905ec89b77d F src/delete.c 0d9d5549d42e79ce4d82ff1db1e6c81e36d2f67c -F src/expr.c 6b186566a120d7d0aa4d0a846d9500704a22530f8f1c216185629dd8aee17743 +F src/expr.c d6b2f5ffa944b6ca950db65b572256e6148496bfc779c09b9e9488b8eebc93c2 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 2e9aabe1aee76273aff8a84ee92c464e095400ae F src/func.c 9d52522cc8ae7f5cdadfe14594262f1618bc1f86083c4cd6da861b4cf5af6174 @@ -1570,7 +1570,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 71ed35ccf7c0f6c49118a44cf6621f46b9ea883e4a74d51b8b1ade6d9a95413a -R 35ab32fb0c98cf97e1b56263304a8725 +P 2b6560ad88b92820c383bcdc1e30c06f8b081ef7c6d9b1af71d2bb76c83e35cd +R 812df0359506624ef6f94f0149739746 U drh -Z 9400dede22aec4be5e7e28c14dab8209 +Z 9b5482ae695747ea67bbfbf192e444a1 diff --git a/manifest.uuid b/manifest.uuid index 7d4e9ca826..a97fdbfc7f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2b6560ad88b92820c383bcdc1e30c06f8b081ef7c6d9b1af71d2bb76c83e35cd \ No newline at end of file +a1cf44763277b6c745b5b5509ca9129b6c3231608b4d1c8aec2815b64b5a2a07 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 8d935764ac..20ccea787c 100644 --- a/src/expr.c +++ b/src/expr.c @@ -1550,20 +1550,19 @@ ExprList *sqlite3ExprListAppendVector( } } - if( pExpr->op==TK_SELECT ){ - if( pList && pList->a[iFirst].pExpr ){ - Expr *pFirst = pList->a[iFirst].pExpr; - assert( pFirst->op==TK_SELECT_COLUMN ); + if( pExpr->op==TK_SELECT && pList ){ + Expr *pFirst = pList->a[iFirst].pExpr; + assert( pFirst!=0 ); + assert( pFirst->op==TK_SELECT_COLUMN ); - /* Store the SELECT statement in pRight so it will be deleted when - ** sqlite3ExprListDelete() is called */ - pFirst->pRight = pExpr; - pExpr = 0; + /* Store the SELECT statement in pRight so it will be deleted when + ** sqlite3ExprListDelete() is called */ + pFirst->pRight = pExpr; + pExpr = 0; - /* Remember the size of the LHS in iTable so that we can check that - ** the RHS and LHS sizes match during code generation. */ - pFirst->iTable = pColumns->nId; - } + /* Remember the size of the LHS in iTable so that we can check that + ** the RHS and LHS sizes match during code generation. */ + pFirst->iTable = pColumns->nId; } vector_append_error: From ac48b751e2e1041fa5728dde2ea58575ad535daf Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 5 Apr 2017 11:57:56 +0000 Subject: [PATCH 16/28] Save a few bytes and a few CPU cycles in sqlite3ExprListDelete() routine. FossilOrigin-Name: 9e6c939144a129b36bb119120442a4a021e00187783da211315d4bb13acd7c3a --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/expr.c | 10 ++++++---- 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index 4619075773..788528ada7 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\sa\sconditional\smade\sunreachable\sby\sthe\sprevious\sExprList\senhancement. -D 2017-04-05T11:49:06.526 +C Save\sa\sfew\sbytes\sand\sa\sfew\sCPU\scycles\sin\ssqlite3ExprListDelete()\sroutine. +D 2017-04-05T11:57:56.171 F Makefile.in 1cc758ce3374a32425e4d130c2fe7b026b20de5b8843243de75f087c0a2661fb F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc a4c0613a18663bda56d8cf76079ab6590a7c3602e54befb4bbdef76bcaa38b6a @@ -354,7 +354,7 @@ F src/ctime.c 47d91a25ad8f199a71a5b1b7b169d6dd0d6e98c5719eca801568798743d1161c F src/date.c ee676e7694dfadbdd2fde1a258a71be8360ba5ae F src/dbstat.c 19ee7a4e89979d4df8e44cfac7a8f905ec89b77d F src/delete.c 0d9d5549d42e79ce4d82ff1db1e6c81e36d2f67c -F src/expr.c d6b2f5ffa944b6ca950db65b572256e6148496bfc779c09b9e9488b8eebc93c2 +F src/expr.c 15f245fd12596cd86027e1f8d15ba670ffb954189696cd529bbc399f2b5ee473 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 2e9aabe1aee76273aff8a84ee92c464e095400ae F src/func.c 9d52522cc8ae7f5cdadfe14594262f1618bc1f86083c4cd6da861b4cf5af6174 @@ -1570,7 +1570,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 2b6560ad88b92820c383bcdc1e30c06f8b081ef7c6d9b1af71d2bb76c83e35cd -R 812df0359506624ef6f94f0149739746 +P a1cf44763277b6c745b5b5509ca9129b6c3231608b4d1c8aec2815b64b5a2a07 +R 4d8790f73d530cb376a3a651b6d64ad6 U drh -Z 9b5482ae695747ea67bbfbf192e444a1 +Z 8197639d1fc47aadec64571253c4a3bb diff --git a/manifest.uuid b/manifest.uuid index a97fdbfc7f..3629a99a8f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a1cf44763277b6c745b5b5509ca9129b6c3231608b4d1c8aec2815b64b5a2a07 \ No newline at end of file +9e6c939144a129b36bb119120442a4a021e00187783da211315d4bb13acd7c3a \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 20ccea787c..47b75766b7 100644 --- a/src/expr.c +++ b/src/expr.c @@ -1656,13 +1656,15 @@ void sqlite3ExprListCheckLength( ** Delete an entire expression list. */ static SQLITE_NOINLINE void exprListDeleteNN(sqlite3 *db, ExprList *pList){ - int i; - struct ExprList_item *pItem; - for(pItem=pList->a, i=0; inExpr; i++, pItem++){ + int i = pList->nExpr; + struct ExprList_item *pItem = pList->a; + assert( pList->nExpr>0 ); + do{ sqlite3ExprDelete(db, pItem->pExpr); sqlite3DbFree(db, pItem->zName); sqlite3DbFree(db, pItem->zSpan); - } + pItem++; + }while( --i>0 ); sqlite3DbFree(db, pList); } void sqlite3ExprListDelete(sqlite3 *db, ExprList *pList){ From dbd6a7dc0685e8c43cb59086779c419eb0ee89e7 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 5 Apr 2017 12:39:49 +0000 Subject: [PATCH 17/28] Split off sqlite3DbFreeNN() from sqlite3DbFree() and use it in cases where we know that the argument to be freed is never NULL. FossilOrigin-Name: ad90e8bb5e47945607c8fb47b6ade8cfc52a9b684805cc40132629be0ecc14cc --- manifest | 30 +++++++++++++++--------------- manifest.uuid | 2 +- src/build.c | 4 ++-- src/expr.c | 6 +++--- src/malloc.c | 11 ++++++++--- src/select.c | 4 ++-- src/sqliteInt.h | 1 + src/tokenize.c | 2 +- src/vdbe.c | 4 ++-- src/vdbeaux.c | 16 ++++++++-------- src/vdbemem.c | 16 ++++++++-------- src/where.c | 16 ++++++++-------- 12 files changed, 59 insertions(+), 53 deletions(-) diff --git a/manifest b/manifest index 788528ada7..7587a14c0a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Save\sa\sfew\sbytes\sand\sa\sfew\sCPU\scycles\sin\ssqlite3ExprListDelete()\sroutine. -D 2017-04-05T11:57:56.171 +C Split\soff\ssqlite3DbFreeNN()\sfrom\ssqlite3DbFree()\sand\suse\sit\sin\scases\swhere\nwe\sknow\sthat\sthe\sargument\sto\sbe\sfreed\sis\snever\sNULL. +D 2017-04-05T12:39:49.042 F Makefile.in 1cc758ce3374a32425e4d130c2fe7b026b20de5b8843243de75f087c0a2661fb F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc a4c0613a18663bda56d8cf76079ab6590a7c3602e54befb4bbdef76bcaa38b6a @@ -347,14 +347,14 @@ F src/btmutex.c 0e9ce2d56159b89b9bc8e197e023ee11e39ff8ca F src/btree.c 24ae5472bd0b53b4130ecdda389deb621af721d1fcb50890b878102b00bd10fa F src/btree.h bf64dfeeddeebdb775a5eba0098bbc00d073290d F src/btreeInt.h a392d353104b4add58b4a59cb185f5d5693dde832c565b77d8d4c343ed98f610 -F src/build.c 43f903c9082040ced2b421543cb0300c2973647d +F src/build.c 4026a9c554b233e50c5e9ad46963e676cf54dd2306d952aa1eaa07a1bc9ce14f F src/callback.c 2e76147783386374bf01b227f752c81ec872d730 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c 47d91a25ad8f199a71a5b1b7b169d6dd0d6e98c5719eca801568798743d1161c F src/date.c ee676e7694dfadbdd2fde1a258a71be8360ba5ae F src/dbstat.c 19ee7a4e89979d4df8e44cfac7a8f905ec89b77d F src/delete.c 0d9d5549d42e79ce4d82ff1db1e6c81e36d2f67c -F src/expr.c 15f245fd12596cd86027e1f8d15ba670ffb954189696cd529bbc399f2b5ee473 +F src/expr.c 6bce2cbdd822963cf28e782938a96274cc37f18ac28dec7a4e35ccac09f66ce8 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 2e9aabe1aee76273aff8a84ee92c464e095400ae F src/func.c 9d52522cc8ae7f5cdadfe14594262f1618bc1f86083c4cd6da861b4cf5af6174 @@ -367,7 +367,7 @@ F src/insert.c d4bb3a135948553d18cf992f76f7ed7b18aa0327f250607b5a6671e55d9947d5 F src/legacy.c e88ed13c2d531decde75d42c2e35623fb9ce3cb0 F src/loadext.c a72909474dadce771d3669bf84bf689424f6f87d471fee898589c3ef9b2acfd9 F src/main.c 158326243c5ddc8b98a1e983fa488650cf76d760 -F src/malloc.c 89c98e3619d362dcffa5c1c639b364b65b474751 +F src/malloc.c e20bb2b48abec52d3faf01cce12e8b4f95973755fafec98d45162dfdab111978 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c c12a42539b1ba105e3707d0e628ad70e611040d8f5e38cf942cee30c867083de F src/mem2.c f1940d9e91948dd6a908fbb9ce3835c36b5d83c3 @@ -401,12 +401,12 @@ F src/printf.c 8757834f1b54dae512fb25eb1acc8e94a0d15dd2290b58f2563f65973265adb2 F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c 3e518b962d932a997fae373366880fc028c75706 F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac -F src/select.c bbcfd919d795ba4796859aeaf2a202d9e0138fbfb5aa6c35fee816343cd82995 +F src/select.c afcf31d8ed7c890328a31d3f350467ccd273af345b24562382b398d6d9cd0664 F src/shell.c ceb2b2f1f958ea2c47a7f37972d0f715fbf9dcf6a34a5e98c886b85e3ce6a238 F src/sqlite.h.in 723107d97f2345a7c103632169dc61366121c4ab65d75a7d83c6dc0e5bbe5ca4 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 58fd0676d3111d02e62e5a35992a7d3da5d3f88753acc174f2d37b774fbbdd28 -F src/sqliteInt.h c5e83040837328293dfec3b89923300591ed1de6ac3d073818d414b55c0e21a0 +F src/sqliteInt.h 6cf244eb06119b44e155717708e54f0638c35e9bd8ef59ea570eb1f093f0da44 F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b F src/status.c a9e66593dfb28a9e746cba7153f84d49c1ddc4b1 F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34 @@ -461,20 +461,20 @@ F src/test_windirent.c 17f91f5f2aa1bb7328abb49414c363b5d2a9d3ff F src/test_windirent.h 5d67483a55442e31e1bde0f4a230e6e932ad5906 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c -F src/tokenize.c de2ec4fed5aa9770791be7528a08597a77a36b2ffbbeb0c2cb6951e80357730b +F src/tokenize.c 1003d6d90c6783206c711f0a9397656fa5b055209f4d092caa43bb3bf5215db5 F src/treeview.c 84d0ac737e1231702679f0289180021e19c5cc186ec413e8dcb704a887c76ec8 F src/trigger.c c9f0810043b265724fdb1bdd466894f984dfc182 F src/update.c 456d4a4656f8a03c2abc88a51b19172197400e58 F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c F src/util.c ca8440ede81e155d15cff7c101654f60b55a9ae6 F src/vacuum.c 1fe4555cd8c9b263afb85b5b4ee3a4a4181ad569 -F src/vdbe.c 1be564c66097e8982229bbc4d3de3042427dfdff0e5e7b7287bf7531faf474bf +F src/vdbe.c b070c9c81a5faff5d9fc9563c7c030e3e1adb69d835259470fd945ef61f3f9fb F src/vdbe.h caa5346d52bae2a3c8c1dcfa60a7a4dc878a9e3865cb8239da55808b316c8158 F src/vdbeInt.h 5db089ce18c4feff8820ec6e4cac2d2c82e03d4b1d96f10a6e43832147b8dffe F src/vdbeapi.c 5b08d82592bcff4470601fe78aaabebd50837860 -F src/vdbeaux.c 514eb1749346b1e587fbeb775198ed9385476d5639bc81aef42914e2fe70962d +F src/vdbeaux.c 0ecacf8c7ca93e430b30819b8fc9b2c1ffe88202d1437e88c08a1f0b6159c58c F src/vdbeblob.c 359891617358deefc85bef7bcf787fa6b77facb9 -F src/vdbemem.c bbd8f5fdb7f11e02d9a6201f18a52325f1d2361a2850ff03a38f8efa5188f2dc +F src/vdbemem.c 8bb4dd22837da969bfda25ef3f92d41aaad192328f89a0951290d5e26ad7dbc4 F src/vdbesort.c e72fe02a2121386ba767ede8942e9450878b8fc873abf3d1b6824485f092570c F src/vdbetrace.c 41963d5376f0349842b5fc4aaaaacd7d9cdc0834 F src/vtab.c 007513c2ef52472fcdea6a741683d50662e82790 @@ -482,7 +482,7 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 40c543f0a2195d1b0dc88ef12142bea690009344 F src/wal.h 06b2a0b599cc0f53ea97f497cf8c6b758c999f71 F src/walker.c b71a992b413b3a022572eccf29ef4b4890223791 -F src/where.c aed99e51153930ce30a6b25968fa61fabdc0160f6198e01ed3d108e9dbb49a15 +F src/where.c 49b48b720184fdde747c468d7270feeb1b88c6a71092cea3a1aa168dc8ac0b0f F src/whereInt.h 2d50c2b74a33be44cb68fdecee30b4d93552f1f4 F src/wherecode.c 677e95413c472c0b413023b6b69a47f40fce1b04 F src/whereexpr.c 130cdd1a43af71b19755270fb1224874cf55158c @@ -1570,7 +1570,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P a1cf44763277b6c745b5b5509ca9129b6c3231608b4d1c8aec2815b64b5a2a07 -R 4d8790f73d530cb376a3a651b6d64ad6 +P 9e6c939144a129b36bb119120442a4a021e00187783da211315d4bb13acd7c3a +R 17c5231ecc5d3d35525c3418d3d62ff7 U drh -Z 8197639d1fc47aadec64571253c4a3bb +Z d994bdccf4db8bedaee3d7cb7c3b925e diff --git a/manifest.uuid b/manifest.uuid index 3629a99a8f..4c24f5cdfb 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9e6c939144a129b36bb119120442a4a021e00187783da211315d4bb13acd7c3a \ No newline at end of file +ad90e8bb5e47945607c8fb47b6ade8cfc52a9b684805cc40132629be0ecc14cc \ No newline at end of file diff --git a/src/build.c b/src/build.c index 2ce7c90747..e04406d857 100644 --- a/src/build.c +++ b/src/build.c @@ -3623,7 +3623,7 @@ void sqlite3IdListDelete(sqlite3 *db, IdList *pList){ sqlite3DbFree(db, pList->a[i].zName); } sqlite3DbFree(db, pList->a); - sqlite3DbFree(db, pList); + sqlite3DbFreeNN(db, pList); } /* @@ -3813,7 +3813,7 @@ void sqlite3SrcListDelete(sqlite3 *db, SrcList *pList){ sqlite3ExprDelete(db, pItem->pOn); sqlite3IdListDelete(db, pItem->pUsing); } - sqlite3DbFree(db, pList); + sqlite3DbFreeNN(db, pList); } /* diff --git a/src/expr.c b/src/expr.c index 47b75766b7..e3db59732e 100644 --- a/src/expr.c +++ b/src/expr.c @@ -1038,7 +1038,7 @@ static SQLITE_NOINLINE void sqlite3ExprDeleteNN(sqlite3 *db, Expr *p){ } if( ExprHasProperty(p, EP_MemToken) ) sqlite3DbFree(db, p->u.zToken); if( !ExprHasProperty(p, EP_Static) ){ - sqlite3DbFree(db, p); + sqlite3DbFreeNN(db, p); } } void sqlite3ExprDelete(sqlite3 *db, Expr *p){ @@ -1400,7 +1400,7 @@ IdList *sqlite3IdListDup(sqlite3 *db, IdList *p){ pNew->nId = p->nId; pNew->a = sqlite3DbMallocRawNN(db, p->nId*sizeof(p->a[0]) ); if( pNew->a==0 ){ - sqlite3DbFree(db, pNew); + sqlite3DbFreeNN(db, pNew); return 0; } /* Note that because the size of the allocation for p->a[] is not @@ -1665,7 +1665,7 @@ static SQLITE_NOINLINE void exprListDeleteNN(sqlite3 *db, ExprList *pList){ sqlite3DbFree(db, pItem->zSpan); pItem++; }while( --i>0 ); - sqlite3DbFree(db, pList); + sqlite3DbFreeNN(db, pList); } void sqlite3ExprListDelete(sqlite3 *db, ExprList *pList){ if( pList ) exprListDeleteNN(db, pList); diff --git a/src/malloc.c b/src/malloc.c index 6d49107790..5eb65bf623 100644 --- a/src/malloc.c +++ b/src/malloc.c @@ -474,11 +474,12 @@ static SQLITE_NOINLINE void measureAllocationSize(sqlite3 *db, void *p){ /* ** Free memory that might be associated with a particular database -** connection. +** connection. Calling sqlite3DbFree(D,X) for X==0 is a harmless no-op. +** The sqlite3DbFreeNN(D,X) version requires that X be non-NULL. */ -void sqlite3DbFree(sqlite3 *db, void *p){ +void sqlite3DbFreeNN(sqlite3 *db, void *p){ assert( db==0 || sqlite3_mutex_held(db->mutex) ); - if( p==0 ) return; + assert( p!=0 ); if( db ){ if( db->pnBytesFreed ){ measureAllocationSize(db, p); @@ -502,6 +503,10 @@ void sqlite3DbFree(sqlite3 *db, void *p){ sqlite3MemdebugSetType(p, MEMTYPE_HEAP); sqlite3_free(p); } +void sqlite3DbFree(sqlite3 *db, void *p){ + assert( db==0 || sqlite3_mutex_held(db->mutex) ); + if( p ) sqlite3DbFreeNN(db, p); +} /* ** Change the size of an existing memory allocation diff --git a/src/select.c b/src/select.c index 297b4d719b..334307cce7 100644 --- a/src/select.c +++ b/src/select.c @@ -76,7 +76,7 @@ static void clearSelect(sqlite3 *db, Select *p, int bFree){ sqlite3ExprDelete(db, p->pLimit); sqlite3ExprDelete(db, p->pOffset); if( p->pWith ) sqlite3WithDelete(db, p->pWith); - if( bFree ) sqlite3DbFree(db, p); + if( bFree ) sqlite3DbFreeNN(db, p); p = pPrior; bFree = 1; } @@ -1055,7 +1055,7 @@ void sqlite3KeyInfoUnref(KeyInfo *p){ if( p ){ assert( p->nRef>0 ); p->nRef--; - if( p->nRef==0 ) sqlite3DbFree(p->db, p); + if( p->nRef==0 ) sqlite3DbFreeNN(p->db, p); } } diff --git a/src/sqliteInt.h b/src/sqliteInt.h index a0acec471d..2b3c934ecd 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -3477,6 +3477,7 @@ void *sqlite3Realloc(void*, u64); void *sqlite3DbReallocOrFree(sqlite3 *, void *, u64); void *sqlite3DbRealloc(sqlite3 *, void *, u64); void sqlite3DbFree(sqlite3*, void*); +void sqlite3DbFreeNN(sqlite3*, void*); int sqlite3MallocSize(void*); int sqlite3DbMallocSize(sqlite3*, void*); void *sqlite3ScratchMalloc(int); diff --git a/src/tokenize.c b/src/tokenize.c index 7f5f298987..2aab334ae9 100644 --- a/src/tokenize.c +++ b/src/tokenize.c @@ -604,7 +604,7 @@ int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzErrMsg){ while( pParse->pAinc ){ AutoincInfo *p = pParse->pAinc; pParse->pAinc = p->pNext; - sqlite3DbFree(db, p); + sqlite3DbFreeNN(db, p); } while( pParse->pZombieTab ){ Table *p = pParse->pZombieTab; diff --git a/src/vdbe.c b/src/vdbe.c index fd4705abcd..51c702a4ad 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -4076,7 +4076,7 @@ case OP_Found: { /* jump, in3 */ } } rc = sqlite3BtreeMovetoUnpacked(pC->uc.pCursor, pIdxKey, 0, 0, &res); - if( pFree ) sqlite3DbFree(db, pFree); + if( pFree ) sqlite3DbFreeNN(db, pFree); if( rc!=SQLITE_OK ){ goto abort_due_to_error; } @@ -5594,7 +5594,7 @@ case OP_ParseSchema: { assert( !db->mallocFailed ); rc = sqlite3_exec(db, zSql, sqlite3InitCallback, &initData, 0); if( rc==SQLITE_OK ) rc = initData.rc; - sqlite3DbFree(db, zSql); + sqlite3DbFreeNN(db, zSql); db->init.busy = 0; } } diff --git a/src/vdbeaux.c b/src/vdbeaux.c index cd765a1773..3fcfb681d1 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -811,7 +811,7 @@ void sqlite3VdbeJumpHere(Vdbe *p, int addr){ */ static void freeEphemeralFunction(sqlite3 *db, FuncDef *pDef){ if( (pDef->funcFlags & SQLITE_FUNC_EPHEM)!=0 ){ - sqlite3DbFree(db, pDef); + sqlite3DbFreeNN(db, pDef); } } @@ -822,11 +822,11 @@ static void vdbeFreeOpArray(sqlite3 *, Op *, int); */ static SQLITE_NOINLINE void freeP4Mem(sqlite3 *db, Mem *p){ if( p->szMalloc ) sqlite3DbFree(db, p->zMalloc); - sqlite3DbFree(db, p); + sqlite3DbFreeNN(db, p); } static SQLITE_NOINLINE void freeP4FuncCtx(sqlite3 *db, sqlite3_context *p){ freeEphemeralFunction(db, p->pFunc); - sqlite3DbFree(db, p); + sqlite3DbFreeNN(db, p); } static void freeP4(sqlite3 *db, int p4type, void *p4){ assert( db ); @@ -885,8 +885,8 @@ static void vdbeFreeOpArray(sqlite3 *db, Op *aOp, int nOp){ sqlite3DbFree(db, pOp->zComment); #endif } + sqlite3DbFreeNN(db, aOp); } - sqlite3DbFree(db, aOp); } /* @@ -1559,7 +1559,7 @@ static void releaseMemArray(Mem *p, int N){ if( p->flags&(MEM_Agg|MEM_Dyn|MEM_Frame|MEM_RowSet) ){ sqlite3VdbeMemRelease(p); }else if( p->szMalloc ){ - sqlite3DbFree(db, p->zMalloc); + sqlite3DbFreeNN(db, p->zMalloc); p->szMalloc = 0; } @@ -3039,7 +3039,7 @@ void sqlite3VdbeDelete(Vdbe *p){ } p->magic = VDBE_MAGIC_DEAD; p->db = 0; - sqlite3DbFree(db, p); + sqlite3DbFreeNN(db, p); } /* @@ -4598,7 +4598,7 @@ static void vdbeFreeUnpacked(sqlite3 *db, int nField, UnpackedRecord *p){ Mem *pMem = &p->aMem[i]; if( pMem->zMalloc ) sqlite3VdbeMemRelease(pMem); } - sqlite3DbFree(db, p); + sqlite3DbFreeNN(db, p); } } #endif /* SQLITE_ENABLE_PREUPDATE_HOOK */ @@ -4665,7 +4665,7 @@ void sqlite3VdbePreUpdateHook( for(i=0; inField; i++){ sqlite3VdbeMemRelease(&preupdate.aNew[i]); } - sqlite3DbFree(db, preupdate.aNew); + sqlite3DbFreeNN(db, preupdate.aNew); } } #endif /* SQLITE_ENABLE_PREUPDATE_HOOK */ diff --git a/src/vdbemem.c b/src/vdbemem.c index 9b1f43a94a..d7963cb7e7 100644 --- a/src/vdbemem.c +++ b/src/vdbemem.c @@ -131,7 +131,7 @@ SQLITE_NOINLINE int sqlite3VdbeMemGrow(Mem *pMem, int n, int bPreserve){ pMem->z = pMem->zMalloc = sqlite3DbReallocOrFree(pMem->db, pMem->z, n); bPreserve = 0; }else{ - if( pMem->szMalloc>0 ) sqlite3DbFree(pMem->db, pMem->zMalloc); + if( pMem->szMalloc>0 ) sqlite3DbFreeNN(pMem->db, pMem->zMalloc); pMem->zMalloc = sqlite3DbMallocRaw(pMem->db, n); } if( pMem->zMalloc==0 ){ @@ -341,7 +341,7 @@ int sqlite3VdbeMemFinalize(Mem *pMem, FuncDef *pFunc){ ctx.pFunc = pFunc; pFunc->xFinalize(&ctx); /* IMP: R-24505-23230 */ assert( (pMem->flags & MEM_Dyn)==0 ); - if( pMem->szMalloc>0 ) sqlite3DbFree(pMem->db, pMem->zMalloc); + if( pMem->szMalloc>0 ) sqlite3DbFreeNN(pMem->db, pMem->zMalloc); memcpy(pMem, &t, sizeof(t)); rc = ctx.isError; } @@ -392,7 +392,7 @@ static SQLITE_NOINLINE void vdbeMemClear(Mem *p){ vdbeMemClearExternAndSetNull(p); } if( p->szMalloc ){ - sqlite3DbFree(p->db, p->zMalloc); + sqlite3DbFreeNN(p->db, p->zMalloc); p->szMalloc = 0; } p->z = 0; @@ -1123,7 +1123,7 @@ static sqlite3_value *valueNew(sqlite3 *db, struct ValueNewStat4Ctx *p){ pRec->aMem[i].db = db; } }else{ - sqlite3DbFree(db, pRec); + sqlite3DbFreeNN(db, pRec); pRec = 0; } } @@ -1235,7 +1235,7 @@ static int valueFromFunction( for(i=0; ipKeyInfo); - sqlite3DbFree(db, pRec); + sqlite3DbFreeNN(db, pRec); } } #endif /* ifdef SQLITE_ENABLE_STAT4 */ @@ -1685,7 +1685,7 @@ void sqlite3ValueSetStr( void sqlite3ValueFree(sqlite3_value *v){ if( !v ) return; sqlite3VdbeMemRelease((Mem *)v); - sqlite3DbFree(((Mem*)v)->db, v); + sqlite3DbFreeNN(((Mem*)v)->db, v); } /* diff --git a/src/where.c b/src/where.c index d9c8b55d01..5a0b35bdf1 100644 --- a/src/where.c +++ b/src/where.c @@ -1786,7 +1786,7 @@ static void whereLoopClearUnion(sqlite3 *db, WhereLoop *p){ p->u.vtab.idxStr = 0; }else if( (p->wsFlags & WHERE_AUTO_INDEX)!=0 && p->u.btree.pIndex!=0 ){ sqlite3DbFree(db, p->u.btree.pIndex->zColAff); - sqlite3DbFree(db, p->u.btree.pIndex); + sqlite3DbFreeNN(db, p->u.btree.pIndex); p->u.btree.pIndex = 0; } } @@ -1796,7 +1796,7 @@ static void whereLoopClearUnion(sqlite3 *db, WhereLoop *p){ ** Deallocate internal memory used by a WhereLoop object */ static void whereLoopClear(sqlite3 *db, WhereLoop *p){ - if( p->aLTerm!=p->aLTermSpace ) sqlite3DbFree(db, p->aLTerm); + if( p->aLTerm!=p->aLTermSpace ) sqlite3DbFreeNN(db, p->aLTerm); whereLoopClearUnion(db, p); whereLoopInit(p); } @@ -1811,7 +1811,7 @@ static int whereLoopResize(sqlite3 *db, WhereLoop *p, int n){ paNew = sqlite3DbMallocRawNN(db, sizeof(p->aLTerm[0])*n); if( paNew==0 ) return SQLITE_NOMEM_BKPT; memcpy(paNew, p->aLTerm, sizeof(p->aLTerm[0])*p->nLSlot); - if( p->aLTerm!=p->aLTermSpace ) sqlite3DbFree(db, p->aLTerm); + if( p->aLTerm!=p->aLTermSpace ) sqlite3DbFreeNN(db, p->aLTerm); p->aLTerm = paNew; p->nLSlot = n; return SQLITE_OK; @@ -1841,7 +1841,7 @@ static int whereLoopXfer(sqlite3 *db, WhereLoop *pTo, WhereLoop *pFrom){ */ static void whereLoopDelete(sqlite3 *db, WhereLoop *p){ whereLoopClear(db, p); - sqlite3DbFree(db, p); + sqlite3DbFreeNN(db, p); } /* @@ -1862,7 +1862,7 @@ static void whereInfoFree(sqlite3 *db, WhereInfo *pWInfo){ pWInfo->pLoops = p->pNextLoop; whereLoopDelete(db, p); } - sqlite3DbFree(db, pWInfo); + sqlite3DbFreeNN(db, pWInfo); } } @@ -3253,7 +3253,7 @@ static int whereLoopAddVirtual( } if( p->needToFreeIdxStr ) sqlite3_free(p->idxStr); - sqlite3DbFree(pParse->db, p); + sqlite3DbFreeNN(pParse->db, p); return rc; } #endif /* SQLITE_OMIT_VIRTUALTABLE */ @@ -4108,7 +4108,7 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){ if( nFrom==0 ){ sqlite3ErrorMsg(pParse, "no query solution"); - sqlite3DbFree(db, pSpace); + sqlite3DbFreeNN(db, pSpace); return SQLITE_ERROR; } @@ -4184,7 +4184,7 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){ pWInfo->nRowOut = pFrom->nRow; /* Free temporary memory and return success */ - sqlite3DbFree(db, pSpace); + sqlite3DbFreeNN(db, pSpace); return SQLITE_OK; } From 6948ed5977b7a7f2ec12c99088ed2f6e9c6dd7ad Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 5 Apr 2017 13:44:40 +0000 Subject: [PATCH 18/28] Remove a confusing and pointless sentence from the documentation for the sqlite3_interrupt() interface. FossilOrigin-Name: c5f1a2b6eb3df879d247a22b3f92f4f74fcf4f0d219450abc420ae6d02481324 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/sqlite.h.in | 3 --- 3 files changed, 7 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 7587a14c0a..ad4644ec59 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Split\soff\ssqlite3DbFreeNN()\sfrom\ssqlite3DbFree()\sand\suse\sit\sin\scases\swhere\nwe\sknow\sthat\sthe\sargument\sto\sbe\sfreed\sis\snever\sNULL. -D 2017-04-05T12:39:49.042 +C Remove\sa\sconfusing\sand\spointless\ssentence\sfrom\sthe\sdocumentation\sfor\sthe\nsqlite3_interrupt()\sinterface. +D 2017-04-05T13:44:40.495 F Makefile.in 1cc758ce3374a32425e4d130c2fe7b026b20de5b8843243de75f087c0a2661fb F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc a4c0613a18663bda56d8cf76079ab6590a7c3602e54befb4bbdef76bcaa38b6a @@ -403,7 +403,7 @@ F src/resolve.c 3e518b962d932a997fae373366880fc028c75706 F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c afcf31d8ed7c890328a31d3f350467ccd273af345b24562382b398d6d9cd0664 F src/shell.c ceb2b2f1f958ea2c47a7f37972d0f715fbf9dcf6a34a5e98c886b85e3ce6a238 -F src/sqlite.h.in 723107d97f2345a7c103632169dc61366121c4ab65d75a7d83c6dc0e5bbe5ca4 +F src/sqlite.h.in ab77e511620eebbd4ed7e4f52fae697b6870dda66c945acd2d3066f99c98e17e F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 58fd0676d3111d02e62e5a35992a7d3da5d3f88753acc174f2d37b774fbbdd28 F src/sqliteInt.h 6cf244eb06119b44e155717708e54f0638c35e9bd8ef59ea570eb1f093f0da44 @@ -1570,7 +1570,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 9e6c939144a129b36bb119120442a4a021e00187783da211315d4bb13acd7c3a -R 17c5231ecc5d3d35525c3418d3d62ff7 +P ad90e8bb5e47945607c8fb47b6ade8cfc52a9b684805cc40132629be0ecc14cc +R 0da0d3fa99b145cb80d7d7b7e70ff343 U drh -Z d994bdccf4db8bedaee3d7cb7c3b925e +Z 6dd2cf9dfbc2819a60bcde96dd9394fa diff --git a/manifest.uuid b/manifest.uuid index 4c24f5cdfb..912a998fe7 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ad90e8bb5e47945607c8fb47b6ade8cfc52a9b684805cc40132629be0ecc14cc \ No newline at end of file +c5f1a2b6eb3df879d247a22b3f92f4f74fcf4f0d219450abc420ae6d02481324 \ No newline at end of file diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 97294c3f81..d12da51444 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -2211,9 +2211,6 @@ int sqlite3_total_changes(sqlite3*); ** ^A call to sqlite3_interrupt(D) that occurs when there are no running ** SQL statements is a no-op and has no effect on SQL statements ** that are started after the sqlite3_interrupt() call returns. -** -** If the database connection closes while [sqlite3_interrupt()] -** is running then bad things will likely happen. */ void sqlite3_interrupt(sqlite3*); From 50da9382f92bd8f2e1fa5e57c5b212eb63e6ff68 Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 6 Apr 2017 12:06:56 +0000 Subject: [PATCH 19/28] Fix the ".lint fkey" shell tool command so that it works for foreign keys that refer implicitly to primary key columns with non-BINARY default collation sequences. FossilOrigin-Name: 327eff25ba2420267cc8dc49dd3c3aab45f4bf9e060d1ad480e25d016d21f3ba --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/shell.c | 12 ++++++------ test/shell6.test | 14 ++++++++++++++ 4 files changed, 29 insertions(+), 15 deletions(-) diff --git a/manifest b/manifest index ad4644ec59..768c769f24 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\sa\sconfusing\sand\spointless\ssentence\sfrom\sthe\sdocumentation\sfor\sthe\nsqlite3_interrupt()\sinterface. -D 2017-04-05T13:44:40.495 +C Fix\sthe\s".lint\sfkey"\sshell\stool\scommand\sso\sthat\sit\sworks\sfor\sforeign\skeys\sthat\nrefer\simplicitly\sto\sprimary\skey\scolumns\swith\snon-BINARY\sdefault\scollation\nsequences. +D 2017-04-06T12:06:56.710 F Makefile.in 1cc758ce3374a32425e4d130c2fe7b026b20de5b8843243de75f087c0a2661fb F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc a4c0613a18663bda56d8cf76079ab6590a7c3602e54befb4bbdef76bcaa38b6a @@ -402,7 +402,7 @@ F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c 3e518b962d932a997fae373366880fc028c75706 F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c afcf31d8ed7c890328a31d3f350467ccd273af345b24562382b398d6d9cd0664 -F src/shell.c ceb2b2f1f958ea2c47a7f37972d0f715fbf9dcf6a34a5e98c886b85e3ce6a238 +F src/shell.c 358aaf2642749697283969d3287bd1088047b08b3f5b98959aa5d1658e358199 F src/sqlite.h.in ab77e511620eebbd4ed7e4f52fae697b6870dda66c945acd2d3066f99c98e17e F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 58fd0676d3111d02e62e5a35992a7d3da5d3f88753acc174f2d37b774fbbdd28 @@ -1120,7 +1120,7 @@ F test/shell2.test e242a9912f44f4c23c3d1d802a83e934e84c853b F test/shell3.test 9b95ba643eaa228376f06a898fb410ee9b6e57c1 F test/shell4.test 89ad573879a745974ff2df20ff97c5d6ffffbd5d F test/shell5.test 50a732c1c2158b1cd62cf53975ce1ea7ce6b9dc9 -F test/shell6.test cff624fadf71bdb5e3a9b0f86eaf59a43c0622b1 +F test/shell6.test 0abf96c5ba713b6868ba93b9c787d636e9a95b437c7fd410b4c5a0178503f18b F test/shell7.test 07751911b294698e0c5df67bcbd29e7d2f0f2907 F test/shortread1.test bb591ef20f0fd9ed26d0d12e80eee6d7ac8897a3 F test/show_speedtest1_rtree.tcl 32e6c5f073d7426148a6936a0408f4b5b169aba5 @@ -1570,7 +1570,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P ad90e8bb5e47945607c8fb47b6ade8cfc52a9b684805cc40132629be0ecc14cc -R 0da0d3fa99b145cb80d7d7b7e70ff343 -U drh -Z 6dd2cf9dfbc2819a60bcde96dd9394fa +P c5f1a2b6eb3df879d247a22b3f92f4f74fcf4f0d219450abc420ae6d02481324 +R 38865868241e76c5f4d0751e4191f43b +U dan +Z 648bbd72dcc7b5fa391514717251386d diff --git a/manifest.uuid b/manifest.uuid index 912a998fe7..3a5b11b74f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c5f1a2b6eb3df879d247a22b3f92f4f74fcf4f0d219450abc420ae6d02481324 \ No newline at end of file +327eff25ba2420267cc8dc49dd3c3aab45f4bf9e060d1ad480e25d016d21f3ba \ No newline at end of file diff --git a/src/shell.c b/src/shell.c index 1236b12a0e..ab26865f3b 100644 --- a/src/shell.c +++ b/src/shell.c @@ -4331,26 +4331,26 @@ static int lintFkeyIndexes( "SELECT " " 'EXPLAIN QUERY PLAN SELECT rowid FROM ' || quote(s.name) || ' WHERE '" " || group_concat(quote(s.name) || '.' || quote(f.[from]) || '=?' " - " || fkey_collate_clause(f.[table], f.[to], s.name, f.[from]),' AND ')" + " || fkey_collate_clause(" + " f.[table], COALESCE(f.[to], p.[name]), s.name, f.[from]),' AND ')" ", " " 'SEARCH TABLE ' || s.name || ' USING COVERING INDEX*('" " || group_concat('*=?', ' AND ') || ')'" ", " " s.name || '(' || group_concat(f.[from], ', ') || ')'" ", " - " f.[table] || '(' || group_concat(COALESCE(f.[to], " - " (SELECT name FROM pragma_table_info(f.[table]) WHERE pk=seq+1)" - " )) || ')'" + " f.[table] || '(' || group_concat(COALESCE(f.[to], p.[name])) || ')'" ", " " 'CREATE INDEX ' || quote(s.name ||'_'|| group_concat(f.[from], '_'))" " || ' ON ' || quote(s.name) || '('" " || group_concat(quote(f.[from]) ||" - " fkey_collate_clause(f.[table], f.[to], s.name, f.[from]), ', ')" + " fkey_collate_clause(" + " f.[table], COALESCE(f.[to], p.[name]), s.name, f.[from]), ', ')" " || ');'" ", " " f.[table] " - "FROM sqlite_master AS s, pragma_foreign_key_list(s.name) AS f " + "LEFT JOIN pragma_table_info AS p ON (pk-1=seq AND p.arg=f.[table]) " "GROUP BY s.name, f.id " "ORDER BY (CASE WHEN ? THEN f.[table] ELSE s.name END)" ; diff --git a/test/shell6.test b/test/shell6.test index a70c4b4298..d762732d59 100644 --- a/test/shell6.test +++ b/test/shell6.test @@ -73,6 +73,20 @@ foreach {tn schema output} { CREATE INDEX 'y1_a' ON 'y1'('a' COLLATE nocase); --> x1(a) } + 7 { + CREATE TABLE x1(a PRIMARY KEY COLLATE nocase, b); + CREATE TABLE y1(a REFERENCES x1); + } { + CREATE INDEX 'y1_a' ON 'y1'('a' COLLATE nocase); --> x1(a) + } + + 8 { + CREATE TABLE x1(a, b COLLATE nocase, c COLLATE rtrim, PRIMARY KEY(c, b, a)); + CREATE TABLE y1(d, e, f, FOREIGN KEY(d, e, f) REFERENCES x1); + } { + CREATE INDEX 'y1_d_e_f' ON 'y1'('d' COLLATE rtrim, 'e' COLLATE nocase, 'f'); --> x1(c,b,a) + } + } { forcedelete test.db sqlite3 db test.db From 54e2efcd2f8fcf07cc796b0881d4ac5b29d7d474 Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 6 Apr 2017 14:56:26 +0000 Subject: [PATCH 20/28] Fix the ".lint fkey" shell command for cases where the child key is also an INTEGER PRIMARY KEY. FossilOrigin-Name: 48826b222c110a90996a84605318ea6b1e502b8c5129f4d561f8350dbdbcd264 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/shell.c | 6 +++++- test/shell6.test | 6 ++++++ 4 files changed, 19 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 768c769f24..50c2d8faef 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sthe\s".lint\sfkey"\sshell\stool\scommand\sso\sthat\sit\sworks\sfor\sforeign\skeys\sthat\nrefer\simplicitly\sto\sprimary\skey\scolumns\swith\snon-BINARY\sdefault\scollation\nsequences. -D 2017-04-06T12:06:56.710 +C Fix\sthe\s".lint\sfkey"\sshell\scommand\sfor\scases\swhere\sthe\schild\skey\sis\salso\san\nINTEGER\sPRIMARY\sKEY. +D 2017-04-06T14:56:26.887 F Makefile.in 1cc758ce3374a32425e4d130c2fe7b026b20de5b8843243de75f087c0a2661fb F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc a4c0613a18663bda56d8cf76079ab6590a7c3602e54befb4bbdef76bcaa38b6a @@ -402,7 +402,7 @@ F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c 3e518b962d932a997fae373366880fc028c75706 F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c afcf31d8ed7c890328a31d3f350467ccd273af345b24562382b398d6d9cd0664 -F src/shell.c 358aaf2642749697283969d3287bd1088047b08b3f5b98959aa5d1658e358199 +F src/shell.c e9fede684f847402c0373fe5e270918e6ef47f51e57ba5aebff121d8c2bc1ea8 F src/sqlite.h.in ab77e511620eebbd4ed7e4f52fae697b6870dda66c945acd2d3066f99c98e17e F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 58fd0676d3111d02e62e5a35992a7d3da5d3f88753acc174f2d37b774fbbdd28 @@ -1120,7 +1120,7 @@ F test/shell2.test e242a9912f44f4c23c3d1d802a83e934e84c853b F test/shell3.test 9b95ba643eaa228376f06a898fb410ee9b6e57c1 F test/shell4.test 89ad573879a745974ff2df20ff97c5d6ffffbd5d F test/shell5.test 50a732c1c2158b1cd62cf53975ce1ea7ce6b9dc9 -F test/shell6.test 0abf96c5ba713b6868ba93b9c787d636e9a95b437c7fd410b4c5a0178503f18b +F test/shell6.test ab1592ebe881371f651f18ee6a0df21cbfb5310f88cb832ab642d4038f679772 F test/shell7.test 07751911b294698e0c5df67bcbd29e7d2f0f2907 F test/shortread1.test bb591ef20f0fd9ed26d0d12e80eee6d7ac8897a3 F test/show_speedtest1_rtree.tcl 32e6c5f073d7426148a6936a0408f4b5b169aba5 @@ -1570,7 +1570,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P c5f1a2b6eb3df879d247a22b3f92f4f74fcf4f0d219450abc420ae6d02481324 -R 38865868241e76c5f4d0751e4191f43b +P 327eff25ba2420267cc8dc49dd3c3aab45f4bf9e060d1ad480e25d016d21f3ba +R 260410c30d599e0993c58e23cef69640 U dan -Z 648bbd72dcc7b5fa391514717251386d +Z 25db1dc906fb1b522f7b655980ddd579 diff --git a/manifest.uuid b/manifest.uuid index 3a5b11b74f..3814e9cddf 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -327eff25ba2420267cc8dc49dd3c3aab45f4bf9e060d1ad480e25d016d21f3ba \ No newline at end of file +48826b222c110a90996a84605318ea6b1e502b8c5129f4d561f8350dbdbcd264 \ No newline at end of file diff --git a/src/shell.c b/src/shell.c index ab26865f3b..b28a1421d3 100644 --- a/src/shell.c +++ b/src/shell.c @@ -4354,6 +4354,7 @@ static int lintFkeyIndexes( "GROUP BY s.name, f.id " "ORDER BY (CASE WHEN ? THEN f.[table] ELSE s.name END)" ; + const char *zGlobIPK = "SEARCH TABLE * USING INTEGER PRIMARY KEY (rowid=?)"; for(i=2; i x1(c,b,a) } + 9 { + CREATE TABLE p1(a, b UNIQUE); + CREATE TABLE c1(x INTEGER PRIMARY KEY REFERENCES p1(b)); + } { + } + } { forcedelete test.db sqlite3 db test.db From 6193d49cdf063444cd1d0c0bfa64e4569a8353be Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 7 Apr 2017 11:45:58 +0000 Subject: [PATCH 21/28] Use replace() instead of char() to quote newline and return characters in strings in the output of .dump, to avoid excess expression complexity. FossilOrigin-Name: 4c2b572969ea2ed2a925444ecfa356aa877018cbb9c4f57d081ab4b535cd1dd0 --- manifest | 17 +++++++------ manifest.uuid | 2 +- src/shell.c | 69 +++++++++++++++++++++++++++++++++++++-------------- 3 files changed, 62 insertions(+), 26 deletions(-) diff --git a/manifest b/manifest index 50c2d8faef..58a053dc81 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sthe\s".lint\sfkey"\sshell\scommand\sfor\scases\swhere\sthe\schild\skey\sis\salso\san\nINTEGER\sPRIMARY\sKEY. -D 2017-04-06T14:56:26.887 +C Use\sreplace()\sinstead\sof\schar()\sto\squote\snewline\sand\sreturn\scharacters\sin\nstrings\sin\sthe\soutput\sof\s.dump,\sto\savoid\sexcess\sexpression\scomplexity. +D 2017-04-07T11:45:58.111 F Makefile.in 1cc758ce3374a32425e4d130c2fe7b026b20de5b8843243de75f087c0a2661fb F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc a4c0613a18663bda56d8cf76079ab6590a7c3602e54befb4bbdef76bcaa38b6a @@ -402,7 +402,7 @@ F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c 3e518b962d932a997fae373366880fc028c75706 F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c afcf31d8ed7c890328a31d3f350467ccd273af345b24562382b398d6d9cd0664 -F src/shell.c e9fede684f847402c0373fe5e270918e6ef47f51e57ba5aebff121d8c2bc1ea8 +F src/shell.c 3680725485ce5022dc683d593e8a4b95f973597d843ddb8be788d7dc24d16de9 F src/sqlite.h.in ab77e511620eebbd4ed7e4f52fae697b6870dda66c945acd2d3066f99c98e17e F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 58fd0676d3111d02e62e5a35992a7d3da5d3f88753acc174f2d37b774fbbdd28 @@ -1570,7 +1570,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 327eff25ba2420267cc8dc49dd3c3aab45f4bf9e060d1ad480e25d016d21f3ba -R 260410c30d599e0993c58e23cef69640 -U dan -Z 25db1dc906fb1b522f7b655980ddd579 +P 48826b222c110a90996a84605318ea6b1e502b8c5129f4d561f8350dbdbcd264 +R 33164644836f84aff2e4df2bff5189e1 +T *branch * shell-fix +T *sym-shell-fix * +T -sym-trunk * +U drh +Z d4f7ac77bbed43ce1dcbcb86734fd32f diff --git a/manifest.uuid b/manifest.uuid index 3814e9cddf..258bb7d642 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -48826b222c110a90996a84605318ea6b1e502b8c5129f4d561f8350dbdbcd264 \ No newline at end of file +4c2b572969ea2ed2a925444ecfa356aa877018cbb9c4f57d081ab4b535cd1dd0 \ No newline at end of file diff --git a/src/shell.c b/src/shell.c index b28a1421d3..5562fd61c2 100644 --- a/src/shell.c +++ b/src/shell.c @@ -1488,6 +1488,27 @@ static void output_hex_blob(FILE *out, const void *pBlob, int nBlob){ raw_printf(out,"'"); } +/* +** Find a string that is not found anywhere in z[]. Return a pointer +** to that string. +** +** Try to use zA and zB first. If both of those are already found in z[] +** then make up some string and store it in the buffer zBuf. +*/ +static const char *unused_string( + const char *z, /* Result must not appear anywhere in z */ + const char *zA, const char *zB, /* Try these first */ + char *zBuf /* Space to store a generated string */ +){ + unsigned i = 0; + if( strstr(z, zA)==0 ) return zA; + if( strstr(z, zB)==0 ) return zB; + do{ + sqlite3_snprintf(20,zBuf,"(%s%u)", zA, i++); + }while( strstr(z,zBuf)!=0 ); + return zBuf; +} + /* ** Output the given string as a quoted string using SQL quoting conventions. ** @@ -1502,40 +1523,52 @@ static void output_quoted_string(FILE *out, const char *z){ if( c==0 ){ utf8_printf(out,"'%s'",z); }else{ - int inQuote = 0; - int bStarted = 0; + const char *zNL = 0; + const char *zCR = 0; + int nNL = 0; + int nCR = 0; + char zBuf1[20], zBuf2[20]; + for(i=0; z[i]; i++){ + if( z[i]=='\n' ) nNL++; + if( z[i]=='\r' ) nCR++; + } + if( nNL ){ + raw_printf(out, "replace("); + zNL = unused_string(z, "\\n", "\\012", zBuf1); + } + if( nCR ){ + raw_printf(out, "replace("); + zCR = unused_string(z, "\\r", "\\015", zBuf2); + } + raw_printf(out, "'"); while( *z ){ for(i=0; (c = z[i])!=0 && c!='\n' && c!='\r' && c!='\''; i++){} if( c=='\'' ) i++; if( i ){ - if( !inQuote ){ - if( bStarted ) raw_printf(out, "||"); - raw_printf(out, "'"); - inQuote = 1; - } utf8_printf(out, "%.*s", i, z); z += i; - bStarted = 1; } if( c=='\'' ){ raw_printf(out, "'"); continue; } - if( inQuote ){ - raw_printf(out, "'"); - inQuote = 0; - } if( c==0 ){ break; } - for(i=0; (c = z[i])=='\r' || c=='\n'; i++){ - if( bStarted ) raw_printf(out, "||"); - raw_printf(out, "char(%d)", c); - bStarted = 1; + z++; + if( c=='\n' ){ + raw_printf(out, "%s", zNL); + continue; } - z += i; + raw_printf(out, "%s", zCR); + } + raw_printf(out, "'"); + if( nCR ){ + raw_printf(out, ",'%s',char(13))", zCR); + } + if( nNL ){ + raw_printf(out, ",'%s',char(10))", zNL); } - if( inQuote ) raw_printf(out, "'"); } setTextMode(out, 1); } From 72507d431b2a25a574b340d8f05f379922b360d5 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 8 Apr 2017 00:55:13 +0000 Subject: [PATCH 22/28] Fix the ".dump" command so that it works with ".headers on". Also fix the display of ".mode insert" with ".headers on". FossilOrigin-Name: a6ce57ee3c7f3527554a75cc1dd5ebcd33c944d4dca07b134d103596a2ae5b32 --- manifest | 13 ++++++------- manifest.uuid | 2 +- src/shell.c | 13 +++++++++++-- 3 files changed, 18 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 17be6d0663..4e3b8e1575 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Use\sreplace()\sinstead\sof\schar()\sto\squote\snewline\sand\sreturn\scharacters\sin\nstrings\sin\sthe\soutput\sof\s.dump,\sto\savoid\sexcess\sexpression\scomplexity. -D 2017-04-07T20:20:08.441 +C Fix\sthe\s".dump"\scommand\sso\sthat\sit\sworks\swith\s".headers\son".\s\sAlso\sfix\sthe\ndisplay\sof\s".mode\sinsert"\swith\s".headers\son". +D 2017-04-08T00:55:13.524 F Makefile.in 1cc758ce3374a32425e4d130c2fe7b026b20de5b8843243de75f087c0a2661fb F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc a4c0613a18663bda56d8cf76079ab6590a7c3602e54befb4bbdef76bcaa38b6a @@ -402,7 +402,7 @@ F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c 3e518b962d932a997fae373366880fc028c75706 F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c afcf31d8ed7c890328a31d3f350467ccd273af345b24562382b398d6d9cd0664 -F src/shell.c 3680725485ce5022dc683d593e8a4b95f973597d843ddb8be788d7dc24d16de9 +F src/shell.c 13512de3e9862c1c2df0b034b1f54810e0b885fcf25475b7c61b7e7ef0a28d33 F src/sqlite.h.in ab77e511620eebbd4ed7e4f52fae697b6870dda66c945acd2d3066f99c98e17e F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 58fd0676d3111d02e62e5a35992a7d3da5d3f88753acc174f2d37b774fbbdd28 @@ -1570,8 +1570,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 48826b222c110a90996a84605318ea6b1e502b8c5129f4d561f8350dbdbcd264 4c2b572969ea2ed2a925444ecfa356aa877018cbb9c4f57d081ab4b535cd1dd0 -R 33164644836f84aff2e4df2bff5189e1 -T +closed 4c2b572969ea2ed2a925444ecfa356aa877018cbb9c4f57d081ab4b535cd1dd0 +P 7307352988174a6c2756dbbe200bf62a45fb4cc1da7faa2c6b0f75e229eab703 +R c90966020932134529ac766bef984a02 U drh -Z b74a0247eea28681dd3f2667b402dd90 +Z e8c368ee65564e309cb032faeb68575a diff --git a/manifest.uuid b/manifest.uuid index 35e56e96e3..53d4b77bf8 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7307352988174a6c2756dbbe200bf62a45fb4cc1da7faa2c6b0f75e229eab703 \ No newline at end of file +a6ce57ee3c7f3527554a75cc1dd5ebcd33c944d4dca07b134d103596a2ae5b32 \ No newline at end of file diff --git a/src/shell.c b/src/shell.c index 5562fd61c2..9ddd11706d 100644 --- a/src/shell.c +++ b/src/shell.c @@ -2039,8 +2039,14 @@ static int shell_callback( if( p->showHeader ){ raw_printf(p->out,"("); for(i=0; i0 ? ",": ""; - utf8_printf(p->out, "%s%s", zSep, azCol[i]); + if( i>0 ) raw_printf(p->out, ","); + if( quoteChar(azCol[i]) ){ + char *z = sqlite3_mprintf("\"%w\"", azCol[i]); + utf8_printf(p->out, "%s", z); + sqlite3_free(z); + }else{ + raw_printf(p->out, "%s", azCol[i]); + } } raw_printf(p->out,")"); } @@ -4717,6 +4723,7 @@ static int do_meta_command(char *zLine, ShellState *p){ if( c=='d' && strncmp(azArg[0], "dump", n)==0 ){ const char *zLike = 0; int i; + int savedShowHeader = p->showHeader; ShellClearFlag(p, SHFLG_PreserveRowid); for(i=1; iout, "PRAGMA foreign_keys=OFF;\n"); raw_printf(p->out, "BEGIN TRANSACTION;\n"); p->writableSchema = 0; + p->showHeader = 0; /* Set writable_schema=ON since doing so forces SQLite to initialize ** as much of the schema as it can even if the sqlite_master table is ** corrupt. */ @@ -4793,6 +4801,7 @@ static int do_meta_command(char *zLine, ShellState *p){ sqlite3_exec(p->db, "PRAGMA writable_schema=OFF;", 0, 0, 0); sqlite3_exec(p->db, "RELEASE dump;", 0, 0, 0); raw_printf(p->out, p->nErr ? "ROLLBACK; -- due to errors\n" : "COMMIT;\n"); + p->showHeader = savedShowHeader; }else if( c=='e' && strncmp(azArg[0], "echo", n)==0 ){ From 297e2bdb8ebaf12f1357f4852f5af6ee3f4978eb Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 8 Apr 2017 01:09:14 +0000 Subject: [PATCH 23/28] Make sure the RTree sqlite3_blob handle is reset prior to renaming the table. FossilOrigin-Name: 1cdae2db3c54970a1811e597065724578408c84d49d75b8fe25d56281ddc2e94 --- ext/rtree/rtree.c | 1 + manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/ext/rtree/rtree.c b/ext/rtree/rtree.c index 42f08a9628..cf233b5d77 100644 --- a/ext/rtree/rtree.c +++ b/ext/rtree/rtree.c @@ -3198,6 +3198,7 @@ static int rtreeRename(sqlite3_vtab *pVtab, const char *zNewName){ , pRtree->zDb, pRtree->zName, zNewName ); if( zSql ){ + nodeBlobReset(pRtree); rc = sqlite3_exec(pRtree->db, zSql, 0, 0, 0); sqlite3_free(zSql); } diff --git a/manifest b/manifest index 4e3b8e1575..1daa23aa3b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sthe\s".dump"\scommand\sso\sthat\sit\sworks\swith\s".headers\son".\s\sAlso\sfix\sthe\ndisplay\sof\s".mode\sinsert"\swith\s".headers\son". -D 2017-04-08T00:55:13.524 +C Make\ssure\sthe\sRTree\ssqlite3_blob\shandle\sis\sreset\sprior\sto\srenaming\sthe\stable. +D 2017-04-08T01:09:14.963 F Makefile.in 1cc758ce3374a32425e4d130c2fe7b026b20de5b8843243de75f087c0a2661fb F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc a4c0613a18663bda56d8cf76079ab6590a7c3602e54befb4bbdef76bcaa38b6a @@ -271,7 +271,7 @@ F ext/rbu/sqlite3rbu.c 2a89efba9eeba8e6c89a498dc195e8efbdde2694 F ext/rbu/sqlite3rbu.h 6fb6294c34a9ca93b5894a33bca530c6f08decba F ext/rbu/test_rbu.c 5aa22616afac6f71ebd3d9bc9bf1006cfabcca88 F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761 -F ext/rtree/rtree.c 0acd285bfacc347579a5df9fe947212fb99e2775a40c43f027c3a16936c58e7e +F ext/rtree/rtree.c fb7c0e62ccbbbd6951ddb1f52feaa2c1a53b7ac1c6f2d5d5e2bbd31c33e57186 F ext/rtree/rtree.h 834dbcb82dc85b2481cde6a07cdadfddc99e9b9e F ext/rtree/rtree1.test 42dadfc7b44a436cd74a1bebc0b9b689e4eaf7ec F ext/rtree/rtree2.test acbb3a4ce0f4fbc2c304d2b4b784cfa161856bba @@ -1570,7 +1570,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 7307352988174a6c2756dbbe200bf62a45fb4cc1da7faa2c6b0f75e229eab703 -R c90966020932134529ac766bef984a02 +P a6ce57ee3c7f3527554a75cc1dd5ebcd33c944d4dca07b134d103596a2ae5b32 +R 3c395c133d10b004a02ebb26bdf0b765 U drh -Z e8c368ee65564e309cb032faeb68575a +Z 01dd2f30379ae3acc62144bb2fdec0d4 diff --git a/manifest.uuid b/manifest.uuid index 53d4b77bf8..2ca0677bc2 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a6ce57ee3c7f3527554a75cc1dd5ebcd33c944d4dca07b134d103596a2ae5b32 \ No newline at end of file +1cdae2db3c54970a1811e597065724578408c84d49d75b8fe25d56281ddc2e94 \ No newline at end of file From be0bc8bb4d32412db9447d193987e360d6eb23f8 Mon Sep 17 00:00:00 2001 From: dan Date: Sat, 8 Apr 2017 09:12:20 +0000 Subject: [PATCH 24/28] Have fts5 close any open blob-handle when a new savepoint is opened. This ensures that fts5 does not prevent DROP TABLE statements (which always open a savepoint) from succeeding. FossilOrigin-Name: a921ada89050ce1d162fd1b0056939573635e2cec7ac0c2a99ae924b3ae593f7 --- ext/fts5/fts5Int.h | 6 +++--- ext/fts5/fts5_index.c | 5 ++--- ext/fts5/fts5_main.c | 6 +++--- ext/fts5/fts5_storage.c | 8 ++++---- ext/fts5/test/fts5aa.test | 16 ++++++++++++++++ manifest | 22 +++++++++++----------- manifest.uuid | 2 +- 7 files changed, 40 insertions(+), 25 deletions(-) diff --git a/ext/fts5/fts5Int.h b/ext/fts5/fts5Int.h index d350856573..83e5238b48 100644 --- a/ext/fts5/fts5Int.h +++ b/ext/fts5/fts5Int.h @@ -446,9 +446,9 @@ int sqlite3Fts5IndexBeginWrite( /* ** Flush any data stored in the in-memory hash tables to the database. -** If the bCommit flag is true, also close any open blob handles. +** Also close any open blob handles. */ -int sqlite3Fts5IndexSync(Fts5Index *p, int bCommit); +int sqlite3Fts5IndexSync(Fts5Index *p); /* ** Discard any data stored in the in-memory hash tables. Do not write it @@ -618,7 +618,7 @@ int sqlite3Fts5StorageDocsize(Fts5Storage *p, i64 iRowid, int *aCol); int sqlite3Fts5StorageSize(Fts5Storage *p, int iCol, i64 *pnAvg); int sqlite3Fts5StorageRowCount(Fts5Storage *p, i64 *pnRow); -int sqlite3Fts5StorageSync(Fts5Storage *p, int bCommit); +int sqlite3Fts5StorageSync(Fts5Storage *p); int sqlite3Fts5StorageRollback(Fts5Storage *p); int sqlite3Fts5StorageConfigValue( diff --git a/ext/fts5/fts5_index.c b/ext/fts5/fts5_index.c index 750e0ca82d..27e28a84ab 100644 --- a/ext/fts5/fts5_index.c +++ b/ext/fts5/fts5_index.c @@ -628,7 +628,6 @@ static void fts5CloseReader(Fts5Index *p){ } } - /* ** Retrieve a record from the %_data table. ** @@ -5131,10 +5130,10 @@ int sqlite3Fts5IndexBeginWrite(Fts5Index *p, int bDelete, i64 iRowid){ /* ** Commit data to disk. */ -int sqlite3Fts5IndexSync(Fts5Index *p, int bCommit){ +int sqlite3Fts5IndexSync(Fts5Index *p){ assert( p->rc==SQLITE_OK ); fts5IndexFlush(p); - if( bCommit ) fts5CloseReader(p); + fts5CloseReader(p); return fts5IndexReturn(p); } diff --git a/ext/fts5/fts5_main.c b/ext/fts5/fts5_main.c index 384d3dd8f7..d20cb7ea39 100644 --- a/ext/fts5/fts5_main.c +++ b/ext/fts5/fts5_main.c @@ -1579,7 +1579,7 @@ static int fts5SyncMethod(sqlite3_vtab *pVtab){ fts5CheckTransactionState(pTab, FTS5_SYNC, 0); pTab->pConfig->pzErrmsg = &pTab->base.zErrMsg; fts5TripCursors(pTab); - rc = sqlite3Fts5StorageSync(pTab->pStorage, 1); + rc = sqlite3Fts5StorageSync(pTab->pStorage); pTab->pConfig->pzErrmsg = 0; return rc; } @@ -2390,7 +2390,7 @@ static int fts5SavepointMethod(sqlite3_vtab *pVtab, int iSavepoint){ UNUSED_PARAM(iSavepoint); /* Call below is a no-op for NDEBUG builds */ fts5CheckTransactionState(pTab, FTS5_SAVEPOINT, iSavepoint); fts5TripCursors(pTab); - return sqlite3Fts5StorageSync(pTab->pStorage, 0); + return sqlite3Fts5StorageSync(pTab->pStorage); } /* @@ -2403,7 +2403,7 @@ static int fts5ReleaseMethod(sqlite3_vtab *pVtab, int iSavepoint){ UNUSED_PARAM(iSavepoint); /* Call below is a no-op for NDEBUG builds */ fts5CheckTransactionState(pTab, FTS5_RELEASE, iSavepoint); fts5TripCursors(pTab); - return sqlite3Fts5StorageSync(pTab->pStorage, 0); + return sqlite3Fts5StorageSync(pTab->pStorage); } /* diff --git a/ext/fts5/fts5_storage.c b/ext/fts5/fts5_storage.c index c8c26bd1b6..ee099154cb 100644 --- a/ext/fts5/fts5_storage.c +++ b/ext/fts5/fts5_storage.c @@ -218,7 +218,7 @@ static void fts5StorageRenameOne( int sqlite3Fts5StorageRename(Fts5Storage *pStorage, const char *zName){ Fts5Config *pConfig = pStorage->pConfig; - int rc = sqlite3Fts5StorageSync(pStorage, 1); + int rc = sqlite3Fts5StorageSync(pStorage); fts5StorageRenameOne(pConfig, &rc, "data", zName); fts5StorageRenameOne(pConfig, &rc, "idx", zName); @@ -1081,15 +1081,15 @@ int sqlite3Fts5StorageRowCount(Fts5Storage *p, i64 *pnRow){ /* ** Flush any data currently held in-memory to disk. */ -int sqlite3Fts5StorageSync(Fts5Storage *p, int bCommit){ +int sqlite3Fts5StorageSync(Fts5Storage *p){ int rc = SQLITE_OK; i64 iLastRowid = sqlite3_last_insert_rowid(p->pConfig->db); if( p->bTotalsValid ){ rc = fts5StorageSaveTotals(p); - if( bCommit ) p->bTotalsValid = 0; + p->bTotalsValid = 0; } if( rc==SQLITE_OK ){ - rc = sqlite3Fts5IndexSync(p->pIndex, bCommit); + rc = sqlite3Fts5IndexSync(p->pIndex); } sqlite3_set_last_insert_rowid(p->pConfig->db, iLastRowid); return rc; diff --git a/ext/fts5/test/fts5aa.test b/ext/fts5/test/fts5aa.test index 428ca6c1ea..9a95d81cfb 100644 --- a/ext/fts5/test/fts5aa.test +++ b/ext/fts5/test/fts5aa.test @@ -561,6 +561,22 @@ do_test 20.1 { execsql { SELECT rowid FROM tmp WHERE tmp MATCH 'y' } } $::ids +#-------------------------------------------------------------------- +# Test that a DROP TABLE may be executed within a transaction that +# writes to an FTS5 table. +# +do_execsql_test 21.0 { + CREATE TEMP TABLE t8(a, b); + CREATE VIRTUAL TABLE ft USING fts5(x, detail=%DETAIL%); +} + +do_execsql_test 21.1 { + BEGIN; + INSERT INTO ft VALUES('a b c'); + DROP TABLE t8; + COMMIT; +} + } diff --git a/manifest b/manifest index 1daa23aa3b..847f11c335 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Make\ssure\sthe\sRTree\ssqlite3_blob\shandle\sis\sreset\sprior\sto\srenaming\sthe\stable. -D 2017-04-08T01:09:14.963 +C Have\sfts5\sclose\sany\sopen\sblob-handle\swhen\sa\snew\ssavepoint\sis\sopened.\sThis\nensures\sthat\sfts5\sdoes\snot\sprevent\sDROP\sTABLE\sstatements\s(which\salways\sopen\sa\nsavepoint)\sfrom\ssucceeding. +D 2017-04-08T09:12:20.282 F Makefile.in 1cc758ce3374a32425e4d130c2fe7b026b20de5b8843243de75f087c0a2661fb F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc a4c0613a18663bda56d8cf76079ab6590a7c3602e54befb4bbdef76bcaa38b6a @@ -99,15 +99,15 @@ F ext/fts3/unicode/mkunicode.tcl ab0543a3b2399092ea2dd75df1bef333405b0d7f6b8c495 F ext/fts3/unicode/parseunicode.tcl da577d1384810fb4e2b209bf3313074353193e95 F ext/fts5/extract_api_docs.tcl a36e54ec777172ddd3f9a88daf593b00848368e0 F ext/fts5/fts5.h 62f3e33ceeb9a428db139f9c012186b371da1cc7 -F ext/fts5/fts5Int.h c629b24d2b92b99596f3b8e82289fddca06df6e1 +F ext/fts5/fts5Int.h 88c1a9a01cd5cd7b9a3c95699d1f61cdb277b2fa087a07d3fc989b49970437d9 F ext/fts5/fts5_aux.c 67acf8d51723cf28ffc3828210ba662df4b8d267 F ext/fts5/fts5_buffer.c 4c1502d4c956cd092c89ce4480867f9d8bf325cd F ext/fts5/fts5_config.c 5af9c360e99669d29f06492c370892394aba0857 F ext/fts5/fts5_expr.c c6ecc2280162a3714d15dce2a8f2299f748b627c F ext/fts5/fts5_hash.c 880998e596b60f078348d48732ca4ad9a90caad2 -F ext/fts5/fts5_index.c f67032a9a529ba52a545e6e3ab970764199c05d4 -F ext/fts5/fts5_main.c f85281445dcf8be32d18841c93a6f90fe27dbfe2 -F ext/fts5/fts5_storage.c 8f0e65cb33bde8f449e1c9b4be4600d18b4da6e9 +F ext/fts5/fts5_index.c a3a9ae1c6f8a3652eb45dd732a71cdc92b48df047af134da38cd0c425649e042 +F ext/fts5/fts5_main.c 24cafdc44c06b9665d73c34b75966f6223e9299cc9fd10184c6bf888e3ff563f +F ext/fts5/fts5_storage.c 7750986004f3f0c94619a85ecb5dd6cbef53e5e3853488e8a906c269d4d11db6 F ext/fts5/fts5_tcl.c 4a901f00c8553740dba63511603f5527d741c26a F ext/fts5/fts5_test_mi.c 783b86697ebf773c18fc109992426c0173a055bc F ext/fts5/fts5_test_tok.c db08af63673c3a7d39f053b36fd6e065017706be @@ -118,7 +118,7 @@ F ext/fts5/fts5_vocab.c e44fefa7f0c1db252998af071daf06a7147e17e7 F ext/fts5/fts5parse.y e51b375403421b8b37428a89b095d00597129aae F ext/fts5/mkportersteps.tcl 5acf962d2e0074f701620bb5308155fa1e4a63ba F ext/fts5/test/fts5_common.tcl b01c584144b5064f30e6c648145a2dd6bc440841 -F ext/fts5/test/fts5aa.test bd2d88182b9f7f30d300044048ad14683306b745 +F ext/fts5/test/fts5aa.test b3cb080db4851580705c5e261c9d4308edf030d5cbbc24b5d6668403b73f023b F ext/fts5/test/fts5ab.test 30325a89453280160106be411bba3acf138e6d1b F ext/fts5/test/fts5ac.test 55cad4275a1f5acabfe14d8442a8046b47e49e5f F ext/fts5/test/fts5ad.test 36995f0586f30f5602074e012b9224c71ec5171c @@ -1570,7 +1570,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P a6ce57ee3c7f3527554a75cc1dd5ebcd33c944d4dca07b134d103596a2ae5b32 -R 3c395c133d10b004a02ebb26bdf0b765 -U drh -Z 01dd2f30379ae3acc62144bb2fdec0d4 +P 1cdae2db3c54970a1811e597065724578408c84d49d75b8fe25d56281ddc2e94 +R 70601a411a243bcad4990e39c82ee1af +U dan +Z dfa6c73936264c9fbb94dc8123013fe7 diff --git a/manifest.uuid b/manifest.uuid index 2ca0677bc2..9f89285dde 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1cdae2db3c54970a1811e597065724578408c84d49d75b8fe25d56281ddc2e94 \ No newline at end of file +a921ada89050ce1d162fd1b0056939573635e2cec7ac0c2a99ae924b3ae593f7 \ No newline at end of file From 13fe138b0a4af0c9fbc102f5d962ffc8d989ed06 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 8 Apr 2017 13:42:55 +0000 Subject: [PATCH 25/28] Fix the quoting mechanism for ".dump" so that it is not applied for the ".mode quote" output. FossilOrigin-Name: 78c1e90305d48917d9423d8e50a7dfd15ec27aa93cb421610062229c7ede13a6 --- manifest | 14 +++--- manifest.uuid | 2 +- src/shell.c | 117 ++++++++++++++++++++++++++++++++++++++------------ 3 files changed, 97 insertions(+), 36 deletions(-) diff --git a/manifest b/manifest index 847f11c335..999a8ca810 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Have\sfts5\sclose\sany\sopen\sblob-handle\swhen\sa\snew\ssavepoint\sis\sopened.\sThis\nensures\sthat\sfts5\sdoes\snot\sprevent\sDROP\sTABLE\sstatements\s(which\salways\sopen\sa\nsavepoint)\sfrom\ssucceeding. -D 2017-04-08T09:12:20.282 +C Fix\sthe\squoting\smechanism\sfor\s".dump"\sso\sthat\sit\sis\snot\sapplied\sfor\sthe\n".mode\squote"\soutput. +D 2017-04-08T13:42:55.616 F Makefile.in 1cc758ce3374a32425e4d130c2fe7b026b20de5b8843243de75f087c0a2661fb F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc a4c0613a18663bda56d8cf76079ab6590a7c3602e54befb4bbdef76bcaa38b6a @@ -402,7 +402,7 @@ F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c 3e518b962d932a997fae373366880fc028c75706 F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c afcf31d8ed7c890328a31d3f350467ccd273af345b24562382b398d6d9cd0664 -F src/shell.c 13512de3e9862c1c2df0b034b1f54810e0b885fcf25475b7c61b7e7ef0a28d33 +F src/shell.c 70f4957b988572315e97c56941fdc81fd35907fee36b7b2e7be5ec4c7e9d065d F src/sqlite.h.in ab77e511620eebbd4ed7e4f52fae697b6870dda66c945acd2d3066f99c98e17e F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 58fd0676d3111d02e62e5a35992a7d3da5d3f88753acc174f2d37b774fbbdd28 @@ -1570,7 +1570,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 1cdae2db3c54970a1811e597065724578408c84d49d75b8fe25d56281ddc2e94 -R 70601a411a243bcad4990e39c82ee1af -U dan -Z dfa6c73936264c9fbb94dc8123013fe7 +P a921ada89050ce1d162fd1b0056939573635e2cec7ac0c2a99ae924b3ae593f7 +R 82737b36216e366238632e12de53d03d +U drh +Z 97234581d28b10577d1d04c415271f72 diff --git a/manifest.uuid b/manifest.uuid index 9f89285dde..e318e00b25 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a921ada89050ce1d162fd1b0056939573635e2cec7ac0c2a99ae924b3ae593f7 \ No newline at end of file +78c1e90305d48917d9423d8e50a7dfd15ec27aa93cb421610062229c7ede13a6 \ No newline at end of file diff --git a/src/shell.c b/src/shell.c index 9ddd11706d..8341d828c1 100644 --- a/src/shell.c +++ b/src/shell.c @@ -1512,10 +1512,48 @@ static const char *unused_string( /* ** Output the given string as a quoted string using SQL quoting conventions. ** -** The "\n" and "\r" characters are converted to char(10) and char(13) -** to prevent them from being transformed by end-of-line translators. +** See also: output_quoted_escaped_string() */ static void output_quoted_string(FILE *out, const char *z){ + int i; + char c; + setBinaryMode(out, 1); + for(i=0; (c = z[i])!=0 && c!='\''; i++){} + if( c==0 ){ + utf8_printf(out,"'%s'",z); + }else{ + raw_printf(out, "'"); + while( *z ){ + for(i=0; (c = z[i])!=0 && c!='\''; i++){} + if( c=='\'' ) i++; + if( i ){ + utf8_printf(out, "%.*s", i, z); + z += i; + } + if( c=='\'' ){ + raw_printf(out, "'"); + continue; + } + if( c==0 ){ + break; + } + z++; + } + raw_printf(out, "'"); + } + setTextMode(out, 1); +} + +/* +** Output the given string as a quoted string using SQL quoting conventions. +** Additionallly , escape the "\n" and "\r" characters so that they do not +** get corrupted by end-of-line translation facilities in some operating +** systems. +** +** This is like output_quoted_string() but with the addition of the \r\n +** escape mechanism. +*/ +static void output_quoted_escaped_string(FILE *out, const char *z){ int i; char c; setBinaryMode(out, 1); @@ -2031,27 +2069,53 @@ static int shell_callback( setTextMode(p->out, 1); break; } - case MODE_Quote: case MODE_Insert: { if( azArg==0 ) break; - if( p->cMode==MODE_Insert ){ - utf8_printf(p->out,"INSERT INTO %s",p->zDestTable); - if( p->showHeader ){ - raw_printf(p->out,"("); - for(i=0; i0 ) raw_printf(p->out, ","); - if( quoteChar(azCol[i]) ){ - char *z = sqlite3_mprintf("\"%w\"", azCol[i]); - utf8_printf(p->out, "%s", z); - sqlite3_free(z); - }else{ - raw_printf(p->out, "%s", azCol[i]); - } + utf8_printf(p->out,"INSERT INTO %s",p->zDestTable); + if( p->showHeader ){ + raw_printf(p->out,"("); + for(i=0; i0 ) raw_printf(p->out, ","); + if( quoteChar(azCol[i]) ){ + char *z = sqlite3_mprintf("\"%w\"", azCol[i]); + utf8_printf(p->out, "%s", z); + sqlite3_free(z); + }else{ + raw_printf(p->out, "%s", azCol[i]); } - raw_printf(p->out,")"); } - raw_printf(p->out," VALUES("); - }else if( p->cnt==0 && p->showHeader ){ + raw_printf(p->out,")"); + } + p->cnt++; + for(i=0; iout, i>0 ? "," : " VALUES("); + if( (azArg[i]==0) || (aiType && aiType[i]==SQLITE_NULL) ){ + utf8_printf(p->out,"NULL"); + }else if( aiType && aiType[i]==SQLITE_TEXT ){ + output_quoted_escaped_string(p->out, azArg[i]); + }else if( aiType && aiType[i]==SQLITE_INTEGER ){ + utf8_printf(p->out,"%s", azArg[i]); + }else if( aiType && aiType[i]==SQLITE_FLOAT ){ + char z[50]; + double r = sqlite3_column_double(p->pStmt, i); + sqlite3_snprintf(50,z,"%!.20g", r); + raw_printf(p->out, "%s", z); + }else if( aiType && aiType[i]==SQLITE_BLOB && p->pStmt ){ + const void *pBlob = sqlite3_column_blob(p->pStmt, i); + int nBlob = sqlite3_column_bytes(p->pStmt, i); + output_hex_blob(p->out, pBlob, nBlob); + }else if( isNumber(azArg[i], 0) ){ + utf8_printf(p->out,"%s", azArg[i]); + }else{ + output_quoted_escaped_string(p->out, azArg[i]); + } + } + raw_printf(p->out,");\n"); + break; + } + case MODE_Quote: { + if( azArg==0 ) break; + if( p->cnt==0 && p->showHeader ){ for(i=0; i0 ) raw_printf(p->out, ","); output_quoted_string(p->out, azCol[i]); @@ -2060,32 +2124,29 @@ static int shell_callback( } p->cnt++; for(i=0; i0 ? ",": ""; + if( i>0 ) raw_printf(p->out, ","); if( (azArg[i]==0) || (aiType && aiType[i]==SQLITE_NULL) ){ - utf8_printf(p->out,"%sNULL",zSep); + utf8_printf(p->out,"NULL"); }else if( aiType && aiType[i]==SQLITE_TEXT ){ - if( zSep[0] ) utf8_printf(p->out,"%s",zSep); output_quoted_string(p->out, azArg[i]); }else if( aiType && aiType[i]==SQLITE_INTEGER ){ - utf8_printf(p->out,"%s%s",zSep, azArg[i]); + utf8_printf(p->out,"%s", azArg[i]); }else if( aiType && aiType[i]==SQLITE_FLOAT ){ char z[50]; double r = sqlite3_column_double(p->pStmt, i); sqlite3_snprintf(50,z,"%!.20g", r); - raw_printf(p->out, "%s%s", zSep, z); + raw_printf(p->out, "%s", z); }else if( aiType && aiType[i]==SQLITE_BLOB && p->pStmt ){ const void *pBlob = sqlite3_column_blob(p->pStmt, i); int nBlob = sqlite3_column_bytes(p->pStmt, i); - if( zSep[0] ) utf8_printf(p->out,"%s",zSep); output_hex_blob(p->out, pBlob, nBlob); }else if( isNumber(azArg[i], 0) ){ - utf8_printf(p->out,"%s%s",zSep, azArg[i]); + utf8_printf(p->out,"%s", azArg[i]); }else{ - if( zSep[0] ) utf8_printf(p->out,"%s",zSep); output_quoted_string(p->out, azArg[i]); } } - raw_printf(p->out,p->cMode==MODE_Quote?"\n":");\n"); + raw_printf(p->out,"\n"); break; } case MODE_Ascii: { From 5b09d13a58859886698d63ea1f75471766ad5b92 Mon Sep 17 00:00:00 2001 From: dan Date: Sat, 8 Apr 2017 13:52:41 +0000 Subject: [PATCH 26/28] Have the rtree module close any open blob-handle within the xSavepoint method. This prevents such an open blob handle from interfering with DROP TABLE operations. FossilOrigin-Name: fa4416adc2a9a3a80db1d5befc0b95c3d0fc41affe38f7f2f45cdfae3f1b49eb --- ext/rtree/rtree.c | 26 ++++++++++++++++++++++++-- ext/rtree/rtree1.test | 18 ++++++++++++++++++ manifest | 16 ++++++++-------- manifest.uuid | 2 +- 4 files changed, 51 insertions(+), 11 deletions(-) diff --git a/ext/rtree/rtree.c b/ext/rtree/rtree.c index cf233b5d77..8196e351bc 100644 --- a/ext/rtree/rtree.c +++ b/ext/rtree/rtree.c @@ -3205,6 +3205,28 @@ static int rtreeRename(sqlite3_vtab *pVtab, const char *zNewName){ return rc; } +/* +** The xSavepoint method. +** +** This module does not need to do anything to support savepoints. However, +** it uses this hook to close any open blob handle. This is done because a +** DROP TABLE command - which fortunately always opens a savepoint - cannot +** succeed if there are any open blob handles. i.e. if the blob handle were +** not closed here, the following would fail: +** +** BEGIN; +** INSERT INTO rtree... +** DROP TABLE ; -- Would fail with SQLITE_LOCKED +** COMMIT; +*/ +static int rtreeSavepoint(sqlite3_vtab *pVtab, int iSavepoint){ + Rtree *pRtree = (Rtree *)pVtab; + int iwt = pRtree->inWrTrans; + pRtree->inWrTrans = 0; + nodeBlobReset(pRtree); + pRtree->inWrTrans = iwt; + return SQLITE_OK; +} /* ** This function populates the pRtree->nRowEst variable with an estimate @@ -3251,7 +3273,7 @@ static int rtreeQueryStat1(sqlite3 *db, Rtree *pRtree){ } static sqlite3_module rtreeModule = { - 0, /* iVersion */ + 2, /* iVersion */ rtreeCreate, /* xCreate - create a table */ rtreeConnect, /* xConnect - connect to an existing table */ rtreeBestIndex, /* xBestIndex - Determine search strategy */ @@ -3271,7 +3293,7 @@ static sqlite3_module rtreeModule = { rtreeEndTransaction, /* xRollback - rollback transaction */ 0, /* xFindFunction - function overloading */ rtreeRename, /* xRename - rename the table */ - 0, /* xSavepoint */ + rtreeSavepoint, /* xSavepoint */ 0, /* xRelease */ 0, /* xRollbackTo */ }; diff --git a/ext/rtree/rtree1.test b/ext/rtree/rtree1.test index 9dc101a7b2..a29cfb945d 100644 --- a/ext/rtree/rtree1.test +++ b/ext/rtree/rtree1.test @@ -39,6 +39,8 @@ set testprefix rtree1 # inserted. Also that if a non-numeric is inserted into one # of the min/max dimension columns, it is converted to the # required type before being inserted. +# rtree-15.*: Check that DROP TABLE works within a transaction that +# writes to an r-tree table. # ifcapable !rtree { @@ -592,4 +594,20 @@ do_execsql_test 14.5 { 3 42 49 } +#------------------------------------------------------------------------- +# +do_execsql_test 15.0 { + CREATE VIRTUAL TABLE rt USING rtree(id, x1,x2, y1,y2); + CREATE TEMP TABLE t13(a, b, c); +} +do_execsql_test 15.1 { + BEGIN; + INSERT INTO rt VALUES(1,2,3,4,5); +} +breakpoint +do_execsql_test 15.2 { + DROP TABLE t13; + COMMIT; +} + finish_test diff --git a/manifest b/manifest index 999a8ca810..e10ca39c0b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sthe\squoting\smechanism\sfor\s".dump"\sso\sthat\sit\sis\snot\sapplied\sfor\sthe\n".mode\squote"\soutput. -D 2017-04-08T13:42:55.616 +C Have\sthe\srtree\smodule\sclose\sany\sopen\sblob-handle\swithin\sthe\sxSavepoint\smethod.\nThis\sprevents\ssuch\san\sopen\sblob\shandle\sfrom\sinterfering\swith\sDROP\sTABLE\noperations. +D 2017-04-08T13:52:41.332 F Makefile.in 1cc758ce3374a32425e4d130c2fe7b026b20de5b8843243de75f087c0a2661fb F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc a4c0613a18663bda56d8cf76079ab6590a7c3602e54befb4bbdef76bcaa38b6a @@ -271,9 +271,9 @@ F ext/rbu/sqlite3rbu.c 2a89efba9eeba8e6c89a498dc195e8efbdde2694 F ext/rbu/sqlite3rbu.h 6fb6294c34a9ca93b5894a33bca530c6f08decba F ext/rbu/test_rbu.c 5aa22616afac6f71ebd3d9bc9bf1006cfabcca88 F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761 -F ext/rtree/rtree.c fb7c0e62ccbbbd6951ddb1f52feaa2c1a53b7ac1c6f2d5d5e2bbd31c33e57186 +F ext/rtree/rtree.c 37c603c6b8aed1a760661ceb5a025bd36bac14cf56d59949bd8de14b2a17e9ed F ext/rtree/rtree.h 834dbcb82dc85b2481cde6a07cdadfddc99e9b9e -F ext/rtree/rtree1.test 42dadfc7b44a436cd74a1bebc0b9b689e4eaf7ec +F ext/rtree/rtree1.test d5f0ba215b3bd1d05269ada86e74073b8445852aa0d33a63e10ec63a09c39473 F ext/rtree/rtree2.test acbb3a4ce0f4fbc2c304d2b4b784cfa161856bba F ext/rtree/rtree3.test 2cafe8265d1ff28f206fce88d114f208349df482 F ext/rtree/rtree4.test c8fe384f60ebd49540a5fecc990041bf452eb6e0 @@ -1570,7 +1570,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P a921ada89050ce1d162fd1b0056939573635e2cec7ac0c2a99ae924b3ae593f7 -R 82737b36216e366238632e12de53d03d -U drh -Z 97234581d28b10577d1d04c415271f72 +P 78c1e90305d48917d9423d8e50a7dfd15ec27aa93cb421610062229c7ede13a6 +R 0c38afb8d28742bfd99c862428490c09 +U dan +Z 475b2e97335280e83d36c7e778a71dcc diff --git a/manifest.uuid b/manifest.uuid index e318e00b25..c1e1fd932b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -78c1e90305d48917d9423d8e50a7dfd15ec27aa93cb421610062229c7ede13a6 \ No newline at end of file +fa4416adc2a9a3a80db1d5befc0b95c3d0fc41affe38f7f2f45cdfae3f1b49eb \ No newline at end of file From a34adaf667878954ee2d1c6c6d4820606eb5a03f Mon Sep 17 00:00:00 2001 From: dan Date: Sat, 8 Apr 2017 14:11:47 +0000 Subject: [PATCH 27/28] Expand on the comment above OP_Destroy to explain why it throws an error if there are any active reader VMs. FossilOrigin-Name: b9a8c2b9bec9f537b2d5aff6659a5748b1f70b53519a1f9dfceb5209154eca8e --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbe.c | 15 +++++++++++---- 3 files changed, 18 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index e10ca39c0b..e3f79625e8 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Have\sthe\srtree\smodule\sclose\sany\sopen\sblob-handle\swithin\sthe\sxSavepoint\smethod.\nThis\sprevents\ssuch\san\sopen\sblob\shandle\sfrom\sinterfering\swith\sDROP\sTABLE\noperations. -D 2017-04-08T13:52:41.332 +C Expand\son\sthe\scomment\sabove\sOP_Destroy\sto\sexplain\swhy\sit\sthrows\san\serror\sif\nthere\sare\sany\sactive\sreader\sVMs. +D 2017-04-08T14:11:47.626 F Makefile.in 1cc758ce3374a32425e4d130c2fe7b026b20de5b8843243de75f087c0a2661fb F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc a4c0613a18663bda56d8cf76079ab6590a7c3602e54befb4bbdef76bcaa38b6a @@ -468,7 +468,7 @@ F src/update.c 456d4a4656f8a03c2abc88a51b19172197400e58 F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c F src/util.c ca8440ede81e155d15cff7c101654f60b55a9ae6 F src/vacuum.c 1fe4555cd8c9b263afb85b5b4ee3a4a4181ad569 -F src/vdbe.c b070c9c81a5faff5d9fc9563c7c030e3e1adb69d835259470fd945ef61f3f9fb +F src/vdbe.c 808fda3d50f544120d27c731449b524b4ec8f8b0f734b228831078f0ba53ecb9 F src/vdbe.h caa5346d52bae2a3c8c1dcfa60a7a4dc878a9e3865cb8239da55808b316c8158 F src/vdbeInt.h 5db089ce18c4feff8820ec6e4cac2d2c82e03d4b1d96f10a6e43832147b8dffe F src/vdbeapi.c 5b08d82592bcff4470601fe78aaabebd50837860 @@ -1570,7 +1570,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 78c1e90305d48917d9423d8e50a7dfd15ec27aa93cb421610062229c7ede13a6 -R 0c38afb8d28742bfd99c862428490c09 +P fa4416adc2a9a3a80db1d5befc0b95c3d0fc41affe38f7f2f45cdfae3f1b49eb +R a9817579cdde3e2d07834f7afee2d7a0 U dan -Z 475b2e97335280e83d36c7e778a71dcc +Z aefe60bc1892ed67bf5beab6d8c742fc diff --git a/manifest.uuid b/manifest.uuid index c1e1fd932b..737a0a72a7 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -fa4416adc2a9a3a80db1d5befc0b95c3d0fc41affe38f7f2f45cdfae3f1b49eb \ No newline at end of file +b9a8c2b9bec9f537b2d5aff6659a5748b1f70b53519a1f9dfceb5209154eca8e \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index 51c702a4ad..a990afb11d 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -5386,10 +5386,17 @@ case OP_IdxGE: { /* jump */ ** might be moved into the newly deleted root page in order to keep all ** root pages contiguous at the beginning of the database. The former ** value of the root page that moved - its value before the move occurred - -** is stored in register P2. If no page -** movement was required (because the table being dropped was already -** the last one in the database) then a zero is stored in register P2. -** If AUTOVACUUM is disabled then a zero is stored in register P2. +** is stored in register P2. If no page movement was required (because the +** table being dropped was already the last one in the database) then a +** zero is stored in register P2. If AUTOVACUUM is disabled then a zero +** is stored in register P2. +** +** This opcode throws an error if there are any active reader VMs when +** it is invoked. This is done to avoid the difficulty associated with +** updating existing cursors when a root page is moved in an AUTOVACUUM +** database. This error is thrown even if the database is not an AUTOVACUUM +** db in order to avoid introducing an incompatibility between autovacuum +** and non-autovacuum modes. ** ** See also: Clear */ From 9fa866a8d9573cb6613cdac00100e24697f43e49 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 8 Apr 2017 18:18:22 +0000 Subject: [PATCH 28/28] Disallow leading zeros on numeric constants in JSON. Fix for ticket [b93be8729a895a528e2] FossilOrigin-Name: 204e72f0080e8f08f99978870bd3cb9d59b068ecffee82192d707c650548b43b --- ext/misc/json1.c | 60 ++++++++++++++++++++++++++--------------------- manifest | 16 ++++++------- manifest.uuid | 2 +- test/json102.test | 21 +++++++++++++++++ 4 files changed, 63 insertions(+), 36 deletions(-) diff --git a/ext/misc/json1.c b/ext/misc/json1.c index bad5cd9b53..b12964ba4d 100644 --- a/ext/misc/json1.c +++ b/ext/misc/json1.c @@ -727,13 +727,14 @@ static int jsonParseValue(JsonParse *pParse, u32 i){ int iThis; int x; JsonNode *pNode; - while( safe_isspace(pParse->zJson[i]) ){ i++; } - if( (c = pParse->zJson[i])=='{' ){ + const char *z = pParse->zJson; + while( safe_isspace(z[i]) ){ i++; } + if( (c = z[i])=='{' ){ /* Parse object */ iThis = jsonParseAddNode(pParse, JSON_OBJECT, 0, 0); if( iThis<0 ) return -1; for(j=i+1;;j++){ - while( safe_isspace(pParse->zJson[j]) ){ j++; } + while( safe_isspace(z[j]) ){ j++; } x = jsonParseValue(pParse, j); if( x<0 ){ if( x==(-2) && pParse->nNode==(u32)iThis+1 ) return j+1; @@ -744,14 +745,14 @@ static int jsonParseValue(JsonParse *pParse, u32 i){ if( pNode->eType!=JSON_STRING ) return -1; pNode->jnFlags |= JNODE_LABEL; j = x; - while( safe_isspace(pParse->zJson[j]) ){ j++; } - if( pParse->zJson[j]!=':' ) return -1; + while( safe_isspace(z[j]) ){ j++; } + if( z[j]!=':' ) return -1; j++; x = jsonParseValue(pParse, j); if( x<0 ) return -1; j = x; - while( safe_isspace(pParse->zJson[j]) ){ j++; } - c = pParse->zJson[j]; + while( safe_isspace(z[j]) ){ j++; } + c = z[j]; if( c==',' ) continue; if( c!='}' ) return -1; break; @@ -763,15 +764,15 @@ static int jsonParseValue(JsonParse *pParse, u32 i){ iThis = jsonParseAddNode(pParse, JSON_ARRAY, 0, 0); if( iThis<0 ) return -1; for(j=i+1;;j++){ - while( safe_isspace(pParse->zJson[j]) ){ j++; } + while( safe_isspace(z[j]) ){ j++; } x = jsonParseValue(pParse, j); if( x<0 ){ if( x==(-3) && pParse->nNode==(u32)iThis+1 ) return j+1; return -1; } j = x; - while( safe_isspace(pParse->zJson[j]) ){ j++; } - c = pParse->zJson[j]; + while( safe_isspace(z[j]) ){ j++; } + c = z[j]; if( c==',' ) continue; if( c!=']' ) return -1; break; @@ -783,13 +784,13 @@ static int jsonParseValue(JsonParse *pParse, u32 i){ u8 jnFlags = 0; j = i+1; for(;;){ - c = pParse->zJson[j]; + c = z[j]; if( c==0 ) return -1; if( c=='\\' ){ - c = pParse->zJson[++j]; + c = z[++j]; if( c=='"' || c=='\\' || c=='/' || c=='b' || c=='f' || c=='n' || c=='r' || c=='t' - || (c=='u' && jsonIs4Hex(pParse->zJson+j+1)) ){ + || (c=='u' && jsonIs4Hex(z+j+1)) ){ jnFlags = JNODE_ESCAPE; }else{ return -1; @@ -799,55 +800,60 @@ static int jsonParseValue(JsonParse *pParse, u32 i){ } j++; } - jsonParseAddNode(pParse, JSON_STRING, j+1-i, &pParse->zJson[i]); + jsonParseAddNode(pParse, JSON_STRING, j+1-i, &z[i]); if( !pParse->oom ) pParse->aNode[pParse->nNode-1].jnFlags = jnFlags; return j+1; }else if( c=='n' - && strncmp(pParse->zJson+i,"null",4)==0 - && !safe_isalnum(pParse->zJson[i+4]) ){ + && strncmp(z+i,"null",4)==0 + && !safe_isalnum(z[i+4]) ){ jsonParseAddNode(pParse, JSON_NULL, 0, 0); return i+4; }else if( c=='t' - && strncmp(pParse->zJson+i,"true",4)==0 - && !safe_isalnum(pParse->zJson[i+4]) ){ + && strncmp(z+i,"true",4)==0 + && !safe_isalnum(z[i+4]) ){ jsonParseAddNode(pParse, JSON_TRUE, 0, 0); return i+4; }else if( c=='f' - && strncmp(pParse->zJson+i,"false",5)==0 - && !safe_isalnum(pParse->zJson[i+5]) ){ + && strncmp(z+i,"false",5)==0 + && !safe_isalnum(z[i+5]) ){ jsonParseAddNode(pParse, JSON_FALSE, 0, 0); return i+5; }else if( c=='-' || (c>='0' && c<='9') ){ /* Parse number */ u8 seenDP = 0; u8 seenE = 0; + assert( '-' < '0' ); + if( c<='0' ){ + j = c=='-' ? i+1 : i; + if( z[j]=='0' && z[j+1]>='0' && z[j+1]<='9' ) return -1; + } j = i+1; for(;; j++){ - c = pParse->zJson[j]; + c = z[j]; if( c>='0' && c<='9' ) continue; if( c=='.' ){ - if( pParse->zJson[j-1]=='-' ) return -1; + if( z[j-1]=='-' ) return -1; if( seenDP ) return -1; seenDP = 1; continue; } if( c=='e' || c=='E' ){ - if( pParse->zJson[j-1]<'0' ) return -1; + if( z[j-1]<'0' ) return -1; if( seenE ) return -1; seenDP = seenE = 1; - c = pParse->zJson[j+1]; + c = z[j+1]; if( c=='+' || c=='-' ){ j++; - c = pParse->zJson[j+1]; + c = z[j+1]; } if( c<'0' || c>'9' ) return -1; continue; } break; } - if( pParse->zJson[j-1]<'0' ) return -1; + if( z[j-1]<'0' ) return -1; jsonParseAddNode(pParse, seenDP ? JSON_REAL : JSON_INT, - j - i, &pParse->zJson[i]); + j - i, &z[i]); return j; }else if( c=='}' ){ return -2; /* End of {...} */ diff --git a/manifest b/manifest index e3f79625e8..2b13eab25a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Expand\son\sthe\scomment\sabove\sOP_Destroy\sto\sexplain\swhy\sit\sthrows\san\serror\sif\nthere\sare\sany\sactive\sreader\sVMs. -D 2017-04-08T14:11:47.626 +C Disallow\sleading\szeros\son\snumeric\sconstants\sin\sJSON.\nFix\sfor\sticket\s[b93be8729a895a528e2] +D 2017-04-08T18:18:22.572 F Makefile.in 1cc758ce3374a32425e4d130c2fe7b026b20de5b8843243de75f087c0a2661fb F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc a4c0613a18663bda56d8cf76079ab6590a7c3602e54befb4bbdef76bcaa38b6a @@ -218,7 +218,7 @@ F ext/misc/eval.c f971962e92ebb8b0a4e6b62949463ee454d88fa2 F ext/misc/fileio.c d4171c815d6543a9edef8308aab2951413cd8d0f F ext/misc/fuzzer.c 7c64b8197bb77b7d64eff7cac7848870235d4c25 F ext/misc/ieee754.c f190d0cc5182529acb15babd177781be1ac1718c -F ext/misc/json1.c 92b9e404bd79cc76d3ef2b3a9e37bf775700f7d645466fd41d2e8742e3fa16fb +F ext/misc/json1.c 312b4ddf4c7399dcbd2189f492e8ca92a872c2df7347473bfb38854f9d60c06a F ext/misc/memvfs.c e5225bc22e79dde6b28380f3a068ddf600683a33 F ext/misc/nextchar.c 35c8b8baacb96d92abbb34a83a997b797075b342 F ext/misc/percentile.c 92699c8cd7d517ff610e6037e56506f8904dae2e @@ -911,7 +911,7 @@ F test/jrnlmode.test 7864d59cf7f6e552b9b99ba0f38acd167edc10fa F test/jrnlmode2.test 81610545a4e6ed239ea8fa661891893385e23a1d F test/jrnlmode3.test 556b447a05be0e0963f4311e95ab1632b11c9eaa F test/json101.test c0897616f32d95431f37fd291cb78742181980ac -F test/json102.test bf3fe7a706d30936a76a0f7a0375e1e8e73aff5a +F test/json102.test de1728e8ffde4a57cbc77b6815a60ccb82a6c759967be44e71952757e7d7947b F test/json103.test c5f6b85e69de05f6b3195f9f9d5ce9cd179099a0 F test/json104.test 877d5845f6303899b7889ea5dd1bea99076e3100574d5c536082245c5805dcaa F test/keyword1.test 37ef6bba5d2ed5b07ecdd6810571de2956599dff @@ -1570,7 +1570,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P fa4416adc2a9a3a80db1d5befc0b95c3d0fc41affe38f7f2f45cdfae3f1b49eb -R a9817579cdde3e2d07834f7afee2d7a0 -U dan -Z aefe60bc1892ed67bf5beab6d8c742fc +P b9a8c2b9bec9f537b2d5aff6659a5748b1f70b53519a1f9dfceb5209154eca8e +R 670b9d233206c31ff293234250b6b1b3 +U drh +Z 7379463864511f4d80e83d3921199e22 diff --git a/manifest.uuid b/manifest.uuid index 737a0a72a7..149c2506cf 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b9a8c2b9bec9f537b2d5aff6659a5748b1f70b53519a1f9dfceb5209154eca8e \ No newline at end of file +204e72f0080e8f08f99978870bd3cb9d59b068ecffee82192d707c650548b43b \ No newline at end of file diff --git a/test/json102.test b/test/json102.test index a4d88dbeaa..d1f2a4d36d 100644 --- a/test/json102.test +++ b/test/json102.test @@ -298,4 +298,25 @@ for {set i 0} {$i<100} {incr i} { } {1} } +#------------------------------------------------------------------------- +# 2017-04-08 ticket b93be8729a895a528e2849fca99f7 +# JSON extension accepts invalid numeric values +# +# JSON does not allow leading zeros. But the JSON extension was +# allowing them. The following tests verify that the problem is now +# fixed. +# +do_execsql_test json102-1401 { SELECT json_valid('{"x":01}') } 0 +do_execsql_test json102-1402 { SELECT json_valid('{"x":-01}') } 0 +do_execsql_test json102-1403 { SELECT json_valid('{"x":0}') } 1 +do_execsql_test json102-1404 { SELECT json_valid('{"x":-0}') } 1 +do_execsql_test json102-1405 { SELECT json_valid('{"x":0.1}') } 1 +do_execsql_test json102-1406 { SELECT json_valid('{"x":-0.1}') } 1 +do_execsql_test json102-1407 { SELECT json_valid('{"x":0.0000}') } 1 +do_execsql_test json102-1408 { SELECT json_valid('{"x":-0.0000}') } 1 +do_execsql_test json102-1409 { SELECT json_valid('{"x":01.5}') } 0 +do_execsql_test json102-1410 { SELECT json_valid('{"x":-01.5}') } 0 +do_execsql_test json102-1411 { SELECT json_valid('{"x":00}') } 0 +do_execsql_test json102-1412 { SELECT json_valid('{"x":-00}') } 0 + finish_test