Apply a join with both explicit equijoin and non equijoin predicates. Note this is a low level API that requires identifying specific predicate types. Most users should use [`join_on`](Self::join_on) that automatically identifies predicates appropriately. `equi_exprs` defines equijoin predicates, of the form `l = r)` for each `(l, r)` tuple. `l`, the first element of the tuple, must only refer
(
self,
right: LogicalPlan,
join_type: JoinType,
equi_exprs: (Vec<impl Into<Expr>>, Vec<impl Into<Expr>>),
filter: Option<Expr>,
)
| 1454 | /// join. Note that `equi_exprs` predicates are evaluated more efficiently |
| 1455 | /// than the filter expressions, so they are preferred. |
| 1456 | pub fn join_with_expr_keys( |
| 1457 | self, |
| 1458 | right: LogicalPlan, |
| 1459 | join_type: JoinType, |
| 1460 | equi_exprs: (Vec<impl Into<Expr>>, Vec<impl Into<Expr>>), |
| 1461 | filter: Option<Expr>, |
| 1462 | ) -> Result<Self> { |
| 1463 | if equi_exprs.0.len() != equi_exprs.1.len() { |
| 1464 | return plan_err!("left_keys and right_keys were not the same length"); |
| 1465 | } |
| 1466 | |
| 1467 | let join_key_pairs = equi_exprs |
| 1468 | .0 |
| 1469 | .into_iter() |
| 1470 | .zip(equi_exprs.1) |
| 1471 | .map(|(l, r)| { |
| 1472 | let left_key = l.into(); |
| 1473 | let right_key = r.into(); |
| 1474 | let mut left_using_columns = HashSet::new(); |
| 1475 | expr_to_columns(&left_key, &mut left_using_columns)?; |
| 1476 | let normalized_left_key = normalize_col_with_schemas_and_ambiguity_check( |
| 1477 | left_key, |
| 1478 | &[&[self.plan.schema()]], |
| 1479 | &[], |
| 1480 | )?; |
| 1481 | |
| 1482 | let mut right_using_columns = HashSet::new(); |
| 1483 | expr_to_columns(&right_key, &mut right_using_columns)?; |
| 1484 | let normalized_right_key = normalize_col_with_schemas_and_ambiguity_check( |
| 1485 | right_key, |
| 1486 | &[&[right.schema()]], |
| 1487 | &[], |
| 1488 | )?; |
| 1489 | |
| 1490 | // find valid equijoin |
| 1491 | find_valid_equijoin_key_pair( |
| 1492 | &normalized_left_key, |
| 1493 | &normalized_right_key, |
| 1494 | self.plan.schema(), |
| 1495 | right.schema(), |
| 1496 | )?.ok_or_else(|| |
| 1497 | plan_datafusion_err!( |
| 1498 | "can't create join plan, join key should belong to one input, error key: ({normalized_left_key},{normalized_right_key})" |
| 1499 | )) |
| 1500 | }) |
| 1501 | .collect::<Result<Vec<_>>>()?; |
| 1502 | |
| 1503 | let join = Join::try_new( |
| 1504 | self.plan, |
| 1505 | Arc::new(right), |
| 1506 | join_key_pairs, |
| 1507 | filter, |
| 1508 | join_type, |
| 1509 | JoinConstraint::On, |
| 1510 | NullEquality::NullEqualsNothing, |
| 1511 | false, // null_aware |
| 1512 | )?; |
| 1513 |