1
0
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:
drh
2009-11-11 00:24:31 +00:00
parent 63b3878921
commit ae6bb9570b
5 changed files with 48 additions and 14 deletions

View File

@@ -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 */