-
Notifications
You must be signed in to change notification settings - Fork 1.9k
Add ExecutionPlan::reset_state #17028
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
Changes from 5 commits
6562cc7
c4838de
9391713
5425c9b
f50d737
5323b11
9073b6a
73b5053
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -905,6 +905,29 @@ impl SortExec { | |||||||||||||||||||||||||||
| self | ||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| /// Add or reset `self.filter` to a new `DynamicFilterPhysicalExpr`. | ||||||||||||||||||||||||||||
| fn create_filter(&self) -> Arc<DynamicFilterPhysicalExpr> { | ||||||||||||||||||||||||||||
| let children = self | ||||||||||||||||||||||||||||
| .expr | ||||||||||||||||||||||||||||
| .iter() | ||||||||||||||||||||||||||||
| .map(|sort_expr| Arc::clone(&sort_expr.expr)) | ||||||||||||||||||||||||||||
| .collect::<Vec<_>>(); | ||||||||||||||||||||||||||||
| Arc::new(DynamicFilterPhysicalExpr::new(children, lit(true))) | ||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| fn cloned(&self) -> Self { | ||||||||||||||||||||||||||||
| SortExec { | ||||||||||||||||||||||||||||
| input: Arc::clone(&self.input), | ||||||||||||||||||||||||||||
| expr: self.expr.clone(), | ||||||||||||||||||||||||||||
| metrics_set: self.metrics_set.clone(), | ||||||||||||||||||||||||||||
| preserve_partitioning: self.preserve_partitioning, | ||||||||||||||||||||||||||||
| common_sort_prefix: self.common_sort_prefix.clone(), | ||||||||||||||||||||||||||||
| fetch: self.fetch, | ||||||||||||||||||||||||||||
| cache: self.cache.clone(), | ||||||||||||||||||||||||||||
| filter: self.filter.clone(), | ||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| /// Modify how many rows to include in the result | ||||||||||||||||||||||||||||
| /// | ||||||||||||||||||||||||||||
| /// If None, then all rows will be returned, in sorted order. | ||||||||||||||||||||||||||||
|
|
@@ -926,25 +949,13 @@ impl SortExec { | |||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
| let filter = fetch.is_some().then(|| { | ||||||||||||||||||||||||||||
| // If we already have a filter, keep it. Otherwise, create a new one. | ||||||||||||||||||||||||||||
| self.filter.clone().unwrap_or_else(|| { | ||||||||||||||||||||||||||||
| let children = self | ||||||||||||||||||||||||||||
| .expr | ||||||||||||||||||||||||||||
| .iter() | ||||||||||||||||||||||||||||
| .map(|sort_expr| Arc::clone(&sort_expr.expr)) | ||||||||||||||||||||||||||||
| .collect::<Vec<_>>(); | ||||||||||||||||||||||||||||
| Arc::new(DynamicFilterPhysicalExpr::new(children, lit(true))) | ||||||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||||||
| self.filter.clone().unwrap_or_else(|| self.create_filter()) | ||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||
| SortExec { | ||||||||||||||||||||||||||||
| input: Arc::clone(&self.input), | ||||||||||||||||||||||||||||
| expr: self.expr.clone(), | ||||||||||||||||||||||||||||
| metrics_set: self.metrics_set.clone(), | ||||||||||||||||||||||||||||
| preserve_partitioning: self.preserve_partitioning, | ||||||||||||||||||||||||||||
| common_sort_prefix: self.common_sort_prefix.clone(), | ||||||||||||||||||||||||||||
| fetch, | ||||||||||||||||||||||||||||
| cache, | ||||||||||||||||||||||||||||
| filter, | ||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
| let mut new_sort = self.cloned(); | ||||||||||||||||||||||||||||
| new_sort.fetch = fetch; | ||||||||||||||||||||||||||||
| new_sort.cache = cache; | ||||||||||||||||||||||||||||
| new_sort.filter = filter; | ||||||||||||||||||||||||||||
| new_sort | ||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| /// Input schema | ||||||||||||||||||||||||||||
|
|
@@ -1116,10 +1127,46 @@ impl ExecutionPlan for SortExec { | |||||||||||||||||||||||||||
| self: Arc<Self>, | ||||||||||||||||||||||||||||
| children: Vec<Arc<dyn ExecutionPlan>>, | ||||||||||||||||||||||||||||
| ) -> Result<Arc<dyn ExecutionPlan>> { | ||||||||||||||||||||||||||||
| let mut new_sort = SortExec::new(self.expr.clone(), Arc::clone(&children[0])) | ||||||||||||||||||||||||||||
| .with_fetch(self.fetch) | ||||||||||||||||||||||||||||
| .with_preserve_partitioning(self.preserve_partitioning); | ||||||||||||||||||||||||||||
| new_sort.filter = self.filter.clone(); | ||||||||||||||||||||||||||||
| let mut new_sort = self.cloned(); | ||||||||||||||||||||||||||||
| assert!( | ||||||||||||||||||||||||||||
| children.len() == 1, | ||||||||||||||||||||||||||||
| "SortExec should have exactly one child" | ||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||
| new_sort.input = Arc::clone(&children[0]); | ||||||||||||||||||||||||||||
| // Recompute the properties based on the new input since they may have changed. | ||||||||||||||||||||||||||||
| let (cache, sort_prefix) = Self::compute_properties( | ||||||||||||||||||||||||||||
| &new_sort.input, | ||||||||||||||||||||||||||||
| new_sort.expr.clone(), | ||||||||||||||||||||||||||||
| new_sort.preserve_partitioning, | ||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||
| .expect(concat!( | ||||||||||||||||||||||||||||
| "Safety: we had already been calling `compute_properties(...).unwrap()` in `new()` ", | ||||||||||||||||||||||||||||
| "and it seems to be okay", | ||||||||||||||||||||||||||||
| "\n", | ||||||||||||||||||||||||||||
| "We assumed that doing the same thing here directly instead ", | ||||||||||||||||||||||||||||
| "of calling `new()` (as we did before this commit) is also okay but it's possible that ", | ||||||||||||||||||||||||||||
| "implementations have drifted and this is no longer safe even if `new()` still works, ", | ||||||||||||||||||||||||||||
| "for example if `new()` now does something different than just calling `compute_properties(...).unwrap()`", | ||||||||||||||||||||||||||||
| "\n", | ||||||||||||||||||||||||||||
| "This is clearly a bug, please report it!" | ||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||
| impl SortExec { | |
| /// Create a new sort execution plan that produces a single, | |
| /// sorted output partition. | |
| pub fn new(expr: LexOrdering, input: Arc<dyn ExecutionPlan>) -> Self { | |
| let preserve_partitioning = false; | |
| let (cache, sort_prefix) = | |
| Self::compute_properties(&input, expr.clone(), preserve_partitioning) | |
| .unwrap(); |
datafusion/datafusion/physical-plan/src/sorts/sort.rs
Lines 1115 to 1119 in eb2b8c0
| fn with_new_children( | |
| self: Arc<Self>, | |
| children: Vec<Arc<dyn ExecutionPlan>>, | |
| ) -> Result<Arc<dyn ExecutionPlan>> { | |
| let mut new_sort = SortExec::new(self.expr.clone(), Arc::clone(&children[0])) |
Returning a Result would be a major breaking change to the ExecutionPlan::with_new_children API which I don't think we should do in this PR.
I do think ExecutionPlan::with_new_children returning a Result would be a good thing. In general I think trait methods should err on the side of returning a result in case some implementation needs to. If none of them do I'd expect compilation to make it pretty much a non issue for performance. But maybe let's do that as it's own PR if we really want to.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if we should also add a note to DynamicFilterPhysicalExpr saying any ExecutionPlan that uses them should also implement
reset_stateThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
98b5a72