uqa_sql/semantics/
cte_names.rs1use 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}