Skip to main content

uqa_sql/catalog/
temporary_namespace.rs

1//
2// Unified Query Algebra
3//
4// Copyright (c) 2023-2026 Cognica, Inc.
5//
6
7//! A session's temporary namespace, `pg_temp_N`, and the TOAST namespace that accompanies it, `pg_toast_temp_N`. The session's first temporary object creates both, as `InitTempTableNamespace` does, each taking the database counter's next OID before the object takes its own; a rollback past that creation forgets them, and the session's next temporary object creates them anew.
8
9/// The name prefix of every temporary namespace, which a session's number completes.
10pub const TEMPORARY_SCHEMA_PREFIX: &str = "pg_temp_";
11/// The name prefix of every temporary namespace's TOAST namespace.
12pub const TEMPORARY_TOAST_SCHEMA_PREFIX: &str = "pg_toast_temp_";
13
14/// The OIDs of a session's temporary namespace and of its TOAST namespace, allocated in that order.
15#[derive(Debug, Clone, Copy, PartialEq, Eq)]
16pub struct TemporaryNamespaceOids {
17    pub namespace: u32,
18    pub toast_namespace: u32,
19}
20
21/// A session's created temporary namespace as the catalog shows it.
22#[derive(Debug, Clone, PartialEq, Eq)]
23pub struct TemporaryNamespace {
24    /// `pg_temp_N`.
25    pub schema: String,
26    pub oids: TemporaryNamespaceOids,
27}
28
29impl TemporaryNamespace {
30    /// `pg_toast_temp_N`, named by the temporary namespace's number.
31    pub fn toast_schema(&self) -> String {
32        temporary_toast_schema_name(&self.schema)
33    }
34
35    /// The OID of `name` when it names the temporary namespace or its TOAST namespace.
36    pub fn namespace_oid(&self, name: &str) -> Option<u32> {
37        if name == self.schema {
38            Some(self.oids.namespace)
39        } else if name == self.toast_schema() {
40            Some(self.oids.toast_namespace)
41        } else {
42            None
43        }
44    }
45
46    /// Whether `oid` is the temporary namespace's or its TOAST namespace's.
47    pub fn holds_oid(&self, oid: i64) -> bool {
48        oid == i64::from(self.oids.namespace) || oid == i64::from(self.oids.toast_namespace)
49    }
50}
51
52/// The TOAST namespace name that accompanies the temporary namespace `schema`.
53pub fn temporary_toast_schema_name(schema: &str) -> String {
54    let number = schema
55        .strip_prefix(TEMPORARY_SCHEMA_PREFIX)
56        .unwrap_or(schema);
57    format!("{TEMPORARY_TOAST_SCHEMA_PREFIX}{number}")
58}
59
60/// Whether `name` names some session's temporary namespace or its TOAST namespace, as `isAnyTempNamespace` decides by the name alone.
61pub fn is_temporary_schema_name(name: &str) -> bool {
62    name.starts_with(TEMPORARY_SCHEMA_PREFIX) || name.starts_with(TEMPORARY_TOAST_SCHEMA_PREFIX)
63}
64
65#[cfg(test)]
66mod tests;