uqa_sql/semantics/
parameters.rs1use std::collections::BTreeMap;
10
11pub mod arguments;
12pub mod catalog;
13pub mod custom;
14pub mod datestyle;
15pub mod definition;
16pub mod identifier_list;
17pub mod intervalstyle;
18pub mod setting;
19pub(crate) mod timezone;
20pub mod units;
21pub mod value;
22
23#[derive(Clone, Copy, Debug, PartialEq, Eq)]
24pub enum ParameterAssignment {
25 Session,
26 Local,
27 Save,
28}
29
30#[derive(Clone, Copy, Debug)]
31pub struct ParameterScope(usize);
32
33#[derive(Clone)]
35pub struct ParameterScopes<T> {
36 transaction: BTreeMap<String, T>,
37 functions: Vec<BTreeMap<String, T>>,
38}
39
40impl<T> Default for ParameterScopes<T> {
41 fn default() -> Self {
42 Self {
43 transaction: BTreeMap::new(),
44 functions: Vec::new(),
45 }
46 }
47}
48
49impl<T> ParameterScopes<T> {
50 pub fn session_assignment(&mut self, name: &str) {
52 self.transaction.remove(name);
53 for saved in &mut self.functions {
54 saved.remove(name);
55 }
56 }
57
58 pub fn enter_function(&mut self) -> ParameterScope {
59 self.functions.push(BTreeMap::new());
60 ParameterScope(self.functions.len())
61 }
62
63 pub fn leave_function(&mut self, scope: ParameterScope) -> BTreeMap<String, T> {
64 assert_eq!(scope.0, self.functions.len(), "parameter scope order");
65 self.functions.pop().expect("active parameter scope")
66 }
67
68 pub fn assigned(
70 &mut self,
71 name: String,
72 previous: T,
73 action: ParameterAssignment,
74 in_transaction: bool,
75 ) -> Option<T> {
76 match action {
77 ParameterAssignment::Session => {
78 self.session_assignment(&name);
79 }
80 ParameterAssignment::Local => {
81 if self.functions.iter().any(|saved| saved.contains_key(&name)) {
82 return None;
83 }
84 if !in_transaction {
85 return Some(previous);
86 }
87 self.transaction.entry(name).or_insert(previous);
88 }
89 ParameterAssignment::Save => {
90 self.functions
91 .last_mut()
92 .expect("function configuration requires a parameter scope")
93 .entry(name)
94 .or_insert(previous);
95 }
96 }
97 None
98 }
99
100 pub fn finish_transaction(&mut self) -> BTreeMap<String, T> {
101 std::mem::take(&mut self.transaction)
102 }
103
104 pub fn reset_all(&mut self) {
106 fn authorization(name: &str) -> bool {
107 matches!(name, "role" | "session_authorization")
108 }
109 self.transaction.retain(|name, _| authorization(name));
110 for saved in &mut self.functions {
111 saved.retain(|name, _| authorization(name));
112 }
113 }
114}
115
116#[cfg(test)]
117mod tests;