nodedb_sql/planner/
union.rs1use sqlparser::ast::{self, SetExpr, SetOperator, SetQuantifier};
4
5use crate::error::{Result, SqlError};
6use crate::functions::registry::FunctionRegistry;
7use crate::types::*;
8
9pub fn plan_set_operation(
11 op: &SetOperator,
12 left: &SetExpr,
13 right: &SetExpr,
14 quantifier: &SetQuantifier,
15 catalog: &dyn SqlCatalog,
16 functions: &FunctionRegistry,
17) -> Result<SqlPlan> {
18 let left_plan = plan_set_expr(left, catalog, functions)?;
19 let right_plan = plan_set_expr(right, catalog, functions)?;
20
21 match op {
22 SetOperator::Union => {
23 let distinct = matches!(quantifier, SetQuantifier::Distinct | SetQuantifier::None);
24 Ok(SqlPlan::Union {
25 inputs: vec![left_plan, right_plan],
26 distinct,
27 })
28 }
29 SetOperator::Intersect => {
30 let all = matches!(quantifier, SetQuantifier::All);
31 Ok(SqlPlan::Intersect {
32 left: Box::new(left_plan),
33 right: Box::new(right_plan),
34 all,
35 })
36 }
37 SetOperator::Except => {
38 let all = matches!(quantifier, SetQuantifier::All);
39 Ok(SqlPlan::Except {
40 left: Box::new(left_plan),
41 right: Box::new(right_plan),
42 all,
43 })
44 }
45 _ => Err(SqlError::Unsupported {
46 detail: format!("set operation: {op}"),
47 }),
48 }
49}
50
51fn plan_set_expr(
52 expr: &SetExpr,
53 catalog: &dyn SqlCatalog,
54 functions: &FunctionRegistry,
55) -> Result<SqlPlan> {
56 match expr {
57 SetExpr::Select(select) => {
58 let query = ast::Query {
60 with: None,
61 body: Box::new(SetExpr::Select(select.clone())),
62 order_by: None,
63 limit_clause: None,
64 fetch: None,
65 locks: Vec::new(),
66 for_clause: None,
67 settings: None,
68 format_clause: None,
69 pipe_operators: Vec::new(),
70 };
71 super::select::plan_query(&query, catalog, functions)
72 }
73 SetExpr::SetOperation {
74 op,
75 left,
76 right,
77 set_quantifier,
78 } => plan_set_operation(op, left, right, set_quantifier, catalog, functions),
79 _ => Err(SqlError::Unsupported {
80 detail: format!("set expression: {expr}"),
81 }),
82 }
83}