Plan a UNION / UNION ALL / INTERSECT / EXCEPT operation.
(
op: &SetOperator,
left: &SetExpr,
right: &SetExpr,
quantifier: &SetQuantifier,
catalog: &dyn SqlCatalog,
functions: &FunctionRegistry,
temporal: crate::TemporalScope,
)
| 10 | |
| 11 | /// Plan a UNION / UNION ALL / INTERSECT / EXCEPT operation. |
| 12 | pub fn plan_set_operation( |
| 13 | op: &SetOperator, |
| 14 | left: &SetExpr, |
| 15 | right: &SetExpr, |
| 16 | quantifier: &SetQuantifier, |
| 17 | catalog: &dyn SqlCatalog, |
| 18 | functions: &FunctionRegistry, |
| 19 | temporal: crate::TemporalScope, |
| 20 | ) -> Result<SqlPlan> { |
| 21 | let left_plan = plan_set_expr(left, catalog, functions, temporal)?; |
| 22 | let right_plan = plan_set_expr(right, catalog, functions, temporal)?; |
| 23 | |
| 24 | match op { |
| 25 | SetOperator::Union => { |
| 26 | let distinct = matches!(quantifier, SetQuantifier::Distinct | SetQuantifier::None); |
| 27 | Ok(SqlPlan::Union { |
| 28 | inputs: vec![left_plan, right_plan], |
| 29 | distinct, |
| 30 | }) |
| 31 | } |
| 32 | SetOperator::Intersect => { |
| 33 | let all = matches!(quantifier, SetQuantifier::All); |
| 34 | Ok(SqlPlan::Intersect { |
| 35 | left: Box::new(left_plan), |
| 36 | right: Box::new(right_plan), |
| 37 | all, |
| 38 | }) |
| 39 | } |
| 40 | SetOperator::Except => { |
| 41 | let all = matches!(quantifier, SetQuantifier::All); |
| 42 | Ok(SqlPlan::Except { |
| 43 | left: Box::new(left_plan), |
| 44 | right: Box::new(right_plan), |
| 45 | all, |
| 46 | }) |
| 47 | } |
| 48 | _ => Err(SqlError::Unsupported { |
| 49 | detail: format!("set operation: {op}"), |
| 50 | }), |
| 51 | } |
| 52 | } |
| 53 | |
| 54 | fn plan_set_expr( |
| 55 | expr: &SetExpr, |
no test coverage detected