Skip to main content

uqa_sql/semantics/
cte_names.rs

1//
2// Unified Query Algebra
3//
4// Copyright (c) 2023-2026 Cognica, Inc.
5//
6
7//! Enumerate the CTE names owned by a query and its sources.
8
9use crate::plan::{QueryPlan, RelationalPlan, SourcePlan};
10use std::collections::BTreeSet;
11
12pub fn query_cte_names(plan: &QueryPlan) -> BTreeSet<String> {
13    let mut names = BTreeSet::new();
14    collect_query_cte_names(plan, &mut names);
15    names
16}
17
18pub fn collect_query_cte_names(plan: &QueryPlan, names: &mut BTreeSet<String>) {
19    for cte in &plan.ctes {
20        names.insert(cte.name.clone());
21        collect_cte_body_names(&cte.body, names);
22    }
23    match &plan.root {
24        RelationalPlan::QueryBlock(block) => {
25            if let Some(source) = &block.from {
26                collect_source_query_cte_names(source, names);
27            }
28        }
29        RelationalPlan::SetOp { left, right, .. } => {
30            collect_query_cte_names(left, names);
31            collect_query_cte_names(right, names);
32        }
33        RelationalPlan::Values { .. } => {}
34    }
35}
36
37fn collect_cte_body_names(body: &crate::plan::CtePlanBody, names: &mut BTreeSet<String>) {
38    match body {
39        crate::plan::CtePlanBody::Query(query) => collect_query_cte_names(query, names),
40        crate::plan::CtePlanBody::Command(command) => {
41            for cte in command.ctes() {
42                names.insert(cte.name.clone());
43                collect_cte_body_names(&cte.body, names);
44            }
45            for query in command.query_inputs() {
46                collect_query_cte_names(query, names);
47            }
48            if let Some(source) = command.source_input() {
49                collect_source_query_cte_names(source, names);
50            }
51        }
52    }
53}
54
55pub fn collect_source_query_cte_names(source: &SourcePlan, names: &mut BTreeSet<String>) {
56    match source {
57        SourcePlan::Join { left, right, .. } => {
58            collect_source_query_cte_names(left, names);
59            collect_source_query_cte_names(right, names);
60        }
61        SourcePlan::Subquery { body, .. } => collect_query_cte_names(body, names),
62        SourcePlan::Table { .. }
63        | SourcePlan::Values { .. }
64        | SourcePlan::Function { .. }
65        | SourcePlan::FunctionGroup { .. } => {}
66    }
67}