-
Notifications
You must be signed in to change notification settings - Fork 4.2k
ARROW-10582: [Rust] [DataFusion] Implement "repartition" operator #8982
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 18 commits
84b0824
3c35af9
7472e25
634c626
ff1dbbc
f5dff60
d546890
72869d4
9c7716b
1441d85
a9f4b42
d845f92
16b69f7
655426b
a7483df
67ee55e
23c0b6c
6c765d7
dc992df
66aa0fc
aabdf94
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 |
|---|---|---|
|
|
@@ -24,6 +24,7 @@ use crate::error::Result; | |
| use crate::execution::context::{ExecutionContext, ExecutionContextState}; | ||
| use crate::logical_plan::{ | ||
| col, DFSchema, Expr, FunctionRegistry, JoinType, LogicalPlan, LogicalPlanBuilder, | ||
| Partitioning, | ||
| }; | ||
| use crate::{arrow::record_batch::RecordBatch, physical_plan::collect}; | ||
|
|
||
|
|
@@ -111,6 +112,16 @@ impl DataFrame for DataFrameImpl { | |
| Ok(Arc::new(DataFrameImpl::new(self.ctx_state.clone(), &plan))) | ||
| } | ||
|
|
||
| fn repartition( | ||
| &self, | ||
| partitioning_scheme: Partitioning, | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: this introduces a new naming, We have:
I do not know the common notation, but we could try to reduce the number of different names we use. In my (little) understanding:
In this understanding, I would replace Even if this understanding is not correct, maybe we could reduce the number of different names?
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I agree keeping the number of different names low is important I suggest using
Thus we would |
||
| ) -> Result<Arc<dyn DataFrame>> { | ||
| let plan = LogicalPlanBuilder::from(&self.plan) | ||
| .repartition(partitioning_scheme)? | ||
| .build()?; | ||
| Ok(Arc::new(DataFrameImpl::new(self.ctx_state.clone(), &plan))) | ||
| } | ||
|
|
||
| /// Convert to logical plan | ||
| fn to_logical_plan(&self) -> LogicalPlan { | ||
| self.plan.clone() | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -110,6 +110,13 @@ pub enum LogicalPlan { | |
| /// The output schema, containing fields from the left and right inputs | ||
| schema: DFSchemaRef, | ||
| }, | ||
| /// Repartition the plan based on a partitioning scheme. | ||
| Repartition { | ||
| /// The incoming logical plan | ||
| input: Arc<LogicalPlan>, | ||
| /// The partitioning scheme | ||
| partitioning_scheme: Partitioning, | ||
| }, | ||
| /// Produces rows from a table provider by reference or from the context | ||
| TableScan { | ||
| /// The name of the table | ||
|
|
@@ -182,6 +189,7 @@ impl LogicalPlan { | |
| LogicalPlan::Aggregate { schema, .. } => &schema, | ||
| LogicalPlan::Sort { input, .. } => input.schema(), | ||
| LogicalPlan::Join { schema, .. } => &schema, | ||
| LogicalPlan::Repartition { input, .. } => input.schema(), | ||
| LogicalPlan::Limit { input, .. } => input.schema(), | ||
| LogicalPlan::CreateExternalTable { schema, .. } => &schema, | ||
| LogicalPlan::Explain { schema, .. } => &schema, | ||
|
|
@@ -198,6 +206,15 @@ impl LogicalPlan { | |
| } | ||
| } | ||
|
|
||
| /// Logical partitioning schemes supported by the repartition operator. | ||
| #[derive(Debug, Clone)] | ||
| pub enum Partitioning { | ||
| /// Allocate batches using a round-robin algorithm | ||
| RoundRobinBatch(usize), | ||
| /// Allocate rows based on a hash of one of more expressions | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Document
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe also add a comment here that |
||
| Hash(Vec<Expr>, usize), | ||
| } | ||
|
|
||
| /// Trait that implements the [Visitor | ||
| /// pattern](https://en.wikipedia.org/wiki/Visitor_pattern) for a | ||
| /// depth first walk of `LogicalPlan` nodes. `pre_visit` is called | ||
|
|
@@ -261,6 +278,7 @@ impl LogicalPlan { | |
| let recurse = match self { | ||
| LogicalPlan::Projection { input, .. } => input.accept(visitor)?, | ||
| LogicalPlan::Filter { input, .. } => input.accept(visitor)?, | ||
| LogicalPlan::Repartition { input, .. } => input.accept(visitor)?, | ||
| LogicalPlan::Aggregate { input, .. } => input.accept(visitor)?, | ||
| LogicalPlan::Sort { input, .. } => input.accept(visitor)?, | ||
| LogicalPlan::Join { left, right, .. } => { | ||
|
|
@@ -464,7 +482,7 @@ impl LogicalPlan { | |
| struct Wrapper<'a>(&'a LogicalPlan); | ||
| impl<'a> fmt::Display for Wrapper<'a> { | ||
| fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | ||
| match *self.0 { | ||
| match &*self.0 { | ||
| LogicalPlan::EmptyRelation { .. } => write!(f, "EmptyRelation"), | ||
| LogicalPlan::TableScan { | ||
| ref table_name, | ||
|
|
@@ -523,6 +541,28 @@ impl LogicalPlan { | |
| keys.iter().map(|(l, r)| format!("{} = {}", l, r)).collect(); | ||
| write!(f, "Join: {}", join_expr.join(", ")) | ||
| } | ||
| LogicalPlan::Repartition { | ||
| partitioning_scheme, | ||
| .. | ||
| } => match partitioning_scheme { | ||
| Partitioning::RoundRobinBatch(n) => { | ||
| write!( | ||
| f, | ||
| "Repartition: RoundRobinBatch partition_count={}", | ||
| n | ||
| ) | ||
| } | ||
| Partitioning::Hash(expr, n) => { | ||
| let hash_expr: Vec<String> = | ||
| expr.iter().map(|e| format!("{:?}", e)).collect(); | ||
| write!( | ||
| f, | ||
| "Repartition: Hash({}) partition_count={}", | ||
| hash_expr.join(", "), | ||
| n | ||
| ) | ||
| } | ||
| }, | ||
| LogicalPlan::Limit { ref n, .. } => write!(f, "Limit: {}", n), | ||
| LogicalPlan::CreateExternalTable { ref name, .. } => { | ||
| write!(f, "CreateExternalTable: {:?}", name) | ||
|
|
||
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 would not place it in an example since we do not support it yet.