-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Minor: reduce cloning in infer_placeholder_types
#5638
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 all commits
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 |
---|---|---|
|
@@ -78,7 +78,7 @@ impl<'a, S: ContextProvider> SqlToRel<'a, S> { | |
let mut expr = self.sql_expr_to_logical_expr(sql, schema, planner_context)?; | ||
expr = self.rewrite_partial_qualifier(expr, schema); | ||
self.validate_schema_satisfies_exprs(schema, &[expr.clone()])?; | ||
let expr = infer_placeholder_types(expr, schema.clone())?; | ||
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. This cloned the schema as well as cloning all BinaryExprs |
||
let expr = infer_placeholder_types(expr, schema)?; | ||
Ok(expr) | ||
} | ||
|
||
|
@@ -499,36 +499,33 @@ impl<'a, S: ContextProvider> SqlToRel<'a, S> { | |
} | ||
} | ||
|
||
/// Find all `PlaceHolder` tokens in a logical plan, and try to infer their type from context | ||
fn infer_placeholder_types(expr: Expr, schema: DFSchema) -> Result<Expr> { | ||
rewrite_expr(expr, |expr| { | ||
let expr = match expr { | ||
Expr::BinaryExpr(BinaryExpr { left, op, right }) => { | ||
let left = (*left).clone(); | ||
let right = (*right).clone(); | ||
let lt = left.get_type(&schema); | ||
let rt = right.get_type(&schema); | ||
let left = match (&left, rt) { | ||
(Expr::Placeholder { id, data_type }, Ok(dt)) => Expr::Placeholder { | ||
id: id.clone(), | ||
data_type: Some(data_type.clone().unwrap_or(dt)), | ||
}, | ||
_ => left.clone(), | ||
}; | ||
let right = match (&right, lt) { | ||
(Expr::Placeholder { id, data_type }, Ok(dt)) => Expr::Placeholder { | ||
id: id.clone(), | ||
data_type: Some(data_type.clone().unwrap_or(dt)), | ||
}, | ||
_ => right.clone(), | ||
}; | ||
Expr::BinaryExpr(BinaryExpr { | ||
left: Box::new(left), | ||
op, | ||
right: Box::new(right), | ||
}) | ||
// modifies expr if it is a placeholder with datatype of right | ||
fn rewrite_placeholder(expr: &mut Expr, other: &Expr, schema: &DFSchema) -> Result<()> { | ||
if let Expr::Placeholder { id: _, data_type } = expr { | ||
if data_type.is_none() { | ||
let other_dt = other.get_type(schema); | ||
match other_dt { | ||
Err(e) => { | ||
return Err(e.context(format!( | ||
"Can not find type of {other} needed to infer type of {expr}" | ||
)))?; | ||
} | ||
Ok(dt) => { | ||
*data_type = Some(dt); | ||
} | ||
} | ||
_ => expr.clone(), | ||
}; | ||
} | ||
Ok(()) | ||
} | ||
|
||
/// Find all [`Expr::PlaceHolder`] tokens in a logical plan, and try to infer their type from context | ||
fn infer_placeholder_types(expr: Expr, schema: &DFSchema) -> Result<Expr> { | ||
rewrite_expr(expr, |mut expr| { | ||
// Default to assuming the arguments are the same type | ||
if let Expr::BinaryExpr(BinaryExpr { left, op: _, right }) = &mut expr { | ||
rewrite_placeholder(left.as_mut(), right.as_ref(), schema)?; | ||
rewrite_placeholder(right.as_mut(), left.as_ref(), schema)?; | ||
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. Much more concise! 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. Nice! :) |
||
}; | ||
Ok(expr) | ||
}) | ||
|
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.
Yay, thank you! I'm happy to see this being used and improved.
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.
Yeah, it is really nice -- thanks for adding it!