aboutsummaryrefslogtreecommitdiff
path: root/src/expr.c
diff options
context:
space:
mode:
authordrh <>2024-03-16 20:15:34 +0000
committerdrh <>2024-03-16 20:15:34 +0000
commit7dc3e923c4066eeb3c8a16f9de736c755b621b00 (patch)
tree85082b35b39fa79979c297da33ebc72f6d9c5716 /src/expr.c
parent4713b2d73ca0053671c7b6e8502647e1a2c0a411 (diff)
downloadsqlite-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.c48
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{