Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is Sql Server's ISNULL() function lazy/short-circuited?

TIs ISNULL() a lazy function?

That is, if i code something like the following:

SELECT ISNULL(MYFIELD, getMyFunction()) FROM MYTABLE

will it always evaluate getMyFunction() or will it only evaluate it in the case where MYFIELD is actually null?

like image 558
eidylon Avatar asked Aug 31 '12 16:08

eidylon


People also ask

Does SQL Server short-circuit?

SQL Server does short-circuit sometimes, but the rules are complex, undocumented, and subject to change at any time.

What is Isnull () operator in SQL?

Definition and Usage The ISNULL() function returns a specified value if the expression is NULL. If the expression is NOT NULL, this function returns the expression.

Does SQL use short-circuit evaluation?

SQL Server does not short-circuit expressions.

What is the use of Isnull () function?

Returns a Boolean value that indicates whether an expression contains no valid data (Null). The required expressionargument is a Variant containing a numeric expression or string expression. IsNull returns True if expression is Null; otherwise, IsNull returns False.


2 Answers

This works fine

declare @X int
set @X = 1
select isnull(@X, 1/0)

But introducing an aggregate will make it fail and proving that the second argument could be evaluated before the first, sometimes.

declare @X int
set @X = 1
select isnull(@X, min(1/0))
like image 141
Mikael Eriksson Avatar answered Sep 19 '22 22:09

Mikael Eriksson


It's whichever it thinks will work best.

Now it's functionally lazy, which is the important thing. E.g. if col1 is a varchar which will always contain a number when col2 is null, then

isnull(col2, cast(col1 as int))

Will work.

However, it's not specified whether it will try the cast before or simultaneously with the null-check and eat the error if col2 isn't null, or if it will only try the cast at all if col2 is null.

At the very least, we would expect it to obtain col1 in any case because a single scan of a table obtaining 2 values is going to be faster than two scans obtaining one each.

The same SQL commands can be executed in very different ways, because the instructions we give are turned into lower-level operations based on knowledge of the indices and statistics about the tables.

For that reason, in terms of performance, the answer is "when it seems like it would be a good idea it is, otherwise it isn't".

In terms of observed behaviour, it is lazy.

Edit: Mikael Eriksson's answer shows that there are cases that may indeed error due to not being lazy. I'll stick by my answer here in terms of the performance impact, but his is vital in terms of correctness impact across at least some cases.

like image 27
Jon Hanna Avatar answered Sep 18 '22 22:09

Jon Hanna