Skip to main content

uqa_sql/semantics/
parameters.rs

1//
2// Unified Query Algebra
3//
4// Copyright (c) 2023-2026 Cognica, Inc.
5//
6
7//! Configuration parameters: their definitions and values, and the lifetimes of SET, SET LOCAL and temporary function configuration over values the host retains.
8
9use 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/// Values remain owned by the host; SQL decides which assignment lifetime restores them.
34#[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    /// A session assignment supersedes pending LOCAL and function configuration restoration for this parameter.
51    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    /// Record a successful assignment. An out-of-transaction LOCAL returns its immediate restoration value.
69    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    /// RESET ALL overrides ordinary settings while leaving both authorization parameters alone.
105    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;