-C Enhance\sthe\squery\splanner\sto\sexploit\stransitivity\sof\sjoin\sconstraints\sin\na\smulti-way\sjoin.
-D 2013-01-16T17:08:58.150
+C Improved\scomments\sexplaining\sthe\soperation\sof\sthe\sfindTerm()\sutility\sroutine\nin\swhere.c.\s\sIncrease\sthe\smaximum\snumber\sof\slevels\sof\stransitivity\sfrom\s4\nto\s11.
+D 2013-01-17T00:08:42.232
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in a48faa9e7dd7d556d84f5456eabe5825dd8a6282
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
F src/wal.c f5c7b5027d0ed0e9bc9afeb4a3a8dfea762ec7d2
F src/wal.h 29c197540b19044e6cd73487017e5e47a1d3dac6
F src/walker.c 3d75ba73de15e0f8cd0737643badbeb0e002f07b
-F src/where.c eb1e1dfc17ff26ba9dc35d6df097e0ecc41d9880
+F src/where.c 24d74ec54a71e01e0672e0838f7dd5757fb6324d
F test/8_3_names.test 631ea964a3edb091cf73c3b540f6bcfdb36ce823
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
F test/aggnested.test 45c0201e28045ad38a530b5a144b73cd4aa2cfd6
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381
F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac
-P d5ebb7877885839e93eee3b322624d4c4215c1c4
-R 3bb8dbee120cecd828508038284032c9
-T *branch * transitive-constraints
-T *sym-transitive-constraints *
-T -sym-trunk *
+P 13171eb5dc19733276fbfd5515d75b70a9f5f5d7
+R 47b8015795abaf8b9e9739389b1b5d3d
U drh
-Z 258dff7809c25174ed1f5fdd919be15b
+Z c72ed7f67d993d6d7e18306e36936017
** where X is a reference to the iColumn of table iCur and <op> is one of
** the WO_xx operator codes specified by the op parameter.
** Return a pointer to the term. Return 0 if not found.
+**
+** The term returned might by Y=<expr> if there is another constraint in
+** the WHERE clause that specifies that X=Y. Any such constraints will be
+** identified by the WO_EQUIV bit in the pTerm->eOperator field. The
+** aEquiv[] array holds X and all its equivalents, with each SQL variable
+** taking up two slots in aEquiv[]. The first slot is for the cursor number
+** and the second is for the column number. There are 22 slots in aEquiv[]
+** so that means we can look for X plus up to 10 other equivalent values.
+** Hence a search for X will return <expr> if X=A1 and A1=A2 and A2=A3
+** and ... and A9=A10 and A10=<expr>.
+**
+** If there are multiple terms in the WHERE clause of the form "X <op> <expr>"
+** then try for the one with no dependencies on <expr> - in other words where
+** <expr> is a constant expression of some kind. Only return entries of
+** the form "X <op> Y" where Y is a column in another table if no terms of
+** the form "X <op> <const-expr>" exist. Other than this priority, if there
+** are two or more terms that match, then the choice of which term to return
+** is arbitrary.
*/
static WhereTerm *findTerm(
WhereClause *pWC, /* The WHERE clause to be searched */
u32 op, /* Mask of WO_xx values describing operator */
Index *pIdx /* Must be compatible with this index, if not NULL */
){
- WhereTerm *pTerm;
- WhereTerm *pResult = 0;
- WhereClause *pWCOrig = pWC;
- int j, k;
- int aEquiv[8];
- int nEquiv = 2;
- int iEquiv = 2;
- Expr *pX;
- Parse *pParse;
+ WhereTerm *pTerm; /* Term being examined as possible result */
+ WhereTerm *pResult = 0; /* The answer to return */
+ WhereClause *pWCOrig = pWC; /* Original pWC value */
+ int j, k; /* Loop counters */
+ Expr *pX; /* Pointer to an expression */
+ Parse *pParse; /* Parsing context */
+ int nEquiv = 2; /* Number of entires in aEquiv[] */
+ int iEquiv = 2; /* Number of entries of aEquiv[] processed so far */
+ int aEquiv[22]; /* iCur,iColumn and up to 10 other equivalents */
assert( iCur>=0 );
aEquiv[0] = iCur;
static int isEquivalenceExpr(Parse *pParse, Expr *pExpr){
const CollSeq *pCLeft, *pCRight;
if( pExpr->op!=TK_EQ ) return 0;
- if( ExprHasProperty(pExpr, EP_FromJoin) ) return 0;
+ if( ExprHasProperty(pExpr, EP_FromJoin) ){
+ return 0;
+ }
assert( sqlite3ExprSkipCollate(pExpr->pRight)->op==TK_COLUMN );
assert( sqlite3ExprSkipCollate(pExpr->pLeft)->op==TK_COLUMN );
if( sqlite3ExprAffinity(pExpr->pLeft)!=sqlite3ExprAffinity(pExpr->pRight) ){
pCLeft = sqlite3ExprCollSeq(pParse, pExpr->pLeft);
if( pCLeft ){
pCRight = sqlite3ExprCollSeq(pParse, pExpr->pRight);
- if( pCRight && pCRight!=pCLeft ) return 0;
+ if( pCRight && pCRight!=pCLeft ){
+ return 0;
+ }
}
return 1;
}