1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-11-18 10:21:03 +03:00

Fix the transitive constraint processing to only allow transitivity if the

operands of the == or IS operator have compatible affinities.

FossilOrigin-Name: a46a247fbcfe6e63b12cef31353835295a650c9b
This commit is contained in:
drh
2015-05-16 19:17:17 +00:00
parent e655a0e34e
commit ea19cc10f5
3 changed files with 28 additions and 10 deletions

View File

@@ -1276,16 +1276,31 @@ static void exprAnalyze(
if( idxNew==0 ) return;
pNew = &pWC->a[idxNew];
markTermAsChild(pWC, idxNew, idxTerm);
if( op==TK_IS ) pNew->wtFlags |= TERM_IS;
pTerm = &pWC->a[idxTerm];
pTerm->wtFlags |= TERM_COPIED;
/* Expressions of the form "A==B" or "A IS B" might be candidates
** for propagating constraints via the transitive property. In other
** words: "A==B AND B==$xyz" implies "A==$xyz". If this term
** qualifies, mark it with WO_EQUIV. Necessary preconditions:
** 1. The term is not in the ON clause of a LEFT JOIN
** 2. The affinities of A and B must be compatible
** 3. The SQLITE_Transitive optimization must be enabled
*/
if( (op==TK_EQ || op==TK_IS)
&& !ExprHasProperty(pExpr, EP_FromJoin)
&& OptimizationEnabled(db, SQLITE_Transitive)
){
pTerm->eOperator |= WO_EQUIV;
eExtraOp = WO_EQUIV;
char aff1 = sqlite3ExprAffinity(pDup->pLeft);
char aff2 = sqlite3ExprAffinity(pDup->pRight);
if( aff1==aff2
|| (sqlite3IsNumericAffinity(aff1) && sqlite3IsNumericAffinity(aff2))
){
pTerm->eOperator |= WO_EQUIV;
eExtraOp = WO_EQUIV;
}
}
if( op==TK_IS ) pNew->wtFlags |= TERM_IS;
}else{
pDup = pExpr;
pNew = pTerm;