mirror of
https://github.com/sqlite/sqlite.git
synced 2025-11-21 09:00:59 +03:00
Use transitivity to move constraints into the outer loops of a join whenever
possible, thereby reducing the amount of work that needs to occur in inner loops. FossilOrigin-Name: 5f4907e1c6230e3dd904bd99e1c48c576c669f63
This commit is contained in:
12
manifest
12
manifest
@@ -1,5 +1,5 @@
|
|||||||
C Add\sthe\s"warning"\scommand\sto\sthe\sTCL\stest\sinfrastructure.\s\sFix\sproblems\nwith\sthe\sloadext.test\smodule.
|
C Use\stransitivity\sto\smove\sconstraints\sinto\sthe\souter\sloops\sof\sa\sjoin\swhenever\npossible,\sthereby\sreducing\sthe\samount\sof\swork\sthat\sneeds\sto\soccur\sin\ninner\sloops.
|
||||||
D 2013-04-19T12:32:52.666
|
D 2013-04-22T02:39:10.341
|
||||||
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
||||||
F Makefile.in 3dd3fcb87b70c78d99b2c8a03e44ec86d6ca9ce2
|
F Makefile.in 3dd3fcb87b70c78d99b2c8a03e44ec86d6ca9ce2
|
||||||
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
||||||
@@ -258,7 +258,7 @@ F src/vtab.c b05e5f1f4902461ba9f5fc49bb7eb7c3a0741a83
|
|||||||
F src/wal.c 436bfceb141b9423c45119e68e444358ee0ed35d
|
F src/wal.c 436bfceb141b9423c45119e68e444358ee0ed35d
|
||||||
F src/wal.h a4d3da523d55a226a0b28e9058ef88d0a8051887
|
F src/wal.h a4d3da523d55a226a0b28e9058ef88d0a8051887
|
||||||
F src/walker.c 3d75ba73de15e0f8cd0737643badbeb0e002f07b
|
F src/walker.c 3d75ba73de15e0f8cd0737643badbeb0e002f07b
|
||||||
F src/where.c e63f84e5583133c77573b78d3696dccd97bfd00d
|
F src/where.c c7c74fe8e354b60dee0810ea8b954c5ccb9e0f3c
|
||||||
F test/8_3_names.test 631ea964a3edb091cf73c3b540f6bcfdb36ce823
|
F test/8_3_names.test 631ea964a3edb091cf73c3b540f6bcfdb36ce823
|
||||||
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
|
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
|
||||||
F test/aggnested.test 45c0201e28045ad38a530b5a144b73cd4aa2cfd6
|
F test/aggnested.test 45c0201e28045ad38a530b5a144b73cd4aa2cfd6
|
||||||
@@ -1051,7 +1051,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381
|
|||||||
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
|
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
|
||||||
F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381
|
F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381
|
||||||
F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac
|
F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac
|
||||||
P a85b6ecefa14fcfe6ebfceabf910f00c3721be7d
|
P 514adbbd8cf3e296f55e8f803bddaac8ad8b2c96
|
||||||
R 2c3aca07297ff95a6b74db849941a18d
|
R a81fa97db156009318d49bf4c6dae35e
|
||||||
U drh
|
U drh
|
||||||
Z bfc695f8f3325c7943f46501f9086d37
|
Z 1c3c5b72018db605301d161eada3f156
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
514adbbd8cf3e296f55e8f803bddaac8ad8b2c96
|
5f4907e1c6230e3dd904bd99e1c48c576c669f63
|
||||||
36
src/where.c
36
src/where.c
@@ -4161,6 +4161,7 @@ static Bitmask codeOneLoopStart(
|
|||||||
int addrCont; /* Jump here to continue with next cycle */
|
int addrCont; /* Jump here to continue with next cycle */
|
||||||
int iRowidReg = 0; /* Rowid is stored in this register, if not zero */
|
int iRowidReg = 0; /* Rowid is stored in this register, if not zero */
|
||||||
int iReleaseReg = 0; /* Temp register to free before returning */
|
int iReleaseReg = 0; /* Temp register to free before returning */
|
||||||
|
Bitmask newNotReady; /* Return value */
|
||||||
|
|
||||||
pParse = pWInfo->pParse;
|
pParse = pWInfo->pParse;
|
||||||
v = pParse->pVdbe;
|
v = pParse->pVdbe;
|
||||||
@@ -4171,6 +4172,7 @@ static Bitmask codeOneLoopStart(
|
|||||||
bRev = (pLevel->plan.wsFlags & WHERE_REVERSE)!=0;
|
bRev = (pLevel->plan.wsFlags & WHERE_REVERSE)!=0;
|
||||||
omitTable = (pLevel->plan.wsFlags & WHERE_IDX_ONLY)!=0
|
omitTable = (pLevel->plan.wsFlags & WHERE_IDX_ONLY)!=0
|
||||||
&& (wctrlFlags & WHERE_FORCE_TABLE)==0;
|
&& (wctrlFlags & WHERE_FORCE_TABLE)==0;
|
||||||
|
VdbeNoopComment((v, "Begin Join Loop %d", iLevel));
|
||||||
|
|
||||||
/* Create labels for the "break" and "continue" instructions
|
/* Create labels for the "break" and "continue" instructions
|
||||||
** for the current loop. Jump to addrBrk to break out of a loop.
|
** for the current loop. Jump to addrBrk to break out of a loop.
|
||||||
@@ -4821,7 +4823,7 @@ static Bitmask codeOneLoopStart(
|
|||||||
pLevel->p2 = 1 + sqlite3VdbeAddOp2(v, aStart[bRev], iCur, addrBrk);
|
pLevel->p2 = 1 + sqlite3VdbeAddOp2(v, aStart[bRev], iCur, addrBrk);
|
||||||
pLevel->p5 = SQLITE_STMTSTATUS_FULLSCAN_STEP;
|
pLevel->p5 = SQLITE_STMTSTATUS_FULLSCAN_STEP;
|
||||||
}
|
}
|
||||||
notReady &= ~getMask(pWC->pMaskSet, iCur);
|
newNotReady = notReady & ~getMask(pWC->pMaskSet, iCur);
|
||||||
|
|
||||||
/* Insert code to test every subexpression that can be completely
|
/* Insert code to test every subexpression that can be completely
|
||||||
** computed using the current set of tables.
|
** computed using the current set of tables.
|
||||||
@@ -4835,7 +4837,7 @@ static Bitmask codeOneLoopStart(
|
|||||||
testcase( pTerm->wtFlags & TERM_VIRTUAL ); /* IMP: R-30575-11662 */
|
testcase( pTerm->wtFlags & TERM_VIRTUAL ); /* IMP: R-30575-11662 */
|
||||||
testcase( pTerm->wtFlags & TERM_CODED );
|
testcase( pTerm->wtFlags & TERM_CODED );
|
||||||
if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue;
|
if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue;
|
||||||
if( (pTerm->prereqAll & notReady)!=0 ){
|
if( (pTerm->prereqAll & newNotReady)!=0 ){
|
||||||
testcase( pWInfo->untestedTerms==0
|
testcase( pWInfo->untestedTerms==0
|
||||||
&& (pWInfo->wctrlFlags & WHERE_ONETABLE_ONLY)!=0 );
|
&& (pWInfo->wctrlFlags & WHERE_ONETABLE_ONLY)!=0 );
|
||||||
pWInfo->untestedTerms = 1;
|
pWInfo->untestedTerms = 1;
|
||||||
@@ -4850,6 +4852,32 @@ static Bitmask codeOneLoopStart(
|
|||||||
pTerm->wtFlags |= TERM_CODED;
|
pTerm->wtFlags |= TERM_CODED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Insert code to test for implied constraints based on transitivity
|
||||||
|
** of the "==" operator.
|
||||||
|
**
|
||||||
|
** Example: If the WHERE clause contains "t1.a=t2.b" and "t2.b=123"
|
||||||
|
** and we are coding the t1 loop and the t2 loop has not yet coded,
|
||||||
|
** then we cannot use the "t1.a=t2.b" constraint, but we can code
|
||||||
|
** the implied "t1.a=123" constraint.
|
||||||
|
*/
|
||||||
|
for(pTerm=pWC->a, j=pWC->nTerm; j>0; j--, pTerm++){
|
||||||
|
Expr *pE;
|
||||||
|
WhereTerm *pAlt;
|
||||||
|
Expr sEq;
|
||||||
|
if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue;
|
||||||
|
if( pTerm->eOperator!=(WO_EQUIV|WO_EQ) ) continue;
|
||||||
|
if( pTerm->leftCursor!=iCur ) continue;
|
||||||
|
pE = pTerm->pExpr;
|
||||||
|
assert( !ExprHasProperty(pE, EP_FromJoin) );
|
||||||
|
assert( (pTerm->prereqRight & newNotReady)!=0 );
|
||||||
|
pAlt = findTerm(pWC, iCur, pTerm->u.leftColumn, notReady, WO_EQ|WO_IN, 0);
|
||||||
|
if( pAlt==0 ) continue;
|
||||||
|
VdbeNoopComment((v, "begin transitive constraint"));
|
||||||
|
sEq = *pAlt->pExpr;
|
||||||
|
sEq.pLeft = pE->pLeft;
|
||||||
|
sqlite3ExprIfFalse(pParse, &sEq, addrCont, SQLITE_JUMPIFNULL);
|
||||||
|
}
|
||||||
|
|
||||||
/* For a LEFT OUTER JOIN, generate code that will record the fact that
|
/* For a LEFT OUTER JOIN, generate code that will record the fact that
|
||||||
** at least one row of the right table has matched the left table.
|
** at least one row of the right table has matched the left table.
|
||||||
*/
|
*/
|
||||||
@@ -4862,7 +4890,7 @@ static Bitmask codeOneLoopStart(
|
|||||||
testcase( pTerm->wtFlags & TERM_VIRTUAL ); /* IMP: R-30575-11662 */
|
testcase( pTerm->wtFlags & TERM_VIRTUAL ); /* IMP: R-30575-11662 */
|
||||||
testcase( pTerm->wtFlags & TERM_CODED );
|
testcase( pTerm->wtFlags & TERM_CODED );
|
||||||
if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue;
|
if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue;
|
||||||
if( (pTerm->prereqAll & notReady)!=0 ){
|
if( (pTerm->prereqAll & newNotReady)!=0 ){
|
||||||
assert( pWInfo->untestedTerms );
|
assert( pWInfo->untestedTerms );
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -4873,7 +4901,7 @@ static Bitmask codeOneLoopStart(
|
|||||||
}
|
}
|
||||||
sqlite3ReleaseTempReg(pParse, iReleaseReg);
|
sqlite3ReleaseTempReg(pParse, iReleaseReg);
|
||||||
|
|
||||||
return notReady;
|
return newNotReady;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(SQLITE_TEST)
|
#if defined(SQLITE_TEST)
|
||||||
|
|||||||
Reference in New Issue
Block a user