aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordrh <drh@noemail.net>2013-09-09 19:37:46 +0000
committerdrh <drh@noemail.net>2013-09-09 19:37:46 +0000
commit0259bc3da21f41adb2492d39898e0b98388bb561 (patch)
tree6d3adb6d94ec907b9f836e5eda9be223520ed3ee /src
parentd36e1041120280adfc9612d8f6e4ade318b3ffa0 (diff)
downloadsqlite-0259bc3da21f41adb2492d39898e0b98388bb561.tar.gz
sqlite-0259bc3da21f41adb2492d39898e0b98388bb561.zip
Make sure that the transitive constraint optimization does not cause
WHERE clause terms to be disabled prematurely. We are unable to find a test case that fails because of this, but it seems prudent to make this preventative change nevertheless. FossilOrigin-Name: d6e361d7fb8013d616af91ef2c10038c97d1be5f
Diffstat (limited to 'src')
-rw-r--r--src/where.c13
1 files changed, 7 insertions, 6 deletions
diff --git a/src/where.c b/src/where.c
index 3c8a1eaac..fb097d2af 100644
--- a/src/where.c
+++ b/src/where.c
@@ -106,6 +106,7 @@ struct WhereLevel {
Index *pCovidx; /* Possible covering index for WHERE_MULTI_OR */
} u;
struct WhereLoop *pWLoop; /* The selected WhereLoop object */
+ Bitmask notReady; /* FROM entries not usable at this level */
};
/*
@@ -2799,6 +2800,7 @@ static void disableTerm(WhereLevel *pLevel, WhereTerm *pTerm){
if( pTerm
&& (pTerm->wtFlags & TERM_CODED)==0
&& (pLevel->iLeftJoin==0 || ExprHasProperty(pTerm->pExpr, EP_FromJoin))
+ && (pLevel->notReady & pTerm->prereqAll)==0
){
pTerm->wtFlags |= TERM_CODED;
if( pTerm->iParent>=0 ){
@@ -3224,7 +3226,6 @@ static Bitmask codeOneLoopStart(
int addrCont; /* Jump here to continue with next cycle */
int iRowidReg = 0; /* Rowid is stored in this register, if not zero */
int iReleaseReg = 0; /* Temp register to free before returning */
- Bitmask newNotReady; /* Return value */
pParse = pWInfo->pParse;
v = pParse->pVdbe;
@@ -3234,6 +3235,7 @@ static Bitmask codeOneLoopStart(
pLoop = pLevel->pWLoop;
pTabItem = &pWInfo->pTabList->a[pLevel->iFrom];
iCur = pTabItem->iCursor;
+ pLevel->notReady = notReady & ~getMask(&pWInfo->sMaskSet, iCur);
bRev = (pWInfo->revMask>>iLevel)&1;
omitTable = (pLoop->wsFlags & WHERE_IDX_ONLY)!=0
&& (pWInfo->wctrlFlags & WHERE_FORCE_TABLE)==0;
@@ -3886,7 +3888,6 @@ static Bitmask codeOneLoopStart(
pLevel->p2 = 1 + sqlite3VdbeAddOp2(v, aStart[bRev], iCur, addrBrk);
pLevel->p5 = SQLITE_STMTSTATUS_FULLSCAN_STEP;
}
- newNotReady = notReady & ~getMask(&pWInfo->sMaskSet, iCur);
/* Insert code to test every subexpression that can be completely
** computed using the current set of tables.
@@ -3896,7 +3897,7 @@ static Bitmask codeOneLoopStart(
testcase( pTerm->wtFlags & TERM_VIRTUAL );
testcase( pTerm->wtFlags & TERM_CODED );
if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue;
- if( (pTerm->prereqAll & newNotReady)!=0 ){
+ if( (pTerm->prereqAll & pLevel->notReady)!=0 ){
testcase( pWInfo->untestedTerms==0
&& (pWInfo->wctrlFlags & WHERE_ONETABLE_ONLY)!=0 );
pWInfo->untestedTerms = 1;
@@ -3928,7 +3929,7 @@ static Bitmask codeOneLoopStart(
if( pLevel->iLeftJoin ) continue;
pE = pTerm->pExpr;
assert( !ExprHasProperty(pE, EP_FromJoin) );
- assert( (pTerm->prereqRight & newNotReady)!=0 );
+ assert( (pTerm->prereqRight & pLevel->notReady)!=0 );
pAlt = findTerm(pWC, iCur, pTerm->u.leftColumn, notReady, WO_EQ|WO_IN, 0);
if( pAlt==0 ) continue;
if( pAlt->wtFlags & (TERM_CODED) ) continue;
@@ -3956,7 +3957,7 @@ static Bitmask codeOneLoopStart(
testcase( pTerm->wtFlags & TERM_VIRTUAL );
testcase( pTerm->wtFlags & TERM_CODED );
if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue;
- if( (pTerm->prereqAll & newNotReady)!=0 ){
+ if( (pTerm->prereqAll & pLevel->notReady)!=0 ){
assert( pWInfo->untestedTerms );
continue;
}
@@ -3967,7 +3968,7 @@ static Bitmask codeOneLoopStart(
}
sqlite3ReleaseTempReg(pParse, iReleaseReg);
- return newNotReady;
+ return pLevel->notReady;
}
#ifdef WHERETRACE_ENABLED