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;