aboutsummaryrefslogtreecommitdiff
path: root/src/expr.c
diff options
context:
space:
mode:
authordrh <>2022-04-25 20:56:55 +0000
committerdrh <>2022-04-25 20:56:55 +0000
commit3e4314b4f8f5505c2bd79c21a3f0dd26fa69f625 (patch)
tree0741eeaf387df95eb03c67896d917f0c94d55fb9 /src/expr.c
parent95fe38f2fc7468be6165552f8ef6bc85bcf1f358 (diff)
parent0e464b5f513bef5b08da17988a47c8baa8b34b90 (diff)
downloadsqlite-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.c36
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().