patternsqlModerate
Microsoft SQL Server 2014 Nested From Query in Cross-Apply
Viewed 0 times
sqlcrossqueryapplymicrosoftnestedserverfrom2014
Problem
When selecting from a nested query in an OUTER APPLY statement the nested query seems to be evaluated only once in certain circumstances.
Bug reported to Azure Feedback Forum: https://feedback.azure.com/forums/908035-sql-server/suggestions/39428632-microsoft-sql-server-2014-incorrect-result-when-s
Is this the expected behavior or am I missing something in the documentation or is this a bug in SQL Server?
Also, is there any possibility to force evaluation of the nested query for every row?
Test Case 1
Evaluates nested FROM query for every row in VALUES (imho expected
behaviour)
Result:
Test Case 2
It also evaluates nested FROM query for every row in VALUES (imho
expected behaviour)
Result:
Testcase 3
Evaluates nested FROM query only once
```
CREATE TABLE TestCaseTemp
(
id int,
v int
);
INSERT INTO TestCaseTemp VALUES (1337, 0);
SELECT
v,
v2
FROM
(VALUES (1), (2), (3), (4)) AS inner_query(v)
OUTER APPLY (
SELECT
MAX(inner_v2) AS v2
Bug reported to Azure Feedback Forum: https://feedback.azure.com/forums/908035-sql-server/suggestions/39428632-microsoft-sql-server-2014-incorrect-result-when-s
Is this the expected behavior or am I missing something in the documentation or is this a bug in SQL Server?
Also, is there any possibility to force evaluation of the nested query for every row?
Test Case 1
Evaluates nested FROM query for every row in VALUES (imho expected
behaviour)
SELECT
v,
v2
FROM
(VALUES (1), (2), (3), (4)) AS inner_query(v)
OUTER APPLY (
SELECT
MAX(inner_v2) AS v2
FROM (
SELECT
15 AS id,
v AS inner_v2
) AS outer_query
GROUP BY id
) AS outer_applyResult:
| v | v2|
|---|---|
| 1 | 1 |
| 2 | 2 |
| 3 | 3 |
| 4 | 4 |Test Case 2
It also evaluates nested FROM query for every row in VALUES (imho
expected behaviour)
SELECT
v,
v2
FROM
(VALUES (1), (2), (3), (4)) AS inner_query(v)
OUTER APPLY (
SELECT
MAX(inner_v2) AS v2
FROM (
SELECT
15 AS id,
v AS inner_v2
UNION ALL
SELECT
id AS id,
TestCaseTemp2.v AS inner_v2
FROM
(VALUES (1337, 0)) AS TestCaseTemp2(id, v)
WHERE TestCaseTemp2.v != 0
) AS outer_query
GROUP BY id
) AS outer_apply;Result:
| v | v2|
|---|---|
| 1 | 1 |
| 2 | 2 |
| 3 | 3 |
| 4 | 4 |Testcase 3
Evaluates nested FROM query only once
```
CREATE TABLE TestCaseTemp
(
id int,
v int
);
INSERT INTO TestCaseTemp VALUES (1337, 0);
SELECT
v,
v2
FROM
(VALUES (1), (2), (3), (4)) AS inner_query(v)
OUTER APPLY (
SELECT
MAX(inner_v2) AS v2
Solution
is this a bug in SQL Server?
Yes, certainly, the
I executed your final query in dbfiddle (SQL Server 2019) and pasted the plan here https://www.brentozar.com/pastetheplan/?id=Sy4sBB5lI It looks like the sort executes 4 times (once for each outer row) but for some reason it rewinds rather than rebinds so doesn't call the child operators of the sort more than once. This is a bug as the reference to the correlated parameter of the outer join (
I see you have now reported it here https://feedback.azure.com/forums/908035-sql-server/suggestions/39428632-microsoft-sql-server-2014-incorrect-result-when-s
Is there any possibility to force evaluation of the nested query for every row?
Adding the query hint
Yes, certainly, the
1 that is returned in all rows in your final result only exists in the first row of the outer input so shouldn't even be in scope for the subsequent rows. It looks like the same basic issue as looked at in detail by Paul White here.I executed your final query in dbfiddle (SQL Server 2019) and pasted the plan here https://www.brentozar.com/pastetheplan/?id=Sy4sBB5lI It looks like the sort executes 4 times (once for each outer row) but for some reason it rewinds rather than rebinds so doesn't call the child operators of the sort more than once. This is a bug as the reference to the correlated parameter of the outer join (
Union1004) should cause a rebind when this has changed value. As a result the reference to Union1004 in Node 5 of the plan is never re-evaluated. I see you have now reported it here https://feedback.azure.com/forums/908035-sql-server/suggestions/39428632-microsoft-sql-server-2014-incorrect-result-when-s
Is there any possibility to force evaluation of the nested query for every row?
Adding the query hint
OPTION (MERGE UNION) works for your example, I don't know if this will necessarily be sufficient to avoid the bug in all cases but from the linked Paul White answer it appears it should work. In the case of your example it works as the sort is pushed down lower in the plan so it only rewinds the TestCaseTemp rows, not the entire unioned result. You could also add appropriate indexing to remove the sort entirely.Context
StackExchange Database Administrators Q#257326, answer score: 10
Revisions (0)
No revisions yet.