mirror of
https://github.com/sqlite/sqlite.git
synced 2025-11-08 03:22:21 +03:00
Generate VDBE code for the built-in COALESCE() and IFNULL() functions. This
allows unused arguments to never be evaluated, which is a performance win when the unused argument is a subquery. FossilOrigin-Name: 30055b257c3c65f8123cad5ac6c62c4c6ca2c900
This commit is contained in:
21
src/expr.c
21
src/expr.c
@@ -2394,6 +2394,27 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){
|
||||
sqlite3ErrorMsg(pParse, "unknown function: %.*s()", nId, zId);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Attempt a direct implementation of the built-in COALESCE() and
|
||||
** IFNULL() functions. This avoids unnecessary evalation of
|
||||
** arguments past the first non-NULL argument.
|
||||
*/
|
||||
if( pDef->flags & SQLITE_FUNC_COALESCE ){
|
||||
int endCoalesce = sqlite3VdbeMakeLabel(v);
|
||||
assert( nFarg>=2 );
|
||||
sqlite3ExprCode(pParse, pFarg->a[0].pExpr, target);
|
||||
for(i=1; i<nFarg; i++){
|
||||
sqlite3VdbeAddOp2(v, OP_NotNull, target, endCoalesce);
|
||||
sqlite3ExprCacheRemove(pParse, target);
|
||||
sqlite3ExprCachePush(pParse);
|
||||
sqlite3ExprCode(pParse, pFarg->a[i].pExpr, target);
|
||||
sqlite3ExprCachePop(pParse, 1);
|
||||
}
|
||||
sqlite3VdbeResolveLabel(v, endCoalesce);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if( pFarg ){
|
||||
r1 = sqlite3GetTempRange(pParse, nFarg);
|
||||
sqlite3ExprCachePush(pParse); /* Ticket 2ea2425d34be */
|
||||
|
||||
Reference in New Issue
Block a user