Extend [52e73eec] so that the IS optimization may be used on primary keys with more than 3 columns.

FossilOrigin-Name: 4e8796af7d40d6ca423e07c68877035e4aa2485c
This commit is contained in:
dan 2015-03-25 15:23:00 +00:00
parent 6da7a0a93d
commit 32c9068adb
5 changed files with 34 additions and 13 deletions

View File

@ -1,5 +1,5 @@
C Merge\sthe\slatest\strunk\schanges\sinto\sthis\sbranch.
D 2015-03-24T18:21:41.611
C Extend\s[52e73eec]\sso\sthat\sthe\sIS\soptimization\smay\sbe\sused\son\sprimary\skeys\swith\smore\sthan\s3\scolumns.
D 2015-03-25T15:23:00.648
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in 88a3e6261286db378fdffa1124cad11b3c05f5bb
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@ -325,8 +325,8 @@ F src/vxworks.h c18586c8edc1bddbc15c004fa16aeb1e1342b4fb
F src/wal.c 878c8e1a51cb2ec45c395d26b7d5cd9e1a098e4a
F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4
F src/walker.c c253b95b4ee44b21c406e2a1052636c31ea27804
F src/where.c d336e91893370787853733e177d4dcd4db0a0283
F src/whereInt.h c1fd5690f91d9551c0c42aa44205248bbd3f7650
F src/where.c bc7276b6e7d4d50055e17cba1d495f804737f872
F src/whereInt.h 1fca2f8c649f0ee38fd52332659d0e7deb11d428
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
F test/aggnested.test b35b4cd69fc913f90d39a575e171e1116c3a4bb7
@ -1195,7 +1195,7 @@ F test/whereG.test 69f5ec4b15760a8c860f80e2d55525669390aab3
F test/whereH.test e4b07f7a3c2f5d31195cd33710054c78667573b2
F test/whereI.test 1d89199697919d4930be05a71e7fe620f114e622
F test/whereJ.test 55a3221706a7ab706293f17cc8f96da563bf0767
F test/whereK.test 424caa7391ca5c41484a37cc4a13dc9ed6243bee
F test/whereK.test 868fed1646f1e720720ec1eb99fc2c4d562c5a85
F test/wherelimit.test 5e9fd41e79bb2b2d588ed999d641d9c965619b31
F test/wild001.test bca33f499866f04c24510d74baf1e578d4e44b1c
F test/win32heap.test ea19770974795cff26e11575e12d422dbd16893c
@ -1265,7 +1265,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
P 6326fd3249bee267da0172f8afd1e7b3f71521b9 cbeb9a1aed8ce3fb569a7717ad03c7c058b68de6
R 1fefa9d8d8de814a981dd2146a1968d2
P 9d9b6c883b4f7d69c615cedfb59a2385aac47b74
R 563e539a9aa7beed43e32c4d3d14e4ca
U dan
Z 463c60d6ebf3658e4a29b2b71d7b17dd
Z d4cd9fd543e406f0ec30b86742c8ca7d

View File

@ -1 +1 @@
9d9b6c883b4f7d69c615cedfb59a2385aac47b74
4e8796af7d40d6ca423e07c68877035e4aa2485c

View File

@ -4310,6 +4310,9 @@ static void whereInfoFree(sqlite3 *db, WhereInfo *pWInfo){
pWInfo->pLoops = p->pNextLoop;
whereLoopDelete(db, p);
}
if( pWInfo->bShortcut ){
whereLoopClear(db, pWInfo->a[0].pWLoop);
}
sqlite3DbFree(db, pWInfo);
}
}
@ -5560,7 +5563,6 @@ static int whereLoopAddAll(WhereLoopBuilder *pBuilder){
/* Loop over the tables in the join, from left to right */
pNew = pBuilder->pNew;
whereLoopInit(pNew);
for(iTab=0, pItem=pTabList->a; iTab<nTabList; iTab++, pItem++){
pNew->iTab = iTab;
pNew->maskSelf = getMask(&pWInfo->sMaskSet, pItem->iCursor);
@ -6276,7 +6278,7 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){
** no-frills query planner. Return zero if this query needs the
** general-purpose query planner.
*/
static int whereShortCut(WhereLoopBuilder *pBuilder){
static int whereShortCut(sqlite3 *db, WhereLoopBuilder *pBuilder){
WhereInfo *pWInfo;
struct SrcList_item *pItem;
WhereClause *pWC;
@ -6311,11 +6313,14 @@ static int whereShortCut(WhereLoopBuilder *pBuilder){
for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
u32 mask = WO_EQ;
assert( pLoop->aLTermSpace==pLoop->aLTerm );
if( HasRowid(pTab)==0 && IsPrimaryKeyIndex(pIdx) ){
mask |= WO_IS;
if( whereLoopResize(db, pLoop, pIdx->nKeyCol) ) return 1;
}else
if( !IsUniqueIndex(pIdx)
|| pIdx->pPartIdxWhere!=0
|| pIdx->nKeyCol>ArraySize(pLoop->aLTermSpace)
) continue;
if( HasRowid(pTab)==0 && IsPrimaryKeyIndex(pIdx) ) mask |= WO_IS;
for(j=0; j<pIdx->nKeyCol; j++){
pTerm = findTerm(pWC, iCur, pIdx->aiColumn[j], 0, mask, pIdx);
if( pTerm==0 ) break;
@ -6347,6 +6352,7 @@ static int whereShortCut(WhereLoopBuilder *pBuilder){
#ifdef SQLITE_DEBUG
pLoop->cId = '0';
#endif
pWInfo->bShortcut = 1;
return 1;
}
return 0;
@ -6617,7 +6623,7 @@ WhereInfo *sqlite3WhereBegin(
}
#endif
if( nTabList!=1 || whereShortCut(&sWLB)==0 ){
if( nTabList!=1 || whereShortCut(db, &sWLB)==0 ){
rc = whereLoopAddAll(&sWLB);
if( rc ) goto whereBeginError;

View File

@ -412,6 +412,7 @@ struct WhereInfo {
u8 untestedTerms; /* Not all WHERE terms resolved by outer loop */
u8 eDistinct; /* One of the WHERE_DISTINCT_* values below */
u8 nLevel; /* Number of nested loop */
u8 bShortcut; /* Plan generated by whereShortCut() */
int iTop; /* The very beginning of the WHERE loop */
int iContinue; /* Jump here to continue with next record */
int iBreak; /* Jump here to break out of the loop */

View File

@ -58,6 +58,20 @@ do_execsql_test 1.4.2 { SELECT v FROM t1 WHERE w = '4' AND x IS 4 } {d}
do_eqp_test 1.5.1 { SELECT b FROM t3 WHERE a IS ? } {/SCAN TABLE/}
do_eqp_test 1.5.2 { SELECT b FROM t3 WHERE a = ? } {/SEARCH TABLE/}
#-------------------------------------------------------------------------
# Check that this works with PRIMARY KEY indexes that have large numbers
# of columns.
do_execsql_test 2.1.1 {
CREATE TABLE x1(a, b, c, d, e, f, g, h, i,
PRIMARY KEY(a, b, c, d, e, f, g)
) WITHOUT ROWID;
}
do_eqp_test 2.1.2 {
SELECT i FROM x1 WHERE
a IS ? AND b IS ? AND c IS ? AND d IS ? AND e IS ? AND f IS ? AND g IS ?
} {/SEARCH TABLE/}
finish_test