aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordrh <>2024-04-06 18:30:09 +0000
committerdrh <>2024-04-06 18:30:09 +0000
commit6951c4977976ddca0b9e4ce75e79fc69c44dfd77 (patch)
tree50b7d2e4c5e99706a66c4c419b748ad023944afe /src
parented27183d835a0a3c4a2f17f9c3097d976aedc624 (diff)
downloadsqlite-6951c4977976ddca0b9e4ce75e79fc69c44dfd77.tar.gz
sqlite-6951c4977976ddca0b9e4ce75e79fc69c44dfd77.zip
Do not allow changes to sqlite3ExprIsTableConstant() that support pushdown of
subqueries interfere with the hash-join logic. FossilOrigin-Name: 8682931f9c6b40e1b09139c10bbe932c38330b5eb0c5c84f2432ad19a6793e37
Diffstat (limited to 'src')
-rw-r--r--src/expr.c25
-rw-r--r--src/select.c2
-rw-r--r--src/sqliteInt.h2
-rw-r--r--src/where.c4
4 files changed, 23 insertions, 10 deletions
diff --git a/src/expr.c b/src/expr.c
index 9513e5ffd..0ccb39cc6 100644
--- a/src/expr.c
+++ b/src/expr.c
@@ -2570,14 +2570,22 @@ static int exprSelectWalkTableConstant(Walker *pWalker, Select *pSelect){
** expression must not refer to any non-deterministic function nor any
** table other than iCur.
**
-** Enhanced on 2024-04-06: Allow pExpr to contain uncorrelated subqueries.
+** Consider uncorrelated subqueries to be constants if the bAllowSubq
+** parameter is true.
*/
-static int sqlite3ExprIsTableConstant(Expr *p, int iCur){
+static int sqlite3ExprIsTableConstant(Expr *p, int iCur, int bAllowSubq){
Walker w;
w.eCode = 3;
w.pParse = 0;
w.xExprCallback = exprNodeIsConstant;
- w.xSelectCallback = exprSelectWalkTableConstant;
+ if( bAllowSubq ){
+ w.xSelectCallback = exprSelectWalkTableConstant;
+ }else{
+ w.xSelectCallback = sqlite3SelectWalkFail;
+#ifdef SQLITE_DEBUG
+ w.xSelectCallback2 = sqlite3SelectWalkAssert2;
+#endif
+ }
w.u.iCur = iCur;
sqlite3WalkExpr(&w, p);
return w.eCode;
@@ -2598,7 +2606,10 @@ static int sqlite3ExprIsTableConstant(Expr *p, int iCur){
**
** (1) pExpr cannot refer to any table other than pSrc->iCursor.
**
-** (2) pExpr cannot use subqueries or non-deterministic functions.
+** (2a) pExpr cannot use subqueries unless the bAllowSubq parameter is
+** true and the subquery is non-correlated
+**
+** (2b) pExpr cannot use non-deterministic functions.
**
** (3) pSrc cannot be part of the left operand for a RIGHT JOIN.
** (Is there some way to relax this constraint?)
@@ -2627,7 +2638,8 @@ static int sqlite3ExprIsTableConstant(Expr *p, int iCur){
int sqlite3ExprIsSingleTableConstraint(
Expr *pExpr, /* The constraint */
const SrcList *pSrcList, /* Complete FROM clause */
- int iSrc /* Which element of pSrcList to use */
+ int iSrc, /* Which element of pSrcList to use */
+ int bAllowSubq /* Allow non-correlated subqueries */
){
const SrcItem *pSrc = &pSrcList->a[iSrc];
if( pSrc->fg.jointype & JT_LTORJ ){
@@ -2652,7 +2664,8 @@ int sqlite3ExprIsSingleTableConstraint(
}
}
}
- return sqlite3ExprIsTableConstant(pExpr, pSrc->iCursor); /* rules (1), (2) */
+ /* Rules (1), (2a), and (2b) handled by the following: */
+ return sqlite3ExprIsTableConstant(pExpr, pSrc->iCursor, bAllowSubq);
}
diff --git a/src/select.c b/src/select.c
index b20051851..b13aae1f9 100644
--- a/src/select.c
+++ b/src/select.c
@@ -5260,7 +5260,7 @@ static int pushDownWhereTerms(
}
#endif
- if( sqlite3ExprIsSingleTableConstraint(pWhere, pSrcList, iSrc) ){
+ if( sqlite3ExprIsSingleTableConstraint(pWhere, pSrcList, iSrc, 1) ){
nChng++;
pSubq->selFlags |= SF_PushDown;
while( pSubq ){
diff --git a/src/sqliteInt.h b/src/sqliteInt.h
index a735c445e..d80a64609 100644
--- a/src/sqliteInt.h
+++ b/src/sqliteInt.h
@@ -5082,7 +5082,7 @@ int sqlite3ExprTruthValue(const Expr*);
int sqlite3ExprIsConstant(Parse*,Expr*);
int sqlite3ExprIsConstantOrFunction(Expr*, u8);
int sqlite3ExprIsConstantOrGroupBy(Parse*, Expr*, ExprList*);
-int sqlite3ExprIsSingleTableConstraint(Expr*,const SrcList*,int);
+int sqlite3ExprIsSingleTableConstraint(Expr*,const SrcList*,int,int);
#ifdef SQLITE_ENABLE_CURSOR_HINTS
int sqlite3ExprContainsSubquery(Expr*);
#endif
diff --git a/src/where.c b/src/where.c
index a1837b587..65b6ae2c9 100644
--- a/src/where.c
+++ b/src/where.c
@@ -942,7 +942,7 @@ static SQLITE_NOINLINE void constructAutomaticIndex(
** WHERE clause (or the ON clause of a LEFT join) that constrain which
** rows of the target table (pSrc) that can be used. */
if( (pTerm->wtFlags & TERM_VIRTUAL)==0
- && sqlite3ExprIsSingleTableConstraint(pExpr, pTabList, pLevel->iFrom)
+ && sqlite3ExprIsSingleTableConstraint(pExpr, pTabList, pLevel->iFrom, 0)
){
pPartial = sqlite3ExprAnd(pParse, pPartial,
sqlite3ExprDup(pParse->db, pExpr, 0));
@@ -1211,7 +1211,7 @@ static SQLITE_NOINLINE void sqlite3ConstructBloomFilter(
for(pTerm=pWInfo->sWC.a; pTerm<pWCEnd; pTerm++){
Expr *pExpr = pTerm->pExpr;
if( (pTerm->wtFlags & TERM_VIRTUAL)==0
- && sqlite3ExprIsSingleTableConstraint(pExpr, pTabList, iSrc)
+ && sqlite3ExprIsSingleTableConstraint(pExpr, pTabList, iSrc, 0)
){
sqlite3ExprIfFalse(pParse, pTerm->pExpr, addrCont, SQLITE_JUMPIFNULL);
}