risingwave_frontend/planner/
set_operation.rs

1// Copyright 2025 RisingWave Labs
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use risingwave_common::util::column_index_mapping::ColIndexMapping;
16
17use crate::PlanRef;
18use crate::binder::{BoundSetExpr, BoundSetOperation};
19use crate::error::Result;
20use crate::optimizer::plan_node::{LogicalExcept, LogicalIntersect, LogicalProject, LogicalUnion};
21use crate::planner::Planner;
22
23impl Planner {
24    pub(super) fn plan_set_operation(
25        &mut self,
26        op: BoundSetOperation,
27        all: bool,
28        corresponding_col_indices: Option<(ColIndexMapping, ColIndexMapping)>,
29        left: BoundSetExpr,
30        right: BoundSetExpr,
31    ) -> Result<PlanRef> {
32        let left = self.plan_set_expr(left, vec![], &[])?;
33        let right = self.plan_set_expr(right, vec![], &[])?;
34
35        // Map the corresponding columns
36        let (left, right) = if let Some((mapping_l, mapping_r)) = corresponding_col_indices {
37            (
38                LogicalProject::with_mapping(left, mapping_l).into(),
39                LogicalProject::with_mapping(right, mapping_r).into(),
40            )
41        } else {
42            (left, right)
43        };
44
45        match op {
46            BoundSetOperation::Union => Ok(LogicalUnion::create(all, vec![left, right])),
47            BoundSetOperation::Intersect => Ok(LogicalIntersect::create(all, vec![left, right])),
48            BoundSetOperation::Except => Ok(LogicalExcept::create(all, vec![left, right])),
49        }
50    }
51}