diff options
author | drh <> | 2022-04-25 20:56:55 +0000 |
---|---|---|
committer | drh <> | 2022-04-25 20:56:55 +0000 |
commit | 3e4314b4f8f5505c2bd79c21a3f0dd26fa69f625 (patch) | |
tree | 0741eeaf387df95eb03c67896d917f0c94d55fb9 /src/expr.c | |
parent | 95fe38f2fc7468be6165552f8ef6bc85bcf1f358 (diff) | |
parent | 0e464b5f513bef5b08da17988a47c8baa8b34b90 (diff) | |
download | sqlite-3e4314b4f8f5505c2bd79c21a3f0dd26fa69f625.tar.gz sqlite-3e4314b4f8f5505c2bd79c21a3f0dd26fa69f625.zip |
Fix a problem with automatic indexes introduced by
check-in [664b461bb5063d980] and reported by
[forum:/forumpost/0d3200f4f3bcd3a3|forum post 0d3200f4f3bcd3a3].
FossilOrigin-Name: 134cfb18ff930e4bccc1a7412a02be353bf67c6d5080bc0673afaac81afa889c
Diffstat (limited to 'src/expr.c')
-rw-r--r-- | src/expr.c | 36 |
1 files changed, 36 insertions, 0 deletions
diff --git a/src/expr.c b/src/expr.c index 170987621..addd5794d 100644 --- a/src/expr.c +++ b/src/expr.c @@ -2296,6 +2296,42 @@ int sqlite3ExprIsTableConstant(Expr *p, int iCur){ return exprIsConst(p, 3, iCur); } +/* +** Check pExpr to see if it is an invariant constraint on data source pSrc. +** This is an optimization. False negatives will perhaps cause slower +** queries, but false positives will yield incorrect answers. So when in +** double, return 0. +** +** To be an invariant constraint, the following must be true: +** +** (1) pExpr cannot refer to any table other than pSrc->iCursor. +** +** (2) pExpr cannot use subqueries or non-deterministic functions. +** +** (3) pSrc cannot be part of the left operand for a RIGHT JOIN. +** (Is there some way to relax this constraint?) +** +** (4) If pSrc is the right operand of a LEFT JOIN, then... +** (4a) pExpr must come from an ON clause.. + (4b) and specifically the ON clause associated with the LEFT JOIN. +** +** (5) If pSrc is not the right operand of a LEFT JOIN or the left +** operand of a RIGHT JOIN, then pExpr must be from the WHERE +** clause, not an ON clause. +*/ +int sqlite3ExprIsTableConstraint(Expr *pExpr, const SrcItem *pSrc){ + if( pSrc->fg.jointype & JT_LTORJ ){ + return 0; /* rule (3) */ + } + if( pSrc->fg.jointype & JT_LEFT ){ + if( !ExprHasProperty(pExpr, EP_FromJoin) ) return 0; /* rule (4a) */ + if( pExpr->w.iJoin!=pSrc->iCursor ) return 0; /* rule (4b) */ + }else{ + if( ExprHasProperty(pExpr, EP_FromJoin) ) return 0; /* rule (5) */ + } + return sqlite3ExprIsTableConstant(pExpr, pSrc->iCursor); /* rules (1), (2) */ +} + /* ** sqlite3WalkExpr() callback used by sqlite3ExprIsConstantOrGroupBy(). |