I am getting strange results when using inline function. Here is the code:
IF EXISTS (
SELECT * FROM sys.objects AS o WHERE name = 'vendor_relation_users'
) DROP FUNCTION dbo.vendor_relation_users;
GO
CREATE FUNCTION [dbo].[vendor_relation_users]
(
@user_name CHAR(12)
)
RETURNS TABLE
AS
RETURN (SELECT @user_name AS user_name WHERE @user_name NOT LIKE '06%');
GO
DECLARE @u CHAR(12) = '066BDLER'
SELECT a.user_name, is_v.user_name
FROM (SELECT @u AS user_name) a
OUTER APPLY [dbo].[vendor_relation_users](@u) AS is_v
SELECT a.user_name, is_v.user_name
FROM (SELECT @u AS user_name) a
OUTER APPLY (SELECT @u AS user_name WHERE @u NOT LIKE '06%') AS is_v
SELECT * FROM [dbo].[vendor_relation_users](@u)
So in the first SELECT statement I've just OUTER APPLied the function and it returns the result.
In the next statement I've took the code from function and put it straight to the OUTER APPLY statement.
And the last statement is just the direct function call.
I can't get why do the FIRST query returns the value...
This is a very interesting query. The behaviour of your first query depends upon whether you use
OPTION (RECOMPILE)
or not.As you point out, this:
returns this:
but if you add
OPTION (RECOMPILE)
like this:you correctly get this:
I suspect this is due to a bug in how the query optimiser short circuits these inline functions due to cardinality estimates. If you look at the query plan for the two queries you will see that the one without the OPTION RECOMPILE just returns a constant.