Skip to main content

uqa_sql/plpgsql/
blocks.rs

1//
2// Unified Query Algebra
3//
4// Copyright (c) 2023-2026 Cognica, Inc.
5//
6
7//! Block-owned datums, taken directly from `PostgreSQL`'s initializer lists.
8use 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}