Welcome to MSDN Blogs Sign in | Join | Help

Syndication

News

Legalese: All postings are provided "AS IS" with no warranties, and confer no rights.
Evaluation Order

A common general SQL question just popped its head up in the Spatial Forum: when presented with a SQL query, in which order are the parts executed?  To be concrete, consider the following table and query:

T:

x
0
1
2
SELECT x
FROM T
WHERE x <> 0 AND (8 / x) > 5

What should the result of this query be?  Focus on the fact that we're chancing a divide-by-zero problem with the second clause of the AND.

If this were C, C++, C#, or Java---languages that short-circuit boolean expressions---then the result depends on the order of execution.  Left-to-right seems to be the universal choice, and so the result would be the singleton 1.  We avoid the the divide-by-zero: since 0 fails the first clause, the second is never executed.

Some languages don't short-circuit these expressions, and so they will raise a divide-by-zero.  Pascal is one example.  The order is still left-to-right, but it doesn't really matter since they all get executed.

So what actually happens in SQL?  SQL is that rare language that does short-circuit these expressions, but in which the order is not guaranteed.  As a result, we know this query will either yield a singleton 1 or an error, but we don't know which one.  This is done so that the optimizer can be clever about reordering operations to improve performance, but the result can often be undesirable.

What's a poor developer to do?  All that's possible is to avoid the situation.  Keep in mind that in many cases there isn't an issue, but if the order is important, then the key is usually to use the CASE statement, for which execution order is guaranteed.  This can be a bit clumsy:

SELECT x
FROM T
WHERE 8 / (CASE WHEN x = 0 THEN null ELSE x END) > 5

This is strange, but it is how it is.

Cheers,
-Isaac

Published Wednesday, May 07, 2008 12:59 AM by isaac

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS

Comments

# re: Evaluation Order @ Wednesday, May 07, 2008 9:26 AM

Is the order guarantee for CASE/WHEN specific to SQL Server, or is it required by the SQL spec?

int19h

# re: Evaluation Order @ Wednesday, May 07, 2008 1:05 PM

Does using this type of where clause allow for index usage? ("sargable")

kd

# re: Evaluation Order @ Monday, May 12, 2008 11:28 AM

Hi,

Sorry for the delayed response.  Regarding the standard, it seems to me that SQL99 requires this ordering.  In particular, it says that:

If the <search condition> of some <searched when clause> in a <case specification> is true, then the value of the <case specification> is the value of the <result> of the first (leftmost) <searched when clause> whose <search condition> is true, cast as the declared type of the <case specification>.

This implies an order (left-to-right) execution in a CASE, and says to me that if a particular WHEN clause returns true, then the corresponding THEN value should be returned, even if a later WHEN or THEN produce an error.

Regarding index use, I don't believe so.  That said, I don't believe the predicate in my example, (8 / x) > 5, would be answered by the index even without the CASE.

Cheers,

-Isaac

isaac

# re: Evaluation Order @ Saturday, May 17, 2008 8:55 AM

> This implies an order (left-to-right) execution in a CASE

It does imply order for sure, but I don't see it requiring short-circuiting - it seems that it is undefined whether that happens or not...

int19h

Leave a Comment

(required) 
required 
(required) 
Page view tracker