-
Notifications
You must be signed in to change notification settings - Fork 1.8k
Handle columns in with_new_exprs with a Join #15055
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 4 commits
be296ab
a8db03a
0482e9f
bd8c18d
65974e6
f97cf6c
daf1744
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 | ||||
|---|---|---|---|---|---|---|
|
|
@@ -906,28 +906,43 @@ impl LogicalPlan { | |||||
| let equi_expr_count = on.len(); | ||||||
| assert!(expr.len() >= equi_expr_count); | ||||||
|
|
||||||
| let col_pair_count = | ||||||
| expr.iter().filter(|e| matches!(e, Expr::Column(_))).count() / 2; | ||||||
|
|
||||||
| // Assume that the last expr, if any, | ||||||
| // is the filter_expr (non equality predicate from ON clause) | ||||||
| let filter_expr = if expr.len() > equi_expr_count { | ||||||
| let filter_expr = if expr.len() - col_pair_count > equi_expr_count { | ||||||
| expr.pop() | ||||||
| } else { | ||||||
| None | ||||||
| }; | ||||||
|
|
||||||
| // The first part of expr is equi-exprs, | ||||||
| // and the struct of each equi-expr is like `left-expr = right-expr`. | ||||||
| assert_eq!(expr.len(), equi_expr_count); | ||||||
| let new_on = expr.into_iter().map(|equi_expr| { | ||||||
| assert_eq!(expr.len() - col_pair_count, equi_expr_count); | ||||||
| let mut new_on = Vec::new(); | ||||||
|
||||||
| let mut iter = expr.into_iter(); | ||||||
| while let Some(equi_expr) = iter.next() { | ||||||
| // SimplifyExpression rule may add alias to the equi_expr. | ||||||
| let unalias_expr = equi_expr.clone().unalias(); | ||||||
| if let Expr::BinaryExpr(BinaryExpr { left, op: Operator::Eq, right }) = unalias_expr { | ||||||
| Ok((*left, *right)) | ||||||
| } else { | ||||||
| internal_err!( | ||||||
| "The front part expressions should be an binary equality expression, actual:{equi_expr}" | ||||||
| ) | ||||||
| match unalias_expr { | ||||||
| Expr::BinaryExpr(BinaryExpr { | ||||||
| left, | ||||||
| op: Operator::Eq, | ||||||
| right, | ||||||
| }) => new_on.push((*left, *right)), | ||||||
| left @ Expr::Column(_) => { | ||||||
| let Some(right) = iter.next() else { | ||||||
| internal_err!("Expected a pair of columns to construct the join on expression")? | ||||||
| }; | ||||||
|
|
||||||
| new_on.push((left, right)); | ||||||
| } | ||||||
| _ => internal_err!( | ||||||
| "The front part expressions should be a binary equality expression or a column expression, actual:{equi_expr}" | ||||||
|
||||||
| "The front part expressions should be a binary equality expression or a column expression, actual:{equi_expr}" | |
| "The front part expressions should be a binary equality expression or a column expression, actual: {equi_expr}" |
Outdated
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.
| fn test_join_with_new_exprs() { | |
| fn test_join_with_new_exprs() -> Result<()> { |
Make the function fallible so that many unwrap's can be replaced with ?
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.
The filter can also be a column expression if it's a boolean column. And the on expression may not be a column expr, e.g.
select * from t1 join t2 on t1.a+2 = t2.a+1 where t2.b.I think we don't need to match expr types; we just extract them according to the format returned by
apply_expressions(), where the firston.len() * 2elements are the on-expression pairs, and the last one is the filter expression.