diff options
author | drh <> | 2024-03-16 20:15:34 +0000 |
---|---|---|
committer | drh <> | 2024-03-16 20:15:34 +0000 |
commit | 7dc3e923c4066eeb3c8a16f9de736c755b621b00 (patch) | |
tree | 85082b35b39fa79979c297da33ebc72f6d9c5716 /src/expr.c | |
parent | 4713b2d73ca0053671c7b6e8502647e1a2c0a411 (diff) | |
download | sqlite-7dc3e923c4066eeb3c8a16f9de736c755b621b00.tar.gz sqlite-7dc3e923c4066eeb3c8a16f9de736c755b621b00.zip |
Further expand the scope of usage for the enhacement to expr-is-constant.
FossilOrigin-Name: d7eadcf7dd089f0f4aa963c58f0df32edd951368c9906375fd62b0a61cd393b8
Diffstat (limited to 'src/expr.c')
-rw-r--r-- | src/expr.c | 48 |
1 files changed, 21 insertions, 27 deletions
diff --git a/src/expr.c b/src/expr.c index 66070db5b..4b312873f 100644 --- a/src/expr.c +++ b/src/expr.c @@ -2372,8 +2372,9 @@ static SQLITE_NOINLINE int exprNodeIsConstantFunction( sqlite3 *db; /* The database */ assert( pExpr->op==TK_FUNCTION ); - pList = pExpr->x.pList; - if( pList==0 ){ + if( ExprHasProperty(pExpr, EP_TokenOnly) + || (pList = pExpr->x.pList)==0 + ){; n = 0; }else{ n = pList->nExpr; @@ -2494,10 +2495,10 @@ static int exprNodeIsConstant(Walker *pWalker, Expr *pExpr){ return WRC_Continue; } } -static int exprIsConst(Expr *p, int initFlag, int iCur){ +static int exprIsConst(Parse *pParse, Expr *p, int initFlag, int iCur){ Walker w; w.eCode = initFlag; - w.pParse = 0; + w.pParse = pParse; w.xExprCallback = exprNodeIsConstant; w.xSelectCallback = sqlite3SelectWalkFail; #ifdef SQLITE_DEBUG @@ -2523,16 +2524,7 @@ static int exprIsConst(Expr *p, int initFlag, int iCur){ ** function and on its parameters. */ int sqlite3ExprIsConstant(Parse *pParse, Expr *p){ - Walker w; - w.eCode = 1; - w.pParse = pParse; - w.xExprCallback = exprNodeIsConstant; - w.xSelectCallback = sqlite3SelectWalkFail; -#ifdef SQLITE_DEBUG - w.xSelectCallback2 = sqlite3SelectWalkAssert2; -#endif - sqlite3WalkExpr(&w, p); - return w.eCode; + return exprIsConst(pParse, p, 1, 0); } /* @@ -2548,8 +2540,8 @@ int sqlite3ExprIsConstant(Parse *pParse, Expr *p){ ** can be added to the pParse->pConstExpr list and evaluated once when ** the prepared statement starts up. See sqlite3ExprCodeRunJustOnce(). */ -int sqlite3ExprIsConstantNotJoin(Expr *p){ - return exprIsConst(p, 2, 0); +static int sqlite3ExprIsConstantNotJoin(Parse *pParse, Expr *p){ + return exprIsConst(pParse, p, 2, 0); } /* @@ -2559,7 +2551,7 @@ int sqlite3ExprIsConstantNotJoin(Expr *p){ ** table other than iCur. */ int sqlite3ExprIsTableConstant(Expr *p, int iCur){ - return exprIsConst(p, 3, iCur); + return exprIsConst(0, p, 3, iCur); } /* @@ -2716,7 +2708,7 @@ int sqlite3ExprIsConstantOrGroupBy(Parse *pParse, Expr *p, ExprList *pGroupBy){ */ int sqlite3ExprIsConstantOrFunction(Expr *p, u8 isInit){ assert( isInit==0 || isInit==1 ); - return exprIsConst(p, 4+isInit, 0); + return exprIsConst(0, p, 4+isInit, 0); } #ifdef SQLITE_ENABLE_CURSOR_HINTS @@ -2961,13 +2953,13 @@ static void sqlite3SetHasNullFlag(Vdbe *v, int iCur, int regHasNull){ ** The argument is an IN operator with a list (not a subquery) on the ** right-hand side. Return TRUE if that list is constant. */ -static int sqlite3InRhsIsConstant(Expr *pIn){ +static int sqlite3InRhsIsConstant(Parse *pParse, Expr *pIn){ Expr *pLHS; int res; assert( !ExprHasProperty(pIn, EP_xIsSelect) ); pLHS = pIn->pLeft; pIn->pLeft = 0; - res = sqlite3ExprIsConstant(0, pIn); + res = sqlite3ExprIsConstant(pParse, pIn); pIn->pLeft = pLHS; return res; } @@ -3236,7 +3228,7 @@ int sqlite3FindInIndex( if( eType==0 && (inFlags & IN_INDEX_NOOP_OK) && ExprUseXList(pX) - && (!sqlite3InRhsIsConstant(pX) || pX->x.pList->nExpr<=2) + && (!sqlite3InRhsIsConstant(pParse,pX) || pX->x.pList->nExpr<=2) ){ pParse->nTab--; /* Back out the allocation of the unused cursor */ iTab = -1; /* Cursor is not allocated */ @@ -3519,7 +3511,7 @@ void sqlite3CodeRhsOfIN( ** this code only executes once. Because for a non-constant ** expression we need to rerun this code each time. */ - if( addrOnce && !sqlite3ExprIsConstant(0, pE2) ){ + if( addrOnce && !sqlite3ExprIsConstant(pParse, pE2) ){ sqlite3VdbeChangeToNoop(v, addrOnce-1); sqlite3VdbeChangeToNoop(v, addrOnce); ExprClearProperty(pExpr, EP_Subrtn); @@ -4856,7 +4848,9 @@ expr_code_doover: } #endif - if( ConstFactorOk(pParse) && sqlite3ExprIsConstantNotJoin(pExpr) ){ + if( ConstFactorOk(pParse) + && sqlite3ExprIsConstantNotJoin(pParse,pExpr) + ){ /* SQL functions can be expensive. So try to avoid running them ** multiple times if we know they always give the same result */ return sqlite3ExprCodeRunJustOnce(pParse, pExpr, -1); @@ -4887,7 +4881,7 @@ expr_code_doover: } for(i=0; i<nFarg; i++){ - if( i<32 && sqlite3ExprIsConstant(0, pFarg->a[i].pExpr) ){ + if( i<32 && sqlite3ExprIsConstant(pParse, pFarg->a[i].pExpr) ){ testcase( i==31 ); constMask |= MASKBIT32(i); } @@ -5354,7 +5348,7 @@ int sqlite3ExprCodeTemp(Parse *pParse, Expr *pExpr, int *pReg){ if( ConstFactorOk(pParse) && ALWAYS(pExpr!=0) && pExpr->op!=TK_REGISTER - && sqlite3ExprIsConstantNotJoin(pExpr) + && sqlite3ExprIsConstantNotJoin(pParse, pExpr) ){ *pReg = 0; r2 = sqlite3ExprCodeRunJustOnce(pParse, pExpr, -1); @@ -5418,7 +5412,7 @@ void sqlite3ExprCodeCopy(Parse *pParse, Expr *pExpr, int target){ ** might choose to code the expression at initialization time. */ void sqlite3ExprCodeFactorable(Parse *pParse, Expr *pExpr, int target){ - if( pParse->okConstFactor && sqlite3ExprIsConstantNotJoin(pExpr) ){ + if( pParse->okConstFactor && sqlite3ExprIsConstantNotJoin(pParse,pExpr) ){ sqlite3ExprCodeRunJustOnce(pParse, pExpr, target); }else{ sqlite3ExprCodeCopy(pParse, pExpr, target); @@ -5477,7 +5471,7 @@ int sqlite3ExprCodeExprList( sqlite3VdbeAddOp2(v, copyOp, j+srcReg-1, target+i); } }else if( (flags & SQLITE_ECEL_FACTOR)!=0 - && sqlite3ExprIsConstantNotJoin(pExpr) + && sqlite3ExprIsConstantNotJoin(pParse,pExpr) ){ sqlite3ExprCodeRunJustOnce(pParse, pExpr, target+i); }else{ |