diff options
author | drh <> | 2022-04-28 12:52:49 +0000 |
---|---|---|
committer | drh <> | 2022-04-28 12:52:49 +0000 |
commit | 09121b0523fd6f2e7795b65222aeace231382ac8 (patch) | |
tree | 80b3f69280a822a56187ffdecca7ef8f29e6ad79 /src/expr.c | |
parent | 7980fadceff1593fe703bb5d0b48ab1772ef81ae (diff) | |
parent | 22b541b55a12a137b533132396cbdf2e71e2f7d3 (diff) | |
download | sqlite-09121b0523fd6f2e7795b65222aeace231382ac8.tar.gz sqlite-09121b0523fd6f2e7795b65222aeace231382ac8.zip |
Merge trunk enhancements into the right-join branch.
FossilOrigin-Name: 3fd9706bba4a71cb5c7ce1341c3be0a7727941445820a073e7b2f0f32512e8ef
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 f532bba2e..2bc5eae20 100644 --- a/src/expr.c +++ b/src/expr.c @@ -2297,6 +2297,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 +** doubt, 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(). |