-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
SanityChecker rejects certain valid UNION
plans
#12446
Comments
I spent some time finding a smaller standalone reproducer create table t(a0 int, a int, b int, c int) as values (1, 2, 3, 4), (5, 6, 7, 8);
select * from (select c, a, NULL::int as a0 from t order by a, c) t1
union all
select * from (select c, NULL::int as a, a0 from t order by a0, c) t2
order by c, a, a0, b
limit 2; When run > select * from (select c, a, NULL::int as a0 from t order by a, c) t1
union all
select * from (select c, NULL::int as a, a0 from t order by a0, c) t2
order by c, a, a0, b
limit 2;
SanityCheckPlan
caused by
Error during planning: Plan: ["SortPreservingMergeExec: [c@0 ASC NULLS LAST,a@1 ASC NULLS LAST,a0@2 ASC NULLS LAST,b@3 ASC NULLS LAST], fetch=2", " UnionExec", " SortExec: TopK(fetch=2), expr=[c@0 ASC NULLS LAST,a@1 ASC NULLS LAST,b@3 ASC NULLS LAST], preserve_partitioning=[false]", " ProjectionExec: expr=[c@2 as c, a@0 as a, NULL as a0, b@1 as b]", " MemoryExec: partitions=1, partition_sizes=[1]", " SortExec: TopK(fetch=2), expr=[c@0 ASC NULLS LAST,a0@2 ASC NULLS LAST,b@3 ASC NULLS LAST], preserve_partitioning=[false]", " ProjectionExec: expr=[c@2 as c, NULL as a, a0@0 as a0, b@1 as b]", " MemoryExec: partitions=1, partition_sizes=[1]"] does not satisfy order requirements: [PhysicalSortRequirement { expr: Column { name: "c", index: 0 }, options: Some(SortOptions { descending: false, nulls_first: false }) }, PhysicalSortRequirement { expr: Column { name: "a", index: 1 }, options: Some(SortOptions { descending: false, nulls_first: false }) }, PhysicalSortRequirement { expr: Column { name: "a0", index: 2 }, options: Some(SortOptions { descending: false, nulls_first: false }) }, PhysicalSortRequirement { expr: Column { name: "b", index: 3 }, options: Some(SortOptions { descending: false, nulls_first: false }) }]. Child-0 order: OrderingEquivalenceClass { orderings: [[PhysicalSortExpr { expr: Column { name: "c", index: 0 }, options: SortOptions { descending: false, nulls_first: false } }, PhysicalSortExpr { expr: Column { name: "a", index: 1 }, options: SortOptions { descending: false, nulls_first: false } }], [PhysicalSortExpr { expr: Column { name: "c", index: 0 }, options: SortOptions { descending: false, nulls_first: false } }, PhysicalSortExpr { expr: Column { name: "a0", index: 2 }, options: SortOptions { descending: false, nulls_first: false } }]] } |
Even simpler: --- Create basic table
create table t(a0 int, a int, b int, c int) as values (1, 2, 3, 4), (5, 6, 7, 8);
--- Use a sorted union with limit
select * from (select c, a, NULL::int as a0 from t order by a, c) t1
union all
select * from (select c, NULL::int as a, a0 from t order by a0, c) t2
order by a, a0, c
limit 2;
|
I am trying to figure out where the bug is (is it in the union equivalence properties calculation). I am not sure it is. I added some debugging information to my small reproducer from #12446 (comment) to try and figure out what the code should be doing The debugging (full output below) shows the input equivalence properties are:
The current code computes the output equivalence properties as
However, this seems correct to me. I worked an example to show this 🤔 Worked exampleIf
And
There are at least two possible outputs Possible output 1: (sorted on
Possible output 2: ( also sorted on
Details
Here is the full output
|
Actually IMO the result should be [[a, a0, c], [a0, a, c]]. To do that, input orderings should be adjusted such that: I could show what is in my mind in a draft if you think my proposal can fix the problem. |
Ah, yes that makes sense -- that
Update: let me give it a try this afternoon and report back here. If I can't make it work, perhaps a draft would help |
I made progress and started a PR here: #12562. It is all tests at the moment, but I think I now have a better handle on what is needed. I'll try and write more tests and finish the code fix soon |
An update here is I have a WIP PR with tests, etc. #12562 I am now trying to figure out an appropriate algorithm to implement the adjustment that @berkaysynnada suggests in #12446 (comment)
I worry that if we are not careful, such an expansion will be some sort of expontential blow up. Maybe I can just hard code a limit of orderings to try 🤔 |
I will share my thoughts on it tomorrow
I have the same concern. We need to provide comprehensive tests. It would also be better if we observe the equivalence properties in the plans that include any Thank you for your effort |
I will do so. I think I have a solution that we can start discussing tomorrow |
An update here is that I think I have a reasonable algorithm in #12562 and have it working for many unit tests. I need to debug one last issue and then polish the PR up for review |
I debugged the issue, and it appers to be a stack overflow unrelated to this particular issue: #12700 |
Update here is that with these two PRs
The end to end tests (added in #12721) now pass successfully without error. 😅 So now it will be a matter of working through those PRs |
Update here is that we have the issued fixed now -- all that is left to close this ticket is to merge in the end to end tests: #12721 |
Describe the bug
There is a regression that was added that in a very very specific circumstance with sorted data and constant predicates and
UNION
queries where the query will now error with aSanityCheckPlan
error when it should complete.To Reproduce
@wiedld found a reproducer as part of #12414
c2e652e
Expected behavior
Query should run
Additional context
We believe this was uncovered by #11196 . The error in the sort order calculation has existed for awhile but #11196 now uncovered the issue
This was released in 40.0.0 https://github.com/apache/datafusion/blob/main/dev/changelog/40.0.0.md
The text was updated successfully, but these errors were encountered: