aboutsummaryrefslogtreecommitdiff
path: root/src/expr.c
diff options
context:
space:
mode:
authordrh <>2022-04-28 12:52:49 +0000
committerdrh <>2022-04-28 12:52:49 +0000
commit09121b0523fd6f2e7795b65222aeace231382ac8 (patch)
tree80b3f69280a822a56187ffdecca7ef8f29e6ad79 /src/expr.c
parent7980fadceff1593fe703bb5d0b48ab1772ef81ae (diff)
parent22b541b55a12a137b533132396cbdf2e71e2f7d3 (diff)
downloadsqlite-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.c36
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().