(
left_qcx: &QueryContext,
left: HirRelationExpr,
left_scope: Scope,
join: &Join<Aug>,
)
| 3754 | } |
| 3755 | |
| 3756 | fn plan_join( |
| 3757 | left_qcx: &QueryContext, |
| 3758 | left: HirRelationExpr, |
| 3759 | left_scope: Scope, |
| 3760 | join: &Join<Aug>, |
| 3761 | ) -> Result<(HirRelationExpr, Scope), PlanError> { |
| 3762 | const ON_TRUE: JoinConstraint<Aug> = JoinConstraint::On(Expr::Value(Value::Boolean(true))); |
| 3763 | let (kind, constraint) = match &join.join_operator { |
| 3764 | JoinOperator::CrossJoin => (JoinKind::Inner, &ON_TRUE), |
| 3765 | JoinOperator::Inner(constraint) => (JoinKind::Inner, constraint), |
| 3766 | JoinOperator::LeftOuter(constraint) => (JoinKind::LeftOuter, constraint), |
| 3767 | JoinOperator::RightOuter(constraint) => (JoinKind::RightOuter, constraint), |
| 3768 | JoinOperator::FullOuter(constraint) => (JoinKind::FullOuter, constraint), |
| 3769 | }; |
| 3770 | |
| 3771 | let mut right_qcx = left_qcx.derived_context(left_scope.clone(), left_qcx.relation_type(&left)); |
| 3772 | if !kind.can_be_correlated() { |
| 3773 | for item in &mut right_qcx.outer_scopes[0].items { |
| 3774 | // Per PostgreSQL (and apparently SQL:2008), we can't simply remove |
| 3775 | // these items from scope. These items need to *exist* because they |
| 3776 | // might shadow variables in outer scopes that would otherwise be |
| 3777 | // valid to reference, but accessing them needs to produce an error. |
| 3778 | item.error_if_referenced = |
| 3779 | Some(|table, column| PlanError::WrongJoinTypeForLateralColumn { |
| 3780 | table: table.cloned(), |
| 3781 | column: column.clone(), |
| 3782 | }); |
| 3783 | } |
| 3784 | } |
| 3785 | let (right, right_scope) = plan_table_factor(&right_qcx, &join.relation)?; |
| 3786 | |
| 3787 | let (expr, scope) = match constraint { |
| 3788 | JoinConstraint::On(expr) => { |
| 3789 | let product_scope = left_scope.product(right_scope)?; |
| 3790 | let ecx = &ExprContext { |
| 3791 | qcx: left_qcx, |
| 3792 | name: "ON clause", |
| 3793 | scope: &product_scope, |
| 3794 | relation_type: &SqlRelationType::new( |
| 3795 | left_qcx |
| 3796 | .relation_type(&left) |
| 3797 | .column_types |
| 3798 | .into_iter() |
| 3799 | .chain(right_qcx.relation_type(&right).column_types) |
| 3800 | .collect(), |
| 3801 | ), |
| 3802 | allow_aggregates: false, |
| 3803 | allow_subqueries: true, |
| 3804 | allow_parameters: true, |
| 3805 | allow_windows: false, |
| 3806 | }; |
| 3807 | let on = plan_expr(ecx, expr)?.type_as(ecx, &SqlScalarType::Bool)?; |
| 3808 | let joined = left.join(right, on, kind); |
| 3809 | (joined, product_scope) |
| 3810 | } |
| 3811 | JoinConstraint::Using { columns, alias } => { |
| 3812 | let column_names = columns |
| 3813 | .iter() |
no test coverage detected