• Hugo Kornelis (3/31/2010)


    So if any of the arguments is a subquery, the implementation if COALESCE((subquery), ...) becomes CASE WHEN (subquery) IS NOT NULL THEN (subquery) ... ELSE NULL END.

    That reminds me of a CASE construction like the following:

    SELECT CASE CHECKSUM(NEWID()) % 3 + 1

    WHEN 1 THEN 'One'

    WHEN 2 THEN 'Two'

    WHEN 3 THEN 'Three'

    ELSE 'WTF?'

    END

    ...which quite frequently hits the ELSE, and that surprises some people.

    And the optimizer that sits a bit further down the line does apparently not realize that the two subqueries are identical, so it happily produces a plan that will evaluate the same subquery twice.

    Once expanded by the CASE, is it true to say that they are identical? It seems to me that the results are non-deterministic, so it would not be safe to collapse these evaluations. (One might argue that it would be safe at the SERIALIZABLE isolation level (or one of the row-versioning isolation levels), but the plan would not then be reusable).

    I blame the expansion of the CASE - which is apparently a documented design decision. I can live with it, though.

    Last thing: the optimizer does a great job at avoiding the extra subquery evaluations where possible. The plan produced is quite likely to feature a PassThrough expression on the joins, so that the subquery is not re-evaluated if a prior term in the COALESCE already produced a non-NULL value.