uqa_sql/plpgsql/
blocks.rs1use super::{PLpgSQLBlock, PLpgSQLFunction, PLpgSQLStmt};
9use std::collections::BTreeSet;
10impl PLpgSQLFunction {
11 pub fn block_variable_datums(&self) -> BTreeSet<usize> {
12 let mut datums = BTreeSet::new();
13 visit_block(&self.action, &mut datums);
14 datums
15 }
16}
17fn visit_block(block: &PLpgSQLBlock, output: &mut BTreeSet<usize>) {
18 output.extend(&block.initvarnos);
19 visit_statements(&block.body, output);
20 for arm in &block.exceptions {
21 visit_statements(&arm.body, output);
22 }
23}
24fn visit_statements(statements: &[PLpgSQLStmt], output: &mut BTreeSet<usize>) {
25 for statement in statements {
26 match statement {
27 PLpgSQLStmt::Block(block) => visit_block(block, output),
28 PLpgSQLStmt::If {
29 then_body,
30 elsifs,
31 else_body,
32 ..
33 } => {
34 visit_statements(then_body, output);
35 for (_, body) in elsifs {
36 visit_statements(body, output);
37 }
38 if let Some(body) = else_body {
39 visit_statements(body, output);
40 }
41 }
42 PLpgSQLStmt::Case {
43 arms, else_body, ..
44 } => {
45 for (_, body) in arms {
46 visit_statements(body, output);
47 }
48 if let Some(body) = else_body {
49 visit_statements(body, output);
50 }
51 }
52 PLpgSQLStmt::Loop { body, .. }
53 | PLpgSQLStmt::While { body, .. }
54 | PLpgSQLStmt::ForI { body, .. }
55 | PLpgSQLStmt::ForQuery { body, .. }
56 | PLpgSQLStmt::ForDynamic { body, .. }
57 | PLpgSQLStmt::ForCursor { body, .. }
58 | PLpgSQLStmt::ForeachArray { body, .. } => visit_statements(body, output),
59 _ => {}
60 }
61 }
62}