diff options
Diffstat (limited to 'src/expr.c')
-rw-r--r-- | src/expr.c | 53 |
1 files changed, 36 insertions, 17 deletions
diff --git a/src/expr.c b/src/expr.c index 82623b14b..e5d8a6129 100644 --- a/src/expr.c +++ b/src/expr.c @@ -70,7 +70,7 @@ Expr *sqlite3ExprAddCollateToken(Parse *pParse, Expr *pExpr, Token *pCollName){ Expr *pNew = sqlite3ExprAlloc(pParse->db, TK_COLLATE, pCollName, 1); if( pNew ){ pNew->pLeft = pExpr; - pNew->flags |= EP_Collate; + pNew->flags |= EP_Collate|EP_Skip; pExpr = pNew; } } @@ -85,13 +85,21 @@ Expr *sqlite3ExprAddCollateString(Parse *pParse, Expr *pExpr, const char *zC){ } /* -** Skip over any TK_COLLATE and/or TK_AS operators at the root of -** an expression. +** Skip over any TK_COLLATE or TK_AS operators and any unlikely() +** or likelihood() function at the root of an expression. */ Expr *sqlite3ExprSkipCollate(Expr *pExpr){ - while( pExpr && (pExpr->op==TK_COLLATE || pExpr->op==TK_AS) ){ - pExpr = pExpr->pLeft; - } + while( pExpr && ExprHasProperty(pExpr, EP_Skip) ){ + if( ExprHasProperty(pExpr, EP_Unlikely) ){ + assert( !ExprHasProperty(pExpr, EP_xIsSelect) ); + assert( pExpr->x.pList->nExpr>0 ); + assert( pExpr->op==TK_FUNCTION ); + pExpr = pExpr->x.pList->a[0].pExpr; + }else{ + assert( pExpr->op==TK_COLLATE || pExpr->op==TK_AS ); + pExpr = pExpr->pLeft; + } + } return pExpr; } @@ -2316,6 +2324,16 @@ static int usedAsColumnCache(Parse *pParse, int iFrom, int iTo){ #endif /* SQLITE_DEBUG || SQLITE_COVERAGE_TEST */ /* +** Convert an expression node to a TK_REGISTER +*/ +static void exprToRegister(Expr *p, int iReg){ + p->op2 = p->op; + p->op = TK_REGISTER; + p->iTable = iReg; + ExprClearProperty(p, EP_Skip); +} + +/* ** Generate code into the current Vdbe to evaluate the given ** expression. Attempt to store the results in register "target". ** Return the register where results are stored. @@ -2648,6 +2666,14 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){ break; } + /* The UNLIKELY() function is a no-op. The result is the value + ** of the first argument. + */ + if( pDef->funcFlags & SQLITE_FUNC_UNLIKELY ){ + assert( nFarg>=1 ); + sqlite3ExprCode(pParse, pFarg->a[0].pExpr, target); + break; + } if( pFarg ){ r1 = sqlite3GetTempRange(pParse, nFarg); @@ -2877,9 +2903,8 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){ cacheX = *pX; testcase( pX->op==TK_COLUMN ); testcase( pX->op==TK_REGISTER ); - cacheX.iTable = sqlite3ExprCodeTemp(pParse, pX, ®Free1); + exprToRegister(&cacheX, sqlite3ExprCodeTemp(pParse, pX, ®Free1)); testcase( regFree1==0 ); - cacheX.op = TK_REGISTER; opCompare.op = TK_EQ; opCompare.pLeft = &cacheX; pTest = &opCompare; @@ -3021,9 +3046,7 @@ int sqlite3ExprCodeAndCache(Parse *pParse, Expr *pExpr, int target){ int iMem; iMem = ++pParse->nMem; sqlite3VdbeAddOp2(v, OP_Copy, inReg, iMem); - pExpr->iTable = iMem; - pExpr->op2 = pExpr->op; - pExpr->op = TK_REGISTER; + exprToRegister(pExpr, iMem); } return inReg; } @@ -3402,9 +3425,7 @@ static int evalConstExpr(Walker *pWalker, Expr *pExpr){ ** but suboptimal, so we want to know about the situation to fix it. ** Hence the following assert: */ assert( r2==r1 ); - pExpr->op2 = pExpr->op; - pExpr->op = TK_REGISTER; - pExpr->iTable = r2; + exprToRegister(pExpr, r2); return WRC_Prune; } return WRC_Continue; @@ -3502,9 +3523,7 @@ static void exprCodeBetween( compRight.op = TK_LE; compRight.pLeft = &exprX; compRight.pRight = pExpr->x.pList->a[1].pExpr; - exprX.iTable = sqlite3ExprCodeTemp(pParse, &exprX, ®Free1); - exprX.op2 = exprX.op; - exprX.op = TK_REGISTER; + exprToRegister(&exprX, sqlite3ExprCodeTemp(pParse, &exprX, ®Free1)); if( jumpIfTrue ){ sqlite3ExprIfTrue(pParse, &exprAnd, dest, jumpIfNull); }else{ |